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> |
19 | #include <BRepMesh.hxx> |
20 | #include <BRepBuilderAPI_MakeEdge.hxx> |
21 | #include <BRepBuilderAPI_MakeVertex.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("Tesselate"); |
73 | ((CTriangulationApp*) AfxGetApp())->SetSamplePath(""); |
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::Mesh(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_BaseApp*) AfxGetApp())->GetInitDataDir()); |
405 | initfile += "\\..\\..\\Data\\"; |
406 | initfile += aFileName; |
407 | |
408 | |
409 | TCollection_AsciiString Path((Standard_CString)(LPCTSTR)initfile); |
410 | /* |
411 | ResetView(); |
412 | |
413 | if (aFileName == "wedge_ok.brep"){ |
414 | SetViewCenter(6.3639597574916, 4.4907309380832); |
415 | SetViewScale(52.722555157077); |
416 | } |
417 | |
418 | if (aFileName == "shell1.brep"){ |
419 | SetViewCenter(60.457553053711, -20.351208944076); |
420 | SetViewScale(26.857478563027); |
421 | } |
422 | |
423 | if (aFileName == "Pump_Nut.brep"){ |
424 | SetViewCenter(248.77723166710, 77.249633819945); |
425 | SetViewScale(12.371719671833); |
426 | } |
427 | |
428 | if (aFileName == "Pump_TopCover.brep"){ |
429 | SetViewCenter(408.72474423160, 169.38361094986); |
430 | SetViewScale(2.1932732873087); |
431 | } |
432 | */ |
433 | |
434 | TopoDS_Shape aShape; |
435 | BRep_Builder aBld; |
436 | //Standard_Boolean isRead = BRepTools::Read (aShape, aPath.ToCString(), aBld); |
437 | //if (!isRead) |
438 | // isRead = BRepTools::Read (aShape, bPath.ToCString(), aBld); |
439 | Standard_Boolean isRead = BRepTools::Read (aShape, Path.ToCString(), aBld); |
440 | if (!isRead) |
441 | { |
442 | Path += " was not found. The sample can not be shown."; |
443 | GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", Path); |
444 | // setResultText(Path.ToCString()); |
445 | return; |
446 | } |
447 | |
448 | tesselateShape (aShape); |
449 | |
450 | } |