0022735: Data races in BRepMesh working in parallel mode
[occt.git] / src / MeshTest / MeshTest_PluginCommands.cxx
CommitLineData
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
33static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** );
34static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
35static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
36static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
37static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
38static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** );
39static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** );
0b97567d 40static Standard_Integer mpparallel (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 41static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** );
e1bcbb52 42static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 43
44//=======================================================================
45//function : PluginCommands
46//purpose :
47//=======================================================================
48void 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//=======================================================================
76static 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//=======================================================================
106static 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//=======================================================================
128static 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//=======================================================================
144static 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//=======================================================================
166static 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//=======================================================================
182static 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//=======================================================================
201static 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//#######################################################################
249static 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 318static 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//=======================================================================
420static 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}