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