Salome HOME
CurveCreator widget: mask detection mode, not implemented
[modules/geom.git] / src / AdvancedEngine / AdvancedEngine_PipeTShapeDriver.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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 "AdvancedEngine_PipeTShapeDriver.hxx"
21 #include "AdvancedEngine_IPipeTShape.hxx"
22 #include "AdvancedEngine_Types.hxx"
23 #include "AdvancedEngine_IOperations.hxx"
24
25 #include "GEOMImpl_Block6Explorer.hxx"
26 #include "GEOM_Function.hxx"
27 #include "GEOM_IOperations.hxx"
28 #include "GEOMUtils.hxx"
29 #include "GEOMAlgo_FinderShapeOn2.hxx"
30 #include "GEOMAlgo_ClsfBox.hxx"
31 #include "GEOMAlgo_ClsfSurf.hxx"
32 #include "GEOMAlgo_Splitter.hxx"
33
34 #include "Geom_CylindricalSurface.hxx"
35 #include <gp_Pnt.hxx>
36 #include <gp_Vec.hxx>
37 #include <gp_Ax2.hxx>
38 #include <gp_Pln.hxx>
39 #include <gp_Dir.hxx>
40 #include <gp_Trsf.hxx>
41 #include <TFunction_Logbook.hxx>
42 #include <StdFail_NotDone.hxx>
43 #include <BRepPrimAPI_MakeCone.hxx>
44 #include <BRepPrimAPI_MakeCylinder.hxx>
45 #include <BRepAlgoAPI_Fuse.hxx>
46 #include <BRepAlgoAPI_Cut.hxx>
47 #include <BRepPrimAPI_MakeBox.hxx>
48 #include <BRepBuilderAPI_MakeEdge.hxx>
49 #include <BRepBuilderAPI_MakeFace.hxx>
50 #include <BRepBuilderAPI_MakeWire.hxx>
51 #include <BRepBuilderAPI_Transform.hxx>
52 #include <BRepFilletAPI_MakeFillet.hxx>
53 #include <BRepFilletAPI_MakeChamfer.hxx>
54 #include <BRep_Builder.hxx>
55 #include <TopoDS_Compound.hxx>
56 #include <TopExp.hxx>
57 #include <TopExp_Explorer.hxx>
58 #include <BRep_Tool.hxx>
59 #include <BRepTools.hxx>
60 #include <TopoDS.hxx>
61 #include <TopTools_IndexedMapOfShape.hxx>
62 #include <TopTools_ListIteratorOfListOfShape.hxx>
63
64 #include <vector>
65
66 // Undefine below macro to enable workaround about problem with wrong 
67 // tolerances of intersection curves in MakePipeTShape and MakeQuarterPipeTShape
68 // VSR 30/12/2014: macro enabled
69 #define FIX_CURVES_TOLERANCES
70
71 //=======================================================================
72 //function : GetID
73 //purpose  :
74 //=======================================================================
75 const Standard_GUID& AdvancedEngine_PipeTShapeDriver::GetID()
76 {
77   static Standard_GUID aGUID("1C3A0F3F-729D-4E83-8232-78E74FC5637C");
78   return aGUID;
79 }
80
81 //=======================================================================
82 //function : AdvancedEngine_PipeTShapeDriver
83 //purpose  :
84 //=======================================================================
85 AdvancedEngine_PipeTShapeDriver::AdvancedEngine_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 AdvancedEngine_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 (!GEOMUtils::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_FinderShapeOn2.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   AdvancedEngine_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 (!GEOMUtils::CheckTriangulation(theShape)) {
183     StdFail_NotDone::Raise("Cannot build triangulation on the shape");
184     return aSeqOfIDs;
185   }
186
187   // Call algo
188   GEOMAlgo_FinderShapeOn2   aFinder;
189   Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
190   Standard_Real             aTol      = 1e-6;
191
192   aClsfSurf->SetSurface(theSurface);
193   aFinder.SetShape(theShape);
194   aFinder.SetTolerance(aTol);
195   aFinder.SetClsf(aClsfSurf);
196   aFinder.SetShapeType(theShapeType);
197   aFinder.SetState(theState);
198
199   // Sets the minimal number of inner points for the faces that do not have own
200   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
201   // Default value=3
202   aFinder.SetNbPntsMin(3);
203   // Sets the maximal number of inner points for edges or faces.
204   // It is usefull for the cases when this number is very big (e.g =2000) to improve
205   // the performance. If this value =0, all inner points will be taken into account.
206   // Default value=0
207   aFinder.SetNbPntsMax(0);
208
209   aFinder.Perform();
210
211   // Interprete results
212   Standard_Integer iErr = aFinder.ErrorStatus();
213   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
214   if (iErr) {
215 //    MESSAGE(" iErr : " << iErr);
216     TCollection_AsciiString aMsg (" iErr : ");
217     aMsg += TCollection_AsciiString(iErr);
218     StdFail_NotDone::Raise(aMsg.ToCString());
219     return aSeqOfIDs;
220   }
221 //  Standard_Integer iWrn = aFinder.WarningStatus();
222   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
223 //  if (iWrn) {
224 //    MESSAGE(" *** iWrn : " << iWrn);
225 //  }
226
227   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
228
229   if (listSS.Extent() < 1) {
230     //StdFail_NotDone::Raise("Not a single sub-shape of the requested type found on the given surface");
231     StdFail_NotDone::Raise(NOT_FOUND_ANY); // NPAL18017
232     return aSeqOfIDs;
233   }
234
235   // Fill sequence of object IDs
236   aSeqOfIDs = new TColStd_HSequenceOfInteger;
237
238   TopTools_IndexedMapOfShape anIndices;
239   TopExp::MapShapes(theShape, anIndices);
240
241   TopTools_ListIteratorOfListOfShape itSub (listSS);
242   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
243     int id = anIndices.FindIndex(itSub.Value());
244     aSeqOfIDs->Append(id);
245   }
246
247   return aSeqOfIDs;
248 }
249
250 //=======================================================================
251 //function : GetCommonShapesOnCylinders
252 //purpose  : return the common shapes between 2 cylindrical surfaces
253 //           along OX and OZ
254 //=======================================================================
255 void AdvancedEngine_PipeTShapeDriver::GetCommonShapesOnCylinders(const TopoDS_Shape& theShape,
256                                                            TopAbs_ShapeEnum theShapeType,
257                                                            double r1,
258                                                            double r2,
259                                                            Handle(TopTools_HSequenceOfShape)& commonShapes) const
260 {
261   gp_Pnt aP0 (0, 0, 0);
262   gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
263   gp_Ax3 anAxis1 (aP0, aVX, aVZ), anAxis2 (aP0, aVZ, aVX);
264
265   TopTools_IndexedMapOfShape aMapOfShapes;
266   aMapOfShapes.Clear();
267   TopExp::MapShapes(theShape, aMapOfShapes);
268
269   commonShapes->Clear();
270
271   int myID;
272   bool found = false;
273
274   // Create a cylinder surface
275   Handle(Geom_Surface) aC1Ext = new Geom_CylindricalSurface(anAxis1, r1);
276   if ( aC1Ext.IsNull() )
277     StdFail_NotDone::Raise("Couldn't build main cylindrical surface");
278   // Find object IDs
279   Handle(TColStd_HSequenceOfInteger) aSeqExt1 = GetShapesOnSurfaceIDs( aC1Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
280   // Create a cylinder surface
281   Handle(Geom_Surface) aC2Ext = new Geom_CylindricalSurface(anAxis2, r2);
282   if ( aC2Ext.IsNull() )
283     StdFail_NotDone::Raise("Couldn't build incident cylindrical surface");
284   // Find object IDs
285   Handle(TColStd_HSequenceOfInteger) aSeqExt2 = GetShapesOnSurfaceIDs( aC2Ext, theShape, theShapeType, GEOMAlgo_ST_ON );
286   // # Recherche (dans le quart de Te) de l'arete d'intersection des 2 cylindres
287   // # Search in theShape for common shape of type theShapeType on the intersection of 2 pipes
288   found = false;
289   for (int i=1; i<=aSeqExt2->Length();i++) {
290 //    std::cerr << "aSeqExt2->Value(i): " << aSeqExt2->Value(i) << std::endl;
291     for (int j=1; j<=aSeqExt1->Length();j++) {
292 //      std::cerr << "aSeqExt1->Value(j): " << aSeqExt1->Value(j) << std::endl;
293       if (aSeqExt1->Value(j) == aSeqExt2->Value(i)) {
294         myID = aSeqExt1->Value(j);
295         commonShapes->Append(aMapOfShapes.FindKey(myID));
296         found = true;
297       }
298     }
299   }
300   if (!found)
301     StdFail_NotDone::Raise("Common shapes couldn't be found");
302 }
303
304 //=======================================================================
305 //function : MakePipeTShape
306 //purpose  :
307 //=======================================================================
308 TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakePipeTShape (const double r1, const double w1, const double l1,
309                                                               const double r2, const double w2, const double l2) const
310 {
311   double r1Ext = r1 + w1;
312   double r2Ext = r2 + w2;
313
314   gp_Pnt aP0 (0, 0, 0);
315   gp_Pnt aP1 (-l1, 0, 0);
316   gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
317   gp_Ax2 anAxes1 (aP1, aVX, aVZ);
318   gp_Ax2 anAxes2 (aP0, aVZ, aVX);
319
320   // Build the initial pipes
321   BRepPrimAPI_MakeCylinder C1Int (anAxes1, r1, Abs(2 * l1));
322   BRepPrimAPI_MakeCylinder C1Ext (anAxes1, r1Ext, Abs(2 * l1));
323   BRepPrimAPI_MakeCylinder C2Int (anAxes2, r2, Abs(l2));
324   BRepPrimAPI_MakeCylinder C2Ext (anAxes2, r2Ext, Abs(l2));
325   C1Int.Build();
326   C1Ext.Build();
327   C2Int.Build();
328   C2Ext.Build();
329   if (!C1Int.IsDone() || !C1Ext.IsDone() || !C2Int.IsDone() || !C2Ext.IsDone()) {
330     StdFail_NotDone::Raise("Cannot build cylinders");
331   }
332
333   // Fuse the 2 pipes
334   BRepAlgoAPI_Fuse fuse1 (C1Ext.Shape(), C2Ext.Shape());
335   if (!fuse1.IsDone()) {
336     StdFail_NotDone::Raise("Cannot fuse cylinders");
337   }
338
339   // Remove small radius main pipe
340   BRepAlgoAPI_Cut cut1 (fuse1.Shape(), C1Int.Shape());
341   if (!cut1.IsDone()) {
342     StdFail_NotDone::Raise("Coudn't cut cylinders");
343   }
344
345   // Remove small radius incident pipe => Te
346   BRepAlgoAPI_Cut Te (cut1.Shape(), C2Int.Shape());
347   if (!Te.IsDone()) {
348     StdFail_NotDone::Raise("Coudn't cut cylinders");
349   }
350
351   TopoDS_Shape aShape = Te.Shape();
352
353   // VSR: 30/12/2014: temporary workaround about intersection curves problem
354 #ifdef FIX_CURVES_TOLERANCES
355   GEOMUtils::FixShapeCurves(aShape);
356 #endif
357
358   return aShape;
359 }
360
361 //=======================================================================
362 //function : MakeQuarterPipeTShape
363 //purpose  :
364 //=======================================================================
365 TopoDS_Shape AdvancedEngine_PipeTShapeDriver::MakeQuarterPipeTShape (const double r1, const double w1, const double l1,
366                                                                      const double r2, const double w2, const double l2) const
367 {
368   TopoDS_Shape Te = MakePipeTShape(r1, w1, l1, r2, w2, l2);
369   if (Te.IsNull())
370     StdFail_NotDone::Raise("Couldn't build Pipe TShape");
371
372   // Get a quarter of shape => Te2
373   double r1Ext = r1 + w1;
374   BRepPrimAPI_MakeBox box1 (gp_Pnt(0, -2*r1Ext, -2*r1Ext), gp_Pnt( Abs(2 * l1), 2*r1Ext, Abs(2*l2)));
375   BRepPrimAPI_MakeBox box2 (gp_Pnt(0,  2*r1Ext, -2*r1Ext), gp_Pnt(-Abs(2 * l1), 0,       Abs(2*l2)));
376   box1.Build();
377   box2.Build();
378   if (!box1.IsDone() || !box2.IsDone()) {
379     StdFail_NotDone::Raise("Couldn't build boxes");
380   }
381   BRepAlgoAPI_Cut cut3 (Te, box1.Shape());
382   if (!cut3.IsDone()) {
383     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
384   }
385   BRepAlgoAPI_Cut Te4 (cut3.Shape(), box2.Shape());
386   if (!Te4.IsDone()) {
387     StdFail_NotDone::Raise("Couldn't cut Pipe Tshape with box");
388   }
389
390   TopoDS_Shape aShape = Te4.Shape();
391
392   // VSR: 30/12/2014: temporary workaround about intersection curves problem
393 #ifdef FIX_CURVES_TOLERANCES
394   GEOMUtils::FixShapeCurves(aShape);
395 #endif
396
397   return Te4.Shape();
398 }
399
400 //=======================================================================
401 //function : Execute
402 //purpose  :
403 //=======================================================================
404 Standard_Integer AdvancedEngine_PipeTShapeDriver::Execute (TFunction_Logbook& log) const
405 {
406   if (Label().IsNull()) return 0;
407   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
408
409   AdvancedEngine_IPipeTShape aData (aFunction);
410   Standard_Integer aType = aFunction->GetType();
411
412   TopoDS_Shape aShape, Te4, Te4Part;
413   //TopoDS_Edge arete_intersect_int;
414   //Handle(TopTools_HSequenceOfShape) edges_e = new TopTools_HSequenceOfShape;
415   Handle(TColStd_HSequenceOfInteger) edges_e;
416   //Handle(TopTools_HSequenceOfShape) edges_i = new TopTools_HSequenceOfShape;
417   //gp_Pnt aP0 (0, 0, 0);
418   //gp_Vec aVX = gp::DX(), aVY = gp::DY(), aVZ = gp::DZ();
419   bool hexMesh = (bool) aData.GetHexMesh();
420
421   // Useful values
422   //double aSize = 2*(aData.GetL1() + aData.GetL2());
423   double epsilon = Precision::Approximation();
424   double aR1Ext = aData.GetR1() + aData.GetW1();
425   double aR2Ext = aData.GetR2() + aData.GetW2();
426
427   if (aData.GetR2() > aData.GetR1() + epsilon) {
428     StdFail_NotDone::Raise("TShape cannot be computed if R2 > R1");
429   }
430
431   if (aR2Ext > aR1Ext + epsilon) {
432     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 > R1+W1");
433   }
434
435   // external radius are equal
436   if (fabs(aR2Ext - aR1Ext) < epsilon) {
437     if (aType == TSHAPE_CHAMFER)
438       StdFail_NotDone::Raise("TShape with chamfer cannot be computed if R2+W2 = R1+W1");
439     if (aType == TSHAPE_FILLET)
440       StdFail_NotDone::Raise("TShape with fillet cannot be computed if R2+W2 = R1+W1");
441     // internal radius are different => not possible
442     if (fabs(aData.GetR2() - aData.GetR1()) > epsilon) {
443       StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 = R1+W1 and R2 != R1");
444     }
445   }
446
447   if (aR1Ext >= aData.GetL2() + epsilon) {
448     StdFail_NotDone::Raise("TShape cannot be computed if R1+W1 >= L2");
449   }
450   if (aR2Ext >= aData.GetL1() + epsilon) {
451     StdFail_NotDone::Raise("TShape cannot be computed if R2+W2 >= L1");
452   }
453
454   if (aType == TSHAPE_CHAMFER) {
455     if (aData.GetH() >= (aData.GetL2() - aR1Ext + epsilon)) {
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     TopTools_IndexedDataMapOfShapeListOfShape M;
522     GEOMImpl_Block6Explorer::MapShapesAndAncestors(Te4, TopAbs_EDGE, TopAbs_FACE, M);
523 //     std::cerr << "Number of IDs: " << edges_e->Length() << std::endl;
524     int nbEdgesInChamfer = 0;
525     for (int i=1;i<=edges_e->Length();i++) {
526 //       std::cerr << "Get Edge with ID #" << i << std::endl;
527       int theId = edges_e->Value(i);
528 //       std::cerr << "ID #" << i << "= " << theId << std::endl;
529 //       std::cerr << "Search for edge in shape" << std::endl;
530       TopoDS_Edge theEdge = TopoDS::Edge(anEdgesIndices.FindKey(theId));
531 //       std::cerr << "Found" << std::endl;
532 //       std::cerr << "Keep only edges with a vertex on (x, x, re1)" << std::endl;
533       TopExp_Explorer ExVertices;
534       for (ExVertices.Init(theEdge,TopAbs_VERTEX); ExVertices.More(); ExVertices.Next()) {
535         gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(ExVertices.Current()));
536         if (aPt.Z() - aR1Ext <= epsilon) {
537 //           std::cerr << "aPt.Z() = aR1Ext => keep this edge" << std::endl;
538           nbEdgesInChamfer ++;
539           const TopTools_ListOfShape& aFL = M.FindFromKey(theEdge);
540           TopoDS_Face F = TopoDS::Face( aFL.First() );
541           if (hexMesh)
542             chamfer.Add(aData.GetH(), aData.GetW(), theEdge, F);
543           else
544             chamfer.Add(aData.GetW(), aData.GetH(), theEdge, F);
545           break;
546         }
547       }
548 //       std::cerr << "Test if hexMesh: ";
549       if (hexMesh && nbEdgesInChamfer == 1) {
550 //         std::cerr << "Yes => stop after 1 edge" << std::endl;
551         break;
552       }
553 //       std::cerr << "No => continue for other edges" << std::endl;
554   //  BB.Add(CC, edges_e->Value(i));
555   //  const TopTools_ListOfShape& aFL = M.FindFromKey(TopoDS::Edge(edges_e->Value(i)));
556   //  chamfer.Add(aData.GetW(), aData.GetH(), TopoDS::Edge(edges_e->Value(i)), F);
557     }
558 //     std::cerr << "Build chamfer with " << nbEdgesInChamfer << " edges" << std::endl;
559 //     }
560     chamfer.Build();
561     if (!chamfer.IsDone()) {
562       StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
563     }
564
565 //     BB.Add(CC, chamfer.Shape());
566
567 //     aShape = CC;
568     aShape = chamfer.Shape();
569   }
570   else if (aType == TSHAPE_FILLET) {
571     // TShape with fillet
572     // Create fillet on the edge arete_intersect_ext
573     BRepFilletAPI_MakeFillet fill (Te4);
574
575     TopTools_IndexedMapOfShape anIndices;
576     TopExp::MapShapes(Te4, anIndices);
577
578     TopoDS_Shape theBox;
579     if (hexMesh) {
580       BRepPrimAPI_MakeBox aBox (gp_Pnt(0,0,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
581       aBox.Build();
582       if (!aBox.IsDone()) {
583         StdFail_NotDone::Raise("Couldn't build box");
584       }
585       theBox = aBox.Shape();
586     }
587     else {
588       BRepPrimAPI_MakeBox aBox (gp_Pnt(aR2Ext,aR2Ext,0),gp_Pnt(-aR2Ext, -aR2Ext, aR1Ext));
589       aBox.Build();
590       if (!aBox.IsDone()) {
591         StdFail_NotDone::Raise("Couldn't build box");
592       }
593       theBox = aBox.Shape();
594     }
595     Handle(TColStd_HSequenceOfInteger) edges_e = new TColStd_HSequenceOfInteger;
596     edges_e = GetShapesOnBoxIDs(theBox, Te4, TopAbs_EDGE, GEOMAlgo_ST_IN);
597     if (edges_e.IsNull() || edges_e->Length() == 0) {
598       StdFail_NotDone::Raise("Common edges not found");
599     }
600
601 //     fill.Add(TopoDS::Edge(edges_e->Value(1)));
602 //     if (!hexMesh) {
603     for (int i=1;i<=edges_e->Length();i++) {
604       if (hexMesh && (i > 1))
605         break;
606       TopoDS_Edge theEdge = TopoDS::Edge(anIndices.FindKey(edges_e->Value(i)));
607       fill.Add(theEdge);
608 //             fill.Add(TopoDS::Edge(edges_e->Value(i)));
609     }
610 //     }
611     fill.SetRadius(aData.GetRF(), 1, 1);
612     fill.Build();
613     if (!fill.IsDone()) {
614       StdFail_NotDone::Raise("Fillet can't be computed on the given shape with the given radius");
615     }
616
617     aShape = fill.Shape();
618   }
619   else {
620     // other construction modes here
621   }
622 */
623   if (aShape.IsNull()) return 0;
624
625   aFunction->SetValue(aShape);
626
627   log.SetTouched(Label());
628
629   return 1;
630 }
631
632 //================================================================================
633 /*!
634  * \brief Returns a name of creation operation and names and values of creation parameters
635  */
636 //================================================================================
637
638 bool AdvancedEngine_PipeTShapeDriver::
639 GetCreationInformation(std::string&             theOperationName,
640                        std::vector<GEOM_Param>& theParams)
641 {
642   if (Label().IsNull()) return 0;
643   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
644
645   AdvancedEngine_IPipeTShape aCI( function );
646   Standard_Integer aType = function->GetType();
647
648   theOperationName = "PIPETSHAPE";
649
650   switch ( aType ) {
651   case TSHAPE_BASIC:
652     AddParam( theParams, "Main radius", aCI.GetR1() );
653     AddParam( theParams, "Main width", aCI.GetW1() );
654     AddParam( theParams, "Main half-length", aCI.GetL1() );
655     AddParam( theParams, "Incident pipe radius", aCI.GetR2() );
656     AddParam( theParams, "Incident pipe width", aCI.GetW2() );
657     AddParam( theParams, "Incident pipe half-length", aCI.GetL2() );
658     AddParam( theParams, "For hex mesh", aCI.GetHexMesh() );
659     break;
660   case TSHAPE_CHAMFER:
661     AddParam( theParams, "Main radius", aCI.GetR1() );
662     AddParam( theParams, "Main width", aCI.GetW1() );
663     AddParam( theParams, "Main half-length", aCI.GetL1() );
664     AddParam( theParams, "Incident pipe radius", aCI.GetR2() );
665     AddParam( theParams, "Incident pipe width", aCI.GetW2() );
666     AddParam( theParams, "Incident pipe half-length", aCI.GetL2() );
667     AddParam( theParams, "Chamfer height", aCI.GetH() );
668     AddParam( theParams, "Chamfer width", aCI.GetW() );
669     AddParam( theParams, "For hex mesh", aCI.GetHexMesh() );
670     break;
671   case TSHAPE_FILLET:
672     AddParam( theParams, "Main radius", aCI.GetR1() );
673     AddParam( theParams, "Main width", aCI.GetW1() );
674     AddParam( theParams, "Main half-length", aCI.GetL1() );
675     AddParam( theParams, "Incident pipe radius", aCI.GetR2() );
676     AddParam( theParams, "Incident pipe width", aCI.GetW2() );
677     AddParam( theParams, "Incident pipe half-length", aCI.GetL2() );
678     AddParam( theParams, "Fillet radius", aCI.GetRF() );
679     AddParam( theParams, "For hex mesh", aCI.GetHexMesh() );
680     break;
681   default:
682     return false;
683   }
684   
685   return true;
686 }
687
688 IMPLEMENT_STANDARD_HANDLE (AdvancedEngine_PipeTShapeDriver,GEOM_BaseDriver);
689 IMPLEMENT_STANDARD_RTTIEXT (AdvancedEngine_PipeTShapeDriver,GEOM_BaseDriver);