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