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