0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / MeshTest / MeshTest_PluginCommands.cxx
CommitLineData
b311480e 1// Created on: 2008-04-11
2// Created by: Peter KURNEV
3// Copyright (c) 2008-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#include <MeshTest.ixx>
22#include <Draw_Interpretor.hxx>
23#include <TColStd_MapOfAsciiString.hxx>
24#include <BRepMesh_DiscretFactory.hxx>
25#include <TCollection_AsciiString.hxx>
26#include <TColStd_MapIteratorOfMapOfAsciiString.hxx>
27#include <BRepMesh_FactoryError.hxx>
28#include <BRepMesh_DiscretRoot.hxx>
0b97567d 29#include <BRepMesh_IncrementalMesh.hxx>
7fd59977 30#include <Bnd_Box.hxx>
31#include <BRepMesh_PDiscretRoot.hxx>
91322f44 32#include <Draw.hxx>
7fd59977 33#include <DBRep.hxx>
34#include <TopTools_IndexedMapOfShape.hxx>
35#include <TopExp.hxx>
36#include <Poly_Triangulation.hxx>
37#include <gp_Vec.hxx>
38#include <GProp_GProps.hxx>
39#include <BRepGProp.hxx>
40#include <DrawTrSurf.hxx>
41#include <BRep_Tool.hxx>
42#include <TopoDS.hxx>
43#include <MeshTest_CheckTopology.hxx>
44#include <TColgp_Array1OfPnt2d.hxx>
45#include <Poly_Polygon3D.hxx>
46#include <Poly_Polygon2D.hxx>
ca0db031 47#include <Standard.hxx>
2e1a4dae 48#include <TopExp_Explorer.hxx>
49#include <TColStd_Array1OfInteger.hxx>
50#include <Poly_PolygonOnTriangulation.hxx>
51#include <TopoDS_Face.hxx>
52#include <BRepMesh_Edge.hxx>
53#include <NCollection_Map.hxx>
7fd59977 54
55static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** );
56static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
57static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
58static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
59static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
60static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** );
61static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** );
0b97567d 62static Standard_Integer mpparallel (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 63static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** );
e1bcbb52 64static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 65
66//=======================================================================
67//function : PluginCommands
68//purpose :
69//=======================================================================
70void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
71{
72 static Standard_Boolean done = Standard_False;
73 if (done) {
74 return;
75 }
76 done = Standard_True;
77 //
78 const char* g = "Mesh Commands";
79 // Commands
80 theCommands.Add("mpnames" , "use mpnames" , __FILE__, mpnames , g);
81 theCommands.Add("mpsetdefaultname" , "use mpsetdefaultname" , __FILE__, mpsetdefaultname , g);
82 theCommands.Add("mpgetdefaultname" , "use mpgetdefaultname" , __FILE__, mpgetdefaultname , g);
83 theCommands.Add("mpsetfunctionname", "use mpsetfunctionname", __FILE__, mpsetfunctionname , g);
84 theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname , g);
85 theCommands.Add("mperror" , "use mperror" , __FILE__, mperror , g);
86 theCommands.Add("mpincmesh" , "use mpincmesh" , __FILE__, mpincmesh , g);
0b97567d
K
87 theCommands.Add("mpparallel" , "mpparallel [toTurnOn] : show / set multi-threading flag for incremental mesh",
88 __FILE__, mpparallel, g);
7fd59977 89 theCommands.Add("triarea","shape [eps] (computes triangles and surface area)",__FILE__, triarea, g);
e1bcbb52 90 theCommands.Add("tricheck", "shape (checks triangulation of shape)", __FILE__, tricheck, g);
7fd59977 91
92}
93
94//=======================================================================
95//function : mpnames
96//purpose :
97//=======================================================================
98static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer n, const char** )
99{
100 Standard_Integer aNb;
101 TColStd_MapIteratorOfMapOfAsciiString aIt;
102 //
103 if (n!=1) {
104 printf(" use mpnames\n");
105 return 0;
106 }
107 //
108 const TColStd_MapOfAsciiString& aMN=BRepMesh_DiscretFactory::Get().Names();
109 aNb=aMN.Extent();
110 if (!aNb) {
111 printf(" *no names found\n");
112 return 0;
113 }
114 //
115 printf(" *available names:\n");
116 aIt.Initialize(aMN);
117 for (; aIt.More(); aIt.Next()) {
118 const TCollection_AsciiString& aName=aIt.Key();
119 printf(" %s\n", aName.ToCString());
120 }
121 //
122 return 0;
123}
124//=======================================================================
125//function : mpsetdefaultname
126//purpose :
127//=======================================================================
128static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer n, const char**a )
129{
130 TCollection_AsciiString aName;
131 //
132 if (n!=2) {
133 printf(" use mpsetdefaultname name\n");
134 return 0;
135 }
136 //
137 aName=a[1];
138 //
0b97567d
K
139 if (BRepMesh_DiscretFactory::Get().SetDefaultName (aName))
140 printf(" *ready\n");
141 else
142 printf(" *fault\n");
7fd59977 143 //
144 return 0;
145}
146//=======================================================================
147//function : mpgetdefaultname
148//purpose :
149//=======================================================================
150static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer n, const char** )
151{
152 if (n!=1) {
153 printf(" use mpgetdefaultname\n");
154 return 0;
155 }
156 //
157 const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().DefaultName();
158 printf(" *default name: %s\n", aName.ToCString());
159 //
160 return 0;
161}
162//=======================================================================
163//function : mpsetfunctionname
164//purpose :
165//=======================================================================
166static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer n, const char**a )
167{
168 TCollection_AsciiString aName;
169 //
170 if (n!=2) {
171 printf(" use mpsetfunctionname name\n");
172 return 0;
173 }
174 //
175 aName=a[1];
176 //
0b97567d
K
177 if (BRepMesh_DiscretFactory::Get().SetFunctionName (aName))
178 printf(" *ready\n");
179 else
180 printf(" *fault\n");
7fd59977 181 //
182 return 0;
183}
184//=======================================================================
185//function : mpgetdefaultname
186//purpose :
187//=======================================================================
188static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer n, const char** )
189{
190 if (n!=1) {
191 printf(" use mpgetfunctionname\n");
192 return 0;
193 }
194 //
195 const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().FunctionName();
196 printf(" *function name: %s\n", aName.ToCString());
197 //
198 return 0;
199}
200//=======================================================================
201//function : mperror
202//purpose :
203//=======================================================================
204static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer n, const char** )
205{
206 BRepMesh_FactoryError aErr;
207 //
208 if (n!=1) {
209 printf(" use mperror\n");
210 return 0;
211 }
212 //
213 aErr=BRepMesh_DiscretFactory::Get().ErrorStatus();
214 printf(" *ErrorStatus: %d\n", (int)aErr);
215 //
216 return 0;
217}
218
219//=======================================================================
220//function :mpincmesh
221//purpose :
222//=======================================================================
223static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const char** a)
224{
7fd59977 225 Standard_Real aDeflection, aAngle;
226 TopoDS_Shape aS;
7fd59977 227 //
228 if (n<3) {
229 printf(" use mpincmesh s deflection [angle]\n");
230 return 0;
231 }
232 //
233 aS=DBRep::Get(a[1]);
234 if (aS.IsNull()) {
235 printf(" null shapes is not allowed here\n");
236 return 0;
237 }
238 //
91322f44 239 aDeflection=Draw::Atof(a[2]);
7fd59977 240 aAngle=0.5;
241 if (n>3) {
91322f44 242 aAngle=Draw::Atof(a[3]);
7fd59977 243 }
244 //
0b97567d
K
245 Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (aS,
246 aDeflection,
247 aAngle);
7fd59977 248 //
0b97567d
K
249 BRepMesh_FactoryError aErr = BRepMesh_DiscretFactory::Get().ErrorStatus();
250 if (aErr != BRepMesh_FE_NOERROR)
251 {
7fd59977 252 printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr);
253 }
254 //
0b97567d
K
255 if (aMeshAlgo.IsNull())
256 {
7fd59977 257 printf(" *Can not create the algo\n");
258 return 0;
259 }
260 //
0b97567d
K
261 aMeshAlgo->Perform();
262 if (!aMeshAlgo->IsDone())
263 {
7fd59977 264 printf(" *Not done\n");
265 }
266 //
267 return 0;
268}
269
270//#######################################################################
271static Standard_Integer triarea (Draw_Interpretor& di, int n, const char ** a)
272{
273
274 if (n < 2) return 1;
275
276 TopoDS_Shape shape = DBRep::Get(a[1]);
277 if (shape.IsNull()) return 1;
278 Standard_Real anEps = -1.;
279 if (n > 2)
91322f44 280 anEps = Draw::Atof(a[2]);
7fd59977 281
282 TopTools_IndexedMapOfShape aMapF;
283 TopExp::MapShapes (shape, TopAbs_FACE, aMapF);
284
285 // detect if a shape has triangulation
286 Standard_Boolean hasPoly = Standard_False;
287 int i;
288 for (i=1; i <= aMapF.Extent(); i++) {
289 const TopoDS_Face& aFace = TopoDS::Face(aMapF(i));
290 TopLoc_Location aLoc;
291 Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
292 if (!aPoly.IsNull()) {
293 hasPoly = Standard_True;
294 break;
295 }
296 }
297
298 // compute area by triangles
299 double aTriArea=0;
300 if (hasPoly) {
301 for (i=1; i <= aMapF.Extent(); i++) {
302 const TopoDS_Face& aFace = TopoDS::Face(aMapF(i));
303 TopLoc_Location aLoc;
304 Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
305 if (aPoly.IsNull()) {
e1bcbb52
O
306 cout << "face "<<i<<" has no triangulation"<<endl;
307 continue;
7fd59977 308 }
309 const Poly_Array1OfTriangle& triangles = aPoly->Triangles();
310 const TColgp_Array1OfPnt& nodes = aPoly->Nodes();
311 for (int j=triangles.Lower(); j <= triangles.Upper(); j++) {
e1bcbb52
O
312 const Poly_Triangle& tri = triangles(j);
313 int n1, n2, n3;
314 tri.Get (n1, n2, n3);
315 const gp_Pnt& p1 = nodes(n1);
316 const gp_Pnt& p2 = nodes(n2);
317 const gp_Pnt& p3 = nodes(n3);
318 gp_Vec v1(p1, p2);
319 gp_Vec v2(p1, p3);
320 double ar = v1.CrossMagnitude(v2);
321 aTriArea += ar;
7fd59977 322 }
323 }
324 aTriArea /= 2;
325 }
326
327 // compute area by geometry
328 GProp_GProps props;
329 if (anEps <= 0.)
330 BRepGProp::SurfaceProperties(shape, props);
331 else
332 BRepGProp::SurfaceProperties(shape, props, anEps);
333 double aGeomArea = props.Mass();
334
d2c43192 335 di << aTriArea << " " << aGeomArea << "\n";
7fd59977 336 return 0;
337}
338
339//#######################################################################
2e1a4dae 340Standard_Boolean IsEqual(const BRepMesh_Edge& theFirst, const BRepMesh_Edge& theSecond)
341{
342 return theFirst.IsEqual(theSecond);
343}
344
e1bcbb52 345static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
7fd59977 346{
347 if (n < 2) return 1;
348
349 TopoDS_Shape shape = DBRep::Get(a[1]);
350 if (shape.IsNull()) return 1;
351
352 TopTools_IndexedMapOfShape aMapF;
353 TopExp::MapShapes (shape, TopAbs_FACE, aMapF);
354 Standard_CString name = ".";
355
446e11f3 356 // execute check
7fd59977 357 MeshTest_CheckTopology aCheck(shape);
d2c43192 358 aCheck.Perform(di);
446e11f3
A
359
360 // dump info on free links inside the triangulation
7fd59977 361 Standard_Integer nbFree = 0;
362 Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k;
363 if (nbFac > 0) {
364 for (k=1; k <= nbFac; k++) {
365 Standard_Integer nbEdge = aCheck.NbFreeLinks(k);
366 Standard_Integer iF = aCheck.GetFaceNumWithFL(k);
367 nbFree += nbEdge;
d2c43192 368 di << "free links of face " << iF << "\n";
2e1a4dae 369
370 const TopoDS_Shape& aShape = aMapF.FindKey(iF);
371 const TopoDS_Face& aFace = TopoDS::Face(aShape);
7fd59977 372 TopLoc_Location aLoc;
373 Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
374 const TColgp_Array1OfPnt& aPoints = aT->Nodes();
375 const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
376 const gp_Trsf& trsf = aLoc.Transformation();
2e1a4dae 377
7fd59977 378 TColgp_Array1OfPnt pnts(1,2);
379 TColgp_Array1OfPnt2d pnts2d(1,2);
380 for (i=1; i <= nbEdge; i++) {
e1bcbb52
O
381 Standard_Integer n1, n2;
382 aCheck.GetFreeLink(k, i, n1, n2);
d2c43192 383 di << "{" << n1 << " " << n2 << "} ";
e1bcbb52
O
384 pnts(1) = aPoints(n1).Transformed(trsf);
385 pnts(2) = aPoints(n2).Transformed(trsf);
386 Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts);
387 DrawTrSurf::Set (name, poly);
388 DrawTrSurf::Set (name, pnts(1));
389 DrawTrSurf::Set (name, pnts(2));
390 pnts2d(1) = aPoints2d(n1);
391 pnts2d(2) = aPoints2d(n2);
392 Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
393 DrawTrSurf::Set (name, poly2d);
394 DrawTrSurf::Set (name, pnts2d(1));
395 DrawTrSurf::Set (name, pnts2d(2));
7fd59977 396 }
d2c43192 397 di << "\n";
7fd59977 398 }
399 }
400
446e11f3 401 // dump info on cross face errors
7fd59977 402 Standard_Integer nbErr = aCheck.NbCrossFaceErrors();
403 if (nbErr > 0) {
d2c43192 404 di << "cross face errors: {face1, node1, face2, node2, distance}" << "\n";
7fd59977 405 for (i=1; i <= nbErr; i++) {
406 Standard_Integer iF1, n1, iF2, n2;
407 Standard_Real aVal;
408 aCheck.GetCrossFaceError(i, iF1, n1, iF2, n2, aVal);
d2c43192 409 di << "{" << iF1 << " " << n1 << " " << iF2 << " " << n2 << " " << aVal << "} ";
7fd59977 410 }
d2c43192 411 di << "\n";
7fd59977 412 }
413
446e11f3 414 // dump info on edges
7fd59977 415 Standard_Integer nbAsync = aCheck.NbAsyncEdges();
416 if (nbAsync > 0) {
d2c43192 417 di << "async edges:" << "\n";
7fd59977 418 for (i=1; i <= nbAsync; i++) {
419 Standard_Integer ie = aCheck.GetAsyncEdgeNum(i);
d2c43192 420 di << ie << " ";
7fd59977 421 }
d2c43192 422 di << "\n";
7fd59977 423 }
424
446e11f3
A
425 // dump info on free nodes
426 Standard_Integer nbFreeNodes = aCheck.NbFreeNodes();
427 if (nbFreeNodes > 0) {
d2c43192 428 di << "free nodes (in pairs: face / node): " << "\n";
446e11f3
A
429 for (i=1; i <= nbFreeNodes; i++) {
430 Standard_Integer iface, inode;
431 aCheck.GetFreeNodeNum(i, iface, inode);
d2c43192 432 di << "{" << iface << " " << inode << "} ";
446e11f3 433 }
d2c43192 434 di << "\n";
446e11f3
A
435 }
436
437 // output errors summary to DRAW
2e1a4dae 438 if ( nbFree > 0 || nbErr > 0 || nbAsync > 0 || nbFreeNodes > 0)
446e11f3
A
439 di << "Free_links " << nbFree
440 << " Cross_face_errors " << nbErr
441 << " Async_edges " << nbAsync
d2c43192 442 << " Free_nodes " << nbFreeNodes << "\n";
2e1a4dae 443
444
445 Standard_Integer aFaceId = 1;
446 TopExp_Explorer aFaceExp(shape, TopAbs_FACE);
447 for ( ; aFaceExp.More(); aFaceExp.Next(), ++aFaceId)
448 {
449 const TopoDS_Shape& aShape = aFaceExp.Current();
450 const TopoDS_Face& aFace = TopoDS::Face(aShape);
451
452 TopLoc_Location aLoc;
453 Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
454
455 // Iterate boundary edges
456 NCollection_Map<BRepMesh_Edge> aBoundaryEdgeMap;
457 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
458 for ( ; anExp.More(); anExp.Next() )
459 {
460 TopLoc_Location anEdgeLoc;
461 const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
462 Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(anEdge, aT, aLoc);
463 if (aPoly.IsNull())
464 {
465 continue;
466 }
467
468 const TColStd_Array1OfInteger& anIndices = aPoly->Nodes();
469 Standard_Integer aLower = anIndices.Lower();
470 Standard_Integer anUpper = anIndices.Upper();
471
472 Standard_Integer aPrevNode = -1;
473 for (Standard_Integer i = aLower; i <= anUpper; ++i)
474 {
475 Standard_Integer aNodeIdx = anIndices.Value(i);
476 if (i != aLower)
477 {
478 BRepMesh_Edge aLink(aPrevNode, aNodeIdx, BRepMesh_Frontier);
479 aBoundaryEdgeMap.Add(aLink);
480 }
481 aPrevNode = aNodeIdx;
482 }
483 }
484
485 if (aBoundaryEdgeMap.Size() == 0)
486 {
487 break;
488 }
489
490 const Poly_Array1OfTriangle& aTris = aT->Triangles();
491 NCollection_Map<BRepMesh_Edge> aFreeEdgeMap;
492 Standard_Integer aTriNum = aTris.Length();
493 for ( Standard_Integer aTriIndx = 1; aTriIndx <= aTriNum; aTriIndx++ )
494 {
495 const Poly_Triangle& aTri = aTris(aTriIndx);
496 Standard_Integer aTriNodes[3] = { aTri.Value(1), aTri.Value(2), aTri.Value(3)};
497
498 for (Standard_Integer i = 1; i <= 3; ++i)
499 {
500 Standard_Integer aLastId = aTriNodes[i % 3];
501 Standard_Integer aFirstId = aTriNodes[i - 1];
502
503 BRepMesh_Edge aLink(aFirstId, aLastId, BRepMesh_Free);
504 if (!aBoundaryEdgeMap.Contains(aLink))
505 {
506 if (!aFreeEdgeMap.Add(aLink))
507 {
508 aFreeEdgeMap.Remove(aLink);
509 }
510 }
511 }
512 }
513
514 if (aFreeEdgeMap.Size() != 0)
515 {
516 di << "Not connected mesh inside face " << aFaceId << "\n";
517 }
518 }
7fd59977 519 return 0;
520}
0b97567d
K
521
522//=======================================================================
523//function : mpparallel
524//purpose :
525//=======================================================================
35e08fe8 526static int mpparallel (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
0b97567d
K
527{
528 if (argc == 2)
529 {
91322f44 530 Standard_Boolean isParallelOn = Draw::Atoi (argv[1]) == 1;
0b97567d
K
531 BRepMesh_IncrementalMesh::SetParallelDefault (isParallelOn);
532 }
533 std::cout << "Incremental Mesh, multi-threading "
534 << (BRepMesh_IncrementalMesh::IsParallelDefault() ? "ON\n" : "OFF\n");
535 return 0;
536}