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