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