1 // File: BRepMesh_IncrementalMesh.cxx
2 // Created: Tue Jun 20 10:34:51 1995
3 // Author: Stagiaire Alain JOURDAIN
7 #include <BRepMesh_IncrementalMesh.ixx>
9 #include <BRepMesh.hxx>
10 #include <BRepMesh_Edge.hxx>
11 #include <BRepMesh_Triangle.hxx>
12 #include <BRepMesh_FastDiscretFace.hxx>
13 #include <BRepMesh_PluginMacro.hxx>
15 #include <Bnd_Box.hxx>
16 #include <BRep_Builder.hxx>
17 #include <BRep_Tool.hxx>
18 #include <BRepLib.hxx>
19 #include <BRepBndLib.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <GCPnts_TangentialDeflection.hxx>
22 #include <Precision.hxx>
24 #include <TopExp_Explorer.hxx>
26 #include <TopTools_ListIteratorOfListOfShape.hxx>
27 #include <TColgp_Array1OfPnt.hxx>
28 #include <TColStd_Array1OfReal.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Edge.hxx>
33 #include <TopTools_HArray1OfShape.hxx>
34 #include <Poly_Triangulation.hxx>
35 #include <Poly_Polygon3D.hxx>
36 #include <Poly_PolygonOnTriangulation.hxx>
41 // paralleling using Intel TBB
42 #include <tbb/parallel_for_each.h>
47 //! Default flag to control parallelization for BRepMesh_IncrementalMesh
48 //! tool returned for Mesh Factory
49 static Standard_Boolean IS_IN_PARALLEL = Standard_False;
52 //=======================================================================
53 //function : BRepMesh_IncrementalMesh
55 //=======================================================================
56 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
57 : myRelative (Standard_False),
58 myInParallel (Standard_False),
59 myModified (Standard_False),
66 //=======================================================================
67 //function : BRepMesh_IncrementalMesh
69 //=======================================================================
70 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
71 const Standard_Real theDeflection,
72 const Standard_Boolean theRelative,
73 const Standard_Real theAngle)
74 : myRelative (theRelative),
75 myInParallel (Standard_False),
76 myModified (Standard_False),
81 myDeflection = theDeflection;
89 //=======================================================================
92 //=======================================================================
93 BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
97 //=======================================================================
98 //function : SetParallel
100 //=======================================================================
101 void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
103 myInParallel = theInParallel;
106 //=======================================================================
107 //function : IsParallel
109 //=======================================================================
110 Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
115 //=======================================================================
118 //=======================================================================
119 void BRepMesh_IncrementalMesh::Init()
121 myModified=Standard_False;
126 //=======================================================================
127 //function : SetRelative
129 //=======================================================================
130 void BRepMesh_IncrementalMesh::SetRelative(const Standard_Boolean theFlag)
135 //=======================================================================
136 //function : Relative
138 //=======================================================================
139 Standard_Boolean BRepMesh_IncrementalMesh::Relative()const
144 //=======================================================================
145 //function : IsModified
147 //=======================================================================
148 Standard_Boolean BRepMesh_IncrementalMesh::IsModified() const
153 //=======================================================================
156 //=======================================================================
157 void BRepMesh_IncrementalMesh::Perform()
165 BRepBndLib::Add(myShape, aBox);
168 if (!myMesh.IsNull()) {
172 myMesh = new BRepMesh_FastDiscret(myDeflection,
183 //=======================================================================
184 //function : GetStatus
186 //=======================================================================
187 Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
192 //=======================================================================
193 //function : Update(shape)
194 //purpose : Builds the incremental mesh of the shape
195 //=======================================================================
196 void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
198 myModified = Standard_False;
201 //AGV 080407: Since version 6.2.0 there would be exception without this check
205 BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
207 for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
208 if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
209 Update(TopoDS::Edge(ex.Current()));
214 TopTools_ListOfShape LF;
215 BRepLib::ReverseSortFaces(S,LF);
217 // make array of faces suitable for processing (excluding faces without surface)
218 std::vector<TopoDS_Face> aFaces;
219 for (TopTools_ListIteratorOfListOfShape it(LF); it.More(); it.Next())
221 TopoDS_Face F = TopoDS::Face(it.Value());
224 const Handle(Geom_Surface)& Surf = BRep_Tool::Surface(F, L1);
229 aFaces.push_back (F);
235 // mesh faces in parallel threads using TBB
236 tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
238 // alternative parallelization not yet available
239 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
240 myMesh->Process (*it);
245 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
246 myMesh->Process (*it);
249 // maillage des edges non contenues dans les faces :
250 Standard_Real f, l, defedge;
251 Standard_Integer i, nbNodes;
253 Standard_Real cdef = 1.;
254 ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
257 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
259 if(!BRep_Tool::IsGeometric(E)) {
265 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
268 defedge = myDeflection;
270 Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
271 Standard_Boolean maill = Standard_False;
273 maill = Standard_True;
275 else if (P3D->Deflection() > 1.1*defedge) {
276 maill = Standard_True;
279 BRepAdaptor_Curve C(E);
280 f = C.FirstParameter();
281 l = C.LastParameter();
283 GCPnts_TangentialDeflection TD(C, f, l, myAngle, defedge, 2);
284 nbNodes = TD.NbPoints();
286 TColgp_Array1OfPnt Nodes(1, nbNodes);
287 TColStd_Array1OfReal UVNodes(1, nbNodes);
288 for ( i = 1; i <= nbNodes; i++) {
289 Nodes(i) = TD.Value(i);
290 UVNodes(i) = TD.Parameter(i);
294 Handle(Poly_Polygon3D) P = new Poly_Polygon3D(Nodes, UVNodes);
295 P->Deflection(myDeflection);
303 //=======================================================================
304 //function : Update(edge)
305 //purpose : Locate a correct discretisation if it exists
306 // Set no one otherwise
307 //=======================================================================
308 void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
311 Standard_Integer i = 1;
312 Handle(Poly_Triangulation) T, TNull;
313 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
314 Standard_Boolean found = Standard_False;
315 Standard_Real defedge;
316 Standard_Real cdef = 1.;
318 Standard_Boolean defined = Standard_False;
321 BRep_Tool::PolygonOnTriangulation(E, Poly, T, l, i);
323 if (!T.IsNull() && !Poly.IsNull()) {
326 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
329 defedge = myDeflection;
330 mymapedge.Bind(E, defedge);
331 defined = Standard_True;
333 if ((!myRelative && Poly->Deflection() <= 1.1*defedge) ||
334 (myRelative && Poly->Deflection() <= 1.1*defedge))
335 found = Standard_True;
337 myModified = Standard_True;
338 B.UpdateEdge(E, NullPoly, T, l);
341 } while (!Poly.IsNull());
343 if (!found) myMap.Add(E);
347 //=======================================================================
348 //function : Update(face)
349 //purpose : If the face is not correctly triangulated, or if one of its
350 // edges is to be discretisated correctly, the triangulation
351 // of this face is built.
352 //=======================================================================
353 void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
356 Handle(Geom_Surface) SS = BRep_Tool::Surface(F, l);
357 if (SS.IsNull()) return;
359 //Standard_Integer i;
360 Standard_Boolean WillBeTriangulated = Standard_False;
361 Handle(Poly_Triangulation) T, TNull;
362 T = BRep_Tool::Triangulation(F, l);
363 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
368 Standard_Real defedge, defface, cdef = 1.;
369 Standard_Integer nbEdge = 0;
373 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
374 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
376 if (mymapedge.IsBound(edge)) {
377 defedge = mymapedge(edge);
380 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
381 defface = defface + defedge;
383 if (nbEdge != 0) defface = defface / nbEdge;
384 else defface = myDeflection;
387 defface = myDeflection;
390 if ((!myRelative && T->Deflection() <= 1.1*defface) ||
391 (myRelative && T->Deflection() <= 1.1*defface)) {
392 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
393 const TopoDS_Shape& E = ex.Current();
394 Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
395 if (Poly.IsNull() || myMap.Contains(E)) {
396 WillBeTriangulated = Standard_True;
397 // cas un peu special. la triangulation est bonne, mais
398 // l'edge n'a pas de representation polygonalisee sur celle-ci.
403 else WillBeTriangulated = Standard_True;
406 if (WillBeTriangulated || T.IsNull()) {
407 myModified = Standard_True;
409 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
410 B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
411 myMap.Remove(ex.Current());
413 B.UpdateFace(F, TNull);
416 myStatus |= (Standard_Integer)(myMesh->CurrentFaceStatus());
417 if (myMesh->CurrentFaceStatus() == BRepMesh_ReMesh) {
419 cout << " face remaillee + finement que prevu."<< endl;
422 Standard_Integer index;
423 if( myancestors.Extent() < 1 )
424 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myancestors);
426 TopTools_MapOfShape MShape;
429 TopoDS_Iterator ex(F),ex2;
430 for (; ex.More(); ex.Next()) {
431 const TopoDS_Shape& aWire = ex.Value();
432 if (aWire.ShapeType() != TopAbs_WIRE)
434 TopoDS_Iterator exW(aWire);
435 for(; exW.More(); exW.Next()) {
436 const TopoDS_Edge& edge = TopoDS::Edge(exW.Value());
437 index = myancestors.FindIndex(edge);
439 const TopTools_ListOfShape& L = myancestors.FindFromKey(edge);
441 TopTools_ListIteratorOfListOfShape it(L);
443 for (; it.More(); it.Next()) {
444 TopoDS_Face F2 = TopoDS::Face(it.Value());
445 if (!MShape.Contains(F2)) {
447 T = BRep_Tool::Triangulation(F2, l);
450 cout <<"triangulation a refaire" <<endl;
452 for (ex2.Initialize(F2); ex2.More(); ex2.Next()) {
453 const TopoDS_Shape& aWire2 = ex2.Value();
454 if (aWire2.ShapeType() != TopAbs_WIRE)
456 TopoDS_Iterator exW2(aWire2);
457 for(; exW2.More(); exW2.Next()) {
458 TopoDS_Edge E2 = TopoDS::Edge(exW2.Value());
459 B.UpdateEdge(E2, NullPoly, T, l);
462 B.UpdateFace(F2, TNull);
474 //=======================================================================
477 //=======================================================================
478 Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape& theShape,
479 const Standard_Real theDeflection,
480 const Standard_Real theAngle,
481 BRepMesh_PDiscretRoot& theAlgo)
483 BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
484 anAlgo->SetDeflection (theDeflection);
485 anAlgo->SetAngle (theAngle);
486 anAlgo->SetShape (theShape);
487 anAlgo->SetParallel (IS_IN_PARALLEL);
489 return 0; // no error
492 //=======================================================================
493 //function : IsParallelDefault
495 //=======================================================================
496 Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
499 return IS_IN_PARALLEL;
501 // no alternative parallelization yet - flag has no meaning
502 return Standard_False;
506 //=======================================================================
509 //=======================================================================
510 void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
512 IS_IN_PARALLEL = theInParallel;
515 //! Export Mesh Plugin entry function
516 DISCRETPLUGIN(BRepMesh_IncrementalMesh)