0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / MeshTest / MeshTest_PluginCommands.cxx
CommitLineData
b311480e 1// Created on: 2008-04-11
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2008-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
42cf5bc1 16
17#include <Bnd_Box.hxx>
18#include <BRep_Tool.hxx>
19#include <BRepGProp.hxx>
7fd59977 20#include <BRepMesh_DiscretFactory.hxx>
7fd59977 21#include <BRepMesh_DiscretRoot.hxx>
42cf5bc1 22#include <BRepMesh_Edge.hxx>
23#include <BRepMesh_FactoryError.hxx>
0b97567d 24#include <BRepMesh_IncrementalMesh.hxx>
7fd59977 25#include <DBRep.hxx>
42cf5bc1 26#include <Draw.hxx>
27#include <Draw_Interpretor.hxx>
28#include <DrawTrSurf.hxx>
7fd59977 29#include <gp_Vec.hxx>
30#include <GProp_GProps.hxx>
42cf5bc1 31#include <MeshTest.hxx>
7fd59977 32#include <MeshTest_CheckTopology.hxx>
42cf5bc1 33#include <NCollection_Map.hxx>
7fd59977 34#include <Poly_Polygon2D.hxx>
42cf5bc1 35#include <Poly_Polygon3D.hxx>
36#include <Poly_PolygonOnTriangulation.hxx>
37#include <Poly_Triangulation.hxx>
ca0db031 38#include <Standard.hxx>
42cf5bc1 39#include <TColgp_Array1OfPnt2d.hxx>
40#include <TCollection_AsciiString.hxx>
2e1a4dae 41#include <TColStd_Array1OfInteger.hxx>
42cf5bc1 42#include <TColStd_MapIteratorOfMapOfAsciiString.hxx>
43#include <TColStd_MapOfAsciiString.hxx>
44#include <TopExp.hxx>
45#include <TopExp_Explorer.hxx>
46#include <TopoDS.hxx>
2e1a4dae 47#include <TopoDS_Face.hxx>
42cf5bc1 48#include <TopTools_IndexedMapOfShape.hxx>
7bd071ed 49#include <Geom_BSplineCurve.hxx>
50#include <Geom2d_BSplineCurve.hxx>
7fd59977 51
52static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer , const char** );
53static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
54static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer , const char** );
55static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
56static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer , const char** );
57static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer , const char** );
58static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer , const char** );
0b97567d 59static Standard_Integer mpparallel (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 60static Standard_Integer triarea (Draw_Interpretor& , Standard_Integer , const char** );
e1bcbb52 61static Standard_Integer tricheck (Draw_Interpretor& , Standard_Integer , const char** );
7fd59977 62
63//=======================================================================
64//function : PluginCommands
65//purpose :
66//=======================================================================
67void MeshTest::PluginCommands(Draw_Interpretor& theCommands)
68{
69 static Standard_Boolean done = Standard_False;
70 if (done) {
71 return;
72 }
73 done = Standard_True;
74 //
75 const char* g = "Mesh Commands";
76 // Commands
77 theCommands.Add("mpnames" , "use mpnames" , __FILE__, mpnames , g);
78 theCommands.Add("mpsetdefaultname" , "use mpsetdefaultname" , __FILE__, mpsetdefaultname , g);
79 theCommands.Add("mpgetdefaultname" , "use mpgetdefaultname" , __FILE__, mpgetdefaultname , g);
80 theCommands.Add("mpsetfunctionname", "use mpsetfunctionname", __FILE__, mpsetfunctionname , g);
81 theCommands.Add("mpgetfunctionname", "use mpgetfunctionname", __FILE__, mpgetfunctionname , g);
82 theCommands.Add("mperror" , "use mperror" , __FILE__, mperror , g);
83 theCommands.Add("mpincmesh" , "use mpincmesh" , __FILE__, mpincmesh , g);
0b97567d
K
84 theCommands.Add("mpparallel" , "mpparallel [toTurnOn] : show / set multi-threading flag for incremental mesh",
85 __FILE__, mpparallel, g);
7fd59977 86 theCommands.Add("triarea","shape [eps] (computes triangles and surface area)",__FILE__, triarea, g);
7bd071ed 87 theCommands.Add("tricheck", "shape [-small] (checks triangulation of shape);\n"
88 "\"-small\"-option allows finding triangles with small area", __FILE__, tricheck, g);
7fd59977 89}
90
91//=======================================================================
92//function : mpnames
93//purpose :
94//=======================================================================
95static Standard_Integer mpnames (Draw_Interpretor& , Standard_Integer n, const char** )
96{
97 Standard_Integer aNb;
98 TColStd_MapIteratorOfMapOfAsciiString aIt;
99 //
100 if (n!=1) {
101 printf(" use mpnames\n");
102 return 0;
103 }
104 //
105 const TColStd_MapOfAsciiString& aMN=BRepMesh_DiscretFactory::Get().Names();
106 aNb=aMN.Extent();
107 if (!aNb) {
108 printf(" *no names found\n");
109 return 0;
110 }
111 //
112 printf(" *available names:\n");
113 aIt.Initialize(aMN);
114 for (; aIt.More(); aIt.Next()) {
115 const TCollection_AsciiString& aName=aIt.Key();
116 printf(" %s\n", aName.ToCString());
117 }
118 //
119 return 0;
120}
121//=======================================================================
122//function : mpsetdefaultname
123//purpose :
124//=======================================================================
125static Standard_Integer mpsetdefaultname (Draw_Interpretor& , Standard_Integer n, const char**a )
126{
127 TCollection_AsciiString aName;
128 //
129 if (n!=2) {
130 printf(" use mpsetdefaultname name\n");
131 return 0;
132 }
133 //
134 aName=a[1];
135 //
0b97567d
K
136 if (BRepMesh_DiscretFactory::Get().SetDefaultName (aName))
137 printf(" *ready\n");
138 else
139 printf(" *fault\n");
7fd59977 140 //
141 return 0;
142}
143//=======================================================================
144//function : mpgetdefaultname
145//purpose :
146//=======================================================================
147static Standard_Integer mpgetdefaultname (Draw_Interpretor& , Standard_Integer n, const char** )
148{
149 if (n!=1) {
150 printf(" use mpgetdefaultname\n");
151 return 0;
152 }
153 //
154 const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().DefaultName();
155 printf(" *default name: %s\n", aName.ToCString());
156 //
157 return 0;
158}
159//=======================================================================
160//function : mpsetfunctionname
161//purpose :
162//=======================================================================
163static Standard_Integer mpsetfunctionname (Draw_Interpretor& , Standard_Integer n, const char**a )
164{
165 TCollection_AsciiString aName;
166 //
167 if (n!=2) {
168 printf(" use mpsetfunctionname name\n");
169 return 0;
170 }
171 //
172 aName=a[1];
173 //
0b97567d
K
174 if (BRepMesh_DiscretFactory::Get().SetFunctionName (aName))
175 printf(" *ready\n");
176 else
177 printf(" *fault\n");
7fd59977 178 //
179 return 0;
180}
181//=======================================================================
182//function : mpgetdefaultname
183//purpose :
184//=======================================================================
185static Standard_Integer mpgetfunctionname (Draw_Interpretor& , Standard_Integer n, const char** )
186{
187 if (n!=1) {
188 printf(" use mpgetfunctionname\n");
189 return 0;
190 }
191 //
192 const TCollection_AsciiString& aName=BRepMesh_DiscretFactory::Get().FunctionName();
193 printf(" *function name: %s\n", aName.ToCString());
194 //
195 return 0;
196}
197//=======================================================================
198//function : mperror
199//purpose :
200//=======================================================================
201static Standard_Integer mperror (Draw_Interpretor& , Standard_Integer n, const char** )
202{
203 BRepMesh_FactoryError aErr;
204 //
205 if (n!=1) {
206 printf(" use mperror\n");
207 return 0;
208 }
209 //
210 aErr=BRepMesh_DiscretFactory::Get().ErrorStatus();
211 printf(" *ErrorStatus: %d\n", (int)aErr);
212 //
213 return 0;
214}
215
216//=======================================================================
217//function :mpincmesh
218//purpose :
219//=======================================================================
220static Standard_Integer mpincmesh (Draw_Interpretor& , Standard_Integer n, const char** a)
221{
7fd59977 222 Standard_Real aDeflection, aAngle;
223 TopoDS_Shape aS;
7fd59977 224 //
225 if (n<3) {
226 printf(" use mpincmesh s deflection [angle]\n");
227 return 0;
228 }
229 //
230 aS=DBRep::Get(a[1]);
231 if (aS.IsNull()) {
232 printf(" null shapes is not allowed here\n");
233 return 0;
234 }
235 //
91322f44 236 aDeflection=Draw::Atof(a[2]);
7fd59977 237 aAngle=0.5;
238 if (n>3) {
91322f44 239 aAngle=Draw::Atof(a[3]);
7fd59977 240 }
241 //
0b97567d
K
242 Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (aS,
243 aDeflection,
244 aAngle);
7fd59977 245 //
0b97567d
K
246 BRepMesh_FactoryError aErr = BRepMesh_DiscretFactory::Get().ErrorStatus();
247 if (aErr != BRepMesh_FE_NOERROR)
248 {
7fd59977 249 printf(" *Factory::Get().ErrorStatus()=%d\n", (int)aErr);
250 }
251 //
0b97567d
K
252 if (aMeshAlgo.IsNull())
253 {
7fd59977 254 printf(" *Can not create the algo\n");
255 return 0;
256 }
257 //
0b97567d
K
258 aMeshAlgo->Perform();
259 if (!aMeshAlgo->IsDone())
260 {
7fd59977 261 printf(" *Not done\n");
262 }
263 //
264 return 0;
265}
266
267//#######################################################################
268static Standard_Integer triarea (Draw_Interpretor& di, int n, const char ** a)
269{
270
271 if (n < 2) return 1;
272
273 TopoDS_Shape shape = DBRep::Get(a[1]);
274 if (shape.IsNull()) return 1;
275 Standard_Real anEps = -1.;
276 if (n > 2)
91322f44 277 anEps = Draw::Atof(a[2]);
7fd59977 278
279 TopTools_IndexedMapOfShape aMapF;
280 TopExp::MapShapes (shape, TopAbs_FACE, aMapF);
281
282 // detect if a shape has triangulation
283 Standard_Boolean hasPoly = Standard_False;
284 int i;
285 for (i=1; i <= aMapF.Extent(); i++) {
286 const TopoDS_Face& aFace = TopoDS::Face(aMapF(i));
287 TopLoc_Location aLoc;
288 Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
289 if (!aPoly.IsNull()) {
290 hasPoly = Standard_True;
291 break;
292 }
293 }
294
295 // compute area by triangles
296 double aTriArea=0;
297 if (hasPoly) {
298 for (i=1; i <= aMapF.Extent(); i++) {
299 const TopoDS_Face& aFace = TopoDS::Face(aMapF(i));
300 TopLoc_Location aLoc;
301 Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
302 if (aPoly.IsNull()) {
04232180 303 std::cout << "face "<<i<<" has no triangulation"<<std::endl;
e1bcbb52 304 continue;
7fd59977 305 }
306 const Poly_Array1OfTriangle& triangles = aPoly->Triangles();
307 const TColgp_Array1OfPnt& nodes = aPoly->Nodes();
308 for (int j=triangles.Lower(); j <= triangles.Upper(); j++) {
e1bcbb52
O
309 const Poly_Triangle& tri = triangles(j);
310 int n1, n2, n3;
311 tri.Get (n1, n2, n3);
312 const gp_Pnt& p1 = nodes(n1);
313 const gp_Pnt& p2 = nodes(n2);
314 const gp_Pnt& p3 = nodes(n3);
315 gp_Vec v1(p1, p2);
316 gp_Vec v2(p1, p3);
317 double ar = v1.CrossMagnitude(v2);
318 aTriArea += ar;
7fd59977 319 }
320 }
321 aTriArea /= 2;
322 }
323
324 // compute area by geometry
325 GProp_GProps props;
326 if (anEps <= 0.)
327 BRepGProp::SurfaceProperties(shape, props);
328 else
329 BRepGProp::SurfaceProperties(shape, props, anEps);
330 double aGeomArea = props.Mass();
331
d2c43192 332 di << aTriArea << " " << aGeomArea << "\n";
7fd59977 333 return 0;
334}
335
336//#######################################################################
2e1a4dae 337Standard_Boolean IsEqual(const BRepMesh_Edge& theFirst, const BRepMesh_Edge& theSecond)
338{
339 return theFirst.IsEqual(theSecond);
340}
341
e1bcbb52 342static Standard_Integer tricheck (Draw_Interpretor& di, int n, const char ** a)
7fd59977 343{
344 if (n < 2) return 1;
345
346 TopoDS_Shape shape = DBRep::Get(a[1]);
347 if (shape.IsNull()) return 1;
348
7bd071ed 349 const Standard_Boolean isToFindSmallTriangles = (n >= 3) ? (strcmp(a[2], "-small") == 0) : Standard_False;
350
7fd59977 351 TopTools_IndexedMapOfShape aMapF;
352 TopExp::MapShapes (shape, TopAbs_FACE, aMapF);
7bd071ed 353 const Standard_CString name = ".";
7fd59977 354
446e11f3 355 // execute check
7fd59977 356 MeshTest_CheckTopology aCheck(shape);
d2c43192 357 aCheck.Perform(di);
446e11f3
A
358
359 // dump info on free links inside the triangulation
7fd59977 360 Standard_Integer nbFree = 0;
361 Standard_Integer nbFac = aCheck.NbFacesWithFL(), i, k;
362 if (nbFac > 0) {
363 for (k=1; k <= nbFac; k++) {
364 Standard_Integer nbEdge = aCheck.NbFreeLinks(k);
365 Standard_Integer iF = aCheck.GetFaceNumWithFL(k);
366 nbFree += nbEdge;
d2c43192 367 di << "free links of face " << iF << "\n";
2e1a4dae 368
369 const TopoDS_Shape& aShape = aMapF.FindKey(iF);
370 const TopoDS_Face& aFace = TopoDS::Face(aShape);
7fd59977 371 TopLoc_Location aLoc;
372 Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
373 const TColgp_Array1OfPnt& aPoints = aT->Nodes();
7fd59977 374 const gp_Trsf& trsf = aLoc.Transformation();
2e1a4dae 375
7fd59977 376 TColgp_Array1OfPnt pnts(1,2);
377 TColgp_Array1OfPnt2d pnts2d(1,2);
378 for (i=1; i <= nbEdge; i++) {
e1bcbb52
O
379 Standard_Integer n1, n2;
380 aCheck.GetFreeLink(k, i, n1, n2);
d2c43192 381 di << "{" << n1 << " " << n2 << "} ";
e1bcbb52
O
382 pnts(1) = aPoints(n1).Transformed(trsf);
383 pnts(2) = aPoints(n2).Transformed(trsf);
384 Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts);
385 DrawTrSurf::Set (name, poly);
386 DrawTrSurf::Set (name, pnts(1));
387 DrawTrSurf::Set (name, pnts(2));
b508cbc5 388 if (aT->HasUVNodes())
389 {
390 const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
391 pnts2d(1) = aPoints2d(n1);
392 pnts2d(2) = aPoints2d(n2);
393 Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
394 DrawTrSurf::Set (name, poly2d);
395 DrawTrSurf::Set (name, pnts2d(1));
396 DrawTrSurf::Set (name, pnts2d(2));
397 }
7fd59977 398 }
d2c43192 399 di << "\n";
7fd59977 400 }
401 }
402
446e11f3 403 // dump info on cross face errors
7fd59977 404 Standard_Integer nbErr = aCheck.NbCrossFaceErrors();
405 if (nbErr > 0) {
586db386 406 di << "cross face errors: {face1, node1, face2, node2, distance}\n";
7fd59977 407 for (i=1; i <= nbErr; i++) {
408 Standard_Integer iF1, n1, iF2, n2;
409 Standard_Real aVal;
410 aCheck.GetCrossFaceError(i, iF1, n1, iF2, n2, aVal);
d2c43192 411 di << "{" << iF1 << " " << n1 << " " << iF2 << " " << n2 << " " << aVal << "} ";
7fd59977 412 }
d2c43192 413 di << "\n";
7fd59977 414 }
415
446e11f3 416 // dump info on edges
7fd59977 417 Standard_Integer nbAsync = aCheck.NbAsyncEdges();
418 if (nbAsync > 0) {
586db386 419 di << "async edges:\n";
7fd59977 420 for (i=1; i <= nbAsync; i++) {
421 Standard_Integer ie = aCheck.GetAsyncEdgeNum(i);
d2c43192 422 di << ie << " ";
7fd59977 423 }
d2c43192 424 di << "\n";
7fd59977 425 }
426
446e11f3
A
427 // dump info on free nodes
428 Standard_Integer nbFreeNodes = aCheck.NbFreeNodes();
429 if (nbFreeNodes > 0) {
586db386 430 di << "free nodes (in pairs: face / node): \n";
446e11f3
A
431 for (i=1; i <= nbFreeNodes; i++) {
432 Standard_Integer iface, inode;
433 aCheck.GetFreeNodeNum(i, iface, inode);
dc66be92 434
435 const TopoDS_Face& aFace = TopoDS::Face(aMapF.FindKey(iface));
436 TopLoc_Location aLoc;
437 Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
438 const TColgp_Array1OfPnt& aPoints = aT->Nodes();
dc66be92 439 const gp_Trsf& trsf = aLoc.Transformation();
440 DrawTrSurf::Set (name, aPoints(inode).Transformed(trsf));
b508cbc5 441 if (aT->HasUVNodes())
442 {
443 DrawTrSurf::Set (name, aT->UVNodes()(inode));
444 }
dc66be92 445
d2c43192 446 di << "{" << iface << " " << inode << "} ";
446e11f3 447 }
d2c43192 448 di << "\n";
446e11f3
A
449 }
450
7bd071ed 451 const Standard_Integer aNbSmallTriangles = isToFindSmallTriangles? aCheck.NbSmallTriangles() : 0;
452 if (aNbSmallTriangles > 0)
453 {
454 di << "triangles with null area (in pairs: face / triangle): \n";
455 for (i = 1; i <= aNbSmallTriangles; i++)
456 {
457 Standard_Integer aFaceId = 0, aTriID = 0;
458 aCheck.GetSmallTriangle(i, aFaceId, aTriID);
459
460 const TopoDS_Face& aFace = TopoDS::Face(aMapF.FindKey(aFaceId));
461 TopLoc_Location aLoc;
462 const gp_Trsf& aTrsf = aLoc.Transformation();
463 const Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
464 const Poly_Triangle &aTri = aT->Triangle(aTriID);
465 Standard_Integer aN1, aN2, aN3;
466 aTri.Get(aN1, aN2, aN3);
467 const TColgp_Array1OfPnt& aPoints = aT->Nodes();
468
469 TColgp_Array1OfPnt aPoles(1, 4);
470 aPoles(1) = aPoles(4) = aPoints(aN1).Transformed(aTrsf);
471 aPoles(2) = aPoints(aN2).Transformed(aTrsf);
472 aPoles(3) = aPoints(aN3).Transformed(aTrsf);
473
474 TColStd_Array1OfInteger aMults(1, 4);
475 aMults(1) = aMults(4) = 2;
476 aMults(2) = aMults(3) = 1;
477
478 TColStd_Array1OfReal aKnots(1, 4);
479 aKnots(1) = 1.0;
480 aKnots(2) = 2.0;
481 aKnots(3) = 3.0;
482 aKnots(4) = 4.0;
483
484 Handle(Geom_BSplineCurve) aBS = new Geom_BSplineCurve(aPoles, aKnots, aMults, 1);
485
486 DrawTrSurf::Set(name, aBS);
487
488 if (aT->HasUVNodes())
489 {
490 TColgp_Array1OfPnt2d aPoles2d(1, 4);
491 aPoles2d(1) = aPoles2d(4) = aT->UVNodes()(aN1);
492 aPoles2d(2) = aT->UVNodes()(aN2);
493 aPoles2d(3) = aT->UVNodes()(aN3);
494
495 Handle(Geom2d_BSplineCurve) aBS2d = new Geom2d_BSplineCurve(aPoles2d, aKnots, aMults, 1);
496
497 DrawTrSurf::Set(name, aBS2d);
498 }
499
500 di << "{" << aFaceId << " " << aTriID << "} ";
501 }
502
503 di << "\n";
504 }
505
446e11f3 506 // output errors summary to DRAW
7bd071ed 507 if (nbFree > 0 ||
508 nbErr > 0 ||
509 nbAsync > 0 ||
510 nbFreeNodes > 0 ||
511 (aNbSmallTriangles > 0))
512 {
446e11f3 513 di << "Free_links " << nbFree
7bd071ed 514 << " Cross_face_errors " << nbErr
515 << " Async_edges " << nbAsync
516 << " Free_nodes " << nbFreeNodes
517 << " Small triangles " << aNbSmallTriangles << "\n";
518 }
2e1a4dae 519
520 Standard_Integer aFaceId = 1;
521 TopExp_Explorer aFaceExp(shape, TopAbs_FACE);
522 for ( ; aFaceExp.More(); aFaceExp.Next(), ++aFaceId)
523 {
524 const TopoDS_Shape& aShape = aFaceExp.Current();
525 const TopoDS_Face& aFace = TopoDS::Face(aShape);
526
527 TopLoc_Location aLoc;
528 Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(aFace, aLoc);
529
530 // Iterate boundary edges
531 NCollection_Map<BRepMesh_Edge> aBoundaryEdgeMap;
532 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
533 for ( ; anExp.More(); anExp.Next() )
534 {
535 TopLoc_Location anEdgeLoc;
536 const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
537 Handle(Poly_PolygonOnTriangulation) aPoly = BRep_Tool::PolygonOnTriangulation(anEdge, aT, aLoc);
538 if (aPoly.IsNull())
539 {
540 continue;
541 }
542
543 const TColStd_Array1OfInteger& anIndices = aPoly->Nodes();
544 Standard_Integer aLower = anIndices.Lower();
545 Standard_Integer anUpper = anIndices.Upper();
546
547 Standard_Integer aPrevNode = -1;
51740958 548 for (Standard_Integer j = aLower; j <= anUpper; ++j)
2e1a4dae 549 {
51740958 550 Standard_Integer aNodeIdx = anIndices.Value(j);
551 if (j != aLower)
2e1a4dae 552 {
553 BRepMesh_Edge aLink(aPrevNode, aNodeIdx, BRepMesh_Frontier);
554 aBoundaryEdgeMap.Add(aLink);
555 }
556 aPrevNode = aNodeIdx;
557 }
558 }
559
560 if (aBoundaryEdgeMap.Size() == 0)
561 {
562 break;
563 }
564
565 const Poly_Array1OfTriangle& aTris = aT->Triangles();
566 NCollection_Map<BRepMesh_Edge> aFreeEdgeMap;
567 Standard_Integer aTriNum = aTris.Length();
568 for ( Standard_Integer aTriIndx = 1; aTriIndx <= aTriNum; aTriIndx++ )
569 {
570 const Poly_Triangle& aTri = aTris(aTriIndx);
571 Standard_Integer aTriNodes[3] = { aTri.Value(1), aTri.Value(2), aTri.Value(3)};
572
51740958 573 for (Standard_Integer j = 1; j <= 3; ++j)
2e1a4dae 574 {
51740958 575 Standard_Integer aLastId = aTriNodes[j % 3];
576 Standard_Integer aFirstId = aTriNodes[j - 1];
2e1a4dae 577
578 BRepMesh_Edge aLink(aFirstId, aLastId, BRepMesh_Free);
579 if (!aBoundaryEdgeMap.Contains(aLink))
580 {
581 if (!aFreeEdgeMap.Add(aLink))
582 {
583 aFreeEdgeMap.Remove(aLink);
584 }
585 }
586 }
587 }
588
589 if (aFreeEdgeMap.Size() != 0)
590 {
591 di << "Not connected mesh inside face " << aFaceId << "\n";
dc66be92 592
593 const TColgp_Array1OfPnt& aPoints = aT->Nodes();
dc66be92 594 const gp_Trsf& trsf = aLoc.Transformation();
595
596 TColgp_Array1OfPnt pnts(1,2);
597 TColgp_Array1OfPnt2d pnts2d(1,2);
598 NCollection_Map<BRepMesh_Edge>::Iterator aMapIt(aFreeEdgeMap);
599 for (; aMapIt.More(); aMapIt.Next())
600 {
601 const BRepMesh_Edge& aLink = aMapIt.Key();
602 di << "{" << aLink.FirstNode() << " " << aLink.LastNode() << "} ";
603 pnts(1) = aPoints(aLink.FirstNode()).Transformed(trsf);
604 pnts(2) = aPoints(aLink.LastNode()).Transformed(trsf);
605 Handle(Poly_Polygon3D) poly = new Poly_Polygon3D (pnts);
606 DrawTrSurf::Set (name, poly);
607 DrawTrSurf::Set (name, pnts(1));
608 DrawTrSurf::Set (name, pnts(2));
b508cbc5 609 if (aT->HasUVNodes())
610 {
611 const TColgp_Array1OfPnt2d& aPoints2d = aT->UVNodes();
612 pnts2d(1) = aPoints2d(aLink.FirstNode());
613 pnts2d(2) = aPoints2d(aLink.LastNode());
614 Handle(Poly_Polygon2D) poly2d = new Poly_Polygon2D (pnts2d);
615 DrawTrSurf::Set (name, poly2d);
616 DrawTrSurf::Set (name, pnts2d(1));
617 DrawTrSurf::Set (name, pnts2d(2));
618 }
dc66be92 619 }
620 di << "\n";
2e1a4dae 621 }
622 }
7fd59977 623 return 0;
624}
0b97567d
K
625
626//=======================================================================
627//function : mpparallel
628//purpose :
629//=======================================================================
35e08fe8 630static int mpparallel (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
0b97567d
K
631{
632 if (argc == 2)
633 {
91322f44 634 Standard_Boolean isParallelOn = Draw::Atoi (argv[1]) == 1;
0b97567d
K
635 BRepMesh_IncrementalMesh::SetParallelDefault (isParallelOn);
636 }
637 std::cout << "Incremental Mesh, multi-threading "
638 << (BRepMesh_IncrementalMesh::IsParallelDefault() ? "ON\n" : "OFF\n");
639 return 0;
640}