0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / BRepMesh / BRepMesh_IncrementalMesh.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 9e4853c..70278be
 // Created on: 1995-06-20
 // Created by: Stagiaire Alain JOURDAIN
 // Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
+#include <BRepMesh_IncrementalMesh.hxx>
 
+#include <OSD_Parallel.hxx>
+#include <Precision.hxx>
+#include <Standard_ErrorHandler.hxx>
 
-#include <BRepMesh_IncrementalMesh.ixx>
-
-#include <BRepMesh.hxx>
+#include <BRepMesh_ShapeTool.hxx>
 #include <BRepMesh_Edge.hxx>
-#include <BRepMesh_Triangle.hxx>
-#include <BRepMesh_FastDiscretFace.hxx>
 #include <BRepMesh_PluginMacro.hxx>
 
 #include <Bnd_Box.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
 #include <BRepLib.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepAdaptor_Curve.hxx>
-#include <GCPnts_TangentialDeflection.hxx>
-#include <Precision.hxx>
+
+#include <Poly_Triangulation.hxx>
+#include <Poly_Polygon3D.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopAbs.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <TopAbs.hxx>
+
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_MutexForShapeProvider.hxx>
 #include <TColgp_Array1OfPnt.hxx>
+#include <TColgp_Array1OfPnt2d.hxx>
 #include <TColStd_Array1OfReal.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS.hxx>
+#include <TColStd_MapOfTransient.hxx>
 #include <TopTools_HArray1OfShape.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Poly_Polygon3D.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 
-#include <vector>
+#include <GCPnts_TangentialDeflection.hxx>
 
-#ifdef HAVE_TBB
-  // paralleling using Intel TBB
-  #include <tbb/parallel_for_each.h>
-#endif
+IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
 
 namespace
 {
   //! Default flag to control parallelization for BRepMesh_IncrementalMesh
   //! tool returned for Mesh Factory
   static Standard_Boolean IS_IN_PARALLEL = Standard_False;
-};
+}
+
 
 //=======================================================================
-//function : BRepMesh_IncrementalMesh
+//function : Default constructor
 //purpose  : 
 //=======================================================================
-BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh() 
-: myRelative (Standard_False),
-  myInParallel (Standard_False),
-  myModified (Standard_False),
-  myStatus (0)
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
+: myMaxShapeSize(0.),
+  myModified(Standard_False),
+  myStatus(0)
 {
-  mymapedge.Clear();
-  myancestors.Clear();
 }
 
 //=======================================================================
-//function : BRepMesh_IncrementalMesh
+//function : Constructor
 //purpose  : 
 //=======================================================================
-BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
-                                                    const Standard_Real theDeflection,
-                                                    const Standard_Boolean theRelative,
-                                                    const Standard_Real theAngle,
-                                                                                                       const Standard_Boolean theInParallel)
-: myRelative (theRelative),
-  myInParallel (theInParallel),
-  myModified (Standard_False),
-  myStatus (0)
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape&    theShape,
+                                                    const Standard_Real    theLinDeflection,
+                                                    const Standard_Boolean isRelative,
+                                                    const Standard_Real    theAngDeflection,
+                                                    const Standard_Boolean isInParallel,
+                                                    const Standard_Boolean adaptiveMin)
+: myMaxShapeSize(0.),
+  myModified(Standard_False),
+  myStatus(0)
 {
-  mymapedge.Clear();
-  myancestors.Clear();
-  myDeflection = theDeflection;
-  myAngle = theAngle;
-  myShape = theShape;
+  myParameters.Deflection = theLinDeflection;
+  myParameters.Relative = isRelative;
+  myParameters.Angle = theAngDeflection;
+  myParameters.InParallel = isInParallel;
+  myParameters.AdaptiveMin = adaptiveMin;
 
-  //
+  myShape = theShape;
   Perform();
 }
 
 //=======================================================================
-//function : ~
+//function : Constructor
 //purpose  : 
 //=======================================================================
-BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh() 
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
+                                                   const BRepMesh_FastDiscret::Parameters& theParameters)
+  : myParameters(theParameters)
 {
+  myShape       = theShape;
+  
+  Perform();
 }
 
 //=======================================================================
-//function : SetParallel
-//purpose  :
+//function : Destructor
+//purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::SetParallel (const Standard_Boolean theInParallel)
+BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
 {
-  myInParallel = theInParallel;
 }
 
 //=======================================================================
-//function : IsParallel
-//purpose  :
+//function : clear
+//purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::IsParallel() const
+void BRepMesh_IncrementalMesh::clear()
 {
-  return myInParallel;
+  // the allocator will be alive while the structures are alive
+  Handle(NCollection_BaseAllocator) anAlloc =
+    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+  myEdges.Clear(anAlloc);
+  myEdgeDeflection.Clear(anAlloc);
+  myFaces.Clear();
+  myMesh.Nullify();
 }
 
 //=======================================================================
-//function : Init
+//function : init
 //purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::Init() 
+void BRepMesh_IncrementalMesh::init() 
 {
-  myModified=Standard_False;
-  mymapedge.Clear();
-  myancestors.Clear();
+  myStatus   = 0;
+  myModified = Standard_False;
+
+  setDone();
+  clear();
+
+  collectFaces();
+
+  Bnd_Box aBox;
+  if ( myParameters.Relative ) 
+  {
+    BRepBndLib::Add(myShape, aBox, Standard_False);
+
+    if (aBox.IsVoid())
+    {
+      // Nothing to mesh.
+      return;
+    }
+
+    BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
+  }
+
+  myMesh = new BRepMesh_FastDiscret (aBox, myParameters);
+  
+  myMesh->InitSharedFaces(myShape);
 }
 
 //=======================================================================
-//function : SetRelative
+//function : collectFaces
 //purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::SetRelative(const Standard_Boolean theFlag)
+void BRepMesh_IncrementalMesh::collectFaces()
 {
-  myRelative=theFlag;
+  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
+  TopTools_ListOfShape aFaceList(anAlloc);
+  BRepLib::ReverseSortFaces(myShape, aFaceList);
+  TColStd_MapOfTransient aTFaceMap(1, anAlloc);
+
+  // make array of faces suitable for processing (excluding faces without surface)
+  TopLoc_Location aDummyLoc;
+  TopTools_ListIteratorOfListOfShape aFaceIter(aFaceList);
+  for (; aFaceIter.More(); aFaceIter.Next())
+  {
+    const TopoDS_Face& aFace = TopoDS::Face(aFaceIter.Value());
+    const Handle(TopoDS_TShape)& aTFace = aFace.TShape();
+    if (!aTFaceMap.Add (aTFace))
+      continue; // already processed
+
+    const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aDummyLoc);
+    if (aSurf.IsNull())
+      continue;
+
+    myFaces.Append(aFace);
+  }
 }
 
 //=======================================================================
-//function : Relative
+//function : Perform
 //purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::Relative()const
+void BRepMesh_IncrementalMesh::Perform()
 {
-  return myRelative;
+  init();
+
+  if (myMesh.IsNull())
+    return;
+
+  update();
 }
 
 //=======================================================================
-//function : IsModified
+//function : update()
 //purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::IsModified() const
+void BRepMesh_IncrementalMesh::update()
 {
-  return myModified;
+  // Update edges data
+  TopExp_Explorer aExplorer(myShape, TopAbs_EDGE);
+  for (; aExplorer.More(); aExplorer.Next())
+  {
+    const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
+    if(!BRep_Tool::IsGeometric(aEdge))
+      continue;
+
+    update(aEdge);
+  }
+
+  // Update faces data
+  NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
+  for (; aFaceIt.More(); aFaceIt.Next())
+    update(aFaceIt.Value());
+
+  // Mesh faces
+  OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel);
+
+  commit();
+  clear();
 }
 
 //=======================================================================
-//function : Perform
+//function : discretizeFreeEdges
 //purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::Perform()
+void BRepMesh_IncrementalMesh::discretizeFreeEdges()
 {
-  Bnd_Box aBox;
-  //
-  SetDone();
-  //
-  Init(); 
-  //
-  BRepBndLib::Add(myShape, aBox);
-  myBox = aBox;
-  //
-  if (!myMesh.IsNull()) {
-    myMesh.Nullify();
+  TopExp_Explorer aExplorer(myShape ,TopAbs_EDGE, TopAbs_FACE);
+  for (; aExplorer.More(); aExplorer.Next())
+  {
+    const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
+    if(!BRep_Tool::IsGeometric(aEdge))
+      continue;
+    
+    TopLoc_Location aLoc;
+    Standard_Real aEdgeDeflection  = edgeDeflection(aEdge);
+    Handle(Poly_Polygon3D) aPoly3D = BRep_Tool::Polygon3D(aEdge, aLoc);
+    if (!aPoly3D.IsNull() && aPoly3D->Deflection() < 1.1 * aEdgeDeflection)
+      continue;
+
+    BRepAdaptor_Curve aCurve(aEdge);
+    GCPnts_TangentialDeflection aDiscret(aCurve, aCurve.FirstParameter(),
+      aCurve.LastParameter(), myParameters.Angle, aEdgeDeflection, 2,
+      Precision::PConfusion(), myParameters.MinSize);
+
+    Standard_Integer aNodesNb = aDiscret.NbPoints();
+    TColgp_Array1OfPnt   aNodes  (1, aNodesNb);
+    TColStd_Array1OfReal aUVNodes(1, aNodesNb);
+    for (Standard_Integer i = 1; i <= aNodesNb; ++i)
+    {
+      aNodes  (i) = aDiscret.Value(i);
+      aUVNodes(i) = aDiscret.Parameter(i);
+    }
+    
+    aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes);
+    aPoly3D->Deflection(myParameters.Deflection);
+
+    BRep_Builder aBuilder;
+    aBuilder.UpdateEdge(aEdge, aPoly3D);
   }
-  //
-  myMesh = new BRepMesh_FastDiscret(myDeflection,
-                                   myAngle,
-                                   aBox,
-                                   Standard_True,
-                                   Standard_True,
-                                   myRelative,
-                                   Standard_True);
-  //
-  Update(myShape);
 }
 
 //=======================================================================
-//function : GetStatus
+//function : edgeDeflection
 //purpose  : 
 //=======================================================================
-Standard_Integer BRepMesh_IncrementalMesh::GetStatusFlags() const
+Standard_Real BRepMesh_IncrementalMesh::edgeDeflection(
+  const TopoDS_Edge& theEdge)
 {
-  return myStatus;
+  const Standard_Real* pDef = myEdgeDeflection.Seek(theEdge);
+  if (pDef)
+    return *pDef;
+
+  Standard_Real aEdgeDeflection;
+  if ( myParameters.Relative ) 
+  {
+    Standard_Real aScale;
+    aEdgeDeflection = BRepMesh_ShapeTool::RelativeEdgeDeflection(theEdge, 
+      myParameters.Deflection, myMaxShapeSize, aScale);
+  }
+  else
+    aEdgeDeflection = myParameters.Deflection;
+
+  myEdgeDeflection.Bind(theEdge, aEdgeDeflection);
+  return aEdgeDeflection;
 }
 
 //=======================================================================
-//function : Update(shape)
-//purpose  : Builds the incremental mesh of the shape
+//function : faceDeflection
+//purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::Update(const TopoDS_Shape& S)
+Standard_Real BRepMesh_IncrementalMesh::faceDeflection(
+  const TopoDS_Face& theFace)
 {
-  myModified = Standard_False;
-  TopExp_Explorer ex;
+  if ( !myParameters.Relative )
+    return myParameters.Deflection;
 
-  //AGV 080407: Since version 6.2.0 there would be exception without this check
-  if (myBox.IsVoid())
-    return;
+  Standard_Integer aEdgesNb        = 0;
+  Standard_Real    aFaceDeflection = 0.;
 
-  TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, myancestors);
-  
-  BRepMesh_FastDiscret::BoxMaxDimension(myBox, mydtotale);
-  
-  for (ex.Init(S, TopAbs_EDGE); ex.More(); ex.Next()) {
-    if(BRep_Tool::IsGeometric(TopoDS::Edge(ex.Current()))) {
-      Update(TopoDS::Edge(ex.Current()));
-    }
+  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+  for (; aEdgeIt.More(); aEdgeIt.Next(), ++aEdgesNb)
+  {
+    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+    aFaceDeflection += edgeDeflection(aEdge);
   }
 
-  // get list of faces
-  std::vector<TopoDS_Face> aFaces;
+  return (aEdgesNb == 0) ? myParameters.Deflection : (aFaceDeflection / aEdgesNb);
+}
+
+//=======================================================================
+//function : update(edge)
+//purpose  : 
+//=======================================================================
+void BRepMesh_IncrementalMesh::update(const TopoDS_Edge& theEdge)
+{
+  if (!myEdges.IsBound(theEdge))
+    myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool(3, myEdges.Allocator()));
+
+  Standard_Real aEdgeDeflection = edgeDeflection(theEdge);
+  // Check that triangulation relies to face of the given shape.
+  const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
+    myMesh->SharedFaces();
+
+  const TopTools_ListOfShape& aSharedFaces = 
+    aMapOfSharedFaces.FindFromKey(theEdge);
+
+  TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
+  for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
   {
-    TopTools_ListOfShape aFaceList;
-    BRepLib::ReverseSortFaces (S, aFaceList);
-    TopTools_MapOfShape aFaceMap;
-    aFaces.reserve (aFaceList.Extent());
-
-    // make array of faces suitable for processing (excluding faces without surface)
-    TopLoc_Location aDummyLoc;
-    const TopLoc_Location anEmptyLoc;
-    for (TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList); aFaceIter.More(); aFaceIter.Next())
+    TopLoc_Location aLoc;
+    const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
+    const Handle(Poly_Triangulation)& aFaceTriangulation = 
+      BRep_Tool::Triangulation(aFace, aLoc);
+
+    if (aFaceTriangulation.IsNull())
+      continue;
+
+    Standard_Boolean isConsistent = Standard_False;
+    const Handle(Poly_PolygonOnTriangulation)& aPolygon =
+      BRep_Tool::PolygonOnTriangulation(theEdge, aFaceTriangulation, aLoc);
+
+    if (!aPolygon.IsNull())
     {
-      TopoDS_Shape aFaceNoLoc = aFaceIter.Value();
-      aFaceNoLoc.Location (anEmptyLoc);
-      if (!aFaceMap.Add (aFaceNoLoc))
-        continue; // already processed
-
-      TopoDS_Face aFace = TopoDS::Face (aFaceIter.Value());
-      const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
-      if (aSurf.IsNull())
-        continue;
+      isConsistent = aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
+        aPolygon->HasParameters();
 
-      Update (aFace);
-      aFaces.push_back (aFace);
+      if (!isConsistent)
+      {
+        myModified = Standard_True;
+        BRepMesh_ShapeTool::NullifyEdge(theEdge, aFaceTriangulation, aLoc);
+      }
     }
+
+    myEdges(theEdge).Bind(aFaceTriangulation, isConsistent);
   }
+}
+
+//=======================================================================
+//function : isToBeMeshed
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_IncrementalMesh::toBeMeshed(
+  const TopoDS_Face&     theFace,
+  const Standard_Boolean isWithCheck)
+{
+  TopLoc_Location aLoc;
+  const Handle(Poly_Triangulation)& aTriangulation = 
+    BRep_Tool::Triangulation(theFace, aLoc);
 
-  if (myInParallel)
+  if (aTriangulation.IsNull())
+    return Standard_True;
+
+  if (isWithCheck)
   {
-  #ifdef HAVE_TBB
-    myMesh->CreateMutexesForSubShapes(S, TopAbs_EDGE);
-    // mesh faces in parallel threads using TBB
-    tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *myMesh.operator->());
-  #else
-    // alternative parallelization not yet available
-    for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
-      myMesh->Process (*it);
-  #endif
-    myMesh->RemoveAllMutexes();
+    Standard_Real aFaceDeflection = faceDeflection(theFace);
+    if (aTriangulation->Deflection() < 1.1 * aFaceDeflection)
+    {
+      Standard_Boolean isEdgesConsistent = Standard_True;
+      TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+      for (; aEdgeIt.More() && isEdgesConsistent; aEdgeIt.Next())
+      {
+        const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+        if (!myEdges.IsBound(aEdge))
+          continue;
+
+        BRepMesh::DMapOfTriangulationBool& aTriMap = myEdges(aEdge);
+        isEdgesConsistent &= aTriMap.IsBound(aTriangulation) &&
+          aTriMap(aTriangulation);
+      }
+
+      if (isEdgesConsistent)
+      {
+        // #25080: check that indices of links forming triangles are in range.
+        Standard_Boolean isTriangulationConsistent = Standard_True;
+        const Standard_Integer aNodesNb = aTriangulation->NbNodes();
+        const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
+        Standard_Integer i = aTriangles.Lower();
+        for (; i <= aTriangles.Upper() && isTriangulationConsistent; ++i)
+        {
+          const Poly_Triangle& aTriangle = aTriangles(i);
+          Standard_Integer n[3];
+          aTriangle.Get(n[0], n[1], n[2]);
+          for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
+            isTriangulationConsistent = (n[j] >= 1 && n[j] <= aNodesNb);
+        }
+
+        if (isTriangulationConsistent)
+          return Standard_False;
+      }
+    }
   }
-  else
+
+  // Nullify edges
+  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+  for (; aEdgeIt.More(); aEdgeIt.Next())
   {
-    for (std::vector<TopoDS_Face>::iterator it(aFaces.begin()); it != aFaces.end(); it++)
-      myMesh->Process (*it);
+    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+    BRepMesh_ShapeTool::NullifyEdge(aEdge, aTriangulation, aLoc);
   }
 
-  // maillage des edges non contenues dans les faces :
-  Standard_Real f, l, defedge;
-  Standard_Integer i, nbNodes;
-  TopLoc_Location L;
-  Standard_Real cdef = 1.;
-  ex.Init(S ,TopAbs_EDGE, TopAbs_FACE);
+  BRepMesh_ShapeTool::NullifyFace(theFace);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : update(face)
+//purpose  : 
+//=======================================================================
+void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace)
+{
+  if (!toBeMeshed(theFace, Standard_True))
+    return;
+
+  myModified = Standard_True;
+  Standard_Integer aStatus = myMesh->Add(theFace);
+
+  myStatus |= aStatus;
+  if (aStatus != BRepMesh_ReMesh)
+    return;
 
-  while (ex.More()) {
-    const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
+  BRepMesh::MapOfShape aUsedFaces;
+  aUsedFaces.Add(theFace);
 
-    if(!BRep_Tool::IsGeometric(E)) {
-      ex.Next();
+  const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
+    myMesh->SharedFaces();
+
+  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
+  for (; aEdgeIt.More(); aEdgeIt.Next())
+  {
+    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
+    if (aMapOfSharedFaces.FindIndex(aEdge) == 0)
       continue;
-    }
+     
+    const TopTools_ListOfShape& aSharedFaces = aMapOfSharedFaces.FindFromKey(aEdge);
+    TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
+    for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
+    {
+      const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
+      if (aUsedFaces.Contains(aFace))
+        continue;
 
-    if (myRelative) 
-      defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection, 
-                                                             mydtotale, cdef);
-    else 
-      defedge = myDeflection;
-    
-    Handle(Poly_Polygon3D) P3D = BRep_Tool::Polygon3D(E, L);
-    Standard_Boolean maill = Standard_False;
-    if (P3D.IsNull()) {
-      maill = Standard_True;
-    }
-    else if (P3D->Deflection() > 1.1*defedge) {
-      maill = Standard_True;
-    }
-    if (maill) {
-      BRepAdaptor_Curve C(E);
-      f = C.FirstParameter();
-      l = C.LastParameter();
-      
-      GCPnts_TangentialDeflection TD(C, f, l, myAngle, defedge, 2);
-      nbNodes = TD.NbPoints();
-      
-      TColgp_Array1OfPnt Nodes(1, nbNodes);
-      TColStd_Array1OfReal UVNodes(1, nbNodes);
-      for ( i = 1; i <= nbNodes; i++) {
-        Nodes(i) = TD.Value(i);
-        UVNodes(i) = TD.Parameter(i);
-      }
-      
-      BRep_Builder B;
-      Handle(Poly_Polygon3D) P = new Poly_Polygon3D(Nodes, UVNodes);
-      P->Deflection(myDeflection);
-      B.UpdateEdge(E, P);
-    }
+      aUsedFaces.Add(aFace);
+      toBeMeshed(aFace, Standard_False);
 
-    ex.Next();
+      myStatus |= myMesh->Add(aFace);
+    }
   }
 }
 
 //=======================================================================
-//function : Update(edge)
-//purpose  : Locate a correct discretisation if it exists
-//           Set no one otherwise
+//function : commit
+//purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::Update(const TopoDS_Edge& E)
+void BRepMesh_IncrementalMesh::commit()
 {
-  TopLoc_Location l;
-  Standard_Integer i = 1;
-  Handle(Poly_Triangulation) T, TNull;
-  Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
-  Standard_Boolean found = Standard_False;
-  Standard_Real defedge = Precision::Confusion();
-  Standard_Real cdef = 1.;
-  BRep_Builder B;
-  Standard_Boolean defined = Standard_False;
-  
-  do {
-    BRep_Tool::PolygonOnTriangulation(E, Poly, T, l, i);
-    i++;
-    if (!T.IsNull() && !Poly.IsNull()) {
-      if (!defined) {
-        if (myRelative) 
-          defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(E, myDeflection, 
-                                                                 mydtotale, cdef);
-        else 
-          defedge = myDeflection;
-        mymapedge.Bind(E, defedge);
-        defined = Standard_True;
-      }
-      if ((!myRelative && Poly->Deflection() <= 1.1*defedge) ||
-          (myRelative && Poly->Deflection() <= 1.1*defedge)) 
-        found = Standard_True;
-      else {
-        myModified = Standard_True;
-        B.UpdateEdge(E, NullPoly, T, l);
-      }
-    }
-  } while (!Poly.IsNull());
+  NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
+  for (; aFaceIt.More(); aFaceIt.Next())
+    commitEdges(aFaceIt.Value());
 
-  if (!found) myMap.Add(E);
+  discretizeFreeEdges();
 }
 
-
 //=======================================================================
-//function : Update(face)
-//purpose  : If the face is not correctly triangulated, or if one of its
-//           edges is to be discretisated correctly, the triangulation
-//           of this face is built.
+//function : commitEdges
+//purpose  : 
 //=======================================================================
-void  BRepMesh_IncrementalMesh::Update(const TopoDS_Face& F)
+void BRepMesh_IncrementalMesh::commitEdges(const TopoDS_Face& theFace)
 {
-  TopLoc_Location l;
-  Handle(Geom_Surface) SS = BRep_Tool::Surface(F, l);
-  if (SS.IsNull()) return;
-
-  //Standard_Integer i;
-  Standard_Boolean WillBeTriangulated = Standard_False;
-  Handle(Poly_Triangulation) T, TNull;
-  T = BRep_Tool::Triangulation(F, l);
-  Handle(Poly_PolygonOnTriangulation) Poly, NullPoly;
-
-  BRep_Builder B;
-  TopExp_Explorer ex;
-  
-  Standard_Real defedge, defface, cdef = 1.;
-  Standard_Integer nbEdge = 0;
-  if (myRelative) {
-    defface = 0.;
-    
-    for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
-      const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
-      nbEdge++;
-      if (mymapedge.IsBound(edge)) {
-        defedge = mymapedge(edge);
-      }
-      else 
-        defedge = BRepMesh_FastDiscret::RelativeEdgeDeflection(edge, myDeflection, mydtotale, cdef);
-      defface = defface + defedge;
-    }
-    if (nbEdge != 0) defface = defface / nbEdge;
-    else             defface = myDeflection;
-  }
-  else
-    defface = myDeflection;
-
-  if (!T.IsNull()) {
-    if ((!myRelative && T->Deflection() <= 1.1*defface) ||
-        (myRelative && T->Deflection() <= 1.1*defface)) {
-      for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
-        const TopoDS_Shape& E = ex.Current();
-        Poly = BRep_Tool::PolygonOnTriangulation(TopoDS::Edge(E), T, l);
-        if (Poly.IsNull() || myMap.Contains(E)) {
-          WillBeTriangulated = Standard_True;
-          // cas un peu special. la triangulation est bonne, mais
-          // l'edge n'a pas de representation polygonalisee sur celle-ci.
-          break;
-        }
-      }
-    } 
-    else WillBeTriangulated = Standard_True;
+  TopoDS_Face aFace = theFace;
+  aFace.Orientation(TopAbs_FORWARD);
+
+  Handle(BRepMesh_FaceAttribute) aFaceAttribute;
+  if (!myMesh->GetFaceAttribute(aFace, aFaceAttribute))
+    return;
+
+  if (!aFaceAttribute->IsValid())
+  {
+    myStatus |= aFaceAttribute->GetStatus();
+    return;
   }
 
-  if (WillBeTriangulated || T.IsNull()) {
-    myModified = Standard_True;
-    if (!T.IsNull()) {
-      for (ex.Init(F, TopAbs_EDGE); ex.More(); ex.Next()) {
-        B.UpdateEdge(TopoDS::Edge(ex.Current()), NullPoly, T, l);
-        myMap.Remove(ex.Current());
-      }
-      B.UpdateFace(F, TNull);
-    }
-    myMesh->Add(F, myancestors);
-    myStatus |= (Standard_Integer)(myMesh->CurrentFaceStatus());
-    if (myMesh->CurrentFaceStatus() == BRepMesh_ReMesh) {
-#ifdef DEB_MESH
-      cout << " face remaillee + finement que prevu."<< endl;
-#endif
-
-      Standard_Integer index;
-      
-      TopTools_MapOfShape MShape;
-      MShape.Add(F);
-
-      TopoDS_Iterator ex(F),ex2;
-      for (; ex.More(); ex.Next()) {
-        const TopoDS_Shape& aWire = ex.Value();
-        if (aWire.ShapeType() != TopAbs_WIRE)
-          continue;
-        TopoDS_Iterator exW(aWire);
-        for(; exW.More(); exW.Next()) {
-          const TopoDS_Edge& edge = TopoDS::Edge(exW.Value());
-          index = myancestors.FindIndex(edge);
-          if (index != 0) {
-            const TopTools_ListOfShape& L = myancestors.FindFromKey(edge);
-         
-            TopTools_ListIteratorOfListOfShape it(L);
-         
-            for (; it.More(); it.Next()) {
-              TopoDS_Face F2 = TopoDS::Face(it.Value());
-              if (!MShape.Contains(F2)) {
-                MShape.Add(F2);
-                T = BRep_Tool::Triangulation(F2, l);     
-                if (!T.IsNull()) {
-#ifdef DEB_MESH
-                  cout <<"triangulation a refaire" <<endl;
-#endif
-                  for (ex2.Initialize(F2); ex2.More(); ex2.Next()) {
-                    const TopoDS_Shape& aWire2 = ex2.Value();
-                    if (aWire2.ShapeType() != TopAbs_WIRE)
-                      continue;
-                    TopoDS_Iterator exW2(aWire2);
-                    for(; exW2.More(); exW2.Next()) {
-                      TopoDS_Edge E2 = TopoDS::Edge(exW2.Value());
-                      B.UpdateEdge(E2, NullPoly, T, l);
-                    }
-                  }
-                  B.UpdateFace(F2, TNull);
-                  myMesh->Add(F2, myancestors);
-                }
-              }
-            }
-          }
-        }
-      }      
+  TopLoc_Location aLoc;
+  Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
+
+  if (aTriangulation.IsNull())
+    return;
+
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    // Store discretization of edges
+    BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = aFaceAttribute->ChangeInternalEdges();
+    BRepMesh::DMapOfShapePairOfPolygon::Iterator aEdgeIt(*aInternalEdges);
+    for (; aEdgeIt.More(); aEdgeIt.Next())
+    {
+      const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Key());
+      const BRepMesh_PairOfPolygon& aPolyPair = aEdgeIt.Value();
+      const Handle(Poly_PolygonOnTriangulation)& aPolygon1 = aPolyPair.First();
+      const Handle(Poly_PolygonOnTriangulation)& aPolygon2 = aPolyPair.Last();
+
+      if (aPolygon1 == aPolygon2)
+        BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aTriangulation, aLoc);
+      else
+        BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aPolygon2, aTriangulation, aLoc);
     }
   }
+  catch (Standard_Failure)
+  {
+    myStatus |= BRepMesh_Failure;
+  }
 }
 
 //=======================================================================
 //function : Discret
 //purpose  :
 //=======================================================================
-Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape&    theShape,
-                                                    const Standard_Real    theDeflection,
-                                                    const Standard_Real    theAngle,
-                                                    BRepMesh_PDiscretRoot& theAlgo)
+Standard_Integer BRepMesh_IncrementalMesh::Discret(
+  const TopoDS_Shape&    theShape,
+  const Standard_Real    theDeflection,
+  const Standard_Real    theAngle,
+  BRepMesh_DiscretRoot* &theAlgo)
 {
   BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
-  anAlgo->SetDeflection (theDeflection);
-  anAlgo->SetAngle (theAngle);
-  anAlgo->SetShape (theShape);
-  anAlgo->SetParallel (IS_IN_PARALLEL);
+  anAlgo->ChangeParameters().Deflection = theDeflection;
+  anAlgo->ChangeParameters().Angle = theAngle;
+  anAlgo->ChangeParameters().InParallel = IS_IN_PARALLEL;
+  anAlgo->SetShape     (theShape);
   theAlgo = anAlgo;
   return 0; // no error
 }
@@ -524,19 +578,15 @@ Standard_Integer BRepMesh_IncrementalMesh::Discret (const TopoDS_Shape&    theSh
 //=======================================================================
 Standard_Boolean BRepMesh_IncrementalMesh::IsParallelDefault()
 {
-#ifdef HAVE_TBB
   return IS_IN_PARALLEL;
-#else
-  // no alternative parallelization yet - flag has no meaning
-  return Standard_False;
-#endif
 }
 
 //=======================================================================
 //function : Discret
 //purpose  :
 //=======================================================================
-void BRepMesh_IncrementalMesh::SetParallelDefault (const Standard_Boolean theInParallel)
+void BRepMesh_IncrementalMesh::SetParallelDefault(
+  const Standard_Boolean theInParallel)
 {
   IS_IN_PARALLEL = theInParallel;
 }