0024002: Overall code and build procedure refactoring - samples
[occt.git] / samples / mfc / standard / 07_Triangulation / src / Tesselate_Presentation.cpp
1 // Tesselate_Presentation.cpp: implementation of the Tesselate_Presentation class.
2 // Tesselate shapes.
3 ////////////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "Tesselate_Presentation.h" 
7 #include "TriangulationApp.h" 
8 #include "TriangulationDoc.h" 
9
10 #include <Precision.hxx>
11 #include <TopoDS.hxx>
12 #include <TopoDS_Edge.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS_Compound.hxx>
15
16 #include <BRep_Builder.hxx>
17 #include <BRepTools.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepBuilderAPI_MakeEdge.hxx>
20 #include <BRepBuilderAPI_MakeVertex.hxx>
21 #include <BRepMesh_IncrementalMesh.hxx>
22
23 #include <TopExp_Explorer.hxx>
24 #include <TopLoc_Location.hxx>
25 #include <TopTools_DataMapOfIntegerShape.hxx>
26 #include <TopTools_SequenceOfShape.hxx>
27
28 #include <Poly_Triangulation.hxx>
29 #include <Poly_PolygonOnTriangulation.hxx>
30 #include <Poly_Array1OfTriangle.hxx>
31 #include <TColgp_Array1OfPnt.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33
34 #include <gp_Pnt.hxx>
35
36
37 #ifdef WNT
38  #define EOL "\r\n"
39 #else
40  #define EOL "\n"
41 #endif
42
43 // Initialization of global variable with an instance of this class
44 OCCDemo_Presentation* OCCDemo_Presentation::Current = new Tesselate_Presentation;
45
46 // Initialization of array of samples
47 Standard_CString Tesselate_Presentation::myFileNames[] =
48 {
49   "wedge_ok.brep",
50   "shell1.brep",
51   "Pump_Nut.brep",
52   "Pump_TopCover.brep",
53   0
54 };
55
56 //////////////////////////////////////////////////////////////////////
57 // Construction/Destruction
58 //////////////////////////////////////////////////////////////////////
59
60 Tesselate_Presentation::Tesselate_Presentation()
61 {
62   for (myNbSamples = 0; myFileNames[myNbSamples]; myNbSamples++);
63   setName ("Tesselate shapes");
64 }
65
66 //////////////////////////////////////////////////////////////////////
67 // Sample execution
68 //////////////////////////////////////////////////////////////////////
69
70 void Tesselate_Presentation::DoSample()
71 {
72         ((CTriangulationApp*) AfxGetApp())->SetSampleName (L"Tesselate");
73         ((CTriangulationApp*) AfxGetApp())->SetSamplePath (L"");
74         getAISContext()->EraseAll();
75         if (myIndex >=0 && myIndex < myNbSamples)
76     sample (myFileNames[myIndex]);
77 }
78
79 //////////////////////////////////////////////////////////////////////
80 // Sample functions
81 //////////////////////////////////////////////////////////////////////
82 //================================================================
83
84 inline Standard_Integer _key(Standard_Integer n1,Standard_Integer n2)
85 {
86
87   Standard_Integer key = 
88     (n2>n1)?(n1<<16)+n2:(n2<<16)+n1;
89   return key;
90 }
91
92 //DATA : [myIndex][{Deflection,NumberOfFace,NumberOfEdge}]
93 static const Standard_Real DATA [][3] = 
94 {
95   {0.2,1,2},{0.5,6,2},{0.7,16,2},{1,1,2}
96 };
97
98
99 void Tesselate_Presentation::tesselateShape(const TopoDS_Shape& aShape)
100 {
101 //  setResultTitle("Tesselate shape");
102   TCollection_AsciiString aText = (
103     "/////////////////////////////////////////////////////////////////" EOL
104     "// Tesselate shape." EOL
105     "/////////////////////////////////////////////////////////////////" EOL EOL
106     ) ;
107
108   Standard_Real aDeflection = DATA[myIndex][0];
109   Standard_Integer aNumOfFace = (Standard_Integer)DATA[myIndex][1];
110   Standard_Integer aNumOfEdge = (Standard_Integer)DATA[myIndex][2];
111
112   aText +=
113     "Standard_Real aDeflection;" EOL
114     "// aDeflection = ... ;" EOL EOL
115
116     "// removes all the triangulations of the faces ," EOL
117     "//and all the polygons on the triangulations of the edges:" EOL
118     "BRepTools::Clean(aShape);" EOL EOL
119
120     "// adds a triangulation of the shape aShape with the deflection aDeflection:" EOL
121     "BRepMesh::Mesh(aShape,aDeflection);" EOL EOL
122
123     "TopExp_Explorer aExpFace,aExpEdge;" EOL
124     "for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())" EOL
125     "{  " EOL
126     "  TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL
127     "  TopLoc_Location aLocation;" EOL EOL
128     
129     "  // takes the triangulation of the face aFace:" EOL
130     "  Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL
131     
132     "  if(!aTr.IsNull()) // if this triangulation is not NULL" EOL
133     "  { " EOL
134     "    // takes the array of nodes for this triangulation:" EOL
135     "    const TColgp_Array1OfPnt& aNodes = aTr->Nodes();" EOL
136     "    // takes the array of triangles for this triangulation:" EOL
137     "    const Poly_Array1OfTriangle& triangles = aTr->Triangles();" EOL EOL
138     
139     "    // create array of node points in absolute coordinate system" EOL
140     "    TColgp_Array1OfPnt aPoints(1, aNodes.Length());" EOL
141     "    for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)" EOL
142     "      aPoints(i) = aNodes(i).Transformed(aLocation);" EOL EOL
143
144     "    // Takes the node points of each triangle of this triangulation." EOL
145     "    // takes a number of triangles:" EOL
146     "    Standard_Integer nnn = aTr->NbTriangles();" EOL
147     "    Standard_Integer nt,n1,n2,n3;" EOL
148     "    for( nt = 1 ; nt < nnn+1 ; nt++)" EOL
149     "    {" EOL
150     "      // takes the node indices of each triangle in n1,n2,n3:" EOL
151     "      triangles(nt).Get(n1,n2,n3);" EOL
152     "      // takes the node points:" EOL
153     "      gp_Pnt aPnt1 = aPoints(n1);" EOL
154     "      gp_Pnt aPnt2 = aPoints(n2);" EOL
155     "      gp_Pnt aPnt3 = aPoints(n3);" EOL
156     "    } " EOL EOL
157     
158     "    // Takes the polygon associated to an edge." EOL
159     "    aExpEdge.Init(aFace,TopAbs_EDGE);" EOL
160     "    TopoDS_Edge aEdge;" EOL
161     "    // for example,working with the first edge:" EOL
162     "    if(aExpEdge.More())" EOL
163     "      aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL
164     
165     "    if(!aEdge.IsNull()) // if this edge is not NULL" EOL
166     "    {" EOL
167     "      // takes the polygon associated to the edge aEdge:" EOL
168     "      Handle_Poly_PolygonOnTriangulation aPol = " EOL
169     "        BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL
170     
171     "      if(!aPol.IsNull()) // if this polygon is not NULL" EOL
172     "        // takes the array of nodes for this polygon" EOL
173     "        // (indexes in the array of nodes for triangulation of theFace):" EOL
174     "        const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL
175     "    }" EOL
176     "  }" EOL
177     "}" EOL EOL
178     
179     "//==================================================" EOL EOL
180     
181       ;
182    aText += "  Result with deflection = ";
183    aText += TCollection_AsciiString(aDeflection);
184    aText += " :" EOL;
185
186    GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
187 //   setResultText(aText.ToCString());  
188
189 //==========================================================================
190
191   BRepTools::Clean(aShape);
192   BRepMesh_IncrementalMesh(aShape,aDeflection);
193
194   BRep_Builder aBuilder,aBuild1,aBuild2;
195   TopoDS_Compound aCompound,aComp1,aComp2;
196   aBuilder.MakeCompound(aCompound);
197   aBuild1.MakeCompound(aComp1);
198   aBuild2.MakeCompound(aComp2);
199
200   TopTools_SequenceOfShape aVertices;
201   Standard_Integer aCount = 0;
202   Standard_Integer aNumOfNodes = 0;
203   Standard_Integer aNumOfTriangles = 0;
204   
205   Handle_AIS_InteractiveObject aShowEdge,aShowFace,aShowShape;
206   
207   TopExp_Explorer aExpFace,aExpEdge;
208
209   for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())
210   {  
211     aCount++;
212   
213     TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
214     TopLoc_Location aLocation;
215
216     Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);
217
218     if(!aTr.IsNull())
219     { 
220       const TColgp_Array1OfPnt& aNodes = aTr->Nodes();
221       aNumOfNodes += aTr->NbNodes();
222       //Standard_Integer aLower = aNodes.Lower();
223       //Standard_Integer anUpper = aNodes.Upper();
224       const Poly_Array1OfTriangle& triangles = aTr->Triangles();
225       aNumOfTriangles += aTr->NbTriangles();
226
227       if(aCount == aNumOfFace)
228       {
229         Standard_Integer aNbOfNodesOfFace = aTr->NbNodes();
230         Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles();
231         aExpEdge.Init(aFace,TopAbs_EDGE);
232
233         TopoDS_Edge aEdge;
234
235         for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++)
236           aEdge = TopoDS::Edge(aExpEdge.Current());
237
238         if(!aEdge.IsNull())
239         {
240           Handle_Poly_PolygonOnTriangulation aPol = 
241             BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());
242
243           if(!aPol.IsNull())
244           {
245             const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();
246             Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes();
247
248             aText += "Number of nodes of the edge = ";
249             aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL;
250             aText += "Number of nodes of the face = ";
251             aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL;
252             aText += "Number of triangles of the face = ";
253             aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL;
254                         GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
255 //            setResultText(aText.ToCString());  
256
257             Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper();
258             for( int i = aLower; i < anUpper ; i++)
259             {
260               gp_Pnt aPnt1 = aNodes(aNodesOfPol(i)).Transformed(aLocation);
261               gp_Pnt aPnt2 = aNodes(aNodesOfPol(i+1)).Transformed(aLocation);
262               TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1);
263               TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2);
264
265               if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive"
266                 !BRep_Tool::Pnt(aVertex1).IsEqual(
267                 BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different
268               {
269                 aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2);
270                 aBuild2.Add(aComp2,aVertex1);
271                 if(!aEdge.IsNull())
272                   aBuild2.Add(aComp2,aEdge);
273                 if(i == anUpper-1)
274                   aBuild2.Add(aComp2,aVertex2);
275               }
276             }
277       
278             getAISContext()->EraseAll();
279             aShowShape = drawShape(aShape);
280             if(WAIT_A_SECOND) return;
281             aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN);
282             getAISContext()->Erase(aShowShape);
283             if(WAIT_A_SECOND) return;
284           }
285         }
286       }
287     
288
289       TopTools_DataMapOfIntegerShape aEdges;
290       TopTools_SequenceOfShape aVertices;
291
292       for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)
293       {
294         gp_Pnt aPnt = aNodes(i).Transformed(aLocation);
295         TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt);
296
297         if(!aVertex.IsNull())
298         {
299           aBuilder.Add(aCompound,aVertex);
300           if(aCount == aNumOfFace ) 
301             aBuild1.Add(aComp1,aVertex);
302           aVertices.Append(aVertex);
303         }
304       }
305
306       Standard_Integer nnn = aTr->NbTriangles();
307       Standard_Integer nt,n1,n2,n3;
308
309       for( nt = 1 ; nt < nnn+1 ; nt++)
310       {     
311         triangles(nt).Get(n1,n2,n3);
312
313         Standard_Integer key[3];
314         
315         TopoDS_Vertex aV1,aV2;
316         key[0] = _key(n1, n2);
317         if(!aEdges.IsBound(key[0]))
318         {
319           aV1 = TopoDS::Vertex(aVertices(n1));
320           aV2 = TopoDS::Vertex(aVertices(n2));
321           if(!aV1.IsNull() && !aV2.IsNull() &&
322             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
323           {
324             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
325             if(!aEdge.IsNull())
326             {
327               aEdges.Bind(key[0], aEdge);
328               aBuilder.Add(aCompound,aEdges(key[0]));
329               if(aCount == aNumOfFace)
330                 aBuild1.Add(aComp1,aEdges(key[0]));
331             } 
332           }
333         }
334         
335         key[1] = _key(n2,n3);
336         if(!aEdges.IsBound(key[1])) 
337         { 
338           aV1 = TopoDS::Vertex(aVertices(n2));
339           aV2 = TopoDS::Vertex(aVertices(n3));
340           if(!aV1.IsNull() && !aV2.IsNull() &&
341             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
342           {
343             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
344             if(!aEdge.IsNull())
345             {
346               aEdges.Bind(key[1],aEdge);
347               aBuilder.Add(aCompound,aEdges(key[1]));
348               if(aCount == aNumOfFace) 
349                 aBuild1.Add(aComp1,aEdges(key[1]));
350             } 
351           } 
352         } 
353  
354         key[2] = _key(n3,n1);
355         if(!aEdges.IsBound(key[2])) 
356         { 
357           aV1 = TopoDS::Vertex(aVertices(n3));
358           aV2 = TopoDS::Vertex(aVertices(n1));
359           if(!aV1.IsNull() && !aV2.IsNull() &&
360             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
361           { 
362             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);  
363             if(!aEdge.IsNull())
364             { 
365               aEdges.Bind(key[2],aEdge);
366               aBuilder.Add(aCompound,aEdges(key[2]));
367               if(aCount == aNumOfFace) 
368                 aBuild1.Add(aComp1,aEdges(key[2]));
369             } 
370           } 
371         } 
372       } 
373       
374       if(aCount == aNumOfFace)
375       {
376         aShowFace = drawShape(aComp1,Quantity_NOC_GREEN);
377         getAISContext()->Erase(aShowEdge);
378       }
379     }
380     else
381     {
382       aText += "Can't compute a triangulation on face ";
383       aText += TCollection_AsciiString(aCount) + EOL;
384           GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
385 //      setResultText(aText.ToCString());
386     }
387   }
388   
389   aText += "Number of nodes of the shape = ";
390   aText += TCollection_AsciiString(aNumOfNodes) + EOL;
391   aText += "Number of triangles of the shape = ";
392   aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL;
393   GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
394 //  setResultText(aText.ToCString());
395
396   if(WAIT_A_SECOND) return;
397   drawShape(aCompound,Quantity_NOC_GREEN);
398   getAISContext()->Erase(aShowFace);
399   
400 }
401
402 void Tesselate_Presentation::sample(const Standard_CString aFileName)
403 {
404   CString initfile(((OCC_App*) AfxGetApp())->GetInitDataDir());
405   initfile += "\\..\\..\\..\\samples\\mfc\\standard\\Data\\";
406   initfile += aFileName;
407
408 /*  
409   ResetView();
410   
411   if (aFileName == "wedge_ok.brep"){
412         SetViewCenter(6.3639597574916, 4.4907309380832);
413         SetViewScale(52.722555157077); 
414   }
415
416   if (aFileName == "shell1.brep"){
417         SetViewCenter(60.457553053711, -20.351208944076);
418         SetViewScale(26.857478563027); 
419   }
420
421   if (aFileName == "Pump_Nut.brep"){
422         SetViewCenter(248.77723166710, 77.249633819945);
423         SetViewScale(12.371719671833); 
424   }
425
426   if (aFileName == "Pump_TopCover.brep"){
427         SetViewCenter(408.72474423160, 169.38361094986);
428         SetViewScale(2.1932732873087); 
429   }
430 */
431
432   std::filebuf aFileBuf;
433   std::istream aStream (&aFileBuf);
434   if (!aFileBuf.open (initfile, ios::in))
435   {
436     initfile += L" was not found. The sample can not be shown.";
437     GetDocument()->PocessTextInDialog ("Compute the triangulation on a shape", initfile);
438     return;
439   }
440
441   TopoDS_Shape aShape;
442   BRep_Builder aBld;
443   BRepTools::Read (aShape, aStream, aBld);
444   if (aShape.IsNull())
445   {
446     initfile += L" was not found. The sample can not be shown.";
447     GetDocument()->PocessTextInDialog ("Compute the triangulation on a shape", initfile);
448     return;
449   }
450
451   tesselateShape (aShape);
452 }