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.hxx>
19 #include <BRepMesh.hxx>
20 #include <BRepMesh_Edge.hxx>
21 #include <BRepMesh_Triangle.hxx>
22 #include <BRepMesh_FastDiscret.hxx>
23 #include <BRepMesh_FastDiscretFace.hxx>
24 #include <BRepMesh_PluginMacro.hxx>
26 #include <Bnd_Box.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepTools.hxx>
30 #include <BRepLib.hxx>
31 #include <BRepBndLib.hxx>
32 #include <BRepAdaptor_Curve.hxx>
33 #include <GCPnts_TangentialDeflection.hxx>
34 #include <Precision.hxx>
36 #include <TopExp_Explorer.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopTools_MutexForShapeProvider.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
41 #include <TColStd_Array1OfReal.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Edge.hxx>
46 #include <TopTools_HArray1OfShape.hxx>
47 #include <Poly_Triangulation.hxx>
48 #include <Poly_Polygon3D.hxx>
49 #include <Poly_PolygonOnTriangulation.hxx>
50 #include <Standard_Mutex.hxx>
51 #include <BRepMesh_FaceChecker.hxx>
54 // paralleling using Intel TBB
55 #include <tbb/parallel_for_each.h>
60 //! Default flag to control parallelization for BRepMesh_IncrementalMesh
61 //! tool returned for Mesh Factory
62 static Standard_Boolean IS_IN_PARALLEL = Standard_False;
65 IMPLEMENT_STANDARD_HANDLE (BRepMesh_IncrementalMesh, BRepMesh_DiscretRoot)
66 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh, BRepMesh_DiscretRoot)
68 //=======================================================================
69 //function : isCorrectPolyData
71 //=======================================================================
72 Standard_Boolean BRepMesh_IncrementalMesh::isCorrectPolyData()
76 BRepMesh_FaceChecker aFaceChecker(myInParallel);
80 // check faces in parallel threads using TBB
81 tbb::parallel_for_each(myFaces.begin(), myFaces.end(), aFaceChecker);
83 // alternative parallelization not yet available
84 for (std::vector<TopoDS_Face>::iterator it(myFaces.begin()); it != myFaces.end(); it++)
90 for (std::vector<TopoDS_Face>::iterator it(myFaces.begin()); it != myFaces.end(); it++)
94 return aFaceChecker.IsValid();
97 //=======================================================================
98 //function : BRepMesh_IncrementalMesh
100 //=======================================================================
101 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
102 : myRelative (Standard_False),
103 myInParallel (Standard_False)
108 //=======================================================================
109 //function : BRepMesh_IncrementalMesh
111 //=======================================================================
112 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
113 const Standard_Real theDeflection,
114 const Standard_Boolean theRelative,
115 const Standard_Real theAngle,
116 const Standard_Boolean theInParallel)
117 : myRelative (theRelative),
118 myInParallel (theInParallel)
121 myDeflection = theDeflection;
129 //=======================================================================
132 //=======================================================================
133 BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
137 //=======================================================================
138 //function : SetParallel
140 //=======================================================================
141 void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
143 myInParallel = theInParallel;
146 //=======================================================================
147 //function : IsParallel
149 //=======================================================================
150 Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
155 //=======================================================================
158 //=======================================================================
159 void BRepMesh_IncrementalMesh::Init()
162 myModified = Standard_False;
168 //=======================================================================
169 //function : SetRelative
171 //=======================================================================
172 void BRepMesh_IncrementalMesh::SetRelative(const Standard_Boolean theFlag)
174 myRelative = theFlag;
177 //=======================================================================
178 //function : Relative
180 //=======================================================================
181 Standard_Boolean BRepMesh_IncrementalMesh::Relative()const
186 //=======================================================================
187 //function : IsModified
189 //=======================================================================
190 Standard_Boolean BRepMesh_IncrementalMesh::IsModified() const
195 //=======================================================================
198 //=======================================================================
199 void BRepMesh_IncrementalMesh::Perform()
203 if (!isCorrectPolyData())
204 BRepTools::Clean(myShape);
210 BRepBndLib::Add(myShape, aBox);
213 if (!myMesh.IsNull()) {
217 myMesh = new BRepMesh_FastDiscret(myDeflection,
228 //=======================================================================
229 //function : GetStatus
231 //=======================================================================
232 Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
237 //=======================================================================
238 //function : collectFaces
240 //=======================================================================
241 void BRepMesh_IncrementalMesh::collectFaces()
243 TopTools_ListOfShape aFaceList;
244 BRepLib::ReverseSortFaces(myShape, aFaceList);
245 TopTools_MapOfShape aFaceMap;
246 myFaces.reserve(aFaceList.Extent());
248 // make array of faces suitable for processing (excluding faces without surface)
249 TopLoc_Location aDummyLoc;
250 const TopLoc_Location aEmptyLoc;
251 TopTools_ListIteratorOfListOfShape aFaceIter(aFaceList);
252 for (; aFaceIter.More(); aFaceIter.Next())
254 TopoDS_Shape aFaceNoLoc = aFaceIter.Value();
255 aFaceNoLoc.Location(aEmptyLoc);
256 if (!aFaceMap.Add (aFaceNoLoc))
257 continue; // already processed
259 TopoDS_Face aFace = TopoDS::Face(aFaceIter.Value());
260 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aDummyLoc);
264 myFaces.push_back(aFace);
268 //=======================================================================
269 //function : Update(shape)
270 //purpose : Builds the incremental mesh of the shape
271 //=======================================================================
272 void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
274 myModified = Standard_False;
277 //AGV 080407: Since version 6.2.0 there would be exception without this check
281 TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, myancestors);
283 BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
285 for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
286 if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
287 Update(TopoDS::Edge(ex.Current()));
292 std::vector<TopoDS_Face>::iterator aFaceIt(myFaces.begin());
293 for (; aFaceIt != myFaces.end(); aFaceIt++)
299 myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
300 // mesh faces in parallel threads using TBB
301 tbb::parallel_for_each (myFaces.begin(), myFaces.end(), *myMesh.operator->());
303 // alternative parallelization not yet available
304 for (std::vector<TopoDS_Face>::iterator it(myFaces.begin()); it != myFaces.end(); it++)
305 myMesh->Process (*it);
307 myMesh->RemoveAllMutexes();
311 for (std::vector<TopoDS_Face>::iterator it(myFaces.begin()); it != myFaces.end(); it++)
312 myMesh->Process (*it);
315 // maillage des edges non contenues dans les faces :
316 Standard_Real f, l, defedge;
317 Standard_Integer i, nbNodes;
319 Standard_Real cdef = 1.;
320 ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
323 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
325 if(!BRep_Tool::IsGeometric(E)) {
331 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
334 defedge = myDeflection;
336 Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
337 Standard_Boolean maill = Standard_False;
339 maill = Standard_True;
341 else if (P3D->Deflection() > 1.1*defedge) {
342 maill = Standard_True;
345 BRepAdaptor_Curve C(E);
346 f = C.FirstParameter();
347 l = C.LastParameter();
349 GCPnts_TangentialDeflection TD(C, f, l, myAngle, defedge, 2);
350 nbNodes = TD.NbPoints();
352 TColgp_Array1OfPnt Nodes(1, nbNodes);
353 TColStd_Array1OfReal UVNodes(1, nbNodes);
354 for ( i = 1; i <= nbNodes; i++) {
355 Nodes(i) = TD.Value(i);
356 UVNodes(i) = TD.Parameter(i);
360 Handle(Poly_Polygon3D) P = new Poly_Polygon3D(Nodes, UVNodes);
361 P->Deflection(myDeflection);
369 //=======================================================================
370 //function : Update(edge)
371 //purpose : Locate a correct discretisation if it exists
372 // Set no one otherwise
373 //=======================================================================
374 void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
377 Standard_Integer i = 1;
378 Handle(Poly_Triangulation) T, TNull;
379 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
380 Standard_Boolean found = Standard_False;
381 Standard_Real defedge = Precision::Confusion();
382 Standard_Real cdef = 1.;
384 Standard_Boolean defined = Standard_False;
387 BRep_Tool::PolygonOnTriangulation(E, Poly, T, l, i);
389 if (!T.IsNull() && !Poly.IsNull())
394 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection,
397 defedge = myDeflection;
399 mymapedge.Bind(E, defedge);
400 defined = Standard_True;
402 if (Poly->Deflection() <= 1.1 * defedge)
404 found = Standard_True;
408 myModified = Standard_True;
409 B.UpdateEdge(E, NullPoly, T, l);
412 } while (!Poly.IsNull());
414 if (!found) myMap.Add(E);
418 //=======================================================================
419 //function : Update(face)
420 //purpose : If the face is not correctly triangulated, or if one of its
421 // edges is to be discretisated correctly, the triangulation
422 // of this face is built.
423 //=======================================================================
424 void BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
427 Handle(Geom_Surface) SS = BRep_Tool::Surface(F, l);
428 if (SS.IsNull()) return;
430 //Standard_Integer i;
431 Standard_Boolean WillBeTriangulated = Standard_False;
432 Handle(Poly_Triangulation) T, TNull;
433 T = BRep_Tool::Triangulation(F, l);
434 Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
439 Standard_Real defedge, defface, cdef = 1.;
440 Standard_Integer nbEdge = 0;
444 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
445 const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
447 if (mymapedge.IsBound(edge)) {
448 defedge = mymapedge(edge);
451 defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
452 defface = defface + defedge;
454 if (nbEdge != 0) defface = defface / nbEdge;
455 else defface = myDeflection;
458 defface = myDeflection;
462 if (T->Deflection() <= 1.1 * defface)
464 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next())
466 const TopoDS_Shape& anEdge = ex.Current();
467 Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(anEdge), T, l);
469 if (Poly.IsNull() || myMap.Contains(anEdge))
471 // Triangulation is built but edge hasn't representation on it.
472 WillBeTriangulated = Standard_True;
479 WillBeTriangulated = Standard_True;
483 if (WillBeTriangulated || T.IsNull()) {
484 myModified = Standard_True;
486 for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
487 B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
488 myMap.Remove(ex.Current());
490 B.UpdateFace(F, TNull);
492 myMesh->Add(F, myancestors);
493 myStatus |= (Standard_Integer)(myMesh->CurrentFaceStatus());
494 if (myMesh->CurrentFaceStatus() == BRepMesh_ReMesh) {
496 cout << " face remaillee + finement que prevu."<< endl;
499 Standard_Integer index;
501 TopTools_MapOfShape MShape;
504 TopoDS_Iterator ex(F),ex2;
505 for (; ex.More(); ex.Next()) {
506 const TopoDS_Shape& aWire = ex.Value();
507 if (aWire.ShapeType() != TopAbs_WIRE)
509 TopoDS_Iterator exW(aWire);
510 for(; exW.More(); exW.Next()) {
511 const TopoDS_Edge& edge = TopoDS::Edge(exW.Value());
512 index = myancestors.FindIndex(edge);
514 const TopTools_ListOfShape& L = myancestors.FindFromKey(edge);
516 TopTools_ListIteratorOfListOfShape it(L);
518 for (; it.More(); it.Next()) {
519 TopoDS_Face F2 = TopoDS::Face(it.Value());
520 if (!MShape.Contains(F2)) {
522 T = BRep_Tool::Triangulation(F2, l);
525 cout <<"triangulation a refaire" <<endl;
527 for (ex2.Initialize(F2); ex2.More(); ex2.Next()) {
528 const TopoDS_Shape& aWire2 = ex2.Value();
529 if (aWire2.ShapeType() != TopAbs_WIRE)
531 TopoDS_Iterator exW2(aWire2);
532 for(; exW2.More(); exW2.Next()) {
533 TopoDS_Edge E2 = TopoDS::Edge(exW2.Value());
534 B.UpdateEdge(E2, NullPoly, T, l);
537 B.UpdateFace(F2, TNull);
538 myMesh->Add(F2, myancestors);
550 //=======================================================================
553 //=======================================================================
554 Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape& theShape,
555 const Standard_Real theDeflection,
556 const Standard_Real theAngle,
557 BRepMesh_PDiscretRoot& theAlgo)
559 BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
560 anAlgo->SetDeflection (theDeflection);
561 anAlgo->SetAngle (theAngle);
562 anAlgo->SetShape (theShape);
563 anAlgo->SetParallel (IS_IN_PARALLEL);
565 return 0; // no error
568 //=======================================================================
569 //function : IsParallelDefault
571 //=======================================================================
572 Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
575 return IS_IN_PARALLEL;
577 // no alternative parallelization yet - flag has no meaning
578 return Standard_False;
582 //=======================================================================
585 //=======================================================================
586 void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
588 IS_IN_PARALLEL = theInParallel;
591 //! Export Mesh Plugin entry function
592 DISCRETPLUGIN(BRepMesh_IncrementalMesh)