Integration of OCCT 6.5.0 from SVN
[occt.git] / samples / mfc / occtdemo / Chamfers / Chamfers_Presentation.cpp
1 // Chamfers_Presentation.cpp: implementation of the Chamfers_Presentation class.
2 //
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "Chamfers_Presentation.h"
7
8 #ifdef WNT
9 #pragma warning (disable : 4786)
10 #endif
11
12 #include <TopoDS_Edge.hxx>
13 #include <BRepPrimAPI_MakeBox.hxx>
14 #include <BRepPrimAPI_MakeCylinder.hxx>
15 #include <BRepAlgo_Fuse.hxx>
16 #include <BRepAlgoAPI_Fuse.hxx>
17 #include <BRepFilletAPI_MakeChamfer.hxx>
18 #include <BRepFilletAPI_MakeFillet.hxx>
19 #include <TopExp.hxx>
20 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
21 #include <TopTools_ListIteratorOfListOfShape.hxx>
22 #include <TopTools_IndexedMapOfShape.hxx>
23 #include <TopoDS_Solid.hxx>
24 #include <TopoDS.hxx>
25 #include <TopOpeBRepBuild_HBuilder.hxx>
26 #include <Precision.hxx>
27
28 #ifdef WNT
29  #define EOL "\r\n"
30 #else
31  #define EOL "\n"
32 #endif
33
34 #define BOX_SIDE_LEN 500
35
36 // Initialization of global variable with an instance of this class
37 OCCDemo_Presentation* OCCDemo_Presentation::Current = new Chamfers_Presentation;
38
39 // Initialization of array of samples
40 const Chamfers_Presentation::PSampleFuncType Chamfers_Presentation::SampleFuncs[] =
41 {
42   &Chamfers_Presentation::sampleBoxChamfer,
43   &Chamfers_Presentation::sampleBoxCylChamfer,
44   &Chamfers_Presentation::sampleBoxCylAngChamfer,
45   &Chamfers_Presentation::sampleBoxFillet,
46   &Chamfers_Presentation::sampleBoxCylFillet,
47   &Chamfers_Presentation::sampleBoxCylAngFillet
48 };
49
50 //////////////////////////////////////////////////////////////////////
51 // Construction/Destruction
52 //////////////////////////////////////////////////////////////////////
53
54 Chamfers_Presentation::Chamfers_Presentation()
55 {
56   myIndex = 0;
57   myNbSamples = sizeof(SampleFuncs)/sizeof(PSampleFuncType);
58   setName ("Chamfers and Fillets");
59 }
60
61 //////////////////////////////////////////////////////////////////////
62 // Sample execution
63 //////////////////////////////////////////////////////////////////////
64
65 void Chamfers_Presentation::DoSample()
66 {
67   getAISContext()->EraseAll();
68   if (myIndex >=0 && myIndex < myNbSamples)
69     (this->*SampleFuncs[myIndex])();
70 }
71
72 //////////////////////////////////////////////////////////////////////
73 // Sample functions
74 //////////////////////////////////////////////////////////////////////
75
76 //================================================================
77 // Function : createDiverseChamferOnBox
78 // Purpose  : makes chamfers of different size on 3 converging edges 
79 //            of the given box using given distances d1, d2, d3; 
80 //            outputs its own source code into result dialog
81 //================================================================
82 Standard_Boolean Chamfers_Presentation::createDiverseChamferOnBox(
83                          TopoDS_Solid& aBox, 
84                          Standard_Real d1, // chamfer on edge 1
85                          Standard_Real d2, // chamfer on edge 2
86                          Standard_Real d3, // chamfer on edge 3
87                          Handle_AIS_InteractiveObject& thePrevShape)// for smoth drawing
88                          // we display the new shape first, then erase the previous one
89 {
90   // initializing a class that builds chamfer
91   BRepFilletAPI_MakeChamfer aMakeChamfer(aBox);
92
93   // a map of "edge-to-list of faces".  Key = edge, value = list of 2 faces 
94   // of the box that "touch" the edge
95   TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;
96   // filling the map with edges and faces of the box
97   TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);
98   
99   // array of indexes of edges to be chamfered
100   int aEdgeInd[] = {6, 2, 10, 12, 5};
101
102   // creating chamfer on one of an edge of the top face, using d1
103   if (d1 > Precision::Confusion())
104   {
105     TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[0]));
106     TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());
107     aMakeChamfer.Add(d1, d1, anEdge, aFace);
108   }
109
110   // creating chamfer on the other 3 edges of the top face, using d2
111   if (d2 > Precision::Confusion())
112   {
113     for (Standard_Integer i = 1; i <= 3; i++)
114     {
115       TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[i]));
116       TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());
117       aMakeChamfer.Add(d2, d2, anEdge, aFace);
118     }
119   }
120
121   // creating chamfer on a vertical edge of box, using d3
122   if (d3 > Precision::Confusion())
123   {
124     TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[4]));
125     TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());
126     aMakeChamfer.Add(d3, d3, anEdge, aFace);
127   }
128
129   aMakeChamfer.Build();
130   if (aMakeChamfer.IsDone())
131   {
132     Handle(AIS_InteractiveObject) aNewShape = new AIS_Shape(aMakeChamfer.Shape());
133     getAISContext()->Erase(thePrevShape, Standard_False);
134     thePrevShape = aNewShape;
135     getAISContext()->Display(aNewShape);
136   }
137
138   TCollection_AsciiString aText;
139   aText = aText +
140     "  // creating a box and centering it on the screen" EOL
141     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
142     "  TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);" EOL EOL
143     
144     "  // initializing a class that builds chamfer" EOL
145     "  BRepFilletAPI_MakeChamfer aMakeChamfer(aBox);" EOL EOL
146     
147     "  // a map of \"edge-to-list of faces\".  Key = edge, value = list of 2 faces " EOL
148     "  // of the box that \"touch\" the edge" EOL
149     "  TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;" EOL
150     "  // filling the map with edges and faces of the box" EOL
151     "  TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);" EOL
152     "" EOL
153     "  Standard_Real d1 = "+TCollection_AsciiString(d1)+";" EOL
154     "  Standard_Real d2 = "+TCollection_AsciiString(d2)+";" EOL
155     "  Standard_Real d3 = "+TCollection_AsciiString(d3)+";" EOL
156     "" EOL
157     "  // array of indexes of edges to be chamfered" EOL
158     "  int aEdgeInd[] = {6, 2, 10, 12, 5};" EOL
159     "" EOL
160     "  // creating chamfer on one of an edge of the top face, using d1" EOL
161     "  if (d1 > Precision::Confusion())" EOL
162     "  {" EOL
163     "    TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[0]));" EOL
164     "    TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());" EOL
165     "    aMakeChamfer.Add(d1, d1, anEdge, aFace);" EOL
166     "  }" EOL
167     "" EOL
168     "  // creating chamfer on the other 3 edges of the top face, using d2" EOL
169     "  if (d2 > Precision::Confusion())" EOL
170     "  {" EOL
171     "    for (Standard_Integer i = 1; i <= 3; i++)" EOL
172     "    {" EOL
173     "      TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[i]));" EOL
174     "      TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());" EOL
175     "      aMakeChamfer.Add(d2, d2, anEdge, aFace);" EOL
176     "    }" EOL
177     "  }" EOL
178     "" EOL
179     "  // creating chamfer on a vertical edge of box, using d3" EOL
180     "  if (d3 > Precision::Confusion())" EOL
181     "  {" EOL
182     "    TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[4]));" EOL
183     "    TopoDS_Face aFace = TopoDS::Face(aMapOfEdgeToFaces.FindFromKey(anEdge).First());" EOL
184     "    aMakeChamfer.Add(d3, d3, anEdge, aFace);" EOL
185     "  }" EOL
186     "    " EOL
187     "  aMakeChamfer.Build();" EOL
188     "  if (aMakeChamfer.IsDone())" EOL
189     "    TopoDS_Shape aChamferedShape = aMakeChamfer.Shape();" EOL;  
190   setResultText(aText.ToCString());
191
192   return WAIT_A_SECOND;
193 }
194
195 //================================================================
196 // Function : createChamferOnBox
197 // Purpose  : makes chamfers on edges of the top face of the given box
198 //            using given distances theDistA and theDistB, outputs its own 
199 //            source code into result dialog
200 //================================================================
201 Standard_Boolean Chamfers_Presentation::createChamferOnBox(
202                          TopoDS_Solid& aBox, 
203                          Standard_Real theDistA, // distance along first face 
204                          Standard_Real theDistB, // distance along second face
205                          Handle_AIS_InteractiveObject& thePrevShape)// for smoth drawing
206                          // we display the new shape first, then erase the previous one
207 {
208   // initializing a class that builds chamfer
209   BRepFilletAPI_MakeChamfer aMakeChamfer(aBox);
210
211   // a map of "edge-to-list of faces".  Key = edge, value = list of 2 faces 
212   // of the box that "touch" the edge
213   TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;
214   // filling the map with edges and faces of the box
215   TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);
216   
217   // array of indexes of edges to be chamfered
218   int aEdgeInd[] = {2, 6, 10, 12};
219
220   // building chamfers
221   for (int i = 0; i <= sizeof(aEdgeInd)/sizeof(int)-1; i++)
222   //for (int i = 1; i <= 12; i++) // uncomment to iterate through ALL edges of the box
223   {
224     TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[i]));
225     //TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(i));
226     // uncomment to iterate through ALL edges of the box
227     const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);
228     TopoDS_Face aFace = TopoDS::Face(aFaces.First());
229     aMakeChamfer.Add(theDistA, theDistB, anEdge, aFace);
230   }
231
232   aMakeChamfer.Build();
233   if (aMakeChamfer.IsDone())
234   {
235     Handle(AIS_InteractiveObject) aNewShape = new AIS_Shape(aMakeChamfer.Shape());
236     getAISContext()->Erase(thePrevShape, Standard_False);
237     getAISContext()->Display(aNewShape, Standard_True);
238     thePrevShape = aNewShape;
239   }
240
241   TCollection_AsciiString aText;
242   aText = aText +
243     "  // creating a box and centering it on the screen" EOL
244     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
245     "  TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);" EOL EOL
246     
247     "  // initializing a class that builds chamfer" EOL
248     "  BRepFilletAPI_MakeChamfer aMakeChamfer(aBox);" EOL EOL
249     
250     "  // a map of \"edge-to-list of faces\".  Key = edge, value = list of 2 faces " EOL
251     "  // of the box that \"touch\" the edge" EOL
252     "  TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;" EOL
253     "  // filling the map with edges and faces of the box" EOL
254     "  TopExp::MapShapesAndAncestors(aBox, TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);" EOL
255     "" EOL
256     "  Standard_Real aDistA = "+TCollection_AsciiString(theDistA)+";" EOL
257     "  Standard_Real aDistB = "+TCollection_AsciiString(theDistB)+";" EOL
258     "" EOL
259     "  // array of indexes of edges to be chamfered" EOL
260     "  int aEdgeInd[] = {2, 6, 10, 12};" EOL EOL
261     
262     "  // building chamfers" EOL
263     "  for (int i = 0; i <= sizeof(aEdgeInd)/sizeof(int)-1; i++)" EOL
264     "  {" EOL
265     "    TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdgeToFaces.FindKey(aEdgeInd[i]));" EOL
266     "    const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);" EOL
267     "    TopoDS_Face aFace = TopoDS::Face(aFaces.First());" EOL
268     "    // creating a chamfer with lengths aDistA, aDistB" EOL 
269     "    aMakeChamfer.Add(aDistA, aDistB, anEdge, aFace);" EOL
270     "  }" EOL EOL
271     
272     "  aMakeChamfer.Build();" EOL
273     "  if (aMakeChamfer.IsDone())" EOL
274     "    TopoDS_Shape aChamferedShape = aMakeChamfer.Shape();" EOL;  
275   setResultText(aText.ToCString());
276
277   return WAIT_A_SECOND;
278 }
279
280 //================================================================
281 // Function : createFilletOnBox
282 // Purpose  : creates a box with side=10, makes fillets on some of its edges
283 //            using given value of radius and shape of fillet, outputs its own 
284 //            source code into theText parameter
285 //================================================================
286 Standard_Boolean Chamfers_Presentation::createFilletOnBox(
287                        TopoDS_Solid& aBox,
288                        Standard_Real theRad, // radius of fillet
289                        ChFi3d_FilletShape theFShape, // shape of fillet
290                        Handle_AIS_InteractiveObject& thePrevObj) // to erase 
291                        // the previous shape
292 {
293   // initializing a class that builds fillet
294   // second parameter is a shape of fillet:
295   // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };
296   BRepFilletAPI_MakeFillet aMakeFillet(aBox, theFShape);
297
298   // a map of edges
299   TopTools_IndexedMapOfShape aMapOfEdges;
300   // filling the map with edges of the box
301   TopExp::MapShapes(aBox, TopAbs_EDGE, aMapOfEdges);
302   
303   // array of indexes of edges to be chamfered
304   int aEdgeInd[] = {2, 6, 10, 12};
305
306   // adding edges that will have fillet
307   for (int i = 0; i <= sizeof(aEdgeInd)/sizeof(int)-1; i++)
308   {
309     TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdges(aEdgeInd[i]));
310     aMakeFillet.Add(theRad, anEdge);
311   }
312
313   aMakeFillet.Build();
314   if (aMakeFillet.IsDone())
315   {
316     Handle(AIS_InteractiveObject) aNewShape = new AIS_Shape(aMakeFillet.Shape());
317     getAISContext()->Erase(thePrevObj, Standard_False);
318     getAISContext()->Display(aNewShape, Standard_True);
319     thePrevObj = aNewShape;
320   }
321
322   // calculating the string corresponding to theFShape 
323   TCollection_AsciiString aFShapeStr;
324   aFShapeStr = ((theFShape==ChFi3d_Rational)?     "ChFi3d_Rational":
325                ((theFShape==ChFi3d_QuasiAngular)? "ChFi3d_QuasiAngular":
326                                                   "ChFi3d_Polynomial"));
327   TCollection_AsciiString aText;
328   aText = aText +
329     "  // creating a box and centering it on the screen" EOL
330     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
331     "  TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);" EOL
332     "  " EOL
333     "  // initializing a class that builds fillet" EOL
334     "  // second parameter is a shape of fillet:" EOL
335     "  // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };" EOL
336     "  BRepFilletAPI_MakeFillet aMakeFillet(aBox, "+aFShapeStr+");" EOL
337     "  " EOL
338     "  // a map of edges" EOL
339     "  TopTools_IndexedMapOfShape aMapOfEdges;" EOL
340     "  // filling the map with edges of the box" EOL
341     "  TopExp::MapShapes(aBox, TopAbs_EDGE, aMapOfEdges);" EOL EOL
342   
343     "  // array of indexes of edges to be chamfered" EOL
344     "  int aEdgeInd[] = {2, 6, 10, 12};" EOL EOL
345
346     "  // adding edges that will have fillet" EOL
347     "  Standard_Real r = "+TCollection_AsciiString(theRad)+";" EOL
348     "  for (int i = 0; i <= sizeof(aEdgeInd)/sizeof(int)-1; i++)" EOL
349     "  {" EOL
350     "    TopoDS_Edge anEdge = TopoDS::Edge(aMapOfEdges(aEdgeInd[i]));" EOL
351     "    aMakeFillet.Add(r, anEdge);" EOL
352     "  }" EOL
353   
354     "  aMakeFillet.Build();" EOL
355     "  if (aMakeFillet.IsDone())" EOL
356     "    TopoDS_Shape aShapeWithFillet = aMakeFillet.Shape();" EOL;
357   setResultText(aText.ToCString());
358
359   return WAIT_A_SECOND;
360 }
361
362
363
364 // ===============================================================
365 //                          CHAMFER CASES
366 // ===============================================================
367 //================================================================
368 // Function : Chamfers_Presentation::sampleBoxChamfer1,2,3
369 // Purpose  : 
370 //================================================================
371 void Chamfers_Presentation::sampleBoxChamfer()
372 {
373   setResultTitle("Creating Chamfer");
374   TCollection_AsciiString aText;
375   aText = aText +
376     "  // creating a box and centering it on the screen" EOL
377     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
378     "  TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);" EOL;
379   setResultText(aText.ToCString());
380
381   // show initial shape
382   Standard_Real a = BOX_SIDE_LEN;
383   TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);
384   Handle(AIS_InteractiveObject) aPrevShape = new AIS_Shape(aBox);
385   getAISContext()->Display(aPrevShape, Standard_False);
386   COCCDemoDoc::Fit();
387
388   if (WAIT_A_SECOND) return;
389
390   // show several chamfers
391   if (createChamferOnBox(aBox, a/10, a/10, aPrevShape)) return;
392   if (createChamferOnBox(aBox, a/24, a/10, aPrevShape)) return;
393   if (createChamferOnBox(aBox, a/10, a/10, aPrevShape)) return;
394   if (createChamferOnBox(aBox, a/10, a/24, aPrevShape)) return;
395   if (createChamferOnBox(aBox, a/10, a/10, aPrevShape)) return;
396   if (createDiverseChamferOnBox(aBox, a/6, a/10, 0, aPrevShape)) return;
397   if (createDiverseChamferOnBox(aBox, a/6, a/10, a/24, aPrevShape)) return;
398 }
399
400 //================================================================
401 // Function : Chamfers_Presentation::sampleBoxCylChamfer
402 // Purpose  : creates a more complecated chamfer on a shape created
403 //            by fusing box and cylinder
404 //================================================================
405 void Chamfers_Presentation::sampleBoxCylChamfer()
406 {
407   setResultTitle("Creating Chamfer");
408   TCollection_AsciiString aText;
409   aText = aText +
410     "  // creating a shape, a result of fusing of a box and cylinder" EOL
411     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
412     "  Standard_Real b = a/2;" EOL
413     "  BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);" EOL
414     "  BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), a/4, a);" EOL
415     "  BRepAlgoAPI_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());" EOL
416     "  aFuser.Build();" EOL EOL
417     
418     "  // initializing a class that builds chamfer" EOL
419     "  BRepFilletAPI_MakeChamfer aMakeChamfer(aFuser.Shape());" EOL EOL
420     
421     "  // a map of \"edge-to-list of faces\".  Key = edge, value = list of 2 faces " EOL
422     "  // of the box that \"touch\" the edge" EOL
423     "  TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;" EOL
424     "  // filling the map with edges and faces of the box" EOL
425     "  TopExp::MapShapesAndAncestors(aFuser.Shape(), TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);" EOL EOL
426     
427     "  // retrieving list of edges to build a chamfer on - edges of " EOL
428     "  // intersection of the cylinder and the box" EOL
429     "  const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();" EOL
430     "  TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);" EOL
431     "" EOL
432     "  // creating fillet on edge intersection edges" EOL
433     "  Standard_Real d = a/20;" EOL
434     "  for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())" EOL
435     "  {" EOL
436     "    TopoDS_Edge anEdge = TopoDS::Edge(anIntersectionEdgesIt.Value());" EOL
437     "    if (!aMapOfEdgeToFaces.Contains(anEdge)) continue;" EOL
438     "    const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);" EOL
439     "    TopoDS_Face aFace = TopoDS::Face(aFaces.First());" EOL
440     "    aMakeChamfer.Add(d, d, anEdge, aFace);" EOL
441     "  }" EOL
442     "    " EOL
443     "  aMakeChamfer.Build();" EOL
444     "  if (aMakeChamfer.IsDone())" EOL
445     "    TopoDS_Shape aChamferedShape = aMakeChamfer.Shape();" EOL;
446   setResultText(aText.ToCString());
447
448   // creating a shape, a result of fusing of a box and cylinder
449   Standard_Real a = BOX_SIDE_LEN;
450   Standard_Real b = a/2;
451   BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);
452   BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), a/4, a);
453   BRepAlgo_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());
454   aFuser.Build();
455
456   Handle(AIS_InteractiveObject) aPrevObj = new AIS_Shape(aFuser.Shape());
457   getAISContext()->Display(aPrevObj, Standard_False);
458   COCCDemoDoc::Fit();
459
460   if (WAIT_A_SECOND) return;
461
462   // initializing a class that builds chamfer
463   BRepFilletAPI_MakeChamfer aMakeChamfer(aFuser.Shape());
464
465   // a map of "edge-to-list of faces".  Key = edge, value = list of 2 faces 
466   // of the box that "touch" the edge
467   TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;
468   // filling the map with edges and faces of the box
469   TopExp::MapShapesAndAncestors(aFuser.Shape(), TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);
470
471   // retrieving list of edges to build a chamfer on - edges of 
472   // intersection of the cylinder and the box
473   const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();
474   TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);
475
476   // creating fillet on edge intersection edges
477   Standard_Real d = a/20;
478   for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())
479   {
480     TopoDS_Edge anEdge = TopoDS::Edge(anIntersectionEdgesIt.Value());
481     if (!aMapOfEdgeToFaces.Contains(anEdge)) continue;
482     const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);
483     TopoDS_Face aFace = TopoDS::Face(aFaces.First());
484     aMakeChamfer.Add(d, d, anEdge, aFace);
485   }
486
487   aMakeChamfer.Build();
488
489   if (aMakeChamfer.IsDone())
490   {
491     getAISContext()->Erase(aPrevObj, Standard_False);
492     getAISContext()->Display(new AIS_Shape(aMakeChamfer.Shape()));
493     //aPrevObj = aNewShape;// uncomment if further thePrevObj is used
494   }
495 }
496
497 //================================================================
498 // Function : Chamfers_Presentation::sampleBoxCylAngChamfer
499 // Purpose  : creates a more complecated chamfer on a shape created
500 //            by fusing box and cylinder
501 //================================================================
502 void Chamfers_Presentation::sampleBoxCylAngChamfer()
503 {
504   setResultTitle("Creating Chamfer");
505   TCollection_AsciiString aText;
506   aText = aText +
507     "  // creating a shape, a result of fusing of a box and cylinder" EOL
508     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
509     "  Standard_Real b = a/2;" EOL
510     "  BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);" EOL
511     "  BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,-0.4,0.6)), a/4, a);" EOL
512     "  BRepAlgoAPI_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());" EOL
513     "  aFuser.Build();" EOL EOL
514     
515     "  // initializing a class that builds chamfer" EOL
516     "  BRepFilletAPI_MakeChamfer aMakeChamfer(aFuser.Shape());" EOL EOL
517     
518     "  // a map of \"edge-to-list of faces\".  Key = edge, value = list of 2 faces " EOL
519     "  // of the box that \"touch\" the edge" EOL
520     "  TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;" EOL
521     "  // filling the map with edges and faces of the box" EOL
522     "  TopExp::MapShapesAndAncestors(aFuser.Shape(), TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);" EOL EOL
523     
524     "  // retrieving list of edges to build a chamfer on - edges of " EOL
525     "  // intersection of the cylinder and the box" EOL
526     "  const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();" EOL
527     "  TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);" EOL EOL
528
529     "  // creating chamfer on intersection edges" EOL
530     "  Standard_Real d = a/20;" EOL
531     "  for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())" EOL
532     "  {" EOL
533     "    TopoDS_Edge anEdge = TopoDS::Edge(anIntersectionEdgesIt.Value());" EOL
534     "    if (!aMapOfEdgeToFaces.Contains(anEdge)) continue;" EOL
535     "    const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);" EOL
536     "    TopoDS_Face aFace = TopoDS::Face(aFaces.First());" EOL
537     "    aMakeChamfer.Add(d, d, anEdge, aFace);" EOL
538     "  }" EOL EOL
539     
540     "  aMakeChamfer.Build();" EOL
541     "  if (aMakeChamfer.IsDone())" EOL
542     "    TopoDS_Shape aChamferedShape = aMakeChamfer.Shape();" EOL;
543   setResultText(aText.ToCString());
544
545   // creating a shape, a result of fusing of a box and cylinder
546   Standard_Real a = BOX_SIDE_LEN;
547   Standard_Real b = a/2;
548   BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);
549   BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,-0.4,0.6)), a/4, a);
550   BRepAlgo_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());
551   aFuser.Build();
552
553   Handle(AIS_InteractiveObject) aPrevObj = new AIS_Shape(aFuser.Shape());
554   getAISContext()->Display(aPrevObj, Standard_False);
555   COCCDemoDoc::Fit();
556
557   if (WAIT_A_SECOND) return;
558
559   // initializing a class that builds chamfer
560   BRepFilletAPI_MakeChamfer aMakeChamfer(aFuser.Shape());
561
562   // a map of "edge-to-list of faces".  Key = edge, value = list of 2 faces 
563   // of the box that "touch" the edge
564   TopTools_IndexedDataMapOfShapeListOfShape aMapOfEdgeToFaces;
565   // filling the map with edges and faces of the box
566   TopExp::MapShapesAndAncestors(aFuser.Shape(), TopAbs_EDGE, TopAbs_FACE, aMapOfEdgeToFaces);
567   
568   // retrieving list of edges to build a chamfer on - edges of 
569   // intersection of the cylinder and the box
570   const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();
571   TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);
572
573   // creating fillet on edge intersection edges
574   Standard_Real d = a/20;
575   for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())
576   {
577     TopoDS_Edge anEdge = TopoDS::Edge(anIntersectionEdgesIt.Value());
578     if (!aMapOfEdgeToFaces.Contains(anEdge)) continue;
579     const TopTools_ListOfShape& aFaces = aMapOfEdgeToFaces.FindFromKey(anEdge);
580     TopoDS_Face aFace = TopoDS::Face(aFaces.First());
581     aMakeChamfer.Add(d, d, anEdge, aFace);
582   }
583
584   aMakeChamfer.Build();
585
586   if (aMakeChamfer.IsDone())
587   {
588     getAISContext()->Erase(aPrevObj, Standard_False);
589     getAISContext()->Display(new AIS_Shape(aMakeChamfer.Shape()));
590     //thePrevShape = aNewShape;// uncomment if further thePrevObj is used
591   }
592 }
593
594 // ===============================================================
595 //                          FILLET CASES
596 // ===============================================================
597 //================================================================
598 // Function : Chamfers_Presentation::sampleBoxFillet1,2,3
599 // Purpose  : 
600 //================================================================
601 void Chamfers_Presentation::sampleBoxFillet()
602 {
603   setResultTitle("Creating Fillet");
604   TCollection_AsciiString aText;
605   aText = aText +
606     "  // creating a box and centering it on the screen" EOL
607     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
608     "  TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);" EOL;
609   setResultText(aText.ToCString());
610
611   // show initial shape
612   Standard_Real a = BOX_SIDE_LEN;
613   TopoDS_Solid aBox = BRepPrimAPI_MakeBox(gp_Pnt(-a/2, -a/2, -a/2), a, a, a);
614
615   Handle_AIS_InteractiveObject aPrevObj = new AIS_Shape(aBox);
616   getAISContext()->Display(aPrevObj, Standard_False);
617   COCCDemoDoc::Fit();
618
619   if (WAIT_A_SECOND) return;
620
621   // show several fillets
622   if (createFilletOnBox(aBox, a/10,  ChFi3d_Polynomial, aPrevObj))   return;
623   if (createFilletOnBox(aBox, a/5,   ChFi3d_QuasiAngular, aPrevObj)) return;
624   if (createFilletOnBox(aBox, a/3.3, ChFi3d_Rational, aPrevObj))     return;
625 }
626
627 //================================================================
628 // Function : Chamfers_Presentation::sampleBoxCylFillet
629 // Purpose  : creates a more complecated chamfer on a shape created
630 //            by fusing box and cylinder
631 //================================================================
632 void Chamfers_Presentation::sampleBoxCylFillet()
633 {
634   setResultTitle("Creating Fillet");
635   TCollection_AsciiString aText;
636   aText = aText +
637     "  // creating a shape - result of fusing a box and a cylinder" EOL
638     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
639     "  Standard_Real b = a/2;" EOL
640     "  BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);" EOL
641     "  BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), a/4, a);" EOL
642     "  BRepAlgoAPI_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());" EOL
643     "  aFuser.Build();" EOL EOL
644     
645     "  // initializing a class that builds fillet" EOL
646     "  // second parameter is a shape of fillet:" EOL
647     "  // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };" EOL
648     "  BRepFilletAPI_MakeFillet aMakeFillet(aFuser.Shape(), ChFi3d_Rational);" EOL EOL
649   
650     "  // retrieving list of edges to build a chamfer on - edges of " EOL
651     "  // intersection of the cylinder and the box" EOL
652     "  const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();" EOL
653     "  TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);" EOL EOL
654
655     "  // creating fillet on edge intersection edges" EOL
656     "  Standard_Real d = a/10;" EOL
657     "  for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())" EOL
658     "    aMakeFillet.Add(d, TopoDS::Edge(anIntersectionEdgesIt.Value()));" EOL
659     "" EOL
660     "  aMakeFillet.Build();" EOL EOL
661
662     "  if (aMakeFillet.IsDone())" EOL
663     "    TopoDS_Shape aShapeWithFillet = aMakeFillet.Shape();" EOL;
664   setResultText(aText.ToCString());
665
666   // creating a shape, a result of fusing of a box and cylinder
667   Standard_Real a = BOX_SIDE_LEN;
668   Standard_Real b = a/2;
669   BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);
670   BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), a/4, a);
671   BRepAlgo_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());
672   aFuser.Build();
673
674   Handle(AIS_InteractiveObject) aPrevObj = new AIS_Shape(aFuser.Shape());
675   getAISContext()->Display(aPrevObj, Standard_False);
676   COCCDemoDoc::Fit();
677
678   if (WAIT_A_SECOND) return;
679
680   // initializing a class that builds fillet
681   // second parameter is a shape of fillet:
682   // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };
683   BRepFilletAPI_MakeFillet aMakeFillet(aFuser.Shape(), ChFi3d_Rational);
684   
685   // retrieving list of edges to build a chamfer on - edges of 
686   // intersection of the cylinder and the box
687   const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();
688   TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);
689
690   // creating fillet on edge intersection edges
691   Standard_Real d = a/10;
692   for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())
693     aMakeFillet.Add(d, TopoDS::Edge(anIntersectionEdgesIt.Value()));
694
695   aMakeFillet.Build();
696
697   if (aMakeFillet.IsDone())
698   {
699     getAISContext()->Erase(aPrevObj, Standard_False);
700     //aPrevObj = new AIS_Shape(aMakeFillet.Shape());// uncomment if aPrevObj is used further
701     getAISContext()->Display(new AIS_Shape(aMakeFillet.Shape()));
702   }
703 }
704
705
706 //================================================================
707 // Function : Chamfers_Presentation::sampleBoxCylAngFillet
708 // Purpose  : creates a fillet on a more complecated shape created
709 //            by fusing box and cylinder
710 //================================================================
711 void Chamfers_Presentation::sampleBoxCylAngFillet()
712 {
713   setResultTitle("Creating Fillet");
714   TCollection_AsciiString aText;
715   aText = aText +
716     "  // creating a shape - result of fusing a box and a cylinder" EOL
717     "  Standard_Real a = "+TCollection_AsciiString(BOX_SIDE_LEN)+";" EOL
718     "  Standard_Real b = a/2;" EOL
719     "  BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);" EOL
720     "  BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,-0.4,0.6)), a/4, a);" EOL
721     "  BRepAlgoAPI_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());" EOL
722     "  aFuser.Build();" EOL EOL
723     
724     "  // initializing a class that builds fillet" EOL
725     "  // second parameter is a shape of fillet:" EOL
726     "  // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };" EOL
727     "  BRepFilletAPI_MakeFillet aMakeFillet(aFuser.Shape(), ChFi3d_Rational);" EOL EOL
728   
729     "  // retrieving list of edges to build a chamfer on - edges of " EOL
730     "  // intersection of the cylinder and the box" EOL
731     "  const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();" EOL
732     "  TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);" EOL EOL
733
734     "  // creating fillet on intersection edges" EOL
735     "  Standard_Real d = a/10;" EOL
736     "  for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())" EOL
737     "    aMakeFillet.Add(d, TopoDS::Edge(anIntersectionEdgesIt.Value()));" EOL
738     "  aMakeFillet.Build();" EOL EOL
739
740     "  if (aMakeFillet.IsDone())" EOL
741     "    TopoDS_Shape aShapeWithFillet = aMakeFillet.Shape();" EOL;
742   setResultText(aText.ToCString());
743
744   // creating a shape, a result of fusing of a box and cylinder
745   Standard_Real a = BOX_SIDE_LEN;
746   Standard_Real b = a/2;
747   BRepPrimAPI_MakeBox aBoxMaker (gp_Pnt(-b, -b, -b), a, a, a);
748   BRepPrimAPI_MakeCylinder aCylMaker(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,-0.4,0.6)), a/4, a);
749   BRepAlgo_Fuse aFuser(aBoxMaker.Solid(), aCylMaker.Solid());
750   aFuser.Build();
751
752   Handle(AIS_InteractiveObject) aPrevObj = new AIS_Shape(aFuser.Shape());
753   getAISContext()->Display(aPrevObj, Standard_False);
754   COCCDemoDoc::Fit();
755
756   if (WAIT_A_SECOND) return;
757
758   // initializing a class that builds fillet
759   // second parameter is a shape of fillet:
760   // enum ChFi3d_FilletShape { ChFi3d_Rational, ChFi3d_QuasiAngular, ChFi3d_Polynomial };
761   BRepFilletAPI_MakeFillet aMakeFillet(aFuser.Shape(), ChFi3d_Rational);
762   
763   // retrieving list of edges to build a chamfer on - edges of 
764   // intersection of the cylinder and the box
765   const TopTools_ListOfShape& aEdgesOfIntersection = aFuser.Builder()->Section();
766   TopTools_ListIteratorOfListOfShape anIntersectionEdgesIt(aEdgesOfIntersection);
767
768   // creating fillet on edge intersection edges
769   Standard_Real d = a/10;
770   for (; anIntersectionEdgesIt.More(); anIntersectionEdgesIt.Next())
771     aMakeFillet.Add(d, TopoDS::Edge(anIntersectionEdgesIt.Value()));
772
773   aMakeFillet.Build();
774
775   if (aMakeFillet.IsDone())
776   {
777     getAISContext()->Erase(aPrevObj, Standard_False);
778     //aPrevObj = new AIS_Shape(aMakeFillet.Shape());// uncomment if aPrevObj is used further
779     getAISContext()->Display(new AIS_Shape(aMakeFillet.Shape()));
780   }
781 }