7fd59977 |
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> |
7fd59977 |
19 | #include <BRepBuilderAPI_MakeEdge.hxx> |
20 | #include <BRepBuilderAPI_MakeVertex.hxx> |
9a148b08 |
21 | #include <BRepMesh_IncrementalMesh.hxx> |
7fd59977 |
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 | |
50fe2dab |
36 | #define EOL "\r\n" |
7fd59977 |
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 | { |
576f8b11 |
67 | ((CTriangulationApp*) AfxGetApp())->SetSampleName (L"Tesselate"); |
68 | ((CTriangulationApp*) AfxGetApp())->SetSamplePath (L""); |
7fd59977 |
69 | getAISContext()->EraseAll(); |
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 |
92efcf78 |
125 | " Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL |
7fd59977 |
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 |
92efcf78 |
163 | " Handle(Poly_PolygonOnTriangulation) aPol = " EOL |
7fd59977 |
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); |
9a148b08 |
187 | BRepMesh_IncrementalMesh(aShape,aDeflection); |
7fd59977 |
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 | |
7fd59977 |
195 | Standard_Integer aCount = 0; |
196 | Standard_Integer aNumOfNodes = 0; |
197 | Standard_Integer aNumOfTriangles = 0; |
198 | |
92efcf78 |
199 | Handle(AIS_InteractiveObject) aShowEdge,aShowFace,aShowShape; |
7fd59977 |
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 | |
92efcf78 |
210 | Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace,aLocation); |
7fd59977 |
211 | |
212 | if(!aTr.IsNull()) |
213 | { |
214 | const TColgp_Array1OfPnt& aNodes = aTr->Nodes(); |
215 | aNumOfNodes += aTr->NbNodes(); |
5c573e69 |
216 | //Standard_Integer aLower = aNodes.Lower(); |
217 | //Standard_Integer anUpper = aNodes.Upper(); |
7fd59977 |
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 | { |
92efcf78 |
234 | Handle(Poly_PolygonOnTriangulation) aPol = |
7fd59977 |
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(); |
273 | aShowShape = drawShape(aShape); |
274 | if(WAIT_A_SECOND) return; |
275 | aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN); |
276 | getAISContext()->Erase(aShowShape); |
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); |
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); |
393 | |
394 | } |
395 | |
396 | void Tesselate_Presentation::sample(const Standard_CString aFileName) |
397 | { |
576f8b11 |
398 | CString initfile(((OCC_App*) AfxGetApp())->GetInitDataDir()); |
3554ea68 |
399 | initfile += "..\\..\\..\\Data\\"; |
576f8b11 |
400 | initfile += aFileName; |
7fd59977 |
401 | |
7fd59977 |
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 | |
576f8b11 |
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 | |
7fd59977 |
435 | TopoDS_Shape aShape; |
436 | BRep_Builder aBld; |
576f8b11 |
437 | BRepTools::Read (aShape, aStream, aBld); |
438 | if (aShape.IsNull()) |
7fd59977 |
439 | { |
576f8b11 |
440 | initfile += L" was not found. The sample can not be shown."; |
441 | GetDocument()->PocessTextInDialog ("Compute the triangulation on a shape", initfile); |
7fd59977 |
442 | return; |
443 | } |
444 | |
445 | tesselateShape (aShape); |
7fd59977 |
446 | } |