Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: MeshTest_PluginCommands.cxx |
2 | // Created: Fri Apr 11 15:41:24 2008 | |
3 | // Author: Peter KURNEV | |
4 | // <pkv@irinox> | |
5 | ||
6 | #include <MeshTest.ixx> | |
7 | #include <Draw_Interpretor.hxx> | |
8 | #include <TColStd_MapOfAsciiString.hxx> | |
9 | #include <BRepMesh_DiscretFactory.hxx> | |
10 | #include <TCollection_AsciiString.hxx> | |
11 | #include <TColStd_MapIteratorOfMapOfAsciiString.hxx> | |
12 | #include <BRepMesh_FactoryError.hxx> | |
13 | #include <BRepMesh_DiscretRoot.hxx> | |
0b97567d | 14 | #include <BRepMesh_IncrementalMesh.hxx> |
7fd59977 | 15 | #include <Bnd_Box.hxx> |
16 | #include <BRepMesh_PDiscretRoot.hxx> | |
17 | #include <DBRep.hxx> | |
18 | #include <TopTools_IndexedMapOfShape.hxx> | |
19 | #include <TopExp.hxx> | |
20 | #include <Poly_Triangulation.hxx> | |
21 | #include <gp_Vec.hxx> | |
22 | #include <GProp_GProps.hxx> | |
23 | #include <BRepGProp.hxx> | |
24 | #include <DrawTrSurf.hxx> | |
25 | #include <BRep_Tool.hxx> | |
26 | #include <TopoDS.hxx> | |
27 | #include <MeshTest_CheckTopology.hxx> | |
28 | #include <TColgp_Array1OfPnt2d.hxx> | |
29 | #include <Poly_Polygon3D.hxx> | |
30 | #include <Poly_Polygon2D.hxx> | |
ca0db031 | 31 | #include <Standard.hxx> |
7fd59977 | 32 | |
33 | static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** ); | |
34 | static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** ); | |
35 | static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** ); | |
36 | static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** ); | |
37 | static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** ); | |
38 | static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** ); | |
39 | static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** ); | |
0b97567d | 40 | static Standard_Integer mpparallel (Draw_Interpretor& , Standard_Integer , const char** ); |
7fd59977 | 41 | static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** ); |
e1bcbb52 | 42 | static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** ); |
7fd59977 | 43 | |
44 | //======================================================================= | |
45 | //function : PluginCommands | |
46 | //purpose : | |
47 | //======================================================================= | |
48 | void MeshTest::PluginCommands(Draw_Interpretor& theCommands) | |
49 | { | |
50 | static Standard_Boolean done = Standard_False; | |
51 | if (done) { | |
52 | return; | |
53 | } | |
54 | done = Standard_True; | |
55 | // | |
56 | const char* g = "Mesh Commands"; | |
57 | // Commands | |
58 | theCommands.Add("mpnames" , "use mpnames" , __FILE__, mpnames , g); | |
59 | theCommands.Add("mpsetdefaultname" , "use mpsetdefaultname" , __FILE__, mpsetdefaultname , g); | |
60 | theCommands.Add("mpgetdefaultname" , "use mpgetdefaultname" , __FILE__, mpgetdefaultname , g); | |
61 | theCommands.Add("mpsetfunctionname", "use mpsetfunctionname", __FILE__, mpsetfunctionname , g); | |
62 | theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname , g); | |
63 | theCommands.Add("mperror" , "use mperror" , __FILE__, mperror , g); | |
64 | theCommands.Add("mpincmesh" , "use mpincmesh" , __FILE__, mpincmesh , g); | |
0b97567d K |
65 | theCommands.Add("mpparallel" , "mpparallel [toTurnOn] : show / set multi-threading flag for incremental mesh", |
66 | __FILE__, mpparallel, g); | |
7fd59977 | 67 | theCommands.Add("triarea","shape [eps] (computes triangles and surface area)",__FILE__, triarea, g); |
e1bcbb52 | 68 | theCommands.Add("tricheck", "shape (checks triangulation of shape)", __FILE__, tricheck, g); |
7fd59977 | 69 | |
70 | } | |
71 | ||
72 | //======================================================================= | |
73 | //function : mpnames | |
74 | //purpose : | |
75 | //======================================================================= | |
76 | static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer n, const char** ) | |
77 | { | |
78 | Standard_Integer aNb; | |
79 | TColStd_MapIteratorOfMapOfAsciiString aIt; | |
80 | // | |
81 | if (n!=1) { | |
82 | printf(" use mpnames\n"); | |
83 | return 0; | |
84 | } | |
85 | // | |
86 | const TColStd_MapOfAsciiString& aMN=BRepMesh_DiscretFactory::Get().Names(); | |
87 | aNb=aMN.Extent(); | |
88 | if (!aNb) { | |
89 | printf(" *no names found\n"); | |
90 | return 0; | |
91 | } | |
92 | // | |
93 | printf(" *available names:\n"); | |
94 | aIt.Initialize(aMN); | |
95 | for (; aIt.More(); aIt.Next()) { | |
96 | const TCollection_AsciiString& aName=aIt.Key(); | |
97 | printf(" %s\n", aName.ToCString()); | |
98 | } | |
99 | // | |
100 | return 0; | |
101 | } | |
102 | //======================================================================= | |
103 | //function : mpsetdefaultname | |
104 | //purpose : | |
105 | //======================================================================= | |
106 | static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer n, const char**a ) | |
107 | { | |
108 | TCollection_AsciiString aName; | |
109 | // | |
110 | if (n!=2) { | |
111 | printf(" use mpsetdefaultname name\n"); | |
112 | return 0; | |
113 | } | |
114 | // | |
115 | aName=a[1]; | |
116 | // | |
0b97567d K |
117 | if (BRepMesh_DiscretFactory::Get().SetDefaultName (aName)) |
118 | printf(" *ready\n"); | |
119 | else | |
120 | printf(" *fault\n"); | |
7fd59977 | 121 | // |
122 | return 0; | |
123 | } | |
124 | //======================================================================= | |
125 | //function : mpgetdefaultname | |
126 | //purpose : | |
127 | //======================================================================= | |
128 | static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer n, const char** ) | |
129 | { | |
130 | if (n!=1) { | |
131 | printf(" use mpgetdefaultname\n"); | |
132 | return 0; | |
133 | } | |
134 | // | |
135 | const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().DefaultName(); | |
136 | printf(" *default name: %s\n", aName.ToCString()); | |
137 | // | |
138 | return 0; | |
139 | } | |
140 | //======================================================================= | |
141 | //function : mpsetfunctionname | |
142 | //purpose : | |
143 | //======================================================================= | |
144 | static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer n, const char**a ) | |
145 | { | |
146 | TCollection_AsciiString aName; | |
147 | // | |
148 | if (n!=2) { | |
149 | printf(" use mpsetfunctionname name\n"); | |
150 | return 0; | |
151 | } | |
152 | // | |
153 | aName=a[1]; | |
154 | // | |
0b97567d K |
155 | if (BRepMesh_DiscretFactory::Get().SetFunctionName (aName)) |
156 | printf(" *ready\n"); | |
157 | else | |
158 | printf(" *fault\n"); | |
7fd59977 | 159 | // |
160 | return 0; | |
161 | } | |
162 | //======================================================================= | |
163 | //function : mpgetdefaultname | |
164 | //purpose : | |
165 | //======================================================================= | |
166 | static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer n, const char** ) | |
167 | { | |
168 | if (n!=1) { | |
169 | printf(" use mpgetfunctionname\n"); | |
170 | return 0; | |
171 | } | |
172 | // | |
173 | const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().FunctionName(); | |
174 | printf(" *function name: %s\n", aName.ToCString()); | |
175 | // | |
176 | return 0; | |
177 | } | |
178 | //======================================================================= | |
179 | //function : mperror | |
180 | //purpose : | |
181 | //======================================================================= | |
182 | static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer n, const char** ) | |
183 | { | |
184 | BRepMesh_FactoryError aErr; | |
185 | // | |
186 | if (n!=1) { | |
187 | printf(" use mperror\n"); | |
188 | return 0; | |
189 | } | |
190 | // | |
191 | aErr=BRepMesh_DiscretFactory::Get().ErrorStatus(); | |
192 | printf(" *ErrorStatus: %d\n", (int)aErr); | |
193 | // | |
194 | return 0; | |
195 | } | |
196 | ||
197 | //======================================================================= | |
198 | //function :mpincmesh | |
199 | //purpose : | |
200 | //======================================================================= | |
201 | static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const char** a) | |
202 | { | |
7fd59977 | 203 | Standard_Real aDeflection, aAngle; |
204 | TopoDS_Shape aS; | |
7fd59977 | 205 | // |
206 | if (n<3) { | |
207 | printf(" use mpincmesh s deflection [angle]\n"); | |
208 | return 0; | |
209 | } | |
210 | // | |
211 | aS=DBRep::Get(a[1]); | |
212 | if (aS.IsNull()) { | |
213 | printf(" null shapes is not allowed here\n"); | |
214 | return 0; | |
215 | } | |
216 | // | |
217 | aDeflection=atof(a[2]); | |
218 | aAngle=0.5; | |
219 | if (n>3) { | |
220 | aAngle=atof(a[3]); | |
221 | } | |
222 | // | |
0b97567d K |
223 | Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (aS, |
224 | aDeflection, | |
225 | aAngle); | |
7fd59977 | 226 | // |
0b97567d K |
227 | BRepMesh_FactoryError aErr = BRepMesh_DiscretFactory::Get().ErrorStatus(); |
228 | if (aErr != BRepMesh_FE_NOERROR) | |
229 | { | |
7fd59977 | 230 | printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr); |
231 | } | |
232 | // | |
0b97567d K |
233 | if (aMeshAlgo.IsNull()) |
234 | { | |
7fd59977 | 235 | printf(" *Can not create the algo\n"); |
236 | return 0; | |
237 | } | |
238 | // | |
0b97567d K |
239 | aMeshAlgo->Perform(); |
240 | if (!aMeshAlgo->IsDone()) | |
241 | { | |
7fd59977 | 242 | printf(" *Not done\n"); |
243 | } | |
244 | // | |
245 | return 0; | |
246 | } | |
247 | ||
248 | //####################################################################### | |
249 | static Standard_Integer triarea (Draw_Interpretor& di, int n, const char ** a) | |
250 | { | |
251 | ||
252 | if (n < 2) return 1; | |
253 | ||
254 | TopoDS_Shape shape = DBRep::Get(a[1]); | |
255 | if (shape.IsNull()) return 1; | |
256 | Standard_Real anEps = -1.; | |
257 | if (n > 2) | |
258 | anEps = atof(a[2]); | |
259 | ||
260 | TopTools_IndexedMapOfShape aMapF; | |
261 | TopExp::MapShapes (shape, TopAbs_FACE, aMapF); | |
262 | ||
263 | // detect if a shape has triangulation | |
264 | Standard_Boolean hasPoly = Standard_False; | |
265 | int i; | |
266 | for (i=1; i <= aMapF.Extent(); i++) { | |
267 | const TopoDS_Face& aFace = TopoDS::Face(aMapF(i)); | |
268 | TopLoc_Location aLoc; | |
269 | Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); | |
270 | if (!aPoly.IsNull()) { | |
271 | hasPoly = Standard_True; | |
272 | break; | |
273 | } | |
274 | } | |
275 | ||
276 | // compute area by triangles | |
277 | double aTriArea=0; | |
278 | if (hasPoly) { | |
279 | for (i=1; i <= aMapF.Extent(); i++) { | |
280 | const TopoDS_Face& aFace = TopoDS::Face(aMapF(i)); | |
281 | TopLoc_Location aLoc; | |
282 | Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); | |
283 | if (aPoly.IsNull()) { | |
e1bcbb52 O |
284 | cout << "face "<<i<<" has no triangulation"<<endl; |
285 | continue; | |
7fd59977 | 286 | } |
287 | const Poly_Array1OfTriangle& triangles = aPoly->Triangles(); | |
288 | const TColgp_Array1OfPnt& nodes = aPoly->Nodes(); | |
289 | for (int j=triangles.Lower(); j <= triangles.Upper(); j++) { | |
e1bcbb52 O |
290 | const Poly_Triangle& tri = triangles(j); |
291 | int n1, n2, n3; | |
292 | tri.Get (n1, n2, n3); | |
293 | const gp_Pnt& p1 = nodes(n1); | |
294 | const gp_Pnt& p2 = nodes(n2); | |
295 | const gp_Pnt& p3 = nodes(n3); | |
296 | gp_Vec v1(p1, p2); | |
297 | gp_Vec v2(p1, p3); | |
298 | double ar = v1.CrossMagnitude(v2); | |
299 | aTriArea += ar; | |
7fd59977 | 300 | } |
301 | } | |
302 | aTriArea /= 2; | |
303 | } | |
304 | ||
305 | // compute area by geometry | |
306 | GProp_GProps props; | |
307 | if (anEps <= 0.) | |
308 | BRepGProp::SurfaceProperties(shape, props); | |
309 | else | |
310 | BRepGProp::SurfaceProperties(shape, props, anEps); | |
311 | double aGeomArea = props.Mass(); | |
312 | ||
d2c43192 | 313 | di << aTriArea << " " << aGeomArea << "\n"; |
7fd59977 | 314 | return 0; |
315 | } | |
316 | ||
317 | //####################################################################### | |
e1bcbb52 | 318 | static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a) |
7fd59977 | 319 | { |
320 | if (n < 2) return 1; | |
321 | ||
322 | TopoDS_Shape shape = DBRep::Get(a[1]); | |
323 | if (shape.IsNull()) return 1; | |
324 | ||
325 | TopTools_IndexedMapOfShape aMapF; | |
326 | TopExp::MapShapes (shape, TopAbs_FACE, aMapF); | |
327 | Standard_CString name = "."; | |
328 | ||
446e11f3 | 329 | // execute check |
7fd59977 | 330 | MeshTest_CheckTopology aCheck(shape); |
d2c43192 | 331 | aCheck.Perform(di); |
446e11f3 A |
332 | |
333 | // dump info on free links inside the triangulation | |
7fd59977 | 334 | Standard_Integer nbFree = 0; |
335 | Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k; | |
336 | if (nbFac > 0) { | |
337 | for (k=1; k <= nbFac; k++) { | |
338 | Standard_Integer nbEdge = aCheck.NbFreeLinks(k); | |
339 | Standard_Integer iF = aCheck.GetFaceNumWithFL(k); | |
340 | nbFree += nbEdge; | |
d2c43192 | 341 | di << "free links of face " << iF << "\n"; |
7fd59977 | 342 | const TopoDS_Face& aFace = TopoDS::Face(aMapF.FindKey(iF)); |
343 | TopLoc_Location aLoc; | |
344 | Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc); | |
345 | const TColgp_Array1OfPnt& aPoints = aT->Nodes(); | |
346 | const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes(); | |
347 | const gp_Trsf& trsf = aLoc.Transformation(); | |
348 | TColgp_Array1OfPnt pnts(1,2); | |
349 | TColgp_Array1OfPnt2d pnts2d(1,2); | |
350 | for (i=1; i <= nbEdge; i++) { | |
e1bcbb52 O |
351 | Standard_Integer n1, n2; |
352 | aCheck.GetFreeLink(k, i, n1, n2); | |
d2c43192 | 353 | di << "{" << n1 << " " << n2 << "} "; |
e1bcbb52 O |
354 | pnts(1) = aPoints(n1).Transformed(trsf); |
355 | pnts(2) = aPoints(n2).Transformed(trsf); | |
356 | Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts); | |
357 | DrawTrSurf::Set (name, poly); | |
358 | DrawTrSurf::Set (name, pnts(1)); | |
359 | DrawTrSurf::Set (name, pnts(2)); | |
360 | pnts2d(1) = aPoints2d(n1); | |
361 | pnts2d(2) = aPoints2d(n2); | |
362 | Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d); | |
363 | DrawTrSurf::Set (name, poly2d); | |
364 | DrawTrSurf::Set (name, pnts2d(1)); | |
365 | DrawTrSurf::Set (name, pnts2d(2)); | |
7fd59977 | 366 | } |
d2c43192 | 367 | di << "\n"; |
7fd59977 | 368 | } |
369 | } | |
370 | ||
446e11f3 | 371 | // dump info on cross face errors |
7fd59977 | 372 | Standard_Integer nbErr = aCheck.NbCrossFaceErrors(); |
373 | if (nbErr > 0) { | |
d2c43192 | 374 | di << "cross face errors: {face1, node1, face2, node2, distance}" << "\n"; |
7fd59977 | 375 | for (i=1; i <= nbErr; i++) { |
376 | Standard_Integer iF1, n1, iF2, n2; | |
377 | Standard_Real aVal; | |
378 | aCheck.GetCrossFaceError(i, iF1, n1, iF2, n2, aVal); | |
d2c43192 | 379 | di << "{" << iF1 << " " << n1 << " " << iF2 << " " << n2 << " " << aVal << "} "; |
7fd59977 | 380 | } |
d2c43192 | 381 | di << "\n"; |
7fd59977 | 382 | } |
383 | ||
446e11f3 | 384 | // dump info on edges |
7fd59977 | 385 | Standard_Integer nbAsync = aCheck.NbAsyncEdges(); |
386 | if (nbAsync > 0) { | |
d2c43192 | 387 | di << "async edges:" << "\n"; |
7fd59977 | 388 | for (i=1; i <= nbAsync; i++) { |
389 | Standard_Integer ie = aCheck.GetAsyncEdgeNum(i); | |
d2c43192 | 390 | di << ie << " "; |
7fd59977 | 391 | } |
d2c43192 | 392 | di << "\n"; |
7fd59977 | 393 | } |
394 | ||
446e11f3 A |
395 | // dump info on free nodes |
396 | Standard_Integer nbFreeNodes = aCheck.NbFreeNodes(); | |
397 | if (nbFreeNodes > 0) { | |
d2c43192 | 398 | di << "free nodes (in pairs: face / node): " << "\n"; |
446e11f3 A |
399 | for (i=1; i <= nbFreeNodes; i++) { |
400 | Standard_Integer iface, inode; | |
401 | aCheck.GetFreeNodeNum(i, iface, inode); | |
d2c43192 | 402 | di << "{" << iface << " " << inode << "} "; |
446e11f3 | 403 | } |
d2c43192 | 404 | di << "\n"; |
446e11f3 A |
405 | } |
406 | ||
407 | // output errors summary to DRAW | |
408 | if ( nbFree > 0 || nbErr > 0 || nbAsync > 0 || nbFreeNodes > 0 ) | |
409 | di << "Free_links " << nbFree | |
410 | << " Cross_face_errors " << nbErr | |
411 | << " Async_edges " << nbAsync | |
d2c43192 | 412 | << " Free_nodes " << nbFreeNodes << "\n"; |
7fd59977 | 413 | return 0; |
414 | } | |
0b97567d K |
415 | |
416 | //======================================================================= | |
417 | //function : mpparallel | |
418 | //purpose : | |
419 | //======================================================================= | |
420 | static int mpparallel (Draw_Interpretor& di, Standard_Integer argc, const char** argv) | |
421 | { | |
422 | if (argc == 2) | |
423 | { | |
424 | Standard_Boolean isParallelOn = atoi (argv[1]) == 1; | |
425 | BRepMesh_IncrementalMesh::SetParallelDefault (isParallelOn); | |
ca0db031 K |
426 | if (isParallelOn) |
427 | Standard::SetReentrant(Standard_True); | |
0b97567d K |
428 | } |
429 | std::cout << "Incremental Mesh, multi-threading " | |
430 | << (BRepMesh_IncrementalMesh::IsParallelDefault() ? "ON\n" : "OFF\n"); | |
431 | return 0; | |
432 | } |