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 
Tesselate_Presentation()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 
DoSample()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 
_key(Standard_Integer n1,Standard_Integer n2)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 
tesselateShape(const TopoDS_Shape & aShape)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     "    // create array of node points in absolute coordinate system" EOL
130     "    TColgp_Array1OfPnt aPoints(1, aTr->NbNodes());" EOL
131     "    for( Standard_Integer i = 1; i < aTr->NbNodes()+1; i++)" EOL
132     "      aPoints(i) = aTr->Node (i).Transformed (aLocation);" EOL EOL
133 
134     "    // Takes the node points of each triangle of this triangulation." EOL
135     "    // takes a number of triangles:" EOL
136     "    Standard_Integer nnn = aTr->NbTriangles();" EOL
137     "    Standard_Integer nt,n1,n2,n3;" EOL
138     "    for( nt = 1 ; nt < nnn+1 ; nt++)" EOL
139     "    {" EOL
140     "      // takes the node indices of each triangle in n1,n2,n3:" EOL
141     "      aTr->Triangle (nt).Get (n1,n2,n3);" EOL
142     "      // takes the node points:" EOL
143     "      gp_Pnt aPnt1 = aPoints(n1);" EOL
144     "      gp_Pnt aPnt2 = aPoints(n2);" EOL
145     "      gp_Pnt aPnt3 = aPoints(n3);" EOL
146     "    } " EOL EOL
147 
148     "    // Takes the polygon associated to an edge." EOL
149     "    aExpEdge.Init(aFace,TopAbs_EDGE);" EOL
150     "    TopoDS_Edge aEdge;" EOL
151     "    // for example,working with the first edge:" EOL
152     "    if(aExpEdge.More())" EOL
153     "      aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL
154 
155     "    if(!aEdge.IsNull()) // if this edge is not NULL" EOL
156     "    {" EOL
157     "      // takes the polygon associated to the edge aEdge:" EOL
158     "      Handle(Poly_PolygonOnTriangulation) aPol = " EOL
159     "        BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL
160 
161     "      if(!aPol.IsNull()) // if this polygon is not NULL" EOL
162     "        // takes the array of nodes for this polygon" EOL
163     "        // (indexes in the array of nodes for triangulation of theFace):" EOL
164     "        const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL
165     "    }" EOL
166     "  }" EOL
167     "}" EOL EOL
168 
169     "//==================================================" EOL EOL
170 
171       ;
172    aText += "  Result with deflection = ";
173    aText += TCollection_AsciiString(aDeflection);
174    aText += " :" EOL;
175 
176    GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
177 //   setResultText(aText.ToCString());
178 
179 //==========================================================================
180 
181   BRepTools::Clean(aShape);
182   BRepMesh_IncrementalMesh(aShape,aDeflection);
183 
184   BRep_Builder aBuilder,aBuild1,aBuild2;
185   TopoDS_Compound aCompound,aComp1,aComp2;
186   aBuilder.MakeCompound(aCompound);
187   aBuild1.MakeCompound(aComp1);
188   aBuild2.MakeCompound(aComp2);
189 
190   Standard_Integer aCount = 0;
191   Standard_Integer aNumOfNodes = 0;
192   Standard_Integer aNumOfTriangles = 0;
193 
194   Handle(AIS_InteractiveObject) aShowEdge,aShowFace,aShowShape;
195 
196   TopExp_Explorer aExpFace,aExpEdge;
197 
198   for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())
199   {
200     aCount++;
201 
202     TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
203     TopLoc_Location aLocation;
204 
205     Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace,aLocation);
206 
207     if(!aTr.IsNull())
208     {
209       aNumOfNodes += aTr->NbNodes();
210       //Standard_Integer aLower = aNodes.Lower();
211       //Standard_Integer anUpper = aNodes.Upper();
212       aNumOfTriangles += aTr->NbTriangles();
213 
214       if(aCount == aNumOfFace)
215       {
216         Standard_Integer aNbOfNodesOfFace = aTr->NbNodes();
217         Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles();
218         aExpEdge.Init(aFace,TopAbs_EDGE);
219 
220         TopoDS_Edge aEdge;
221 
222         for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++)
223           aEdge = TopoDS::Edge(aExpEdge.Current());
224 
225         if(!aEdge.IsNull())
226         {
227           Handle(Poly_PolygonOnTriangulation) aPol =
228             BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());
229 
230           if(!aPol.IsNull())
231           {
232             const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();
233             Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes();
234 
235             aText += "Number of nodes of the edge = ";
236             aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL;
237             aText += "Number of nodes of the face = ";
238             aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL;
239             aText += "Number of triangles of the face = ";
240             aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL;
241 			GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
242 //            setResultText(aText.ToCString());
243 
244             Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper();
245             for( int i = aLower; i < anUpper ; i++)
246             {
247               gp_Pnt aPnt1 = aTr->Node (aNodesOfPol (i)).Transformed (aLocation);
248               gp_Pnt aPnt2 = aTr->Node (aNodesOfPol (i+1)).Transformed (aLocation);
249               TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1);
250               TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2);
251 
252               if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive"
253                 !BRep_Tool::Pnt(aVertex1).IsEqual(
254                 BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different
255               {
256                 aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2);
257                 aBuild2.Add(aComp2,aVertex1);
258                 if(!aEdge.IsNull())
259                   aBuild2.Add(aComp2,aEdge);
260                 if(i == anUpper-1)
261                   aBuild2.Add(aComp2,aVertex2);
262               }
263             }
264 
265             getAISContext()->EraseAll (Standard_False);
266             aShowShape = drawShape(aShape);
267             if(WAIT_A_SECOND) return;
268             aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN);
269             getAISContext()->Erase (aShowShape, Standard_True);
270             if(WAIT_A_SECOND) return;
271           }
272         }
273       }
274 
275 
276       TopTools_DataMapOfIntegerShape aEdges;
277       TopTools_SequenceOfShape aVertices;
278 
279       for( Standard_Integer i = 1; i < aTr->NbNodes()+1; i++)
280       {
281         gp_Pnt aPnt = aTr->Node (i).Transformed (aLocation);
282         TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt);
283 
284         if(!aVertex.IsNull())
285         {
286           aBuilder.Add(aCompound,aVertex);
287           if(aCount == aNumOfFace )
288             aBuild1.Add(aComp1,aVertex);
289           aVertices.Append(aVertex);
290         }
291       }
292 
293       Standard_Integer nnn = aTr->NbTriangles();
294       Standard_Integer nt,n1,n2,n3;
295 
296       for( nt = 1 ; nt < nnn+1 ; nt++)
297       {
298         aTr->Triangle (nt).Get (n1,n2,n3);
299 
300         Standard_Integer key[3];
301 
302         TopoDS_Vertex aV1,aV2;
303         key[0] = _key(n1, n2);
304         if(!aEdges.IsBound(key[0]))
305         {
306           aV1 = TopoDS::Vertex(aVertices(n1));
307           aV2 = TopoDS::Vertex(aVertices(n2));
308           if(!aV1.IsNull() && !aV2.IsNull() &&
309             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
310           {
311             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);
312             if(!aEdge.IsNull())
313             {
314               aEdges.Bind(key[0], aEdge);
315               aBuilder.Add(aCompound,aEdges(key[0]));
316               if(aCount == aNumOfFace)
317                 aBuild1.Add(aComp1,aEdges(key[0]));
318             }
319           }
320         }
321 
322         key[1] = _key(n2,n3);
323         if(!aEdges.IsBound(key[1]))
324         {
325           aV1 = TopoDS::Vertex(aVertices(n2));
326           aV2 = TopoDS::Vertex(aVertices(n3));
327           if(!aV1.IsNull() && !aV2.IsNull() &&
328             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
329           {
330             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);
331             if(!aEdge.IsNull())
332             {
333               aEdges.Bind(key[1],aEdge);
334               aBuilder.Add(aCompound,aEdges(key[1]));
335               if(aCount == aNumOfFace)
336                 aBuild1.Add(aComp1,aEdges(key[1]));
337             }
338           }
339         }
340 
341         key[2] = _key(n3,n1);
342         if(!aEdges.IsBound(key[2]))
343         {
344           aV1 = TopoDS::Vertex(aVertices(n3));
345           aV2 = TopoDS::Vertex(aVertices(n1));
346           if(!aV1.IsNull() && !aV2.IsNull() &&
347             !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion()))
348           {
349             TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2);
350             if(!aEdge.IsNull())
351             {
352               aEdges.Bind(key[2],aEdge);
353               aBuilder.Add(aCompound,aEdges(key[2]));
354               if(aCount == aNumOfFace)
355                 aBuild1.Add(aComp1,aEdges(key[2]));
356             }
357           }
358         }
359       }
360 
361       if(aCount == aNumOfFace)
362       {
363         aShowFace = drawShape(aComp1,Quantity_NOC_GREEN);
364         getAISContext()->Erase (aShowEdge, Standard_True);
365       }
366     }
367     else
368     {
369       aText += "Can't compute a triangulation on face ";
370       aText += TCollection_AsciiString(aCount) + EOL;
371 	  GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
372 //      setResultText(aText.ToCString());
373     }
374   }
375 
376   aText += "Number of nodes of the shape = ";
377   aText += TCollection_AsciiString(aNumOfNodes) + EOL;
378   aText += "Number of triangles of the shape = ";
379   aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL;
380   GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText);
381 //  setResultText(aText.ToCString());
382 
383   if(WAIT_A_SECOND) return;
384   drawShape(aCompound,Quantity_NOC_GREEN);
385   getAISContext()->Erase (aShowFace, Standard_True);
386 
387 }
388 
sample(const Standard_CString aFileName)389 void Tesselate_Presentation::sample(const Standard_CString aFileName)
390 {
391   CString anOCCTDataPathValue;
392   anOCCTDataPathValue.GetEnvironmentVariable(L"CSF_OCCTDataPath");
393   CString initfile = (anOCCTDataPathValue + L"\\occ\\" + aFileName);
394 
395 /*
396   ResetView();
397 
398   if (aFileName == "wedge_ok.brep"){
399 	SetViewCenter(6.3639597574916, 4.4907309380832);
400 	SetViewScale(52.722555157077);
401   }
402 
403   if (aFileName == "shell1.brep"){
404 	SetViewCenter(60.457553053711, -20.351208944076);
405 	SetViewScale(26.857478563027);
406   }
407 
408   if (aFileName == "Pump_Nut.brep"){
409 	SetViewCenter(248.77723166710, 77.249633819945);
410 	SetViewScale(12.371719671833);
411   }
412 
413   if (aFileName == "Pump_TopCover.brep"){
414 	SetViewCenter(408.72474423160, 169.38361094986);
415 	SetViewScale(2.1932732873087);
416   }
417 */
418 
419   std::filebuf aFileBuf;
420   std::istream aStream (&aFileBuf);
421   if (!aFileBuf.open (initfile, std::ios::in))
422   {
423     initfile += L" was not found. The sample can not be shown.";
424     GetDocument()->PocessTextInDialog ("Compute the triangulation on a shape", initfile);
425     return;
426   }
427 
428   TopoDS_Shape aShape;
429   BRep_Builder aBld;
430   BRepTools::Read (aShape, aStream, aBld);
431   if (aShape.IsNull())
432   {
433     initfile += L" was not found. The sample can not be shown.";
434     GetDocument()->PocessTextInDialog ("Compute the triangulation on a shape", initfile);
435     return;
436   }
437 
438   tesselateShape (aShape);
439 }
440