1 // Created on: 1995-06-20
2 // Created by: Stagiaire Alain JOURDAIN
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepMesh_IncrementalMesh.ixx>
19 #include <BRepMesh.hxx>
20 #include <BRepMesh_Edge.hxx>
21 #include <BRepMesh_Triangle.hxx>
22 #include <BRepMesh_FastDiscretFace.hxx>
23 #include <BRepMesh_PluginMacro.hxx>
25 #include <Bnd_Box.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepLib.hxx>
29 #include <BRepBndLib.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <GCPnts_TangentialDeflection.hxx>
32 #include <Precision.hxx>
34 #include <TopExp_Explorer.hxx>
36 #include <TopTools_ListIteratorOfListOfShape.hxx>
37 #include <TopTools_MutexForShapeProvider.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
39 #include <TColStd_Array1OfReal.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Edge.hxx>
44 #include <TopTools_HArray1OfShape.hxx>
45 #include <Poly_Triangulation.hxx>
46 #include <Poly_Polygon3D.hxx>
47 #include <Poly_PolygonOnTriangulation.hxx>
52 // paralleling using Intel TBB
53 #include <tbb/parallel_for_each.h>
58 //! Default flag to control parallelization for BRepMesh_IncrementalMesh
59 //! tool returned for Mesh Factory
60 static Standard_Boolean IS_IN_PARALLEL = Standard_False;
63 //=======================================================================
64 //function : BRepMesh_IncrementalMesh
66 //=======================================================================
67 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
68 : myRelative (Standard_False),
69 myInParallel (Standard_False),
70 myModified (Standard_False),
77 //=======================================================================
78 //function : BRepMesh_IncrementalMesh
80 //=======================================================================
81 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
82 const Standard_Real theDeflection,
83 const Standard_Boolean theRelative,
84 const Standard_Real theAngle,
85 const Standard_Boolean theInParallel)
86 : myRelative (theRelative),
87 myInParallel (theInParallel),
88 myModified (Standard_False),
93 myDeflection = theDeflection;
101 //=======================================================================
104 //=======================================================================
105 BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
109 //=======================================================================
110 //function : SetParallel
112 //=======================================================================
113 void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
115 myInParallel = theInParallel;
118 //=======================================================================
119 //function : IsParallel
121 //=======================================================================
122 Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
127 //=======================================================================
130 //=======================================================================
131 void BRepMesh_IncrementalMesh::Init()
133 myModified=Standard_False;
138 //=======================================================================
139 //function : SetRelative
141 //=======================================================================
142 void BRepMesh_IncrementalMesh::SetRelative(const Standard_Boolean theFlag)
147 //=======================================================================
148 //function : Relative
150 //=======================================================================
151 Standard_Boolean BRepMesh_IncrementalMesh::Relative()const
156 //=======================================================================
157 //function : IsModified
159 //=======================================================================
160 Standard_Boolean BRepMesh_IncrementalMesh::IsModified() const
165 //=======================================================================
168 //=======================================================================
169 void BRepMesh_IncrementalMesh::Perform()
177 BRepBndLib::Add(myShape, aBox);
180 if (!myMesh.IsNull()) {
184 myMesh = new BRepMesh_FastDiscret(myDeflection,
195 //=======================================================================
196 //function : GetStatus
198 //=======================================================================
199 Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
204 //=======================================================================
205 //function : Update(shape)
206 //purpose : Builds the incremental mesh of the shape
207 //=======================================================================
208 void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
210 myModified = Standard_False;
213 //AGV 080407: Since version 6.2.0 there would be exception without this check
217 TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, myancestors);
219 BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
221 for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
222 if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
223 Update(TopoDS::Edge(ex.Current()));
228 std::vector<TopoDS_Face> aFaces;
230 TopTools_ListOfShape aFaceList;
231 BRepLib::ReverseSortFaces (S, aFaceList);
232 TopTools_MapOfShape aFaceMap;
233 aFaces.reserve (aFaceList.Extent());
235 // make array of faces suitable for processing (excluding faces without surface)
236 TopLoc_Location aDummyLoc;
237 const TopLoc_Location anEmptyLoc;
238 for (TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList); aFaceIter.More(); aFaceIter.Next())
240 TopoDS_Shape aFaceNoLoc = aFaceIter.Value();
241 aFaceNoLoc.Location (anEmptyLoc);
242 if (!aFaceMap.Add (aFaceNoLoc))
243 continue; // already processed
245 TopoDS_Face aFace = TopoDS::Face (aFaceIter.Value());
246 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
251 aFaces.push_back (aFace);
258 myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
259 // mesh faces in parallel threads using TBB
260 tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
262 // alternative parallelization not yet available
263 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
264 myMesh->Process (*it);
266 myMesh->RemoveAllMutexes();
270 for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
271 myMesh->Process (*it);
274 // maillage des edges non contenues dans les faces :
275 Standard_Real f, l, defedge;
276 Standard_Integer i, nbNodes;
278 Standard_Real cdef = 1.;
279 ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
282 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
284 if(!BRep_Tool::IsGeometric(E)) {
290 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
293 defedge = myDeflection;
295 Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
296 Standard_Boolean maill = Standard_False;
298 maill = Standard_True;
300 else if (P3D->Deflection() > 1.1*defedge) {
301 maill = Standard_True;
304 BRepAdaptor_Curve C(E);
305 f = C.FirstParameter();
306 l = C.LastParameter();
308 GCPnts_TangentialDeflection TD(C, f, l, myAngle, defedge, 2);
309 nbNodes = TD.NbPoints();
311 TColgp_Array1OfPnt Nodes(1, nbNodes);
312 TColStd_Array1OfReal UVNodes(1, nbNodes);
313 for ( i = 1; i <= nbNodes; i++) {
314 Nodes(i) = TD.Value(i);
315 UVNodes(i) = TD.Parameter(i);
319 Handle(Poly_Polygon3D) P = new Poly_Polygon3D(Nodes, UVNodes);
320 P->Deflection(myDeflection);
328 //=======================================================================
329 //function : Update(edge)
330 //purpose : Locate a correct discretisation if it exists
331 // Set no one otherwise
332 //=======================================================================
333 void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
336 Standard_Integer i = 1;
337 Handle(Poly_Triangulation) T, TNull;
338 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
339 Standard_Boolean found = Standard_False;
340 Standard_Real defedge = Precision::Confusion();
341 Standard_Real cdef = 1.;
343 Standard_Boolean defined = Standard_False;
346 BRep_Tool::PolygonOnTriangulation(E, Poly, T, l, i);
348 if (!T.IsNull() && !Poly.IsNull())
353 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
356 defedge = myDeflection;
358 mymapedge.Bind(E, defedge);
359 defined = Standard_True;
361 if (Poly->Deflection() <= 1.1 * defedge)
363 found = Standard_True;
367 myModified = Standard_True;
368 B.UpdateEdge(E, NullPoly, T, l);
371 } while (!Poly.IsNull());
373 if (!found) myMap.Add(E);
377 //=======================================================================
378 //function : Update(face)
379 //purpose : If the face is not correctly triangulated, or if one of its
380 // edges is to be discretisated correctly, the triangulation
381 // of this face is built.
382 //=======================================================================
383 void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
386 Handle(Geom_Surface) SS = BRep_Tool::Surface(F, l);
387 if (SS.IsNull()) return;
389 //Standard_Integer i;
390 Standard_Boolean WillBeTriangulated = Standard_False;
391 Handle(Poly_Triangulation) T, TNull;
392 T = BRep_Tool::Triangulation(F, l);
393 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
398 Standard_Real defedge, defface, cdef = 1.;
399 Standard_Integer nbEdge = 0;
403 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
404 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
406 if (mymapedge.IsBound(edge)) {
407 defedge = mymapedge(edge);
410 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
411 defface = defface + defedge;
413 if (nbEdge != 0) defface = defface / nbEdge;
414 else defface = myDeflection;
417 defface = myDeflection;
421 if (T->Deflection() <= 1.1 * defface)
423 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next())
425 const TopoDS_Shape& anEdge = ex.Current();
426 Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(anEdge), T, l);
428 if (Poly.IsNull() || myMap.Contains(anEdge))
430 // Triangulation is built but edge hasn't representation on it.
431 WillBeTriangulated = Standard_True;
438 WillBeTriangulated = Standard_True;
442 if (WillBeTriangulated || T.IsNull()) {
443 myModified = Standard_True;
445 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
446 B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
447 myMap.Remove(ex.Current());
449 B.UpdateFace(F, TNull);
451 myMesh->Add(F, myancestors);
452 myStatus |= (Standard_Integer)(myMesh->CurrentFaceStatus());
453 if (myMesh->CurrentFaceStatus() == BRepMesh_ReMesh) {
455 cout << " face remaillee + finement que prevu."<< endl;
458 Standard_Integer index;
460 TopTools_MapOfShape MShape;
463 TopoDS_Iterator ex(F),ex2;
464 for (; ex.More(); ex.Next()) {
465 const TopoDS_Shape& aWire = ex.Value();
466 if (aWire.ShapeType() != TopAbs_WIRE)
468 TopoDS_Iterator exW(aWire);
469 for(; exW.More(); exW.Next()) {
470 const TopoDS_Edge& edge = TopoDS::Edge(exW.Value());
471 index = myancestors.FindIndex(edge);
473 const TopTools_ListOfShape& L = myancestors.FindFromKey(edge);
475 TopTools_ListIteratorOfListOfShape it(L);
477 for (; it.More(); it.Next()) {
478 TopoDS_Face F2 = TopoDS::Face(it.Value());
479 if (!MShape.Contains(F2)) {
481 T = BRep_Tool::Triangulation(F2, l);
484 cout <<"triangulation a refaire" <<endl;
486 for (ex2.Initialize(F2); ex2.More(); ex2.Next()) {
487 const TopoDS_Shape& aWire2 = ex2.Value();
488 if (aWire2.ShapeType() != TopAbs_WIRE)
490 TopoDS_Iterator exW2(aWire2);
491 for(; exW2.More(); exW2.Next()) {
492 TopoDS_Edge E2 = TopoDS::Edge(exW2.Value());
493 B.UpdateEdge(E2, NullPoly, T, l);
496 B.UpdateFace(F2, TNull);
497 myMesh->Add(F2, myancestors);
509 //=======================================================================
512 //=======================================================================
513 Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape& theShape,
514 const Standard_Real theDeflection,
515 const Standard_Real theAngle,
516 BRepMesh_PDiscretRoot& theAlgo)
518 BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
519 anAlgo->SetDeflection (theDeflection);
520 anAlgo->SetAngle (theAngle);
521 anAlgo->SetShape (theShape);
522 anAlgo->SetParallel (IS_IN_PARALLEL);
524 return 0; // no error
527 //=======================================================================
528 //function : IsParallelDefault
530 //=======================================================================
531 Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
534 return IS_IN_PARALLEL;
536 // no alternative parallelization yet - flag has no meaning
537 return Standard_False;
541 //=======================================================================
544 //=======================================================================
545 void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
547 IS_IN_PARALLEL = theInParallel;
550 //! Export Mesh Plugin entry function
551 DISCRETPLUGIN(BRepMesh_IncrementalMesh)