]> OCCT Git - occt-copy.git/commitdiff
Adding new files
authorbugmaster <bugmaster@opencascade.com>
Fri, 13 Jul 2018 10:02:15 +0000 (13:02 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 13 Jul 2018 10:02:15 +0000 (13:02 +0300)
85 files changed:
src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Context.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Context.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CurveTessellator.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CurveTessellator.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Deflection.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Deflection.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_EdgeDiscret.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_EdgeDiscret.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_FaceChecker.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_FaceChecker.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_FaceDiscret.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_FaceDiscret.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_IncAllocator.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshBuilder.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshBuilder.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshTool.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshTool.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelBuilder.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelBuilder.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelHealer.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelHealer.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelPostProcessor.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelPostProcessor.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelPreProcessor.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ModelPreProcessor.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ShapeExplorer.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ShapeExplorer.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ShapeVisitor.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ShapeVisitor.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Curve.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Curve.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Edge.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Edge.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Face.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Face.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Model.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Model.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_PCurve.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_PCurve.hxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Wire.cxx [new file with mode: 0644]
src/BRepMeshData/BRepMeshData_Wire.hxx [new file with mode: 0644]
src/BRepMeshData/FILES [new file with mode: 0644]
src/IMeshData/FILES [new file with mode: 0644]
src/IMeshData/IMeshData_Curve.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Edge.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Face.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Model.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_PCurve.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_ParametersList.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Shape.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Status.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_StatusOwner.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_TessellatedShape.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Types.hxx [new file with mode: 0644]
src/IMeshData/IMeshData_Wire.hxx [new file with mode: 0644]
src/IMeshTools/FILES [new file with mode: 0644]
src/IMeshTools/IMeshTools_Context.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_CurveTessellator.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_MeshAlgo.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_MeshBuilder.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_ModelAlgo.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_ModelBuilder.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_Parameters.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_ShapeExplorer.hxx [new file with mode: 0644]
src/IMeshTools/IMeshTools_ShapeVisitor.hxx [new file with mode: 0644]

diff --git a/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx
new file mode 100644 (file)
index 0000000..af1c8e7
--- /dev/null
@@ -0,0 +1,315 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_BaseMeshAlgo.hxx>
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <IMeshData_Curve.hxx>
+#include <BRepMesh_Delaun.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_BaseMeshAlgo::BRepMesh_BaseMeshAlgo()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_BaseMeshAlgo::~BRepMesh_BaseMeshAlgo()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+void BRepMesh_BaseMeshAlgo::Perform(
+  const IMeshData::IFaceHandle& theDFace,
+  const IMeshTools_Parameters&  theParameters)
+{
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    myDFace      = theDFace;
+    myParameters = theParameters;
+    myAllocator  = new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+    myStructure  = new BRepMesh_DataStructureOfDelaun(myAllocator);
+    myNodesMap   = new VectorOfPnt(256, myAllocator);
+    myUsedNodes  = new DMapOfIntegerInteger(1, myAllocator);
+
+    if (initDataStructure())
+    {
+      generateMesh();
+      commitSurfaceTriangulation();
+    }
+  }
+  catch (Standard_Failure& /*theExeption*/)
+  {
+  }
+
+  myDFace.reset(); // Do not hold link to face.
+  myStructure.Nullify();
+  myNodesMap.Nullify();
+  myUsedNodes.Nullify();
+}
+
+//=======================================================================
+//function : initDataStructure
+//purpose  :
+//=======================================================================
+Standard_Boolean BRepMesh_BaseMeshAlgo::initDataStructure()
+{
+  for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
+  {
+    const IMeshData::IWireHandle& aDWire = myDFace->GetWire(aWireIt);
+    if (aDWire->IsSet(IMeshData_SelfIntersectingWire))
+    {
+      // TODO: here we can add points of self-intersecting wire as fixed points
+      // in order to keep consistency of nodes with adjacent faces.
+      continue;
+    }
+
+    for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+    {
+      const IMeshData::IEdgeHandle&   aDEdge = aDWire->GetEdge(aEdgeIt).lock();
+      const IMeshData::ICurveHandle&  aCurve = aDEdge->GetCurve();
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+        myDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+      const TopAbs_Orientation aOri = fixSeamEdgeOrientation(aDEdge, aPCurve);
+
+      Standard_Integer aPrevNodeIndex = -1;
+      const Standard_Integer aLastPoint = aPCurve->ParametersNb() - 1;
+      for (Standard_Integer aPointIt = 0; aPointIt <= aLastPoint; ++aPointIt)
+      {
+        const Standard_Integer aNodeIndex = registerNode(
+          aCurve ->GetPoint(aPointIt),
+          aPCurve->GetPoint(aPointIt),
+          BRepMesh_Frontier, Standard_False/*aPointIt > 0 && aPointIt < aLastPoint*/);
+
+        aPCurve->GetIndex(aPointIt) = aNodeIndex;
+        myUsedNodes->Bind(aNodeIndex, aNodeIndex);
+
+        if (aPrevNodeIndex != -1 && aPrevNodeIndex != aNodeIndex)
+        {
+          const Standard_Integer aLinksNb   = myStructure->NbLinks();
+          const Standard_Integer aLinkIndex = addLinkToMesh(aPrevNodeIndex, aNodeIndex, aOri);
+          if (aWireIt != 0 && aLinkIndex <= aLinksNb)
+          {
+            // Prevent holes around wire of zero area.
+            BRepMesh_Edge& aLink = const_cast<BRepMesh_Edge&>(myStructure->GetLink(aLinkIndex));
+            aLink.SetMovability(BRepMesh_Fixed);
+          }
+        }
+
+        aPrevNodeIndex = aNodeIndex;
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+// Function: registerNode
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::registerNode(
+  const gp_Pnt&                  thePoint,
+  const gp_Pnt2d&                thePoint2d,
+  const BRepMesh_DegreeOfFreedom theMovability,
+  const Standard_Boolean         isForceAdd)
+{
+  const Standard_Integer aNodeIndex = addNodeToStructure(
+    thePoint2d, myNodesMap->Size(), theMovability, isForceAdd);
+
+  if (aNodeIndex > myNodesMap->Size())
+  {
+    myNodesMap->Append(thePoint);
+  }
+
+  return aNodeIndex;
+}
+
+//=======================================================================
+// Function: addNode
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::addNodeToStructure(
+  const gp_Pnt2d&                thePoint,
+  const Standard_Integer         theLocation3d,
+  const BRepMesh_DegreeOfFreedom theMovability,
+  const Standard_Boolean         isForceAdd)
+{
+  BRepMesh_Vertex aNode(thePoint.XY(), theLocation3d, theMovability);
+  return myStructure->AddNode(aNode, isForceAdd);
+}
+
+//=======================================================================
+//function : addLinkToMesh
+//purpose  :
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::addLinkToMesh(
+  const Standard_Integer   theFirstNodeId,
+  const Standard_Integer   theLastNodeId,
+  const TopAbs_Orientation theOrientation)
+{
+  Standard_Integer aLinkIndex;
+  if (theOrientation == TopAbs_REVERSED)
+    aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier));
+  else if (theOrientation == TopAbs_INTERNAL)
+    aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed));
+  else
+    aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier));
+
+  return Abs(aLinkIndex);
+}
+
+//=======================================================================
+//function : fixSeamEdgeOrientation
+//purpose  :
+//=======================================================================
+TopAbs_Orientation BRepMesh_BaseMeshAlgo::fixSeamEdgeOrientation(
+  const IMeshData::IEdgeHandle&   theDEdge,
+  const IMeshData::IPCurveHandle& thePCurve) const
+{
+  for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+  {
+    const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
+    if (aPCurve->GetFace().lock() == myDFace && thePCurve != aPCurve)
+    {
+      // Simple check that another pcurve of seam edge does not coincide with reference one.
+      const gp_Pnt2d& aPnt1_1 = thePCurve->GetPoint(0);
+      const gp_Pnt2d& aPnt2_1 = thePCurve->GetPoint(thePCurve->ParametersNb() - 1);
+
+      const gp_Pnt2d& aPnt1_2 = aPCurve->GetPoint(0);
+      const gp_Pnt2d& aPnt2_2 = aPCurve->GetPoint(aPCurve->ParametersNb() - 1);
+
+      const Standard_Real aSqDist1 = Min(aPnt1_1.SquareDistance(aPnt1_2), aPnt1_1.SquareDistance(aPnt2_2));
+      const Standard_Real aSqDist2 = Min(aPnt2_1.SquareDistance(aPnt1_2), aPnt2_1.SquareDistance(aPnt2_2));
+      if (aSqDist1 < Precision::SquareConfusion() &&
+          aSqDist2 < Precision::SquareConfusion())
+      {
+        return TopAbs_INTERNAL;
+      }
+    }
+  }
+
+  return thePCurve->GetOrientation();
+}
+
+//=======================================================================
+//function : commitSurfaceTriangulation
+//purpose  :
+//=======================================================================
+void BRepMesh_BaseMeshAlgo::commitSurfaceTriangulation()
+{
+  Handle(Poly_Triangulation) aTriangulation = collectTriangles();
+  if (aTriangulation.IsNull())
+  {
+    myDFace->SetStatus(IMeshData_Failure);
+    return;
+  }
+
+  collectNodes(aTriangulation);
+
+  aTriangulation->Deflection(myDFace->GetDeflection());
+  BRepMesh_ShapeTool::AddInFace(myDFace->GetFace(), aTriangulation);
+}
+
+//=======================================================================
+//function : collectTriangles
+//purpose  :
+//=======================================================================
+Handle(Poly_Triangulation) BRepMesh_BaseMeshAlgo::collectTriangles()
+{
+  const IMeshData::MapOfInteger& aTriangles = myStructure->ElementsOfDomain();
+  if (aTriangles.IsEmpty())
+  {
+    return Handle(Poly_Triangulation)();
+  }
+
+  Poly_Array1OfTriangle aPolyTrianges(1, aTriangles.Extent());
+  IMeshData::IteratorOfMapOfInteger aTriIt(aTriangles);
+  for (Standard_Integer aTriangeId = 1; aTriIt.More(); aTriIt.Next(), ++aTriangeId)
+  {
+    const BRepMesh_Triangle& aCurElem = myStructure->GetElement(aTriIt.Key());
+
+    Standard_Integer aNode[3];
+    myStructure->ElementNodes(aCurElem, aNode);
+
+    for (Standard_Integer i = 0; i < 3; ++i)
+    {
+      if (!myUsedNodes->IsBound(aNode[i]))
+      {
+        myUsedNodes->Bind(aNode[i], myUsedNodes->Size() + 1);
+      }
+
+      aNode[i] = myUsedNodes->Find(aNode[i]);
+    }
+
+    aPolyTrianges(aTriangeId).Set(aNode[0], aNode[1], aNode[2]);
+  }
+
+  Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation(
+    myUsedNodes->Extent(), aTriangles.Extent(), Standard_True);
+
+  aTriangulation->ChangeTriangles() = aPolyTrianges;
+  return aTriangulation;
+}
+
+//=======================================================================
+//function : collectNodes
+//purpose  :
+//=======================================================================
+void BRepMesh_BaseMeshAlgo::collectNodes(
+  const Handle(Poly_Triangulation)& theTriangulation)
+{
+  // Store mesh nodes
+  TColgp_Array1OfPnt&   aNodes   = theTriangulation->ChangeNodes();
+  TColgp_Array1OfPnt2d& aNodes2d = theTriangulation->ChangeUVNodes();
+
+  for (Standard_Integer i = 1; i <= myNodesMap->Size(); ++i)
+  {
+    if (myUsedNodes->IsBound(i))
+    {
+      const BRepMesh_Vertex& aVertex = myStructure->GetNode(i);
+
+      const Standard_Integer aNodeIndex = myUsedNodes->Find(i);
+      aNodes(aNodeIndex) = myNodesMap->Value(aVertex.Location3d());
+      aNodes2d(aNodeIndex) = getNodePoint2d(aVertex);
+    }
+  }
+}
+
+//=======================================================================
+// Function: getNodePoint2d
+// Purpose : 
+//=======================================================================
+gp_Pnt2d BRepMesh_BaseMeshAlgo::getNodePoint2d(
+  const BRepMesh_Vertex& theVertex) const
+{
+  return theVertex.Coord();
+}
diff --git a/src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..56c03b2
--- /dev/null
@@ -0,0 +1,143 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_BaseMeshAlgo_HeaderFile
+#define _BRepMesh_BaseMeshAlgo_HeaderFile
+
+#include <IMeshTools_MeshAlgo.hxx>
+#include <NCollection_Shared.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <BRepMesh_DegreeOfFreedom.hxx>
+#include <Poly_Triangulation.hxx>
+
+class BRepMesh_DataStructureOfDelaun;
+class BRepMesh_Delaun;
+
+//! Class provides base fuctionality for algorithms building face triangulation.
+//! Performs initialization of BRepMesh_DataStructureOfDelaun and nodes map structures.
+class BRepMesh_BaseMeshAlgo : public IMeshTools_MeshAlgo
+{
+public:
+
+  typedef NCollection_Shared<NCollection_Vector<gp_Pnt> > VectorOfPnt;
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_BaseMeshAlgo();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_BaseMeshAlgo();
+
+  //! Performs processing of the given face.
+  Standard_EXPORT virtual void Perform(
+    const IMeshData::IFaceHandle& theDFace,
+    const IMeshTools_Parameters&  theParameters) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_BaseMeshAlgo, IMeshTools_MeshAlgo)
+
+protected:
+
+  //! Gets discrete face.
+  inline const IMeshData::IFaceHandle& getDFace() const
+  {
+    return myDFace;
+  }
+
+  //! Gets meshing parameters.
+  inline const IMeshTools_Parameters& getParameters() const
+  {
+    return myParameters;
+  }
+
+  //! Gets common allocator.
+  inline const Handle(NCollection_IncAllocator)& getAllocator() const
+  {
+    return myAllocator;
+  }
+
+  //! Gets mesh structure.
+  inline const Handle(BRepMesh_DataStructureOfDelaun)& getStructure() const
+  {
+    return myStructure;
+  }
+
+  //! Gets 3d nodes map.
+  inline const Handle(VectorOfPnt)& getNodesMap() const
+  {
+    return myNodesMap;
+  }
+
+protected:
+
+  //! Registers the given point in vertex map and adds 2d point to mesh data structure.
+  //! Returns index of node in the structure.
+  Standard_EXPORT virtual Standard_Integer registerNode(
+    const gp_Pnt&                  thePoint,
+    const gp_Pnt2d&                thePoint2d,
+    const BRepMesh_DegreeOfFreedom theMovability,
+    const Standard_Boolean         isForceAdd);
+
+  //! Adds the given 2d point to mesh data structure.
+  //! Returns index of node in the structure.
+  Standard_EXPORT virtual Standard_Integer addNodeToStructure(
+    const gp_Pnt2d&                thePoint,
+    const Standard_Integer         theLocation3d,
+    const BRepMesh_DegreeOfFreedom theMovability,
+    const Standard_Boolean         isForceAdd);
+
+  //! Returns 2d point associated to the given vertex.
+  Standard_EXPORT virtual gp_Pnt2d getNodePoint2d(const BRepMesh_Vertex& theVertex) const;
+
+  //! Performs initialization of data structure using existing model data.
+  Standard_EXPORT virtual Standard_Boolean initDataStructure();
+
+  //! Generates mesh for the contour stored in data structure.
+  Standard_EXPORT virtual void generateMesh() = 0;
+
+private:
+
+  //! If the given edge has another pcurve for current face coinsiding with specified one,
+  //! returns TopAbs_INTERNAL flag. Elsewhere returns orientation of specified pcurve.
+  TopAbs_Orientation fixSeamEdgeOrientation(
+    const IMeshData::IEdgeHandle&   theDEdge,
+    const IMeshData::IPCurveHandle& thePCurve) const;
+
+  //! Adds new link to the mesh data structure.
+  //! Movability of the link and order of nodes depend on orientation parameter.
+  Standard_Integer addLinkToMesh(
+    const Standard_Integer   theFirstNodeId,
+    const Standard_Integer   theLastNodeId,
+    const TopAbs_Orientation theOrientation);
+
+  //! Commits generated triangulation to TopoDS face.
+  void commitSurfaceTriangulation();
+
+  //! Collects triangles to output data.
+  Handle(Poly_Triangulation) collectTriangles();
+
+  //! Collects nodes to output data.
+  void collectNodes(const Handle(Poly_Triangulation)& theTriangulation);
+
+private:
+  typedef NCollection_Shared<NCollection_DataMap<Standard_Integer, Standard_Integer> > DMapOfIntegerInteger;
+
+  IMeshData::IFaceHandle                 myDFace;
+  IMeshTools_Parameters                  myParameters;
+  Handle(NCollection_IncAllocator)       myAllocator;
+  Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+  Handle(VectorOfPnt)                    myNodesMap;
+  Handle(DMapOfIntegerInteger)           myUsedNodes;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx b/src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..95e0534
--- /dev/null
@@ -0,0 +1,53 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_BoundaryParamsRangeSplitter_HeaderFile
+#define _BRepMesh_BoundaryParamsRangeSplitter_HeaderFile
+
+#include <BRepMesh_NURBSRangeSplitter.hxx>
+
+//! Auxiliary class extending UV range splitter in order to generate
+//! internal nodes for NURBS surface.
+class BRepMesh_BoundaryParamsRangeSplitter : public BRepMesh_NURBSRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_BoundaryParamsRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_BoundaryParamsRangeSplitter()
+  {
+  }
+
+  //! Registers border point.
+  Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint)
+  {
+    BRepMesh_NURBSRangeSplitter::AddPoint(thePoint);
+    GetParametersU().Add(thePoint.X());
+    GetParametersV().Add(thePoint.Y());
+  }
+
+protected:
+
+  //! Initializes U and V parameters lists using CN continuity intervals.
+  Standard_EXPORT virtual void initParameters() const
+  {
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx b/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..f0bc5df
--- /dev/null
@@ -0,0 +1,80 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ConeRangeSplitter_HeaderFile
+#define _BRepMesh_ConeRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for conical surface.
+class BRepMesh_ConeRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ConeRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ConeRangeSplitter()
+  {
+  }
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+  {
+    const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+    const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+    gp_Cone aCone = GetDFace()->GetSurface()->Cone();
+    Standard_Real aRefR = aCone.RefRadius();
+    Standard_Real aSAng = aCone.SemiAngle();
+    Standard_Real aRadius = Max(Abs(aRefR + aRangeV.first  * Sin(aSAng)),
+                                Abs(aRefR + aRangeV.second * Sin(aSAng)));
+
+    Standard_Real Dv, Du = GCPnts_TangentialDeflection::ArcAngularStep(
+      aRadius, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+    const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
+    const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
+    Standard_Integer nbU = (Standard_Integer) (aDiffU / Du);
+    Standard_Integer nbV = (Standard_Integer) (nbU * (aDiffV) / (aDiffU * aRadius));
+    Du = aDiffU / (nbU + 1);
+    Dv = aDiffV / (nbV + 1);
+
+    const Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+    Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+    const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5;
+    const Standard_Real aPasMaxU = aRangeU.second - Du*0.5;
+    for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv)
+    {
+      for (Standard_Real aPasU = aRangeV.first + Du; aPasU < aPasMaxU; aPasU += Du)
+      {
+        aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+      }
+    }
+
+    return aNodes;
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_Context.cxx b/src/BRepMesh/BRepMesh_Context.cxx
new file mode 100644 (file)
index 0000000..e48d038
--- /dev/null
@@ -0,0 +1,45 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_Context.hxx>
+#include <BRepMesh_ModelBuilder.hxx>
+#include <BRepMesh_EdgeDiscret.hxx>
+#include <BRepMesh_ModelHealer.hxx>
+#include <BRepMesh_FaceDiscret.hxx>
+#include <BRepMesh_ModelPreProcessor.hxx>
+#include <BRepMesh_ModelPostProcessor.hxx>
+#include <BRepMesh_MeshAlgoFactory.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_Context::BRepMesh_Context ()
+{
+  SetModelBuilder (new BRepMesh_ModelBuilder);
+  SetEdgeDiscret  (new BRepMesh_EdgeDiscret);
+  SetModelHealer  (new BRepMesh_ModelHealer);
+  SetPreProcessor (new BRepMesh_ModelPreProcessor);
+  SetFaceDiscret  (new BRepMesh_FaceDiscret(new BRepMesh_MeshAlgoFactory));
+  SetPostProcessor(new BRepMesh_ModelPostProcessor);
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_Context::~BRepMesh_Context ()
+{
+}
diff --git a/src/BRepMesh/BRepMesh_Context.hxx b/src/BRepMesh/BRepMesh_Context.hxx
new file mode 100644 (file)
index 0000000..a802a6b
--- /dev/null
@@ -0,0 +1,36 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_Context_HeaderFile
+#define _BRepMesh_Context_HeaderFile
+
+#include <IMeshTools_Context.hxx>
+
+//! Class implemeting default context of BRepMesh algorithm.
+//! Initializes context by default algorithms.
+class BRepMesh_Context : public IMeshTools_Context
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_Context ();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_Context ();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Context, IMeshTools_Context)
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.cxx b/src/BRepMesh/BRepMesh_CurveTessellator.cxx
new file mode 100644 (file)
index 0000000..e6b5fa3
--- /dev/null
@@ -0,0 +1,318 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_CurveTessellator.hxx>
+#include <gp_Pnt.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Edge.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <TopExp_Explorer.hxx>
+#include <Geom_Plane.hxx>
+#include <TopExp.hxx>
+#include <Adaptor3d_HCurveOnSurface.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+BRepMesh_CurveTessellator::BRepMesh_CurveTessellator(
+  const IMeshData::IEdgeHandle& theEdge,
+  const IMeshTools_Parameters&  theParameters)
+  : myDEdge(theEdge),
+    myParameters(theParameters),
+    myEdge(theEdge->GetEdge()),
+    myCurve(myEdge)
+{
+  init();
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+BRepMesh_CurveTessellator::BRepMesh_CurveTessellator (
+  const IMeshData::IEdgeHandle& theEdge,
+  const TopAbs_Orientation      theOrientation,
+  const IMeshData::IFaceHandle& theFace,
+  const IMeshTools_Parameters&  theParameters)
+  : myDEdge(theEdge),
+    myParameters(theParameters),
+    myEdge(TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation))),
+    myCurve(myEdge, theFace->GetFace())
+{
+  init();
+}
+
+//=======================================================================
+//function : init
+//purpose  : 
+//=======================================================================
+void BRepMesh_CurveTessellator::init()
+{
+  TopExp::Vertices(myEdge, myFirstVertex, myLastVertex);
+
+  Standard_Real aPreciseAngDef = 0.5 * myDEdge->GetAngularDeflection();
+  Standard_Real aPreciseLinDef = 0.5 * myDEdge->GetDeflection();
+  if (myEdge.Orientation() == TopAbs_INTERNAL)
+  {
+    aPreciseLinDef *= 0.5;
+  }
+
+  mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
+  mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize);
+
+  myEdgeSqTol  = BRep_Tool::Tolerance(myEdge);
+  myEdgeSqTol *= myEdgeSqTol;
+
+  const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
+
+  myDiscretTool.Initialize(myCurve,
+                           myCurve.FirstParameter(), myCurve.LastParameter(),
+                           aPreciseAngDef, aPreciseLinDef, aMinPntNb,
+                           Precision::PConfusion(), myParameters.MinSize);
+
+  if (myCurve.IsCurveOnSurface())
+  {
+    const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface();
+    const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface();
+
+    const Standard_Real aTol = Precision::Confusion();
+    const Standard_Real aDu = aSurface->UResolution(aTol);
+    const Standard_Real aDv = aSurface->VResolution(aTol);
+
+    myFaceRangeU[0] = aSurface->FirstUParameter() - aDu;
+    myFaceRangeU[1] = aSurface->LastUParameter()  + aDu;
+
+    myFaceRangeV[0] = aSurface->FirstVParameter() - aDv;
+    myFaceRangeV[1] = aSurface->LastVParameter()  + aDv;
+  }
+
+  addInternalVertices();
+  splitByDeflection2d();
+}
+
+//=======================================================================
+//function : Destructor
+//purpose  : 
+//=======================================================================
+BRepMesh_CurveTessellator::~BRepMesh_CurveTessellator ()
+{
+}
+
+//=======================================================================
+//function : NbPoints
+//purpose  : 
+//=======================================================================
+Standard_Integer BRepMesh_CurveTessellator::PointsNb () const
+{
+  return myDiscretTool.NbPoints ();
+}
+
+//=======================================================================
+//function : splitByDeflection2d
+//purpose  : 
+//=======================================================================
+void BRepMesh_CurveTessellator::splitByDeflection2d ()
+{
+  const Standard_Integer aNodesNb = myDiscretTool.NbPoints ();
+  if (!myDEdge->IsFree ()      &&
+      myDEdge->GetSameParam () &&
+      myDEdge->GetSameRange () &&
+      aNodesNb > 1)
+  {
+    for (Standard_Integer aPCurveIt = 0; aPCurveIt < myDEdge->PCurvesNb (); ++aPCurveIt)
+    {
+      TopLoc_Location aLoc;
+      const IMeshData::IPCurveHandle& aPCurve = myDEdge->GetPCurve(aPCurveIt);
+      const TopoDS_Face&              aFace   = aPCurve->GetFace ().lock ()->GetFace ();
+      const Handle (Geom_Surface)&    aSurface = BRep_Tool::Surface (aFace, aLoc);
+      if (aSurface->IsInstance(STANDARD_TYPE(Geom_Plane)))
+      {
+        continue;
+      }
+
+      const TopoDS_Edge aCurrEdge = TopoDS::Edge(myEdge.Oriented(aPCurve->GetOrientation()));
+
+      Standard_Real aF, aL;
+      Handle (Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface (aCurrEdge, aFace, aF, aL);
+      TColStd_Array1OfReal aParamArray (1, aNodesNb);
+      for (Standard_Integer i = 1; i <= aNodesNb; ++i)
+        aParamArray.SetValue (i, myDiscretTool.Parameter (i));
+
+      for (Standard_Integer i = 1; i < aNodesNb; ++i)
+        splitSegment (aSurface, aCurve2d, aParamArray (i), aParamArray (i + 1), 1);
+    }
+  }
+}
+
+//=======================================================================
+//function : addInternalVertices
+//purpose  : 
+//=======================================================================
+void BRepMesh_CurveTessellator::addInternalVertices ()
+{
+  // PTv, chl/922/G9, Take into account internal vertices
+  // it is necessary for internal edges, which do not split other edges, by their vertex
+  TopExp_Explorer aVertexIt (myEdge, TopAbs_VERTEX);
+  for (; aVertexIt.More (); aVertexIt.Next ())
+  {
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVertexIt.Current ());
+    if (aVertex.Orientation() != TopAbs_INTERNAL)
+    {
+      continue;
+    }
+
+    myDiscretTool.AddPoint (BRep_Tool::Pnt (aVertex),
+      BRep_Tool::Parameter (aVertex, myEdge), Standard_True);
+  }
+}
+
+//=======================================================================
+//function : isInToleranceOfVertex
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_CurveTessellator::isInToleranceOfVertex (
+  const gp_Pnt&        thePoint,
+  const TopoDS_Vertex& theVertex) const
+{
+  const gp_Pnt        aPoint     = BRep_Tool::Pnt(theVertex);
+  const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex);
+
+  return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
+}
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_CurveTessellator::Value (
+  const Standard_Integer theIndex,
+  gp_Pnt&                thePoint,
+  Standard_Real&         theParameter) const
+{
+  thePoint     = myDiscretTool.Value     (theIndex);
+  theParameter = myDiscretTool.Parameter (theIndex);
+
+  /*if (!isInToleranceOfVertex(thePoint, myFirstVertex) &&
+      !isInToleranceOfVertex(thePoint, myLastVertex))
+  {*/
+    if (!myCurve.IsCurveOnSurface())
+    {
+      return Standard_True;
+    }
+
+    // If point coordinates are out of surface range, 
+    // it is necessary to re-project point.
+    const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface();
+    const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface();
+    if (aSurface->GetType() != GeomAbs_BSplineSurface &&
+        aSurface->GetType() != GeomAbs_BezierSurface  &&
+        aSurface->GetType() != GeomAbs_OtherSurface)
+    {
+      return Standard_True;
+    }
+
+    // Let skip periodic case.
+    if (aSurface->IsUPeriodic() || aSurface->IsVPeriodic())
+    {
+      return Standard_True;
+    }
+
+    gp_Pnt2d aUV;
+    aCurve.GetCurve()->D0(theParameter, aUV);
+    // Point lies within the surface range - nothing to do.
+    if (aUV.X() > myFaceRangeU[0] && aUV.X() < myFaceRangeU[1] &&
+        aUV.Y() > myFaceRangeV[0] && aUV.Y() < myFaceRangeV[1])
+    {
+      return Standard_True;
+    }
+
+    gp_Pnt aPntOnSurf;
+    aSurface->D0(aUV.X(), aUV.Y(), aPntOnSurf);
+
+    return (thePoint.SquareDistance(aPntOnSurf) < myEdgeSqTol);
+  /*}
+
+  return Standard_False;*/
+}
+
+//=======================================================================
+//function : splitSegment
+//purpose  : 
+//=======================================================================
+void BRepMesh_CurveTessellator::splitSegment (
+  const Handle (Geom_Surface)& theSurf,
+  const Handle (Geom2d_Curve)& theCurve2d,
+  const Standard_Real          theFirst,
+  const Standard_Real          theLast,
+  const Standard_Integer       theNbIter)
+{
+  // limit iteration depth
+  if (theNbIter > 10)
+  {
+    return;
+  }
+
+  gp_Pnt2d uvf, uvl, uvm;
+  gp_Pnt   P3dF, P3dL, midP3d, midP3dFromSurf;
+  Standard_Real midpar;
+
+  if (Abs(theLast - theFirst) < 2 * Precision::PConfusion())
+  {
+    return;
+  }
+
+  theCurve2d->D0 (theFirst, uvf);
+  theCurve2d->D0 (theLast, uvl);
+
+  P3dF = theSurf->Value (uvf.X (), uvf.Y ());
+  P3dL = theSurf->Value (uvl.X (), uvl.Y ());
+
+  if (P3dF.SquareDistance(P3dL) < mySquareMinSize)
+  {
+    return;
+  }
+
+  uvm = gp_Pnt2d ((uvf.XY () + uvl.XY ())*0.5);
+  midP3dFromSurf = theSurf->Value (uvm.X (), uvm.Y ());
+
+  gp_XYZ Vec1 = midP3dFromSurf.XYZ () - P3dF.XYZ ();
+  if (Vec1.SquareModulus() < mySquareMinSize)
+  {
+    return;
+  }
+
+  gp_XYZ aVec = P3dL.XYZ () - P3dF.XYZ ();
+  aVec.Normalize ();
+
+  Standard_Real aModulus = Vec1.Dot (aVec);
+  gp_XYZ aProj = aVec * aModulus;
+  gp_XYZ aDist = Vec1 - aProj;
+
+  if (aDist.SquareModulus() < mySquareEdgeDef)
+  {
+    return;
+  }
+
+  midpar = (theFirst + theLast) * 0.5;
+  myCurve.D0 (midpar, midP3d);
+  myDiscretTool.AddPoint (midP3d, midpar, Standard_False);
+
+  splitSegment (theSurf, theCurve2d, theFirst, midpar, theNbIter + 1);
+  splitSegment (theSurf, theCurve2d, midpar, theLast, theNbIter + 1);
+}
diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.hxx b/src/BRepMesh/BRepMesh_CurveTessellator.hxx
new file mode 100644 (file)
index 0000000..4a666be
--- /dev/null
@@ -0,0 +1,110 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_EdgeTessellator_HeaderFile
+#define _BRepMesh_EdgeTessellator_HeaderFile
+
+#include <IMeshTools_CurveTessellator.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <IMeshData_Types.hxx>
+
+class TopoDS_Face;
+class Geom_Surface;
+class Geom2d_Curve;
+struct IMeshTools_Parameters;
+
+//! Auxiliary class performing tessellation of passed edge according to specified parameters.
+class BRepMesh_CurveTessellator : public IMeshTools_CurveTessellator
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_CurveTessellator(
+    const IMeshData::IEdgeHandle& theEdge,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_CurveTessellator (
+    const IMeshData::IEdgeHandle& theEdge,
+    const TopAbs_Orientation      theOrientation,
+    const IMeshData::IFaceHandle& theFace,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_CurveTessellator ();
+
+  //! Returns number of tessellation points.
+  Standard_EXPORT virtual Standard_Integer PointsNb () const Standard_OVERRIDE;
+
+  //! Returns parameters of solution with the given index.
+  //! @param theIndex index of tessellation point.
+  //! @param theParameter parameters on PCurve corresponded to the solution.
+  //! @param thePoint tessellation point.
+  //! @return True in case of valid result, false elewhere.
+  Standard_EXPORT virtual Standard_Boolean Value (
+    const Standard_Integer theIndex,
+    gp_Pnt&                thePoint,
+    Standard_Real&         theParameter) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_CurveTessellator, IMeshTools_CurveTessellator)
+
+private:
+
+  //! Performs initialization of this tool.
+  void init();
+
+  //! Adds internal vertices to discrete polygon.
+  void addInternalVertices ();
+
+  //Check deflection in 2d space for improvement of edge tesselation.
+  void splitByDeflection2d ();
+
+  void splitSegment (
+    const Handle (Geom_Surface)& theSurf,
+    const Handle (Geom2d_Curve)& theCurve2d,
+    const Standard_Real          theFirst,
+    const Standard_Real          theLast,
+    const Standard_Integer       theNbIter);
+
+  //! Checks whether the given point lies within tolerance of the vertex.
+  Standard_Boolean isInToleranceOfVertex (
+    const gp_Pnt&        thePoint,
+    const TopoDS_Vertex& theVertex) const;
+
+private:
+
+  BRepMesh_CurveTessellator (const BRepMesh_CurveTessellator& theOther);
+
+  void operator=(const BRepMesh_CurveTessellator& theOther);
+
+private:
+
+  const IMeshData::IEdgeHandle& myDEdge;
+  const IMeshTools_Parameters&  myParameters;
+  TopoDS_Edge                   myEdge;
+  BRepAdaptor_Curve             myCurve;
+  GCPnts_TangentialDeflection   myDiscretTool;
+  TopoDS_Vertex                 myFirstVertex;
+  TopoDS_Vertex                 myLastVertex;
+  Standard_Real                 mySquareEdgeDef;
+  Standard_Real                 mySquareMinSize;
+  Standard_Real                 myEdgeSqTol;
+  Standard_Real                 myFaceRangeU[2];
+  Standard_Real                 myFaceRangeV[2];
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx b/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..131f110
--- /dev/null
@@ -0,0 +1,118 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_CylinderRangeSplitter_HeaderFile
+#define _BRepMesh_CylinderRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for cylindrical surface.
+class BRepMesh_CylinderRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_CylinderRangeSplitter()
+    : myDu(1.)
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_CylinderRangeSplitter()
+  {
+  }
+
+  //! Resets this splitter. Must be called before first use.
+  Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+                                     const IMeshTools_Parameters&  theParameters) Standard_OVERRIDE
+  {
+    BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters);
+
+    const Standard_Real aRadius = GetDFace()->GetSurface()->Cylinder().Radius();
+    myDu = GCPnts_TangentialDeflection::ArcAngularStep(
+      aRadius, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+  }
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& /*theParameters*/) const Standard_OVERRIDE
+  {
+    const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+    const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+    const Standard_Real aRadius = GetDFace()->GetSurface()->Cylinder().Radius();
+
+    Standard_Integer nbU = 0;
+    Standard_Integer nbV = 0;
+    const Standard_Real su = aRangeU.second - aRangeU.first;
+    const Standard_Real sv = aRangeV.second - aRangeV.first;
+    const Standard_Real aArcLen = su * aRadius;
+    if (aArcLen > GetDFace()->GetDeflection())
+    {
+      // Calculate parameters for iteration in U direction
+      nbU = (Standard_Integer) (su / myDu);
+
+      /*
+      // Calculate parameters for iteration in V direction
+      const Standard_Real aDv = nbU*sv / aArcLen;
+      // Protection against overflow during casting to int in case 
+      // of long cylinder with small radius.
+      nbV = aDv > static_cast<Standard_Real> (IntegerLast()) ?
+        0 : (Standard_Integer) (aDv);
+      nbV = Min(nbV, 100 * nbU);
+      */
+    }
+
+    const Standard_Real Du = su / (nbU + 1);
+    const Standard_Real Dv = sv / (nbV + 1);
+
+    const Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+    Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+    const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5;
+    const Standard_Real aPasMaxU = aRangeU.second - Du*0.5;
+    for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv)
+    {
+      for (Standard_Real aPasU = aRangeU.first + Du; aPasU < aPasMaxU; aPasU += Du)
+      {
+        aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+      }
+    }
+  
+    return aNodes;
+  }
+
+protected:
+
+  //! Computes parametric delta taking length along U and V into account.
+  virtual void computeDelta(
+    const Standard_Real /*theLengthU*/,
+    const Standard_Real theLengthV) Standard_OVERRIDE
+  {
+    const std::pair<double, double>& aRangeV = GetRangeV();
+    myDelta.first  = myDu / Max(theLengthV, aRangeV.second - aRangeV.first);
+    myDelta.second = 1.;
+  }
+
+private:
+
+  Standard_Real myDu;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx b/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..37d0bad
--- /dev/null
@@ -0,0 +1,289 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_DefaultRangeSplitter_HeaderFile
+#define _BRepMesh_DefaultRangeSplitter_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <gp_Pnt2d.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <IMeshData_Types.hxx>
+#include <IMeshData_Face.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAbs_IsoType.hxx>
+
+struct IMeshTools_Parameters;
+
+//! Default tool to define range of discrete face model and 
+//! obtain grid points disturbed within this range.
+class BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_DefaultRangeSplitter()
+    : myIsValid (Standard_True)
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_DefaultRangeSplitter()
+  {
+  }
+
+  //! Resets this splitter. Must be called before first use.
+  Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+                                     const IMeshTools_Parameters& /*theParameters*/)
+  {
+    myDFace = theDFace;
+    myRangeU.first  = myRangeV.first  =  1.e100;
+    myRangeU.second = myRangeV.second = -1.e100;
+    myDelta.first   = myDelta.second  = 1.;
+    myTolerance.first = myTolerance.second = Precision::Confusion();
+  }
+
+  //! Registers border point.
+  Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint)
+  {
+    myRangeU.first  = Min(thePoint.X(), myRangeU.first);
+    myRangeU.second = Max(thePoint.X(), myRangeU.second);
+    myRangeV.first  = Min(thePoint.Y(), myRangeV.first);
+    myRangeV.second = Max(thePoint.Y(), myRangeV.second);
+  }
+
+  //! Updates discrete range of surface according to its geometric range.
+  Standard_EXPORT virtual void AdjustRange()
+  {
+    const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
+    updateRange(aSurface->FirstUParameter(), aSurface->LastUParameter(),
+                aSurface->IsUPeriodic(), myRangeU.first, myRangeU.second);
+
+    updateRange(aSurface->FirstVParameter(), aSurface->LastVParameter(),
+                aSurface->IsVPeriodic(), myRangeV.first, myRangeV.second);
+
+    const Standard_Real aLengthU = computeLengthU();
+    const Standard_Real aLengthV = computeLengthV();
+    myIsValid = aLengthU > Precision::PConfusion () && aLengthV > Precision::PConfusion ();
+
+    if (myIsValid)
+    {
+      computeTolerance(aLengthU, aLengthV);
+      computeDelta    (aLengthU, aLengthV);
+    }
+  }
+
+  //! Returns True if computed range is valid.
+  Standard_EXPORT virtual Standard_Boolean IsValid()
+  {
+    return myIsValid;
+  }
+
+  //! Scales the given point from real parametric space 
+  //! to face basis and otherwise.
+  //! @param thePoint point to be scaled.
+  //! @param isToFaceBasis if TRUE converts point to face basis,
+  //! otherwise performs reverse conversion.
+  //! @return scaled point.
+  Standard_EXPORT gp_Pnt2d Scale(const gp_Pnt2d&        thePoint,
+                                 const Standard_Boolean isToFaceBasis) const
+  {
+    return isToFaceBasis ?
+      gp_Pnt2d ((thePoint.X () - myRangeU.first) / myDelta.first,
+                (thePoint.Y () - myRangeV.first) / myDelta.second) :
+      gp_Pnt2d (thePoint.X () * myDelta.first  + myRangeU.first,
+                thePoint.Y () * myDelta.second + myRangeV.first);
+  }
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  //! By default returns null ptr.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& /*theParameters*/) const
+  {
+    return Handle(IMeshData::ListOfPnt2d)();
+  }
+
+  //! Returns point in 3d space corresponded to the given 
+  //! point defined in parameteric space of surface.
+  inline gp_Pnt Point(const gp_Pnt2d& thePoint2d) const
+  {
+    return GetSurface()->Value(thePoint2d.X(), thePoint2d.Y());
+  }
+
+protected:
+
+  //! Computes parametric tolerance taking length along U and V into account.
+  virtual void computeTolerance(
+    const Standard_Real /*theLenU*/,
+    const Standard_Real /*theLenV*/)
+  {
+    const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
+    const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
+
+    const Standard_Real aDeflectionUV = 1.e-05;
+    myTolerance.first  = Max(aDeflectionUV, Precision::Confusion() * aDiffU);
+    myTolerance.second = Max(aDeflectionUV, Precision::Confusion() * aDiffV);
+  }
+
+  //! Computes parametric delta taking length along U and V and value of tolerance into account.
+  virtual void computeDelta(
+    const Standard_Real theLengthU,
+    const Standard_Real theLengthV)
+  {
+    const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
+    const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
+
+    myDelta.first  = aDiffU / (theLengthU < myTolerance.first  ? 1. : theLengthU);
+    myDelta.second = aDiffV / (theLengthV < myTolerance.second ? 1. : theLengthV);
+  }
+
+public:
+  //! Returns face model.
+  inline const IMeshData::IFaceHandle& GetDFace() const
+  {
+    return myDFace;
+  }
+
+  //! Returns surface.
+  inline const Handle(BRepAdaptor_HSurface)& GetSurface() const
+  {
+    return myDFace->GetSurface();
+  }
+
+  //! Returns U range.
+  inline const std::pair<Standard_Real, Standard_Real>& GetRangeU() const
+  {
+    return myRangeU;
+  }
+
+  //! Returns V range.
+  inline const std::pair<Standard_Real, Standard_Real>& GetRangeV() const
+  {
+    return myRangeV;
+  }
+
+  //! Returns delta.
+  inline const std::pair<Standard_Real, Standard_Real>& GetDelta () const
+  {
+    return myDelta;
+  }
+
+  inline const std::pair<Standard_Real, Standard_Real>& GetToleranceUV() const
+  {
+    return myTolerance;
+  }
+
+private:
+
+  //! Computes length along U direction.
+  inline Standard_Real computeLengthU()
+  {
+    Standard_Real longu = 0.0;
+    gp_Pnt P11, P12, P21, P22, P31, P32;
+
+    Standard_Real du     = 0.05 * (myRangeU.second - myRangeU.first);
+    Standard_Real dfvave = 0.5  * (myRangeV.second + myRangeV.first);
+    Standard_Real dfucur;
+    Standard_Integer i1;
+
+    const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
+    gFace->D0(myRangeU.first, myRangeV.first,  P11);
+    gFace->D0(myRangeU.first, dfvave,          P21);
+    gFace->D0(myRangeU.first, myRangeV.second, P31);
+    for (i1 = 1, dfucur = myRangeU.first + du; i1 <= 20; i1++, dfucur += du)
+    {
+      gFace->D0(dfucur, myRangeV.first,  P12);
+      gFace->D0(dfucur, dfvave,          P22);
+      gFace->D0(dfucur, myRangeV.second, P32);
+      longu += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
+      P11 = P12;
+      P21 = P22;
+      P31 = P32;
+    }
+
+    return longu / 3.;
+  }
+
+  //! Computes length along V direction.
+  inline Standard_Real computeLengthV()
+  {
+    Standard_Real longv = 0.0;
+    gp_Pnt P11, P12, P21, P22, P31, P32;
+
+    Standard_Real dv     = 0.05 * (myRangeV.second - myRangeV.first);
+    Standard_Real dfuave = 0.5  * (myRangeU.second + myRangeU.first);
+    Standard_Real dfvcur;
+    Standard_Integer i1;
+
+    const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
+    gFace->D0(myRangeU.first,  myRangeV.first, P11);
+    gFace->D0(dfuave,          myRangeV.first, P21);
+    gFace->D0(myRangeU.second, myRangeV.first, P31);
+    for (i1 = 1, dfvcur = myRangeV.first + dv; i1 <= 20; i1++, dfvcur += dv)
+    {
+      gFace->D0(myRangeU.first,  dfvcur, P12);
+      gFace->D0(dfuave,          dfvcur, P22);
+      gFace->D0(myRangeU.second, dfvcur, P32);
+      longv += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
+      P11 = P12;
+      P21 = P22;
+      P31 = P32;
+    }
+
+    return longv / 3.;
+  }
+
+  //! Updates discrete range of surface according to its geometric range.
+  inline void updateRange(const Standard_Real     theGeomFirst,
+                          const Standard_Real     theGeomLast,
+                          const Standard_Boolean  isPeriodic,
+                          Standard_Real&          theDiscreteFirst,
+                          Standard_Real&          theDiscreteLast)
+  {
+    if (theDiscreteFirst < theGeomFirst ||
+        theDiscreteLast  > theGeomLast)
+    {
+      if (isPeriodic)
+      {
+        if ((theDiscreteLast - theDiscreteFirst) > (theGeomLast - theGeomFirst))
+        {
+          theDiscreteLast = theDiscreteFirst + (theGeomLast - theGeomFirst);
+        }
+      }
+      else
+      {
+        if (theGeomFirst > theDiscreteFirst)
+        {
+          theDiscreteFirst = theGeomFirst;
+        }
+
+        if (theGeomLast < theDiscreteLast)
+        {
+          theDiscreteLast = theGeomLast;
+        }
+      }
+    }
+  }
+
+protected:
+  IMeshData::IFaceHandle                  myDFace;
+  std::pair<Standard_Real, Standard_Real> myRangeU;
+  std::pair<Standard_Real, Standard_Real> myRangeV;
+  std::pair<Standard_Real, Standard_Real> myDelta;
+  std::pair<Standard_Real, Standard_Real> myTolerance;
+  Standard_Boolean                        myIsValid;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_Deflection.cxx b/src/BRepMesh/BRepMesh_Deflection.cxx
new file mode 100644 (file)
index 0000000..94258f8
--- /dev/null
@@ -0,0 +1,157 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_Deflection.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Face.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopExp.hxx>
+
+//=======================================================================
+//function : RelativeEdgeDeflection
+//purpose  : 
+//=======================================================================
+Standard_Real BRepMesh_Deflection::RelativeEdgeDeflection(
+  const TopoDS_Edge&  theEdge,
+  const Standard_Real theDeflection,
+  const Standard_Real theMaxShapeSize,
+  Standard_Real&      theAdjustmentCoefficient)
+{
+  theAdjustmentCoefficient = 1.;
+  Standard_Real aEdgeDeflection = theDeflection;
+  if (theEdge.IsNull())
+  {
+    return aEdgeDeflection;
+  }
+
+  Bnd_Box aBox;
+  BRepBndLib::Add (theEdge, aBox, Standard_False);
+  BRepMesh_ShapeTool::BoxMaxDimension (aBox, aEdgeDeflection);
+
+  // Adjust resulting value in relation to the total size
+  theAdjustmentCoefficient = theMaxShapeSize / (2 * aEdgeDeflection);
+  if (theAdjustmentCoefficient < 0.5)
+  {
+    theAdjustmentCoefficient = 0.5;
+  }
+  else if (theAdjustmentCoefficient > 2.)
+  {
+    theAdjustmentCoefficient = 2.;
+  }
+
+  return (theAdjustmentCoefficient * aEdgeDeflection * theDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (edge)
+// Purpose : 
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+  const IMeshData::IEdgeHandle& theDEdge,
+  const Standard_Real           theMaxShapeSize,
+  const IMeshTools_Parameters&  theParameters)
+{
+  Standard_Real aLinDeflection;
+  Standard_Real aAngDeflection;
+  if (theParameters.Relative)
+  {
+    Standard_Real aScale;
+    aLinDeflection = RelativeEdgeDeflection (theDEdge->GetEdge (),
+      theParameters.Deflection, theMaxShapeSize, aScale);
+    aAngDeflection = theParameters.Angle * aScale;
+  }
+  else
+  {
+    aLinDeflection = theParameters.Deflection;
+    aAngDeflection = theParameters.Angle;
+  }
+
+  TopoDS_Vertex aFirstVertex, aLastVertex;
+  TopExp::Vertices(theDEdge->GetEdge(), aFirstVertex, aLastVertex);
+
+  Handle(Geom_Curve) aCurve;
+  Standard_Real aFirstParam, aLastParam;
+  if (BRepMesh_ShapeTool::Range(theDEdge->GetEdge(), aCurve, aFirstParam, aLastParam))
+  {
+    const Standard_Real aVertexAdjustDistance =
+      Max(BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam)),
+          BRep_Tool::Pnt(aLastVertex ).Distance(aCurve->Value(aLastParam)));
+
+    aLinDeflection = Max(aVertexAdjustDistance, aLinDeflection);
+  }
+
+  theDEdge->SetDeflection        (aLinDeflection);
+  theDEdge->SetAngularDeflection (aAngDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (wire)
+// Purpose : 
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+  const IMeshData::IWireHandle& theDWire,
+  const IMeshTools_Parameters&  theParameters)
+{
+  Standard_Real aWireDeflection = 0.;
+  if (theDWire->EdgesNb () > 0)
+  {
+    for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
+    {
+      aWireDeflection += theDWire->GetEdge(aEdgeIt).lock()->GetDeflection();
+    }
+
+    aWireDeflection /= theDWire->EdgesNb ();
+  }
+  else
+  {
+    aWireDeflection = theParameters.Deflection;
+  }
+
+  theDWire->SetDeflection (aWireDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (face)
+// Purpose : 
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+  const IMeshData::IFaceHandle& theDFace,
+  const IMeshTools_Parameters&  theParameters)
+{
+  Standard_Real aFaceDeflection = 0.;
+  if (theDFace->WiresNb () > 0)
+  {
+    for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
+    {
+      aFaceDeflection += theDFace->GetWire(aWireIt)->GetDeflection();
+    }
+
+    aFaceDeflection /= theDFace->WiresNb ();
+  }
+  else
+  {
+    aFaceDeflection = theParameters.Deflection;
+  }
+
+  theDFace->SetDeflection (Max(2.* BRepMesh_ShapeTool::MaxFaceTolerance(
+    theDFace->GetFace()), aFaceDeflection));
+}
diff --git a/src/BRepMesh/BRepMesh_Deflection.hxx b/src/BRepMesh/BRepMesh_Deflection.hxx
new file mode 100644 (file)
index 0000000..7c3b5ae
--- /dev/null
@@ -0,0 +1,66 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_Deflection_HeaderFile
+#define _BRepMesh_Deflection_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Transient.hxx>
+#include <IMeshData_Types.hxx>
+
+class Bnd_Box;
+class TopoDS_Face;
+class TopoDS_Edge;
+struct IMeshTools_Parameters;
+
+//! Auxiliary tool encompassing methods to compute deflection of shapes.
+class BRepMesh_Deflection : public Standard_Transient
+{
+public:
+
+  //! Returns relative deflection for edge with respect to shape size.
+  //! @param theEdge edge for which relative deflection should be computed.
+  //! @param theDeflection absolute deflection.
+  //! @param theMaxShapeSize maximum size of a shape.
+  //! @param theAdjustmentCoefficient coefficient of adjustment between maximum 
+  //! size of shape and calculated relative deflection.
+  //! @return relative deflection for the edge.
+  Standard_EXPORT static Standard_Real RelativeEdgeDeflection (
+    const TopoDS_Edge&  theEdge,
+    const Standard_Real theDeflection,
+    const Standard_Real theMaxShapeSize,
+    Standard_Real&      theAdjustmentCoefficient);
+
+  //! Computes and updates deflection of the given discrete edge.
+  Standard_EXPORT static void ComputeDeflection (
+    const IMeshData::IEdgeHandle& theDEdge,
+    const Standard_Real           theMaxShapeSize,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Computes and updates deflection of the given discrete wire.
+  Standard_EXPORT static void ComputeDeflection (
+    const IMeshData::IWireHandle& theDWire,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Computes and updates deflection of the given discrete face.
+  Standard_EXPORT static void ComputeDeflection (
+    const IMeshData::IFaceHandle& theDFace,
+    const IMeshTools_Parameters&  theParameters);
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Deflection, Standard_Transient)
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx
new file mode 100644 (file)
index 0000000..c130094
--- /dev/null
@@ -0,0 +1,56 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_DelaunayBaseMeshAlgo.hxx>
+#include <BRepMesh_MeshTool.hxx>
+#include <BRepMesh_Delaun.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_DelaunayBaseMeshAlgo::BRepMesh_DelaunayBaseMeshAlgo()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_DelaunayBaseMeshAlgo::~BRepMesh_DelaunayBaseMeshAlgo()
+{
+}
+
+//=======================================================================
+//function : generateMesh
+//purpose  :
+//=======================================================================
+void BRepMesh_DelaunayBaseMeshAlgo::generateMesh()
+{
+  const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = getStructure();
+  const Handle(VectorOfPnt)&                    aNodesMap  = getNodesMap();
+
+  IMeshData::VectorOfInteger aVerticesOrder(aNodesMap->Size(), getAllocator());
+  for (Standard_Integer i = 1; i <= aNodesMap->Size(); ++i)
+  {
+    aVerticesOrder.Append(i);
+  }
+
+  BRepMesh_Delaun aMesher(aStructure, aVerticesOrder);
+  BRepMesh_MeshTool aCleaner(aStructure);
+  aCleaner.EraseFreeLinks();
+
+  postProcessMesh(aMesher);
+}
diff --git a/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..864ae35
--- /dev/null
@@ -0,0 +1,52 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
+#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
+
+#include <BRepMesh_BaseMeshAlgo.hxx>
+#include <NCollection_Shared.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+class BRepMesh_DataStructureOfDelaun;
+class BRepMesh_Delaun;
+
+//! Class provides base fuctionality to build face triangulation using Dealunay approach.
+//! Performs generation of mesh using raw data from model.
+class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_DelaunayBaseMeshAlgo();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
+
+protected:
+
+  //! Generates mesh for the contour stored in data structure.
+  Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
+
+  //! Perfroms processing of generated mesh.
+  //! By default does nothing.
+  Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/)
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..c7c62f7
--- /dev/null
@@ -0,0 +1,414 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshTools_DelaunayDeflectionControlMeshAlgo_HeaderFile
+#define _BRepMeshTools_DelaunayDeflectionControlMeshAlgo_HeaderFile
+
+#include <BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx>
+#include <BRepMesh_GeomTool.hxx>
+
+//! Extends node insertion Delaunay meshing algo in order to control 
+//! deflection of generated trianges. Splits triangles failing the check.
+template<class RangeSplitter>
+class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter>
+{
+private:
+  // Typedef for OCCT RTTI
+  typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> DelaunayInsertionBaseClass;
+
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_DelaunayDeflectionControlMeshAlgo()
+    : myMaxSqDeflection(-1.),
+      myIsAllDegenerated(Standard_False)
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_DelaunayDeflectionControlMeshAlgo()
+  {
+  }
+
+protected:
+
+  //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+  Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE
+  {
+    // Insert surface nodes.
+    DelaunayInsertionBaseClass::postProcessMesh(theMesher);
+
+    if (this->getParameters().ControlSurfaceDeflection &&
+        this->getStructure()->ElementsOfDomain().Extent() > 0)
+    {
+      optimizeMesh(theMesher);
+    }
+  }
+
+  //! Checks deviation of a mesh from geometrical surface.
+  //! Inerts additional nodes in case of huge deviation.
+  Standard_EXPORT virtual void optimizeMesh(BRepMesh_Delaun& theMesher)
+  {
+    Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+    myCouplesMap   = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc);
+    myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+    myCircles      = &theMesher.Circles();
+
+    const Standard_Integer aIterationsNb = 11;
+    Standard_Boolean isInserted = Standard_True;
+    for (Standard_Integer aPass = 1; aPass <= aIterationsNb && isInserted && !myIsAllDegenerated; ++aPass)
+    {
+      // Reset stop condition
+      myMaxSqDeflection = -1.;
+      myIsAllDegenerated = Standard_True;
+      myControlNodes->Clear();
+
+      if (this->getStructure()->ElementsOfDomain().Extent() < 1)
+      {
+        break;
+      }
+
+      // Iterate on current triangles
+      IMeshData::IteratorOfMapOfInteger aTriangleIt(this->getStructure()->ElementsOfDomain());
+      for (; aTriangleIt.More(); aTriangleIt.Next())
+      {
+        const BRepMesh_Triangle& aTriangle = this->getStructure()->GetElement(aTriangleIt.Key());
+        splitTriangleGeometry(aTriangle);
+      }
+
+      isInserted = this->insertNodes(myControlNodes, theMesher);
+    }
+
+    myCouplesMap.Nullify();
+    myControlNodes.Nullify();
+
+    if (!(myMaxSqDeflection < 0.))
+    {
+      this->getDFace()->SetDeflection(Sqrt(myMaxSqDeflection));
+    }
+  }
+
+private:
+  //! Contains geometrical data related to node of triangle.
+  struct TriangleNodeInfo
+  {
+    gp_XY            Point2d;
+    gp_XYZ           Point;
+    Standard_Boolean isFrontierLink;
+  };
+
+  //! Functor computing deflection of a point from surface.
+  class NormalDeviation
+  {
+  public:
+    NormalDeviation(
+      const gp_Pnt& theRefPnt,
+      const gp_Vec& theNormal)
+      : myRefPnt(theRefPnt),
+        myNormal(theNormal)
+    {
+    }
+
+    Standard_Real SquareDeviation(const gp_Pnt& thePoint) const
+    {
+      const Standard_Real aDeflection = Abs(myNormal.Dot(gp_Vec(myRefPnt, thePoint)));
+      return aDeflection * aDeflection;
+    }
+
+  private:
+
+    NormalDeviation (const NormalDeviation& theOther);
+
+    void operator= (const NormalDeviation& theOther);
+
+  private:
+
+    const gp_Pnt& myRefPnt;
+    const gp_Vec& myNormal;
+  };
+
+  //! Functor computing deflection of a point on triangle link from surface.
+  class LineDeviation
+  {
+  public:
+
+    LineDeviation(
+      const gp_Pnt& thePnt1,
+      const gp_Pnt& thePnt2)
+      : myPnt1(thePnt1),
+        myPnt2(thePnt2)
+    {
+    }
+
+    Standard_Real SquareDeviation(const gp_Pnt& thePoint) const
+    {
+      return BRepMesh_GeomTool::SquareDeflectionOfSegment(myPnt1, myPnt2, thePoint);
+    }
+
+  private:
+
+    LineDeviation (const LineDeviation& theOther);
+
+    void operator= (const LineDeviation& theOther);
+
+  private:
+    const gp_Pnt& myPnt1;
+    const gp_Pnt& myPnt2;
+  };
+
+  //! Returns nodes info of the given triangle.
+  inline void getTriangleInfo(
+    const BRepMesh_Triangle& theTriangle,
+    const Standard_Integer (&theNodesIndices)[3],
+    TriangleNodeInfo       (&theInfo)[3]) const
+  {
+    const Standard_Integer(&e)[3] = theTriangle.myEdges;
+    for (Standard_Integer i = 0; i < 3; ++i)
+    {
+      const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(theNodesIndices[i]);
+      theInfo[i].Point2d        = this->getRangeSplitter().Scale(aVertex.Coord(), Standard_False).XY();
+      theInfo[i].Point          = this->getNodesMap()->Value(aVertex.Location3d()).XYZ();
+      theInfo[i].isFrontierLink = (this->getStructure()->GetLink(e[i]).Movability() == BRepMesh_Frontier);
+    }
+  }
+
+  // Check geometry of the given triangle. If triangle does not suit specified deflection, inserts new point.
+  void splitTriangleGeometry(const BRepMesh_Triangle& theTriangle)
+  {
+    if (theTriangle.Movability() != BRepMesh_Deleted)
+    {
+      Standard_Integer aNodexIndices[3];
+      this->getStructure()->ElementNodes(theTriangle, aNodexIndices);
+
+      TriangleNodeInfo aNodesInfo[3];
+      getTriangleInfo(theTriangle, aNodexIndices, aNodesInfo);
+
+      gp_Vec aNormal;
+      gp_Vec aLinkVec[3];
+      if (computeTriangleGeometry(aNodesInfo, aLinkVec, aNormal))
+      {
+        myIsAllDegenerated = Standard_False;
+
+        const gp_XY aCenter2d = (aNodesInfo[0].Point2d +
+                                 aNodesInfo[1].Point2d +
+                                 aNodesInfo[2].Point2d) / 3.;
+
+        usePoint(aCenter2d, NormalDeviation(aNodesInfo[0].Point, aNormal));
+        splitLinks(aNodesInfo, aNodexIndices);
+      }
+    }
+  }
+
+  //! Updates array of links vectors.
+  //! @return False on degenerative triangle.
+  inline Standard_Boolean computeTriangleGeometry(
+    const TriangleNodeInfo(&theNodesInfo)[3],
+    gp_Vec                (&theLinks)[3],
+    gp_Vec                 &theNormal)
+  {
+    if (checkTriangleForDegenerativityAndGetLinks(theNodesInfo, theLinks))
+    {
+      if (checkTriangleArea2d(theNodesInfo))
+      {
+        if (computeNormal(theLinks[0], theLinks[1], theNormal))
+        {
+          return Standard_True;
+        }
+      }
+    }
+
+    return Standard_False;
+  }
+
+  //! Updates array of links vectors.
+  //! @return False on degenerative triangle.
+  inline Standard_Boolean checkTriangleForDegenerativityAndGetLinks(
+    const TriangleNodeInfo (&theNodesInfo)[3],
+    gp_Vec                 (&theLinks)[3])
+  {
+    const Standard_Real MinimalSqLength3d = 1.e-12;
+    for (Standard_Integer i = 0; i < 3; ++i)
+    {
+      theLinks[i] = theNodesInfo[(i + 1) % 3].Point - theNodesInfo[i].Point;
+      if (theLinks[i].SquareMagnitude() < MinimalSqLength3d)
+      {
+        return Standard_False;
+      }
+    }
+
+    return Standard_True;
+  }
+
+  //! Checks area of triangle in parametric space for degenerativity.
+  //! @return False on degenerative triangle.
+  inline Standard_Boolean checkTriangleArea2d(
+    const TriangleNodeInfo (&theNodesInfo)[3])
+  {
+    const gp_Vec2d aLink2d1(theNodesInfo[0].Point2d, theNodesInfo[1].Point2d);
+    const gp_Vec2d aLink2d2(theNodesInfo[1].Point2d, theNodesInfo[2].Point2d);
+
+    const Standard_Real MinimalArea2d = 1.e-9;
+    return (Abs(aLink2d1 ^ aLink2d2) > MinimalArea2d);
+  }
+
+  //! Computes normal using two link vectors.
+  //! @return True on success, False in case of normal of null magnitude.
+  inline Standard_Boolean computeNormal(const gp_Vec& theLink1,
+                                        const gp_Vec& theLink2,
+                                        gp_Vec&       theNormal)
+  {
+    const gp_Vec aNormal(theLink1 ^ theLink2);
+    if (aNormal.SquareMagnitude() > gp::Resolution())
+    {
+      theNormal = aNormal.Normalized();
+      return Standard_True;
+    }
+
+    return Standard_False;
+  }
+
+  //! Computes deflection of midpoints of triangles links.
+  //! @return True if point fits specified deflection.
+  inline void splitLinks(
+    const TriangleNodeInfo (&theNodesInfo)[3],
+    const Standard_Integer (&theNodesIndices)[3])
+  {
+    // Check deflection at triangle links
+    for (Standard_Integer i = 0; i < 3; ++i)
+    {
+      if (theNodesInfo[i].isFrontierLink)
+      {
+        continue;
+      }
+
+      const Standard_Integer j = (i + 1) % 3;
+      // Check if this link was already processed
+      Standard_Integer aFirstVertex, aLastVertex;
+      if (theNodesIndices[i] < theNodesIndices[j])
+      {
+        aFirstVertex = theNodesIndices[i];
+        aLastVertex  = theNodesIndices[j];
+      }
+      else
+      {
+        aFirstVertex = theNodesIndices[j];
+        aLastVertex  = theNodesIndices[i];
+      }
+
+      if (myCouplesMap->Add(BRepMesh_OrientedEdge(aFirstVertex, aLastVertex)))
+      {
+        const gp_XY aMidPnt2d = (theNodesInfo[i].Point2d +
+                                 theNodesInfo[j].Point2d) / 2.;
+
+        usePoint(aMidPnt2d, LineDeviation(theNodesInfo[i].Point, theNodesInfo[j].Point));
+      }
+    }
+  }
+
+  //! Computes deflection of the given point and caches it for
+  //! insertion in case if it overflows deflection.
+  //! @return True if point has been cached for insertion.
+  template<class DeflectionFunctor>
+  inline void usePoint(
+    const gp_XY&             thePnt2d,
+    const DeflectionFunctor& theDeflectionFunctor)
+  {
+    gp_Pnt aPnt;
+    this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
+    if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
+    {
+      myControlNodes->Append(thePnt2d);
+    }
+  }
+
+  //! Checks the given point for specified deflection.
+  //! Updates value of total mesh defleciton.
+  Standard_Boolean checkDeflectionOfPointAndUpdateCache(
+    const gp_XY&        thePnt2d,
+    const gp_Pnt&       thePnt3d,
+    const Standard_Real theSqDeflection)
+  {
+    if (theSqDeflection > myMaxSqDeflection)
+    {
+      myMaxSqDeflection = theSqDeflection;
+    }
+
+    const Standard_Real aSqDeflection = this->getDFace()->GetDeflection() * this->getDFace()->GetDeflection();
+    if (theSqDeflection < aSqDeflection)
+    {
+      return Standard_True;
+    }
+
+    if (this->getParameters().MinSize > Precision::Confusion())
+    {
+      return rejectByMinSize(thePnt2d, thePnt3d);
+    }
+
+    return Standard_False;
+  }
+
+  //! Checks the given node for 
+  Standard_Boolean rejectByMinSize(
+    const gp_XY&  thePnt2d,
+    const gp_Pnt& thePnt3d)
+  {
+    const Standard_Real aSqMinSize = this->getParameters().MinSize * this->getParameters().MinSize;
+
+    Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+    IMeshData::MapOfInteger aUsedNodes;
+    IMeshData::ListOfInteger& aCirclesList =
+      const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
+        this->getRangeSplitter().Scale(thePnt2d, Standard_True).XY());
+
+    IMeshData::ListOfInteger::Iterator aCircleIt(aCirclesList);
+    for (; aCircleIt.More(); aCircleIt.Next())
+    {
+      const BRepMesh_Triangle& aTriangle = this->getStructure()->GetElement(aCircleIt.Value());
+
+      Standard_Integer aNodes[3];
+      this->getStructure()->ElementNodes(aTriangle, aNodes);
+
+      for (Standard_Integer i = 0; i < 3; ++i)
+      {
+        if (!aUsedNodes.Contains(aNodes[i]))
+        {
+          aUsedNodes.Add(aNodes[i]);
+          const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
+          const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
+
+          if (thePnt3d.SquareDistance(aPoint) < aSqMinSize)
+          {
+            return Standard_True;
+          }
+        }
+      }
+    }
+
+    return Standard_False;
+  }
+
+private:
+  Standard_Real                         myMaxSqDeflection;
+  Standard_Boolean                      myIsAllDegenerated;
+  Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
+  Handle(IMeshData::ListOfPnt2d)        myControlNodes;
+  const BRepMesh_CircleTool*            myCircles;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..e15cd53
--- /dev/null
@@ -0,0 +1,82 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile
+#define _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile
+
+#include <BRepMesh_NodeInsertionMeshAlgo.hxx>
+
+//! Extends base Delaunay meshing algo in order to enable possibility 
+//! of addition of free vertices and internal nodes into the mesh.
+template<class RangeSplitter>
+class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo>
+{
+private:
+  // Typedef for OCCT RTTI
+  typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> InsertionBaseClass;
+
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_DelaunayNodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_DelaunayNodeInsertionMeshAlgo()
+  {
+  }
+
+protected:
+
+  //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+  Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE
+  {
+    InsertionBaseClass::postProcessMesh(theMesher);
+
+    const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
+      this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
+
+    insertNodes(aSurfaceNodes, theMesher);
+  }
+
+  //! Inserts nodes into mesh.
+  Standard_EXPORT Standard_Boolean insertNodes(
+    const Handle(IMeshData::ListOfPnt2d)& theNodes,
+    BRepMesh_Delaun&                      theMesher)
+  {
+    if (theNodes.IsNull() || theNodes->IsEmpty())
+    {
+      return Standard_False;
+    }
+
+    IMeshData::VectorOfInteger aVertexIndexes(theNodes->Size(), this->getAllocator());
+    IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
+    for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
+    {
+      const gp_Pnt2d& aPnt2d = aNodesIt.Value();
+      if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
+      {
+        aVertexIndexes.Append(this->registerNode(this->getRangeSplitter().Point(aPnt2d),
+                                                 aPnt2d, BRepMesh_Free, Standard_False));
+      }
+    }
+
+    theMesher.AddVertices(aVertexIndexes);
+    return !aVertexIndexes.IsEmpty();
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.cxx b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx
new file mode 100644 (file)
index 0000000..ecf3fc9
--- /dev/null
@@ -0,0 +1,317 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_EdgeDiscret.hxx>
+#include <BRepMesh_Deflection.hxx>
+#include <IMeshData_Model.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <TopExp.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <BRepMesh_EdgeTessellationExtractor.hxx>
+#include <IMeshData_ParametersListArrayAdaptor.hxx>
+#include <BRepMesh_CurveTessellator.hxx>
+#include <OSD_Parallel.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_EdgeDiscret::BRepMesh_EdgeDiscret ()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_EdgeDiscret::~BRepMesh_EdgeDiscret ()
+{
+}
+
+//=======================================================================
+// Function: CreateFreeEdgeTessellator
+// Purpose : 
+//=======================================================================
+Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+  const IMeshData::IEdgeHandle& theDEdge,
+  const IMeshTools_Parameters&  theParameters)
+{
+  return new BRepMesh_CurveTessellator(theDEdge, theParameters);
+}
+
+//=======================================================================
+// Function: CreateEdgeTessellator
+// Purpose : 
+//=======================================================================
+Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+  const IMeshData::IEdgeHandle& theDEdge,
+  const TopAbs_Orientation      theOrientation,
+  const IMeshData::IFaceHandle& theDFace,
+  const IMeshTools_Parameters&  theParameters)
+{
+  return theDEdge->GetSameParam() ? 
+    new BRepMesh_CurveTessellator(theDEdge, theParameters) :
+    new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters);
+}
+
+//=======================================================================
+// Function: CreateEdgeTessellationExtractor
+// Purpose : 
+//=======================================================================
+Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellationExtractor(
+  const IMeshData::IEdgeHandle& theDEdge,
+  const IMeshData::IFaceHandle& theDFace)
+{
+  return new BRepMesh_EdgeTessellationExtractor(theDEdge, theDFace);
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_EdgeDiscret::Perform (
+  const Handle (IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&    theParameters)
+{
+  myModel      = theModel;
+  myParameters = theParameters;
+  if (myModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  OSD_Parallel::For (0, myModel->EdgesNb (), *this, !myParameters.InParallel);
+
+  myModel.Nullify(); // Do not hold link to model.
+  return Standard_True;
+}
+
+//=======================================================================
+// Function: process
+// Purpose : 
+//=======================================================================
+void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
+{
+  const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
+  BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
+
+  Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
+  if (!aDEdge->IsFree ())
+  {
+    // Iterate over pcurves and check deflection on corresponding face.
+    Standard_Real    aMinDeflection = RealLast ();
+    Standard_Integer aMinPCurveIndex = -1;
+    for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
+    {
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
+      const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
+      if (aTmpDeflection < aMinDeflection)
+      {
+        // Identify pcurve with the smallest deflection in order to
+        // retrieve polygon that represents the most smooth discretization.
+        aMinDeflection  = aTmpDeflection;
+        aMinPCurveIndex = aPCurveIt;
+      }
+
+      BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
+    }
+
+    if (aMinPCurveIndex != -1)
+    {
+      aDEdge->SetDeflection (aMinDeflection);
+      const IMeshData::IFaceHandle& aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace().lock();
+      aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
+    }
+    else
+    {
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+      const IMeshData::IFaceHandle&   aDFace  = aPCurve->GetFace().lock();
+      aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+        aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
+    }
+  }
+  else
+  {
+    TopLoc_Location aLoc;
+    const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
+    if (!aPoly3D.IsNull ()        &&
+        aPoly3D->HasParameters () &&
+        aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
+    {
+      // Edge already has suitable 3d polygon.
+      aDEdge->SetStatus(IMeshData_Reused);
+      return;
+    }
+    else
+    {
+      aDEdge->SetStatus(IMeshData_Outdated);
+    }
+
+    aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
+  }
+
+  Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
+  if (!aDEdge->IsFree())
+  {
+    Tessellate2d(aDEdge, Standard_True);
+  }
+}
+
+//=======================================================================
+// Function: checkExistingPolygonAndUpdateStatus
+// Purpose : 
+//=======================================================================
+Standard_Real BRepMesh_EdgeDiscret::checkExistingPolygonAndUpdateStatus(
+  const IMeshData::IEdgeHandle&   theDEdge,
+  const IMeshData::IPCurveHandle& thePCurve) const
+{
+  const TopoDS_Edge& aEdge = theDEdge->GetEdge ();
+  const TopoDS_Face& aFace = thePCurve->GetFace ().lock ()->GetFace ();
+
+  TopLoc_Location aLoc;
+  const Handle (Poly_Triangulation)& aFaceTriangulation =
+    BRep_Tool::Triangulation (aFace, aLoc);
+
+  Standard_Real aDeflection = RealLast ();
+  if (aFaceTriangulation.IsNull())
+  {
+    return aDeflection;
+  }
+
+  const Handle (Poly_PolygonOnTriangulation)& aPolygon =
+    BRep_Tool::PolygonOnTriangulation (aEdge, aFaceTriangulation, aLoc);
+
+  if (!aPolygon.IsNull ())
+  {
+    Standard_Boolean isConsistent = aPolygon->HasParameters () &&
+      aPolygon->Deflection () < 1.1 * theDEdge->GetDeflection ();
+
+    if (!isConsistent)
+    {
+      // Nullify edge data and mark discrete pcurve to 
+      // notify necessity to mesh the entire face.
+      theDEdge->SetStatus(IMeshData_Outdated);
+    }
+    else
+    {
+      aDeflection = aPolygon->Deflection();
+    }
+  }
+
+  return aDeflection;
+}
+
+//=======================================================================
+// Function: Tessellate3d
+// Purpose : 
+//=======================================================================
+void BRepMesh_EdgeDiscret::Tessellate3d(
+  const IMeshData::IEdgeHandle&               theDEdge,
+  const Handle (IMeshTools_CurveTessellator)& theTessellator,
+  const Standard_Boolean                      theUpdateEnds)
+{
+  // Create 3d polygon.
+  const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+
+  const TopoDS_Edge& aEdge = theDEdge->GetEdge();
+  TopoDS_Vertex aFirstVertex, aLastVertex;
+  TopExp::Vertices(aEdge, aFirstVertex, aLastVertex);
+
+  if (theUpdateEnds)
+  {
+    gp_Pnt aPoint;
+    Standard_Real aParam;
+    theTessellator->Value(1, aPoint, aParam);
+    aCurve->AddPoint(BRep_Tool::Pnt(aFirstVertex), aParam);
+  }
+
+  if (!theDEdge->GetDegenerated())
+  {
+    for (Standard_Integer i = 2; i < theTessellator->PointsNb(); ++i)
+    {
+      gp_Pnt aPoint;
+      Standard_Real aParam;
+      if (!theTessellator->Value(i, aPoint, aParam))
+        continue;
+
+      if (theUpdateEnds)
+      {
+        aCurve->AddPoint(aPoint, aParam);
+      }
+      else
+      {
+        aCurve->InsertPoint(aCurve->ParametersNb() - 1, aPoint, aParam);
+      }
+    }
+  }
+
+  if (theUpdateEnds)
+  {
+    gp_Pnt aPoint;
+    Standard_Real aParam;
+    theTessellator->Value(theTessellator->PointsNb(), aPoint, aParam);
+    aCurve->AddPoint(BRep_Tool::Pnt(aLastVertex), aParam);
+  }
+}
+
+//=======================================================================
+// Function: Tessellate2d
+// Purpose : 
+//=======================================================================
+void BRepMesh_EdgeDiscret::Tessellate2d(
+  const IMeshData::IEdgeHandle& theDEdge,
+  const Standard_Boolean        theUpdateEnds)
+{
+  const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+  for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+  {
+    const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
+    IMeshData::ICurveArrayAdaptorHandle aCurveArray(new IMeshData::ICurveArrayAdaptor(aCurve));
+    BRepMesh_EdgeParameterProvider<IMeshData::ICurveArrayAdaptorHandle> aProvider(
+      theDEdge, aPCurve->GetOrientation(), aPCurve->GetFace().lock(), aCurveArray);
+
+    const Handle(Adaptor2d_HCurve2d)& aGeomPCurve = aProvider.GetPCurve();
+
+    Standard_Integer aParamIdx, aParamNb;
+    if (theUpdateEnds)
+    {
+      aParamIdx = 0;
+      aParamNb  = aCurve->ParametersNb();
+    }
+    else
+    {
+      aParamIdx = 1;
+      aParamNb  = aCurve->ParametersNb() - 1;
+    }
+
+    for (; aParamIdx < aParamNb; ++aParamIdx)
+    {
+      const Standard_Real aParam = aProvider.Parameter(aParamIdx, aCurve->GetPoint(aParamIdx));
+
+      gp_Pnt2d aPoint2d;
+      aGeomPCurve->D0(aParam, aPoint2d);
+      if (theUpdateEnds)
+      {
+        aPCurve->AddPoint(aPoint2d, aParam);
+      }
+      else
+      {
+        aPCurve->InsertPoint(aPCurve->ParametersNb() - 1, aPoint2d, aParam);
+      }
+    }
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.hxx b/src/BRepMesh/BRepMesh_EdgeDiscret.hxx
new file mode 100644 (file)
index 0000000..0793d01
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_EdgeDiscret_HeaderFile
+#define _BRepMesh_EdgeDiscret_HeaderFile
+
+#include <IMeshTools_ModelAlgo.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+
+class IMeshTools_CurveTessellator;
+
+//! Class implements functionality of edge discret tool.
+//! Performs check of the edges for existing Poly_PolygonOnTriangulation.
+//! In case if it fits specified deflection, restores data structure using
+//! it, else clears edges from outdated data.
+class BRepMesh_EdgeDiscret : public IMeshTools_ModelAlgo
+{
+public:
+  //! Constructor.
+  Standard_EXPORT BRepMesh_EdgeDiscret ();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_EdgeDiscret ();
+
+  //! Creates instance of free edge tessellator.
+  Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellator(
+    const IMeshData::IEdgeHandle& theDEdge,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Creates instance of edge tessellator.
+  Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellator(
+    const IMeshData::IEdgeHandle& theDEdge,
+    const TopAbs_Orientation      theOrientation,
+    const IMeshData::IFaceHandle& theDFace,
+    const IMeshTools_Parameters&  theParameters);
+
+  //! Creates instance of tessellation extractor.
+  Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellationExtractor(
+    const IMeshData::IEdgeHandle& theDEdge,
+    const IMeshData::IFaceHandle& theDFace);
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) Standard_OVERRIDE;
+
+  //! Functor API to discretize the given edge.
+  inline void operator() (const Standard_Integer theEdgeIndex) const {
+    process (theEdgeIndex);
+  }
+
+  //! Updates 3d discrete edge model using the given tessellation tool.
+  Standard_EXPORT static void Tessellate3d(
+    const IMeshData::IEdgeHandle&              theDEdge,
+    const Handle(IMeshTools_CurveTessellator)& theTessellator,
+    const Standard_Boolean                     theUpdateEnds);
+
+  //! Updates 2d discrete edge model using tessellation of 3D curve.
+  Standard_EXPORT static void Tessellate2d(
+    const IMeshData::IEdgeHandle& theDEdge,
+    const Standard_Boolean        theUpdateEnds);
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
+
+private:
+
+  //! Checks existing discretization of the edge and updates data model.
+  void process (const Standard_Integer theEdgeIndex) const;
+
+  //! Checks existing polygon on triangulation does it fit edge deflection or not.
+  //! @return deflection of polygon or RealLast () in case if edge has no polygon 
+  //! or it was dropped.
+  Standard_Real checkExistingPolygonAndUpdateStatus(
+    const IMeshData::IEdgeHandle&   theDEdge,
+    const IMeshData::IPCurveHandle& thePCurve) const;
+
+private:
+
+  Handle (IMeshData_Model) myModel;
+  IMeshTools_Parameters    myParameters;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_FaceChecker.cxx b/src/BRepMesh/BRepMesh_FaceChecker.cxx
new file mode 100644 (file)
index 0000000..0a2c73f
--- /dev/null
@@ -0,0 +1,317 @@
+// Created on: 2016-07-04
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_FaceChecker.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <OSD_Parallel.hxx>
+#include <BRepMesh_GeomTool.hxx>
+#include <BRepMesh_IncAllocator.hxx>
+
+namespace
+{
+  const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
+
+  //! Functor to be used to fill segments and bounding box tree in parallel.
+  class SegmentsFiller
+  {
+  public:
+    //! Constructor.
+    SegmentsFiller(const IMeshData::IFaceHandle&                    theDFace,
+                   Handle(BRepMesh_FaceChecker::ArrayOfSegments)&   theWiresSegments,
+                   Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
+      : myDFace(theDFace),
+        myWiresSegments(theWiresSegments),
+        myWiresBndBoxTree(theWiresBndBoxTree)
+    {
+      myWiresSegments   = new BRepMesh_FaceChecker::ArrayOfSegments   (0, myDFace->WiresNb() - 1);
+      myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
+    }
+
+    //! Performs initialization of wire with the given index.
+    void operator()(const Standard_Integer theWireIndex) const
+    {
+      const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
+
+      Handle(NCollection_IncAllocator) aTmpAlloc1 =
+        new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+      Handle(BRepMesh_FaceChecker::Segments) aSegments = 
+        new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
+      Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
+
+      myWiresSegments  ->ChangeValue(theWireIndex) = aSegments;
+      myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
+
+      Handle(NCollection_IncAllocator) aTmpAlloc2 = 
+        new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+      IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
+
+      for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+      {
+        // TODO: check 2d wire for consistency.
+
+        const IMeshData::IEdgePtr&      aDEdge  = aDWire->GetEdge(aEdgeIt);
+        const IMeshData::IPCurveHandle& aPCurve = aDEdge.lock()->GetPCurve(myDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+        for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
+        {
+          gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
+          gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
+
+          Bnd_Box2d aBox;
+          aBox.Add(aPnt1);
+          aBox.Add(aPnt2);
+          aBox.Enlarge(Precision::Confusion());
+
+          aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
+          aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
+        }
+      }
+
+      aBndBoxTreeFiller.Fill();
+    }
+
+  private:
+
+    SegmentsFiller (const SegmentsFiller& theOther);
+
+    void operator=(const SegmentsFiller& theOther);
+
+  private:
+
+    const IMeshData::IFaceHandle&                    myDFace;
+    Handle(BRepMesh_FaceChecker::ArrayOfSegments)&   myWiresSegments;
+    Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
+  };
+
+  //! Selector.
+  //! Used to identify segments with overlapped bounding boxes.
+  //! Selector.
+  //! Used to identify segments with overlapped bounding boxes.
+  class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
+  {
+  public:
+    //! Constructor.
+    BndBox2dTreeSelector(const Standard_Real theTolerance)
+      : myMaxLoopSize(M_PI * theTolerance * theTolerance),
+        mySelfSegmentIndex(-1),
+        myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
+    {
+    }
+
+    //! Sets working set of segments.
+    void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
+    {
+      mySegments = theSegments;
+    }
+
+    //! Resets current selector.
+    void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
+               const Standard_Integer               theSelfSegmentIndex)
+    {
+      myIndices.Clear();
+
+      mySelfSegmentIndex = theSelfSegmentIndex;
+      mySegment = theSegment;
+
+      myBox.SetVoid();
+      myBox.Add(*mySegment->Point1);
+      myBox.Add(*mySegment->Point2);
+      myBox.Enlarge(Precision::Confusion());
+    }
+
+    //! Indicates should the given box be rejected or not.
+    virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
+    {
+      return myBox.IsOut(theBox);
+    }
+
+    //! Accepts segment with the given index in case if it fits conditions.
+    virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
+    {
+      const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
+
+      gp_Pnt2d aIntPnt;
+      const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
+        mySegment->Point1->XY(), mySegment->Point2->XY(),
+        aSegment.Point1->XY(), aSegment.Point2->XY(),
+        Standard_False, Standard_False, aIntPnt);
+
+      if (aIntStatus == BRepMesh_GeomTool::Cross)
+      {
+        const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
+                                     gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
+
+        if (Abs(aAngle) < MaxTangentAngle)
+        {
+          return Standard_False;
+        }
+
+        if (mySelfSegmentIndex != -1)
+        {
+          gp_XY aPrevVec;
+          Standard_Real aSumS = 0.;
+          const gp_XY& aRefPnt = aIntPnt.Coord();
+          for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
+          {
+            const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
+            gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
+
+            if (aCurVec.SquareModulus() < gp::Resolution())
+              continue;
+
+            if (aPrevVec.SquareModulus() > gp::Resolution())
+              aSumS += aPrevVec ^ aCurVec;
+
+            aPrevVec = aCurVec;
+          }
+
+          if (Abs(aSumS / 2.) < myMaxLoopSize)
+          {
+            return Standard_False;
+          }
+        }
+
+        myIndices.Append(theSegmentIndex);
+        return Standard_True;
+      }
+
+      return Standard_False;
+    }
+
+    //! Returns indices of intersecting segments.
+    const IMeshData::VectorOfInteger& Indices() const
+    {
+      return myIndices;
+    }
+
+  private:
+
+    Standard_Real                          myMaxLoopSize;
+    Standard_Integer                       mySelfSegmentIndex;
+    Handle(BRepMesh_FaceChecker::Segments) mySegments;
+    const BRepMesh_FaceChecker::Segment*   mySegment;
+    Bnd_Box2d                              myBox;
+    IMeshData::VectorOfInteger             myIndices;
+  };
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+BRepMesh_FaceChecker::BRepMesh_FaceChecker(
+  const IMeshData::IFaceHandle& theFace,
+  const IMeshTools_Parameters&  theParameters)
+  : myDFace(theFace),
+    myParameters(theParameters)
+{
+}
+
+//=======================================================================
+//function : Destructor
+//purpose  : 
+//=======================================================================
+BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
+{
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_FaceChecker::Perform()
+{
+  myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
+  collectSegments();
+
+  OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
+  collectResult();
+
+  myWiresBndBoxTree.Nullify();
+  myWiresSegments.Nullify();
+  myWiresIntersectingEdges.Nullify();
+  return myIntersectingEdges->IsEmpty();
+}
+
+//=======================================================================
+//function : collectSegments
+//purpose  : 
+//=======================================================================
+void BRepMesh_FaceChecker::collectSegments()
+{
+  SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
+  OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
+
+  myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
+}
+
+//=======================================================================
+//function : perform
+//purpose  : 
+//=======================================================================
+void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
+{
+  const Handle(Segments)&           aSegments1     = myWiresSegments->Value(theWireIndex);
+  Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
+
+  // TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
+  BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
+  for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
+  {
+    const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
+    const Handle(Segments)&                aSegments2 = myWiresSegments->Value(aWireIt);
+
+    aSelector.SetSegments(aSegments2);
+    for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
+    {
+      const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
+      aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
+      if (aBndBoxTree2->Select(aSelector) != 0)
+      {
+        if (aIntersections.IsNull())
+        {
+          aIntersections = new IMeshData::MapOfIEdgePtr;
+        }
+
+        aIntersections->Add(aSegment1.EdgePtr);
+
+        const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
+        for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
+        {
+          const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
+          aIntersections->Add(aSegment2.EdgePtr);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : collectResult
+//purpose  : 
+//=======================================================================
+void BRepMesh_FaceChecker::collectResult()
+{
+  for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
+  {
+    const Handle(IMeshData::MapOfIEdgePtr)& aEdges = myWiresIntersectingEdges->Value(aWireIt);
+    if (!aEdges.IsNull())
+    {
+      myIntersectingEdges->Unite(*aEdges);
+    }
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_FaceChecker.hxx b/src/BRepMesh/BRepMesh_FaceChecker.hxx
new file mode 100644 (file)
index 0000000..93f574a
--- /dev/null
@@ -0,0 +1,122 @@
+// Created on: 2016-07-04
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_FaceChecker_HeaderFile
+#define _BRepMesh_FaceChecker_HeaderFile
+
+#include <IMeshTools_Parameters.hxx>
+#include <Standard_Transient.hxx>
+#include <IMeshData_Face.hxx>
+#include <Standard_Type.hxx>
+#include <NCollection_Shared.hxx>
+
+//! Auxiliary class checking wires of target face for self-intersections.
+//! Explodes wires of discrete face on sets of segments using tessellation 
+//! data stored in model. Each segment is then checked for intersection with
+//! other ones. All collisions are registerd and returned as result of check.
+class BRepMesh_FaceChecker : public Standard_Transient
+{
+public: //! @name mesher API
+
+  //! Identifies segment inside face.
+  struct Segment
+  {
+    IMeshData::IEdgePtr      EdgePtr;
+    gp_Pnt2d*                Point1; // \ Use explicit pointers to points instead of accessing
+    gp_Pnt2d*                Point2; // / using indices.
+
+    Segment()
+      : Point1(NULL)
+      , Point2(NULL)
+    {
+    }
+
+    Segment(const IMeshData::IEdgePtr& theEdgePtr,
+            gp_Pnt2d*                  thePoint1,
+            gp_Pnt2d*                  thePoint2)
+      : EdgePtr(theEdgePtr)
+      , Point1(thePoint1)
+      , Point2(thePoint2)
+    {
+    }
+  };
+
+  typedef NCollection_Shared<NCollection_Vector<Segment> >                          Segments;
+  typedef NCollection_Shared<NCollection_Array1<Handle(Segments)> >                 ArrayOfSegments;
+  typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::BndBox2dTree)> >  ArrayOfBndBoxTree;
+  typedef NCollection_Shared<NCollection_Array1<Handle(IMeshData::MapOfIEdgePtr)> > ArrayOfMapOfIEdgePtr;
+
+
+  //! Default constructor
+  Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace,
+                                       const IMeshTools_Parameters&  theParameters);
+
+  //! Destructor
+  Standard_EXPORT virtual ~BRepMesh_FaceChecker();
+
+  //! Performs check wires of the face for intersections.
+  //! @return True if there is no intersection, False elsewhere.
+  Standard_EXPORT Standard_Boolean Perform();
+
+  //! Returns intersecting edges.
+  const Handle(IMeshData::MapOfIEdgePtr)& GetIntersectingEdges() const
+  {
+    return myIntersectingEdges;
+  }
+
+  //! Checks wire with the given index for intersection with others.
+  inline void operator()(const Standard_Integer theWireIndex) const
+  {
+    perform(theWireIndex);
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient)
+
+private:
+
+  //! Returns True in case if check can be performed in parallel mode.
+  inline Standard_Boolean isParallel() const
+  {
+    return (myParameters.InParallel && myDFace->WiresNb() > 1);
+  }
+
+  //! Collects face segments.
+  void collectSegments();
+
+  //! Collects intersecting edges.
+  void collectResult();
+
+  //! Checks wire with the given index for intersection with others.
+  void perform(const Standard_Integer theWireIndex) const;
+
+private:
+
+  BRepMesh_FaceChecker (const BRepMesh_FaceChecker& theOther);
+
+  void operator=(const BRepMesh_FaceChecker& theOther);
+
+private:
+
+  IMeshData::IFaceHandle            myDFace;
+  const IMeshTools_Parameters&      myParameters;
+
+  Handle(ArrayOfSegments)           myWiresSegments;
+  Handle(ArrayOfBndBoxTree)         myWiresBndBoxTree;
+  Handle(ArrayOfMapOfIEdgePtr)      myWiresIntersectingEdges;
+  Handle(IMeshData::MapOfIEdgePtr)  myIntersectingEdges;
+
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_FaceDiscret.cxx b/src/BRepMesh/BRepMesh_FaceDiscret.cxx
new file mode 100644 (file)
index 0000000..5a0688b
--- /dev/null
@@ -0,0 +1,86 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_FaceDiscret.hxx>
+#include <IMeshData_Model.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshTools_MeshAlgo.hxx>
+#include <OSD_Parallel.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_FaceDiscret::BRepMesh_FaceDiscret(
+  const Handle(IMeshTools_MeshAlgoFactory)& theAlgoFactory)
+  : myAlgoFactory(theAlgoFactory)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_FaceDiscret::Perform(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   theParameters)
+{
+  myModel      = theModel;
+  myParameters = theParameters;
+  if (myModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  OSD_Parallel::For(0, myModel->FacesNb(), *this, !(myParameters.InParallel && myModel->FacesNb() > 1));
+
+  myModel.Nullify(); // Do not hold link to model.
+  return Standard_True;
+}
+
+//=======================================================================
+// Function: process
+// Purpose : 
+//=======================================================================
+void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
+{
+  const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+  if (aDFace->IsSet(IMeshData_Failure) ||
+      aDFace->IsSet(IMeshData_Reused))
+  {
+    return;
+  }
+
+  Handle(IMeshTools_MeshAlgo) aMeshingAlgo = 
+    myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
+
+  if (aMeshingAlgo.IsNull())
+  {
+    aDFace->SetStatus(IMeshData_Failure);
+    return;
+  }
+
+  aMeshingAlgo->Perform(aDFace, myParameters);
+}
diff --git a/src/BRepMesh/BRepMesh_FaceDiscret.hxx b/src/BRepMesh/BRepMesh_FaceDiscret.hxx
new file mode 100644 (file)
index 0000000..cf706cb
--- /dev/null
@@ -0,0 +1,63 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_FaceDiscret_HeaderFile
+#define _BRepMesh_FaceDiscret_HeaderFile
+
+#include <IMeshTools_ModelAlgo.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+#include <IMeshTools_MeshAlgoFactory.hxx>
+
+//! Class implements functionality starting triangulation of model's faces.
+//! Each face is processed separately and can be executed in parallel mode.
+//! Uses mesh algo factory passed as initializer to create instace of triangulation 
+//! algorithm according to type of surface of target face.
+class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_FaceDiscret(
+    const Handle(IMeshTools_MeshAlgoFactory)& theAlgoFactory);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_FaceDiscret();
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform(
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+  //! Functor API to discretize the given edge.
+  inline void operator() (const Standard_Integer theFaceIndex) const {
+    process(theFaceIndex);
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo)
+
+private:
+
+  //! Checks existing discretization of the face and updates data model.
+  void process(const Standard_Integer theFaceIndex) const;
+
+private:
+
+  Handle(IMeshTools_MeshAlgoFactory) myAlgoFactory;
+  Handle(IMeshData_Model)            myModel;
+  IMeshTools_Parameters              myParameters;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_IncAllocator.hxx b/src/BRepMesh/BRepMesh_IncAllocator.hxx
new file mode 100644 (file)
index 0000000..ebe5fda
--- /dev/null
@@ -0,0 +1,50 @@
+// Created on: 2016-06-20
+// Created by: Oleg AGASHIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_IncAllocator_HeaderFile
+#define _BRepMesh_IncAllocator_HeaderFile
+
+#include <NCollection_IncAllocator.hxx>
+#include <Standard_Mutex.hxx>
+
+//! Extension for NCollection_IncAllocator implementing simple thread safety
+//! by introduction of Mutex. Intended for use in couple with BRepMeshData
+//! entities in order to prevent data races while building data model in
+//! parallel mode. Note that this allocator is supposed for use by collections
+//! which allocate memory by huge blocks at arbitrary moment, thus it should
+//! not introduce significant performance slow down.
+class BRepMesh_IncAllocator : public NCollection_IncAllocator
+{
+public:
+  //! Constructor
+  Standard_EXPORT BRepMesh_IncAllocator(const size_t theBlockSize = DefaultBlockSize)
+    : NCollection_IncAllocator(theBlockSize)
+  {
+  }
+
+  //! Allocate memory with given size. Returns NULL on failure
+  Standard_EXPORT virtual void* Allocate(const size_t size) Standard_OVERRIDE
+  {
+    Standard_Mutex::Sentry aSentry(myMutex);
+    return NCollection_IncAllocator::Allocate(size);
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_IncAllocator, NCollection_IncAllocator)
+
+private:
+  Standard_Mutex myMutex;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx b/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx
new file mode 100644 (file)
index 0000000..f73e95d
--- /dev/null
@@ -0,0 +1,103 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_MeshAlgoFactory.hxx>
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <BRepMesh_NURBSRangeSplitter.hxx>
+#include <BRepMesh_SphereRangeSplitter.hxx>
+#include <BRepMesh_CylinderRangeSplitter.hxx>
+#include <BRepMesh_ConeRangeSplitter.hxx>
+#include <BRepMesh_TorusRangeSplitter.hxx>
+#include <BRepMesh_DelaunayBaseMeshAlgo.hxx>
+#include <BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx>
+#include <BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx>
+#include <BRepMesh_BoundaryParamsRangeSplitter.hxx>
+
+namespace
+{
+  struct BaseMeshAlgo
+  {
+    typedef BRepMesh_DelaunayBaseMeshAlgo Type;
+  };
+
+  template<class RangeSplitter>
+  struct NodeInsertionMeshAlgo
+  {
+    typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> Type;
+  };
+
+  template<class RangeSplitter>
+  struct DeflectionControlMeshAlgo
+  {
+    typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter> Type;
+  };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshAlgoFactory::BRepMesh_MeshAlgoFactory()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshAlgoFactory::~BRepMesh_MeshAlgoFactory()
+{
+}
+
+//=======================================================================
+// Function: GetAlgo
+// Purpose : 
+//=======================================================================
+Handle(IMeshTools_MeshAlgo) BRepMesh_MeshAlgoFactory::GetAlgo(
+  const GeomAbs_SurfaceType    theSurfaceType,
+  const IMeshTools_Parameters& theParameters) const
+{
+  switch (theSurfaceType)
+  {
+  case GeomAbs_Plane:
+    return theParameters.InternalVerticesMode ?
+      new NodeInsertionMeshAlgo<BRepMesh_DefaultRangeSplitter>::Type :
+      new BaseMeshAlgo::Type;
+    break;
+
+  case GeomAbs_Sphere:
+    return new NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type;
+    break;
+
+  case GeomAbs_Cylinder:
+    return new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type;
+    break;
+
+  case GeomAbs_Cone:
+    return new NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type;
+    break;
+
+  case GeomAbs_Torus:
+    return new NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type;
+    break;
+
+  case GeomAbs_SurfaceOfRevolution:
+    return new DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type;
+    break;
+
+  default:
+    return new DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type;
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx b/src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx
new file mode 100644 (file)
index 0000000..72a27c5
--- /dev/null
@@ -0,0 +1,44 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_MeshAlgoFactory_HeaderFile
+#define _BRepMesh_MeshAlgoFactory_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <GeomAbs_SurfaceType.hxx>
+#include <IMeshTools_MeshAlgoFactory.hxx>
+
+//! Default implementation of IMeshTools_MeshAlgoFactory providing algorithms 
+//! of different compexity depending on type of target surface.
+class BRepMesh_MeshAlgoFactory : public IMeshTools_MeshAlgoFactory
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_MeshAlgoFactory();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_MeshAlgoFactory();
+
+  //! Creates instance of meshing algorithm for the given type of surface.
+  Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo(
+    const GeomAbs_SurfaceType    theSurfaceType,
+    const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshAlgoFactory, IMeshTools_MeshAlgoFactory)
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_MeshBuilder.cxx b/src/BRepMesh/BRepMesh_MeshBuilder.cxx
new file mode 100644 (file)
index 0000000..78cd8ca
--- /dev/null
@@ -0,0 +1,118 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_MeshBuilder.hxx>
+#include <IMeshData_Face.hxx>
+#include <OSD_Parallel.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshBuilder::BRepMesh_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshBuilder::BRepMesh_MeshBuilder (
+  const Handle (IMeshTools_Context)& theContext)
+  : IMeshTools_MeshBuilder (theContext)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshBuilder::~BRepMesh_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+void BRepMesh_MeshBuilder::Perform ()
+{
+  ClearStatus ();
+
+  const Handle (IMeshTools_Context)& aContext = GetContext ();
+  if (aContext.IsNull ())
+  {
+    SetStatus (Message_Fail1);
+    return;
+  }
+
+  if (aContext->BuildModel ())
+  {
+    if (aContext->DiscretizeEdges ())
+    {
+      if (aContext->HealModel ())
+      {
+        if (aContext->PreProcessModel())
+        {
+          if (aContext->DiscretizeFaces())
+          {
+            if (aContext->PostProcessModel())
+            {
+              SetStatus(Message_Done1);
+            }
+            else
+            {
+              SetStatus(Message_Fail6);
+            }
+          }
+          else
+          {
+            SetStatus(Message_Fail5);
+          }
+        }
+        else
+        {
+          SetStatus(Message_Fail4);
+        }
+      }
+      else
+      {
+        SetStatus(Message_Fail3);
+      }
+    }
+    else
+    {
+      SetStatus (Message_Fail1);
+    }
+  }
+  else
+  {
+    const Handle (IMeshTools_ModelBuilder)& aModelBuilder =
+      aContext->GetModelBuilder ();
+
+    if (aModelBuilder.IsNull ())
+    {
+      SetStatus (Message_Fail1);
+    }
+    else
+    {
+      // Is null shape or another problem?
+      SetStatus (aModelBuilder->GetStatus ().IsSet (Message_Fail1) ?
+        Message_Warn1 : Message_Fail2);
+    }
+  }
+
+  aContext->Clean ();
+}
diff --git a/src/BRepMesh/BRepMesh_MeshBuilder.hxx b/src/BRepMesh/BRepMesh_MeshBuilder.hxx
new file mode 100644 (file)
index 0000000..d35ab93
--- /dev/null
@@ -0,0 +1,52 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_MeshBuilder_HeaderFile
+#define _BRepMesh_MeshBuilder_HeaderFile
+
+#include <IMeshTools_MeshBuilder.hxx>
+
+//! Builds mesh for each face of shape without triangulation.
+//! In case if some faces of shape have already been triangulated
+//! checks deflection of existing polygonal model and re-uses it
+//! if deflection satisfies the specified parameter. Otherwise
+//! nullifies existing triangulation and build triangulation anew.
+//!
+//! The following statuses are used:
+//! Message_Done1 - algorithm has finished without errors.
+//! Message_Fail1 - invalid context.
+//! Message_Fail2 - algorithm has faced unexpected error.
+//! Message_Fail3 - can't heal discrete model.
+//! Message_Warn1 - shape contains no objects to mesh.
+class BRepMesh_MeshBuilder : public IMeshTools_MeshBuilder
+{
+public: //! @name mesher API
+
+  //! Default constructor
+  Standard_EXPORT BRepMesh_MeshBuilder ();
+
+  //! Default constructor
+  Standard_EXPORT BRepMesh_MeshBuilder (const Handle (IMeshTools_Context)& theContext);
+
+  //! Destructor
+  Standard_EXPORT virtual ~BRepMesh_MeshBuilder ();
+
+  //! Performs meshing ot the shape.
+  Standard_EXPORT virtual void Perform () Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshBuilder, IMeshTools_MeshBuilder)
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_MeshTool.cxx b/src/BRepMesh/BRepMesh_MeshTool.cxx
new file mode 100644 (file)
index 0000000..31a304f
--- /dev/null
@@ -0,0 +1,368 @@
+// Created on: 2016-08-22
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_MeshTool.hxx>
+#include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx>
+#include <stack>
+
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakePolygon.hxx>
+#include <BRep_Builder.hxx>
+#include <TopoDS_Compound.hxx>
+#include <BRepTools.hxx>
+#include <gp_Pln.hxx>
+
+namespace
+{
+  //! Returns index of triangle node opposite to the given link.
+  inline Standard_Integer findApexIndex(
+    const Standard_Integer(&aNodes)[3],
+    const BRepMesh_Edge&   theLink)
+  {
+    Standard_Integer i = 0;
+    for (; i < 3; ++i)
+    {
+      if (aNodes[i] != theLink.FirstNode() &&
+          aNodes[i] != theLink.LastNode())
+      {
+        break;
+      }
+    }
+
+    return i;
+  }
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshTool::BRepMesh_MeshTool(
+  const Handle(BRepMesh_DataStructureOfDelaun)& theStructure)
+  : myStructure(theStructure)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_MeshTool::~BRepMesh_MeshTool()
+{
+}
+
+//=======================================================================
+//function : Legalize
+//purpose  :
+//=======================================================================
+void BRepMesh_MeshTool::Legalize(const Standard_Integer theLinkIndex)
+{
+  std::stack<Standard_Integer> aStack;
+  aStack.push(theLinkIndex);
+
+  IMeshData::MapOfInteger aUsedLinks;
+  while (!aStack.empty())
+  {
+    const Standard_Integer aLinkIndex = aStack.top();
+    aStack.pop();
+    
+    aUsedLinks.Add(aLinkIndex);
+    const BRepMesh_Edge& aLink = myStructure->GetLink(aLinkIndex);
+    if (aLink.Movability() != BRepMesh_Frontier)
+    {
+      const BRepMesh_PairOfIndex& aPair = myStructure->ElementsConnectedTo(aLinkIndex);
+      if (aPair.Extent() == 2)
+      {
+        const BRepMesh_Triangle& aTriangle1 = myStructure->GetElement(aPair.FirstIndex());
+        const BRepMesh_Triangle& aTriangle2 = myStructure->GetElement(aPair.LastIndex());
+
+        Standard_Integer aNodes[2][3];
+        myStructure->ElementNodes(aTriangle1, aNodes[0]);
+        myStructure->ElementNodes(aTriangle2, aNodes[1]);
+
+        const Standard_Integer aApexIndex[2] = {
+          findApexIndex(aNodes[0], aLink),
+          findApexIndex(aNodes[1], aLink)
+        };
+
+        if (checkCircle(aNodes[0], aNodes[1][aApexIndex[1]]) ||
+            checkCircle(aNodes[1], aNodes[0][aApexIndex[0]]))
+        {
+          myStructure->RemoveElement(aPair.FirstIndex());
+          myStructure->RemoveElement(aPair.LastIndex());
+          myStructure->RemoveLink(aLinkIndex);
+
+          addTriangleAndUpdateStack(
+            aNodes[0][(aApexIndex[0])],
+            aNodes[0][(aApexIndex[0] + 1) % 3],
+            aNodes[1][(aApexIndex[1])],
+            aUsedLinks, aStack);
+
+          addTriangleAndUpdateStack(
+            aNodes[1][(aApexIndex[1])],
+            aNodes[1][(aApexIndex[1] + 1) % 3],
+            aNodes[0][(aApexIndex[0])],
+            aUsedLinks, aStack);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : EraseItemsConnectedTo
+//purpose  :
+//=======================================================================
+void BRepMesh_MeshTool::EraseItemsConnectedTo(
+  const Standard_Integer theNodeIndex)
+{
+  BRepMesh_SelectorOfDataStructureOfDelaun aSelector(myStructure);
+  aSelector.NeighboursOfNode(theNodeIndex);
+
+  IMeshData::MapOfIntegerInteger aLoopEdges(1, new NCollection_IncAllocator);
+  EraseTriangles(aSelector.Elements(), aLoopEdges);
+  EraseFreeLinks(aLoopEdges);
+  myStructure->RemoveNode(theNodeIndex);
+}
+
+//=======================================================================
+//function : CleanFrontierLinks
+//purpose  : 
+//=======================================================================
+void BRepMesh_MeshTool::CleanFrontierLinks()
+{
+  Handle(NCollection_IncAllocator) aAlloc = new NCollection_IncAllocator;
+  IMeshData::MapOfInteger aTrianglesToErase;
+  IMeshData::MapOfIntegerInteger aLoopEdges(1, aAlloc);
+
+  Handle(IMeshData::MapOfInteger) aFrontier = GetEdgesByType(BRepMesh_Frontier);
+  IMeshData::IteratorOfMapOfInteger aFrontierIt(*aFrontier);
+  for (; aFrontierIt.More(); aFrontierIt.Next())
+  {
+    Standard_Integer aFrontierId = aFrontierIt.Key();
+    const BRepMesh_Edge& aLink = myStructure->GetLink(aFrontierId);
+
+    Standard_Boolean isTriangleFound = Standard_False;
+    const BRepMesh_PairOfIndex& aPair = myStructure->ElementsConnectedTo(aFrontierId);
+    for (Standard_Integer aElemIt = 1; aElemIt <= aPair.Extent() && !isTriangleFound; ++aElemIt)
+    {
+      const Standard_Integer aPriorElemId = aPair.Index(aElemIt);
+      const BRepMesh_Triangle& aElement = myStructure->GetElement(aPriorElemId);
+      const Standard_Integer(&e)[3] = aElement.myEdges;
+      const Standard_Boolean(&o)[3] = aElement.myOrientations;
+
+      for (Standard_Integer n = 0; n < 3 && !isTriangleFound; ++n)
+      {
+        if (aFrontierId == e[n] && !o[n])
+        {
+          // Destruction of external triangles on boundary edges
+          isTriangleFound = Standard_True;
+          aTrianglesToErase.Add(aPriorElemId);
+
+          collectTrianglesOnFreeLinksAroundNodesOf(aLink, e[(n + 1) % 3], aTrianglesToErase);
+          collectTrianglesOnFreeLinksAroundNodesOf(aLink, e[(n + 2) % 3], aTrianglesToErase);
+        }
+      }
+    }
+  }
+
+  EraseTriangles(aTrianglesToErase, aLoopEdges);
+  EraseFreeLinks(aLoopEdges);
+}
+
+//=======================================================================
+//function : EraseTriangles
+//purpose  : 
+//=======================================================================
+void BRepMesh_MeshTool::EraseTriangles(
+  const IMeshData::MapOfInteger&  theTriangles,
+  IMeshData::MapOfIntegerInteger& theLoopEdges)
+{
+  IMeshData::IteratorOfMapOfInteger aFreeTriangles(theTriangles);
+  for (; aFreeTriangles.More(); aFreeTriangles.Next())
+  {
+    EraseTriangle(aFreeTriangles.Key(), theLoopEdges);
+  }
+}
+
+//=======================================================================
+//function : EraseTriangle
+//purpose  : 
+//=======================================================================
+void BRepMesh_MeshTool::EraseTriangle(
+  const Standard_Integer          theTriangleIndex,
+  IMeshData::MapOfIntegerInteger& theLoopEdges)
+{
+  const BRepMesh_Triangle& aElement = myStructure->GetElement(theTriangleIndex);
+  const Standard_Integer(&e)[3] = aElement.myEdges;
+  const Standard_Boolean(&o)[3] = aElement.myOrientations;
+
+  myStructure->RemoveElement(theTriangleIndex);
+
+  for (Standard_Integer i = 0; i < 3; ++i)
+  {
+    if (!theLoopEdges.Bind(e[i], o[i]))
+    {
+      theLoopEdges.UnBind(e[i]);
+      myStructure->RemoveLink(e[i]);
+    }
+  }
+}
+
+//=======================================================================
+//function : EraseFreeLinks
+//purpose  :
+//=======================================================================
+void BRepMesh_MeshTool::EraseFreeLinks()
+{
+  for (Standard_Integer i = 1; i <= myStructure->NbLinks(); i++)
+  {
+    if (myStructure->ElementsConnectedTo(i).IsEmpty())
+    {
+      BRepMesh_Edge& anEdge = (BRepMesh_Edge&) myStructure->GetLink(i);
+      if (anEdge.Movability() == BRepMesh_Deleted)
+      {
+        continue;
+      }
+
+      anEdge.SetMovability(BRepMesh_Free);
+      myStructure->RemoveLink(i);
+    }
+  }
+}
+
+//=======================================================================
+//function : collectTrianglesOnFreeLinksAroundNodesOf
+//purpose  :
+//=======================================================================
+void BRepMesh_MeshTool::collectTrianglesOnFreeLinksAroundNodesOf(
+  const BRepMesh_Edge&     theConstraint,
+  const Standard_Integer   theStartLink,
+  IMeshData::MapOfInteger& theTriangles)
+{
+  IMeshData::MapOfInteger aUsedLinks;
+  std::stack<Standard_Integer> aStack;
+  aStack.push(theStartLink);
+  aUsedLinks.Add(theStartLink);
+
+  while (!aStack.empty())
+  {
+    const Standard_Integer aLinkIndex = aStack.top();
+    aStack.pop();
+
+    const BRepMesh_Edge& aLink = myStructure->GetLink(aLinkIndex);
+    if (aLink.Movability() == BRepMesh_Free &&
+        (aLink.FirstNode() == theConstraint.FirstNode() ||
+         aLink.LastNode () == theConstraint.FirstNode() ||
+         aLink.FirstNode() == theConstraint.LastNode () ||
+         aLink.LastNode () == theConstraint.LastNode ()))
+    {
+      const BRepMesh_PairOfIndex& aPair = myStructure->ElementsConnectedTo(aLinkIndex);
+      for (Standard_Integer aElemIt = 1; aElemIt <= aPair.Extent(); ++aElemIt)
+      {
+        const Standard_Integer aIndex = aPair.Index(aElemIt);
+        theTriangles.Add(aIndex);
+
+        const BRepMesh_Triangle& aElement = myStructure->GetElement(aIndex);
+        const Standard_Integer(&aEdges)[3] = aElement.myEdges;
+
+        for (Standard_Integer i = 0; i < 3; ++i)
+        {
+          if (aEdges[i] != aLinkIndex && !aUsedLinks.Contains(aEdges[i]))
+          {
+            aUsedLinks.Add(aEdges[i]);
+            aStack   .push(aEdges[i]);
+          }
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : EraseFreeLinks
+//purpose  :
+//=======================================================================
+void BRepMesh_MeshTool::EraseFreeLinks(
+  const IMeshData::MapOfIntegerInteger& theLinks)
+{
+  IMeshData::MapOfIntegerInteger::Iterator aFreeEdges(theLinks);
+  for (; aFreeEdges.More(); aFreeEdges.Next())
+  {
+    if (myStructure->ElementsConnectedTo(aFreeEdges.Key()).IsEmpty())
+    {
+      myStructure->RemoveLink(aFreeEdges.Key());
+    }
+  }
+}
+
+//=======================================================================
+//function : GetEdgesByType
+//purpose  : 
+//=======================================================================
+Handle(IMeshData::MapOfInteger) BRepMesh_MeshTool::GetEdgesByType(
+  const BRepMesh_DegreeOfFreedom theEdgeType) const
+{
+  Handle(IMeshData::MapOfInteger) aResult = new IMeshData::MapOfInteger;
+  IMeshData::IteratorOfMapOfInteger aEdgeIt(myStructure->LinksOfDomain());
+
+  for (; aEdgeIt.More(); aEdgeIt.Next())
+  {
+    const BRepMesh_Edge& aEdge = myStructure->GetLink(aEdgeIt.Key());
+    if (aEdge.Movability() == theEdgeType)
+    {
+      aResult->Add(aEdgeIt.Key());
+    }
+  }
+
+  return aResult;
+}
+
+//=======================================================================
+//function : DumpStruct
+//purpose  : 
+//=======================================================================
+void BRepMesh_MeshTool::DumpTriangles(const Standard_CString   theFileName,
+                                      IMeshData::MapOfInteger* theTriangles)
+{
+  BRep_Builder aBuilder;
+  TopoDS_Compound aResult;
+  aBuilder.MakeCompound(aResult);
+
+  const IMeshData::MapOfInteger& aTriangles = myStructure->ElementsOfDomain();
+  for (IMeshData::IteratorOfMapOfInteger aIt(aTriangles); aIt.More(); aIt.Next())
+  {
+    if (theTriangles != NULL && !theTriangles->Contains(aIt.Key()))
+      continue;
+
+    Standard_Integer aNodes[3];
+    const BRepMesh_Triangle& aTri = myStructure->GetElement(aIt.Key());
+    myStructure->ElementNodes(aTri, aNodes);
+
+    const gp_XY& aV1 = myStructure->GetNode(aNodes[0]).Coord();
+    const gp_XY& aV2 = myStructure->GetNode(aNodes[1]).Coord();
+    const gp_XY& aV3 = myStructure->GetNode(aNodes[2]).Coord();
+
+    BRepBuilderAPI_MakePolygon aPoly(gp_Pnt(aV1.X(), aV1.Y(), 0.),
+                                     gp_Pnt(aV2.X(), aV2.Y(), 0.),
+                                     gp_Pnt(aV3.X(), aV3.Y(), 0.),
+                                     Standard_True);
+
+    BRepBuilderAPI_MakeFace aFaceBuilder(gp_Pln(gp::XOY()), aPoly.Wire());
+    aBuilder.Add(aResult, aFaceBuilder.Shape());
+  }
+
+  BRepTools::Write(aResult, theFileName);
+}
diff --git a/src/BRepMesh/BRepMesh_MeshTool.hxx b/src/BRepMesh/BRepMesh_MeshTool.hxx
new file mode 100644 (file)
index 0000000..7ca0294
--- /dev/null
@@ -0,0 +1,235 @@
+// Created on: 2016-08-22
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_MeshTool_HeaderFile
+#define _BRepMesh_MeshTool_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_DefineHandle.hxx>
+#include <BRepMesh_DataStructureOfDelaun.hxx>
+#include <BRepMesh_CircleTool.hxx>
+#include <gp_Lin2d.hxx>
+#include <IMeshData_Types.hxx>
+#include <BRepMesh_Edge.hxx>
+
+#include <stack>
+
+//! Auxiliary tool providing API for manipulation with BRepMesh_DataStructureOfDelaun.
+class BRepMesh_MeshTool : public Standard_Transient
+{
+public:
+
+  //! Helper functor intended to separate points to left and right from the constraint.
+  class NodeClassifier
+  {
+  public:
+
+    NodeClassifier(
+      const BRepMesh_Edge&                          theConstraint,
+      const Handle(BRepMesh_DataStructureOfDelaun)& theStructure)
+      : myStructure(theStructure)
+    {
+      const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(theConstraint.FirstNode());
+      const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(theConstraint.LastNode());
+
+      myConstraint.SetLocation(aVertex1.Coord());
+      myConstraint.SetDirection(gp_Vec2d(aVertex1.Coord(), aVertex2.Coord()));
+      mySign = myConstraint.Direction().X() > 0;
+    }
+
+    inline Standard_Boolean IsAbove(const Standard_Integer theNodeIndex) const
+    {
+      const BRepMesh_Vertex& aVertex = myStructure->GetNode(theNodeIndex);
+      const gp_Vec2d aNodeVec(myConstraint.Location(), aVertex.Coord());
+      if (aNodeVec.SquareMagnitude() > gp::Resolution())
+      {
+        const Standard_Real aCross = aNodeVec.Crossed(myConstraint.Direction());
+        if (Abs(aCross) > gp::Resolution())
+        {
+          return mySign ? 
+            aCross < 0. :
+            aCross > 0.;
+        }
+      }
+
+      return Standard_False;
+    }
+
+  private:
+
+    NodeClassifier (const NodeClassifier& theOther);
+
+    void operator=(const NodeClassifier& theOther);
+
+  private:
+
+    const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
+    gp_Lin2d                                      myConstraint;
+    Standard_Boolean                              mySign;
+  };
+
+  //! Constructor.
+  //! Initializes tool by the given data structure.
+  Standard_EXPORT BRepMesh_MeshTool(const Handle(BRepMesh_DataStructureOfDelaun)& theStructure);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_MeshTool();
+
+  //! Returns data structure manipulated by this tool.
+  inline const Handle(BRepMesh_DataStructureOfDelaun)& GetStructure() const
+  {
+    return myStructure;
+  }
+
+  //! Dumps triangles to specified file.
+  void DumpTriangles(const Standard_CString theFileName, IMeshData::MapOfInteger* theTriangles);
+
+  //! Adds new triangle with specified nodes to mesh.
+  //! Legalizes triangle in case if it violates circle criteria.
+  inline void AddAndLegalizeTriangle(
+    const Standard_Integer thePoint1,
+    const Standard_Integer thePoint2,
+    const Standard_Integer thePoint3)
+  {
+    Standard_Integer aEdges[3];
+    AddTriangle(thePoint1, thePoint2, thePoint3, aEdges);
+
+    Legalize(aEdges[0]);
+    Legalize(aEdges[1]);
+    Legalize(aEdges[2]);
+  }
+
+  //! Adds new triangle with specified nodes to mesh.
+  inline void AddTriangle(
+    const Standard_Integer thePoint1,
+    const Standard_Integer thePoint2,
+    const Standard_Integer thePoint3,
+    Standard_Integer     (&theEdges)[3])
+  {
+    Standard_Boolean aOri[3];
+    AddLink(thePoint1, thePoint2, theEdges[0], aOri[0]);
+    AddLink(thePoint2, thePoint3, theEdges[1], aOri[1]);
+    AddLink(thePoint3, thePoint1, theEdges[2], aOri[2]);
+
+    myStructure->AddElement(BRepMesh_Triangle(theEdges, aOri, BRepMesh_Free));
+  }
+
+  //! Adds new link to mesh.
+  //! Updates link index and link orientaion parameters.
+  inline void AddLink(const Standard_Integer theFirstNode,
+                      const Standard_Integer theLastNode,
+                      Standard_Integer&      theLinkIndex,
+                      Standard_Boolean&      theLinkOri)
+  {
+    const Standard_Integer aLinkIt = myStructure->AddLink(
+      BRepMesh_Edge(theFirstNode, theLastNode, BRepMesh_Free));
+
+    theLinkIndex = Abs(aLinkIt);
+    theLinkOri = (aLinkIt > 0);
+  }
+
+  //! Performs legalization of triangles connected to the specified link.
+  Standard_EXPORT void Legalize(const Standard_Integer theLinkIndex);
+
+  //! Erases all elements connected to the specified artificial node.
+  //! In addition, erases the artificial node itself.
+  Standard_EXPORT void EraseItemsConnectedTo(const Standard_Integer theNodeIndex);
+
+  //! Cleans frontier links from triangles to the right.
+  Standard_EXPORT void CleanFrontierLinks();
+
+  //! Erases the given set of triangles.
+  //! Fills map of loop edges forming the countour surrounding the erased triangles.
+  void EraseTriangles(const IMeshData::MapOfInteger&  theTriangles,
+                      IMeshData::MapOfIntegerInteger& theLoopEdges);
+
+  //! Erases triangle with the given index and adds the free edges into the map.
+  //! When an edge is suppressed more than one time it is destroyed.
+  Standard_EXPORT void EraseTriangle(const Standard_Integer          theTriangleIndex,
+                                     IMeshData::MapOfIntegerInteger& theLoopEdges);
+
+  //! Erases all links that have no elements connected to them.
+  Standard_EXPORT void EraseFreeLinks();
+
+  //! Erases links from the specified map that have no elements connected to them.
+  Standard_EXPORT void EraseFreeLinks(const IMeshData::MapOfIntegerInteger& theLinks);
+
+  //! Gives the list of edges with type defined by input parameter.
+  Standard_EXPORT Handle(IMeshData::MapOfInteger) GetEdgesByType(const BRepMesh_DegreeOfFreedom theEdgeType) const;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshTool, Standard_Transient)
+
+private:
+
+  //! Returns True if the given point lies within circumcircle of the given triangle.
+  inline Standard_Boolean checkCircle(
+    const Standard_Integer(&aNodes)[3],
+    const Standard_Integer thePoint)
+  {
+    const BRepMesh_Vertex& aVertex0 = myStructure->GetNode(aNodes[0]);
+    const BRepMesh_Vertex& aVertex1 = myStructure->GetNode(aNodes[1]);
+    const BRepMesh_Vertex& aVertex2 = myStructure->GetNode(aNodes[2]);
+
+    gp_XY aLocation;
+    Standard_Real aRadius;
+    const Standard_Boolean isOk = BRepMesh_CircleTool::MakeCircle(
+      aVertex0.Coord(), aVertex1.Coord(), aVertex2.Coord(),
+      aLocation, aRadius);
+
+    if (isOk)
+    {
+      const BRepMesh_Vertex& aVertex = myStructure->GetNode(thePoint);
+      const Standard_Real aDist = (aVertex.Coord() - aLocation).SquareModulus() - (aRadius * aRadius);
+      return (aDist < Precision::SquareConfusion());
+    }
+
+    return Standard_False;
+  }
+
+  //! Adds new triangle with the given nodes and updates
+  //! links stack by ones are not in used map.
+  inline void addTriangleAndUpdateStack(
+    const Standard_Integer         theNode0,
+    const Standard_Integer         theNode1,
+    const Standard_Integer         theNode2,
+    const IMeshData::MapOfInteger& theUsedLinks,
+    std::stack<Standard_Integer>&  theStack)
+  {
+    Standard_Integer aEdges[3];
+    AddTriangle(theNode0, theNode1, theNode2, aEdges);
+
+    for (Standard_Integer i = 0; i < 3; ++i)
+    {
+      if (!theUsedLinks.Contains(aEdges[i]))
+      {
+        theStack.push(aEdges[i]);
+      }
+    }
+  }
+
+  //! Iteratively erases triangles and their neighbours consisting
+  //! of free links using the given link as starting front.
+  //! Only triangles around the constraint's saddle nodes will be removed.
+  void collectTrianglesOnFreeLinksAroundNodesOf(
+    const BRepMesh_Edge&     theConstraint,
+    const Standard_Integer   theStartLink,
+    IMeshData::MapOfInteger& theTriangles);
+
+private:
+
+  Handle(BRepMesh_DataStructureOfDelaun) myStructure;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ModelBuilder.cxx b/src/BRepMesh/BRepMesh_ModelBuilder.cxx
new file mode 100644 (file)
index 0000000..2f4a377
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ModelBuilder.hxx>
+#include <BRepMeshData_Model.hxx>
+#include <BRepMesh_ShapeVisitor.hxx>
+#include <BRepMesh_ShapeExplorer.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelBuilder::BRepMesh_ModelBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
+  const TopoDS_Shape&          theShape,
+  const IMeshTools_Parameters& theParameters)
+{
+  ClearStatus ();
+
+  Handle (BRepMeshData_Model) aModel;
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    Bnd_Box aBox;
+    BRepBndLib::Add (theShape, aBox, Standard_False);
+
+    if (!aBox.IsVoid ())
+    {
+      // Build data model for further processing.
+      aModel = new BRepMeshData_Model (theShape);
+
+      if (theParameters.Relative)
+      {
+        Standard_Real aMaxSize;
+        BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
+        aModel->SetMaxSize(aMaxSize);
+      }
+      else
+      {
+        aModel->SetMaxSize(theParameters.Deflection);
+      }
+
+      Handle (IMeshTools_ShapeVisitor) aVisitor =
+        new BRepMesh_ShapeVisitor (aModel);
+
+      Handle (IMeshTools_ShapeExplorer) aExplorer =
+        new BRepMesh_ShapeExplorer (theShape);
+
+      aExplorer->Accept (aVisitor);
+      SetStatus (Message_Done1);
+    }
+    else
+    {
+      SetStatus(Message_Fail1);
+    }
+  }
+  catch (Standard_Failure&)
+  {
+    SetStatus (Message_Fail2);
+  }
+
+  return aModel;
+}
diff --git a/src/BRepMesh/BRepMesh_ModelBuilder.hxx b/src/BRepMesh/BRepMesh_ModelBuilder.hxx
new file mode 100644 (file)
index 0000000..aa1850a
--- /dev/null
@@ -0,0 +1,48 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ModelBuilder_HeaderFile
+#define _BRepMesh_ModelBuilder_HeaderFile
+
+#include <IMeshTools_ModelBuilder.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Class implements interface representing tool for discrete model building.
+//! 
+//! The following statuses should be used by default:
+//! Message_Done1 - model has been sucessfully built.
+//! Message_Fail1 - empty shape.
+//! Message_Fail2 - model has not been build due to unexpected reason.
+class BRepMesh_ModelBuilder : public IMeshTools_ModelBuilder
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ModelBuilder ();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ModelBuilder ();
+
+  //! Creates discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_ModelHealer.cxx b/src/BRepMesh/BRepMesh_ModelHealer.cxx
new file mode 100644 (file)
index 0000000..96e3735
--- /dev/null
@@ -0,0 +1,440 @@
+// Created on: 2016-06-23
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ModelHealer.hxx>
+#include <BRepMesh_Deflection.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <BRepMesh_FaceChecker.hxx>
+#include <BRepMesh_EdgeDiscret.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <OSD_Parallel.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#ifdef DEBUG_HEALER
+#include <BRepBuilderAPI_MakePolygon.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Builder.hxx>
+#include <TopoDS_Compound.hxx>
+#endif
+
+namespace
+{
+  //! Decreases deflection of the given edge and tries to update discretization.
+  class EdgeAmplifier
+  {
+  public:
+    //! Constructor.
+    EdgeAmplifier(const IMeshTools_Parameters& theParameters)
+      : myParameters(theParameters)
+    {
+    }
+
+    //! Main operator.
+    void operator()(const IMeshData::IEdgePtr& theDEdge) const
+    {
+      const IMeshData::IEdgeHandle& aDEdge = theDEdge.lock();
+      aDEdge->Clear(Standard_True);
+      aDEdge->SetDeflection(Max(aDEdge->GetDeflection() / 3., Precision::Confusion()));
+
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+      const IMeshData::IFaceHandle&   aDFace = aPCurve->GetFace().lock();
+      Handle(IMeshTools_CurveTessellator) aTessellator =
+        BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+          aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
+
+      BRepMesh_EdgeDiscret::Tessellate3d(aDEdge, aTessellator, Standard_False);
+      BRepMesh_EdgeDiscret::Tessellate2d(aDEdge, Standard_False);
+    }
+
+  private:
+
+    EdgeAmplifier (const EdgeAmplifier& theOther);
+
+    void operator=(const EdgeAmplifier& theOther);
+
+  private:
+    const IMeshTools_Parameters& myParameters;
+  };
+
+  //! Returns True if some of two vertcies is same with reference one.
+  inline Standard_Boolean isSameWithSomeOf(
+    const TopoDS_Vertex& theRefVertex,
+    const TopoDS_Vertex& theVertex1,
+    const TopoDS_Vertex& theVertex2)
+  {
+    return (theRefVertex.IsSame(theVertex1) ||
+            theRefVertex.IsSame(theVertex2));
+  }
+
+  //! Returns True if some of two vertcies is within tolerance of reference one.
+  inline Standard_Boolean isInToleranceWithSomeOf(
+    const gp_Pnt& theRefPoint,
+    const gp_Pnt& thePoint1,
+    const gp_Pnt& thePoint2,
+    const Standard_Real theTol)
+  {
+    const Standard_Real aSqTol = theTol * theTol;
+    return (theRefPoint.SquareDistance(thePoint1) < aSqTol ||
+            theRefPoint.SquareDistance(thePoint2) < aSqTol);
+  }
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelHealer::BRepMesh_ModelHealer()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelHealer::~BRepMesh_ModelHealer()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::Perform(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   theParameters)
+{
+  myModel      = theModel;
+  myParameters = theParameters;
+  if (myModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  myFaceIntersectingEdges = new IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs;
+  for (Standard_Integer aFaceIt = 0; aFaceIt < myModel->FacesNb(); ++aFaceIt)
+  {
+    myFaceIntersectingEdges->Bind(myModel->GetFace(aFaceIt), Handle(IMeshData::MapOfIEdgePtr)());
+  }
+
+  // TODO: Here we can process edges in order to remove close discrete points.
+  OSD_Parallel::For(0, myModel->FacesNb(), *this, !isParallel());
+  amplifyEdges();
+
+  IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges);
+  for (; aFaceIt.More(); aFaceIt.Next())
+  {
+    if (!aFaceIt.Value().IsNull())
+    {
+      const IMeshData::IFaceHandle& aDFace = aFaceIt.Key().lock();
+      aDFace->SetStatus(IMeshData_SelfIntersectingWire);
+      aDFace->SetStatus(IMeshData_Failure);
+    }
+  }
+
+  myFaceIntersectingEdges.Nullify();
+  myModel.Nullify(); // Do not hold link to model.
+  return Standard_True;
+}
+
+//=======================================================================
+// Function: amplifyEdges
+// Purpose : 
+//=======================================================================
+void BRepMesh_ModelHealer::amplifyEdges()
+{
+  Handle(NCollection_IncAllocator) aTmpAlloc =
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+  Standard_Integer aAmpIt = 0;
+  const Standard_Real aIterNb = 5;
+  IMeshData::MapOfIEdgePtr aEdgesToUpdate(1, aTmpAlloc);
+  while (aAmpIt++ < aIterNb && popEdgesToUpdate(aEdgesToUpdate))
+  {
+    // Try to update discretization by decreasing deflection of problematic edges.
+    OSD_Parallel::ForEach(aEdgesToUpdate.cbegin(), aEdgesToUpdate.cend(),
+                          EdgeAmplifier(myParameters),
+                          !(myParameters.InParallel && aEdgesToUpdate.Size() > 1));
+
+    IMeshData::MapOfIFacePtr aFacesToCheck(1, aTmpAlloc);
+    IMeshData::MapOfIEdgePtr::Iterator aEdgeIt(aEdgesToUpdate);
+    for (; aEdgeIt.More(); aEdgeIt.Next())
+    {
+      const IMeshData::IEdgeHandle& aDEdge = aEdgeIt.Value().lock();
+      for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt)
+      {
+        aFacesToCheck.Add(aDEdge->GetPCurve(aPCurveIt)->GetFace());
+      }
+    }
+
+    OSD_Parallel::ForEach(aFacesToCheck.cbegin(), aFacesToCheck.cend(),
+                          *this, !(myParameters.InParallel && aFacesToCheck.Size() > 1));
+
+    aEdgesToUpdate.Clear();
+    aTmpAlloc->Reset(Standard_False);
+  }
+}
+
+//=======================================================================
+// Function: popEdgesToUpdate
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate(
+  IMeshData::MapOfIEdgePtr& theEdgesToUpdate)
+{
+  IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges);
+  for (; aFaceIt.More(); aFaceIt.Next())
+  {
+    Handle(IMeshData::MapOfIEdgePtr)& aIntersections = aFaceIt.ChangeValue();
+    if (!aIntersections.IsNull())
+    {
+      theEdgesToUpdate.Unite(*aIntersections);
+      aIntersections.Nullify();
+    }
+  }
+
+  return !theEdgesToUpdate.IsEmpty();
+}
+
+//=======================================================================
+// Function: process
+// Purpose : 
+//=======================================================================
+void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
+{
+  Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace);
+  aIntersections.Nullify();
+
+  fixFaceBoundaries(theDFace);
+
+  if (!theDFace->IsSet(IMeshData_Failure))
+  {
+    BRepMesh_FaceChecker aChecker(theDFace, myParameters);
+    if (!aChecker.Perform())
+    {
+#ifdef DEBUG_HEALER
+      std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
+#endif
+      aIntersections = aChecker.GetIntersectingEdges();
+    }
+  }
+}
+
+//=======================================================================
+// Function: fixFaceBoundaries
+// Purpose : 
+//=======================================================================
+void BRepMesh_ModelHealer::fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const
+{
+#ifdef DEBUG_HEALER
+  TopoDS_Compound aComp;
+  BRep_Builder aBuilder;
+  aBuilder.MakeCompound(aComp);
+#endif
+
+  for (int aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
+  {
+    const IMeshData::IWireHandle& aDWire = theDFace->GetWire(aWireIt);
+    BRepMesh_Deflection::ComputeDeflection(aDWire, myParameters);
+    for (int aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+    {
+      const int aPrevEdgeIt = (aEdgeIt + aDWire->EdgesNb() - 1) % aDWire->EdgesNb();
+      const int aNextEdgeIt = (aEdgeIt + 1) % aDWire->EdgesNb();
+
+      const IMeshData::IEdgeHandle& aPrevEdge = aDWire->GetEdge(aPrevEdgeIt).lock();
+      const IMeshData::IEdgeHandle& aCurrEdge = aDWire->GetEdge(aEdgeIt).lock();
+      const IMeshData::IEdgeHandle& aNextEdge = aDWire->GetEdge(aNextEdgeIt).lock();
+
+      Standard_Boolean isConnected = !getCommonVertex(aCurrEdge, aNextEdge).IsNull() &&
+                                     !getCommonVertex(aPrevEdge, aCurrEdge).IsNull();
+
+      if (isConnected)
+      {
+        const IMeshData::IPCurveHandle& aPrevPCurve =
+          aPrevEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aPrevEdgeIt));
+
+        const IMeshData::IPCurveHandle& aCurrPCurve =
+          aCurrEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+        const IMeshData::IPCurveHandle& aNextPCurve =
+          aNextEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aNextEdgeIt));
+
+        isConnected = connectClosestPoints(aPrevPCurve, aCurrPCurve, aNextPCurve);
+
+#ifdef DEBUG_HEALER
+        BRepBuilderAPI_MakePolygon aPoly;
+        for (int i = 0; i < aCurrPCurve->ParametersNb(); ++i)
+        {
+          const gp_Pnt2d& aPnt = aCurrPCurve->GetPoint(i);
+          aPoly.Add(gp_Pnt(aPnt.X(), aPnt.Y(), 0.));
+        }
+
+        if (aPoly.IsDone())
+        {
+          aBuilder.Add(aComp, aPoly.Shape());
+        }
+        TCollection_AsciiString aName("face_discr.brep");
+        BRepTools::Write(aComp, aName.ToCString());
+#endif
+      }
+
+      if (!isConnected || aCurrEdge->IsSet(IMeshData_Outdated))
+      {
+        // We have to clean face from triangulation.
+        theDFace->SetStatus(IMeshData_Outdated);
+
+        if (!isConnected)
+        {
+          // Just mark wire as open, but continue fixing other inconsistencies
+          // in hope that this data could be suitable to build mesh somehow.
+          aDWire->SetStatus(IMeshData_OpenWire);
+        }
+      }
+    }
+  }
+
+#ifdef DEBUG_HEALER
+  TCollection_AsciiString aName    ("face_discr.brep");
+  TCollection_AsciiString aFaceName("face_geom.brep");
+  BRepTools::Write(aComp, aName.ToCString());
+  BRepTools::Write(theDFace->GetFace(), aFaceName.ToCString());
+#endif
+
+  BRepMesh_Deflection::ComputeDeflection(theDFace, myParameters);
+}
+
+//=======================================================================
+// Function: hasCommonVertex
+// Purpose : 
+//=======================================================================
+TopoDS_Vertex BRepMesh_ModelHealer::getCommonVertex(
+  const IMeshData::IEdgeHandle& theEdge1,
+  const IMeshData::IEdgeHandle& theEdge2) const
+{
+  TopoDS_Vertex aVertex1_1, aVertex1_2;
+  TopExp::Vertices(theEdge1->GetEdge(), aVertex1_1, aVertex1_2);
+  if (theEdge1->GetEdge().IsSame(theEdge2->GetEdge()))
+  {
+    return aVertex1_1.IsSame(aVertex1_2) ? aVertex1_1 : TopoDS_Vertex();
+  }
+
+  TopoDS_Vertex aVertex2_1, aVertex2_2;
+  TopExp::Vertices(theEdge2->GetEdge(), aVertex2_1, aVertex2_2);
+
+  if (isSameWithSomeOf(aVertex1_1, aVertex2_1, aVertex2_2))
+  {
+    return aVertex1_1;
+  }
+  else if (isSameWithSomeOf(aVertex1_2, aVertex2_1, aVertex2_2))
+  {
+    return aVertex1_2;
+  }
+
+  const gp_Pnt        aPnt1_1 = BRep_Tool::Pnt(aVertex1_1);
+  const gp_Pnt        aPnt1_2 = BRep_Tool::Pnt(aVertex1_2);
+  const Standard_Real aTol1_1 = BRep_Tool::Tolerance(aVertex1_1);
+  const Standard_Real aTol1_2 = BRep_Tool::Tolerance(aVertex1_2);
+
+  const gp_Pnt        aPnt2_1 = BRep_Tool::Pnt(aVertex2_1);
+  const gp_Pnt        aPnt2_2 = BRep_Tool::Pnt(aVertex2_2);
+  const Standard_Real aTol2_1 = BRep_Tool::Tolerance(aVertex2_1);
+  const Standard_Real aTol2_2 = BRep_Tool::Tolerance(aVertex2_2);
+
+  if (isInToleranceWithSomeOf(aPnt1_1, aPnt2_1, aPnt2_2, aTol1_1 + Max(aTol2_1, aTol2_2)))
+  {
+    return aVertex1_1;
+  }
+  else if (isInToleranceWithSomeOf(aPnt1_2, aPnt2_1, aPnt2_2, aTol1_2 + Max(aTol2_1, aTol2_2)))
+  {
+    return aVertex1_2;
+  }
+
+  return TopoDS_Vertex();
+}
+
+//=======================================================================
+// Function: connectClosestPoints
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::connectClosestPoints(
+  const IMeshData::IPCurveHandle& thePrevDEdge,
+  const IMeshData::IPCurveHandle& theCurrDEdge,
+  const IMeshData::IPCurveHandle& theNextDEdge) const
+{
+  if (thePrevDEdge->IsInternal() ||
+      theCurrDEdge->IsInternal() ||
+      theNextDEdge->IsInternal())
+  {
+    return Standard_True;
+  }
+
+  gp_Pnt2d& aPrevFirstUV = thePrevDEdge->GetPoint(0);
+  gp_Pnt2d& aPrevLastUV  = thePrevDEdge->GetPoint(thePrevDEdge->ParametersNb() - 1);
+
+  if (thePrevDEdge == theCurrDEdge)
+  {
+    // Wire consists of a single edge.
+    aPrevFirstUV = aPrevLastUV;
+    return Standard_True;
+  }
+
+  gp_Pnt2d& aCurrFirstUV = theCurrDEdge->GetPoint(0);
+  gp_Pnt2d& aCurrLastUV  = theCurrDEdge->GetPoint(theCurrDEdge->ParametersNb() - 1);
+
+  gp_Pnt2d *aPrevUV = NULL, *aCurrPrevUV = NULL;
+  const Standard_Real aPrevSqDist = closestPoints(aPrevFirstUV, aPrevLastUV,
+                                                  aCurrFirstUV, aCurrLastUV,
+                                                  aPrevUV, aCurrPrevUV);
+
+  gp_Pnt2d *aNextUV = NULL, *aCurrNextUV = NULL;
+  if (thePrevDEdge == theNextDEdge)
+  {
+    // Wire consists of two edges. Connect both ends.
+    aNextUV     = (aPrevUV     == &aPrevFirstUV) ? &aPrevLastUV : &aPrevFirstUV;
+    aCurrNextUV = (aCurrPrevUV == &aCurrFirstUV) ? &aCurrLastUV : &aCurrFirstUV;
+
+    *aNextUV = *aCurrNextUV;
+    *aPrevUV = *aCurrPrevUV;
+    return Standard_True;
+  }
+
+  gp_Pnt2d& aNextFirstUV = theNextDEdge->GetPoint(0);
+  gp_Pnt2d& aNextLastUV  = theNextDEdge->GetPoint(theNextDEdge->ParametersNb() - 1);
+
+  const Standard_Real aNextSqDist = closestPoints(aNextFirstUV, aNextLastUV,
+                                                  aCurrFirstUV, aCurrLastUV,
+                                                  aNextUV, aCurrNextUV);
+
+#ifdef DEBUG_HEALER
+  std::cout << "PrevSqDist = " << aPrevSqDist << std::endl;
+  std::cout << "NextSqDist = " << aNextSqDist << std::endl;
+#endif
+
+  // Connect closest points first. This can help to identify 
+  // which ends should be connected in case of gap.
+  if (aPrevSqDist - aNextSqDist > gp::Resolution())
+  {
+    adjustSamePoints(aCurrNextUV, aNextUV, aCurrPrevUV, aPrevUV, aCurrFirstUV, aCurrLastUV, aPrevFirstUV, aPrevLastUV);
+  }
+  else
+  {
+    adjustSamePoints(aCurrPrevUV, aPrevUV, aCurrNextUV, aNextUV, aCurrFirstUV, aCurrLastUV, aNextFirstUV, aNextLastUV);
+  }
+
+  return Standard_True;
+}
diff --git a/src/BRepMesh/BRepMesh_ModelHealer.hxx b/src/BRepMesh/BRepMesh_ModelHealer.hxx
new file mode 100644 (file)
index 0000000..e6612b1
--- /dev/null
@@ -0,0 +1,183 @@
+// Created on: 2016-06-23
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ModelHealer_HeaderFile
+#define _BRepMesh_ModelHealer_HeaderFile
+
+#include <IMeshTools_ModelAlgo.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+#include <IMeshData_Model.hxx>
+#include <TopoDS_Vertex.hxx>
+
+//! Class implements functionality of model healer tool.
+//! Iterates over model's faces and checks consistency of their wires, 
+//! i.e.whether wires are closed and do not contain self - intersections.
+//! In case if wire contains disconnected parts, ends of adjacent edges 
+//! forming the gaps are connected in parametric space forcibly. The notion 
+//! of this operation is to create correct discrete model defined relatively 
+//! parametric space of target face taking into account connectivity and 
+//! tolerances of 3D space only. This means that there are no specific 
+//! computations are made for the sake of determination of U and V tolerance.
+//! Registers intersections on edges forming the face\92s shape and tries to 
+//! amplify discrete represenation by decreasing of deflection for the target edge. 
+//! Checks can be performed in parallel mode.
+class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ModelHealer();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ModelHealer();
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform(
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+  //! Functor API to discretize the given edge.
+  inline void operator() (const Standard_Integer theEdgeIndex) const {
+    process(theEdgeIndex);
+  }
+
+  //! Functor API to discretize the given edge.
+  inline void operator() (const IMeshData::IFacePtr& theDFace) const {
+    process(theDFace.lock());
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
+
+private:
+
+  //! Checks existing discretization of the face and updates data model.
+  inline void process(const Standard_Integer theFaceIndex) const
+  {
+    const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+    process(aDFace);
+  }
+
+  //! Checks existing discretization of the face and updates data model.
+  void process(const IMeshData::IFaceHandle& theDFace) const;
+
+  //! Amplifies discretization of edges in case if self-intersection problem has been found.
+  void amplifyEdges();
+
+  //! Returns common vertex of two edges or null ptr in case if there is no such vertex.
+  TopoDS_Vertex getCommonVertex(
+    const IMeshData::IEdgeHandle& theEdge1,
+    const IMeshData::IEdgeHandle& theEdge2) const;
+
+  //! Connects pcurves of previous and current edge on the specified face 
+  //! according to topological connectivity. Uses next edge in order to
+  //! identify closest point in case of signle vertex shared between both
+  //! ends of edge (degenerative edge)
+  Standard_Boolean connectClosestPoints(
+    const IMeshData::IPCurveHandle& thePrevDEdge,
+    const IMeshData::IPCurveHandle& theCurrDEdge,
+    const IMeshData::IPCurveHandle& theNextDEdge) const;
+
+  //! Chooses the most closest point to reference one from the given pair.
+  //! Returns square distance between reference point and closest one as 
+  //! well as pointer to closest point.
+  inline Standard_Real closestPoint(
+    gp_Pnt2d&  theRefPnt,
+    gp_Pnt2d&  theFristPnt,
+    gp_Pnt2d&  theSecondPnt,
+    gp_Pnt2d*& theClosestPnt) const
+  {
+    // Find the most closest end-points.
+    const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
+    const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
+    if (aSqDist1 < aSqDist2)
+    {
+      theClosestPnt = &theFristPnt;
+      return aSqDist1;
+    }
+
+    theClosestPnt = &theSecondPnt;
+    return aSqDist2;
+  }
+
+  //! Chooses the most closest points among the given to reference one from the given pair.
+  //! Returns square distance between reference point and closest one as 
+  //! well as pointer to closest point.
+  inline Standard_Real closestPoints(
+    gp_Pnt2d&  theFirstPnt1,
+    gp_Pnt2d&  theSecondPnt1,
+    gp_Pnt2d&  theFirstPnt2,
+    gp_Pnt2d&  theSecondPnt2,
+    gp_Pnt2d*& theClosestPnt1,
+    gp_Pnt2d*& theClosestPnt2) const
+  {
+    gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL;
+    const Standard_Real aSqDist1 = closestPoint(theFirstPnt1,  theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
+    const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
+    if (aSqDist1 - aSqDist2 < gp::Resolution())
+    {
+      theClosestPnt1 = &theFirstPnt1;
+      theClosestPnt2 = aCurrPrevUV1;
+      return aSqDist1;
+    }
+
+    theClosestPnt1 = &theSecondPnt1;
+    theClosestPnt2 = aCurrPrevUV2;
+    return aSqDist2;
+  }
+
+  //! Adjusts the given pair of points supposed to be the same.
+  //! In addition, adjusts another end-point of an edge in order
+  //! to perform correct matching in case of gap.
+  inline void adjustSamePoints(
+    gp_Pnt2d*& theMajorSamePnt1,
+    gp_Pnt2d*& theMinorSamePnt1,
+    gp_Pnt2d*& theMajorSamePnt2,
+    gp_Pnt2d*& theMinorSamePnt2,
+    gp_Pnt2d&  theMajorFirstPnt,
+    gp_Pnt2d&  theMajorLastPnt,
+    gp_Pnt2d&  theMinorFirstPnt,
+    gp_Pnt2d&  theMinorLastPnt) const
+  {
+    if (theMajorSamePnt2 == theMajorSamePnt1)
+    {
+      theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
+      closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
+    }
+
+    *theMajorSamePnt1 = *theMinorSamePnt1;
+    *theMajorSamePnt2 = *theMinorSamePnt2;
+  }
+
+  //! Connects ends of pcurves of face's wires according to topological coherency.
+  void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
+
+  //! Returns True if check can be done in parallel.
+  inline Standard_Boolean isParallel() const
+  {
+    return (myParameters.InParallel && myModel->FacesNb() > 1);
+  }
+
+  //! Collects unique edges to be updated from face map. Clears data stored in face map.
+  Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
+
+private:
+
+  Handle(IMeshData_Model)                           myModel;
+  IMeshTools_Parameters                             myParameters;
+  Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs)  myFaceIntersectingEdges;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_ModelPostProcessor.cxx b/src/BRepMesh/BRepMesh_ModelPostProcessor.cxx
new file mode 100644 (file)
index 0000000..f7a9e93
--- /dev/null
@@ -0,0 +1,189 @@
+// Created on: 2016-07-04
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ModelPostProcessor.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <IMeshData_Model.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <OSD_Parallel.hxx>
+
+namespace
+{
+  //! Commits 3D polygons and polygons on triangulations for corresponding edges.
+  class PolygonCommitter
+  {
+  public:
+    //! Constructor
+    PolygonCommitter(const Handle(IMeshData_Model)& theModel)
+      : myModel(theModel)
+    {
+    }
+
+    //! Main functor.
+    void operator()(const Standard_Integer theEdgeIndex) const
+    {
+      const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge(theEdgeIndex);
+      if (aDEdge->IsFree())
+      {
+        if (!aDEdge->IsSet(IMeshData_Reused))
+        {
+          commitPolygon3D(aDEdge);
+        }
+      }
+      else
+      {
+        commitPolygons(aDEdge);
+      }
+    }
+
+  private:
+
+    //! Commits 3d polygon to topological edge
+    void commitPolygon3D(const IMeshData::IEdgeHandle& theDEdge) const
+    {
+      const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+
+      TColgp_Array1OfPnt   aNodes  (1, aCurve->ParametersNb());
+      TColStd_Array1OfReal aUVNodes(1, aCurve->ParametersNb());
+      for (Standard_Integer i = 1; i <= aCurve->ParametersNb(); ++i)
+      {
+        aNodes  (i) = aCurve->GetPoint    (i - 1);
+        aUVNodes(i) = aCurve->GetParameter(i - 1);
+      }
+
+      Handle(Poly_Polygon3D) aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes);
+      aPoly3D->Deflection(theDEdge->GetDeflection());
+
+      BRepMesh_ShapeTool::UpdateEdge(theDEdge->GetEdge(), aPoly3D);
+    }
+
+    //! Commits all polygons on triangulations correspondent to the given edge.
+    void commitPolygons(const IMeshData::IEdgeHandle& theDEdge) const
+    {
+      // Collect pcurves associated with the given edge on the specific surface.
+      IMeshData::IDMapOfIFacePtrsListOfIPCurves aMapOfPCurves;
+      for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+      {
+        const IMeshData::IPCurveHandle& aPCurve   = theDEdge->GetPCurve(aPCurveIt);
+        const IMeshData::IFacePtr&      aDFacePtr = aPCurve->GetFace();
+        const IMeshData::IFaceHandle&   aDFace    = aDFacePtr.lock();
+        if (aDFace->IsSet(IMeshData_Failure) ||
+            aDFace->IsSet(IMeshData_Reused))
+        {
+          continue;
+        }
+
+        if (!aMapOfPCurves.Contains(aDFacePtr))
+        {
+          aMapOfPCurves.Add(aDFacePtr, IMeshData::ListOfIPCurves());
+        }
+
+        IMeshData::ListOfIPCurves& aPCurves = aMapOfPCurves.ChangeFromKey(aDFacePtr);
+        aPCurves.Append(aPCurve);
+      }
+
+      // Commit polygons related to separate face.
+      const TopoDS_Edge& aEdge = theDEdge->GetEdge();
+      IMeshData::IDMapOfIFacePtrsListOfIPCurves::Iterator aPolygonIt(aMapOfPCurves);
+      for (; aPolygonIt.More(); aPolygonIt.Next())
+      {
+        const TopoDS_Face& aFace = aPolygonIt.Key().lock()->GetFace();
+
+        TopLoc_Location aLoc;
+        const Handle(Poly_Triangulation)& aTriangulation =
+          BRep_Tool::Triangulation(aFace, aLoc);
+
+        if (!aTriangulation.IsNull())
+        {
+          const IMeshData::ListOfIPCurves& aPCurves = aPolygonIt.Value();
+          if (aPCurves.Size() == 2)
+          {
+            BRepMesh_ShapeTool::UpdateEdge(
+              aEdge,
+              collectPolygon(aPCurves.First(), theDEdge->GetDeflection()),
+              collectPolygon(aPCurves.Last (), theDEdge->GetDeflection()),
+              aTriangulation, aLoc);
+          }
+          else
+          {
+            BRepMesh_ShapeTool::UpdateEdge(
+              aEdge,
+              collectPolygon(aPCurves.First(), theDEdge->GetDeflection()),
+              aTriangulation, aLoc);
+          }
+        }
+      }
+    }
+
+    //! Collects polygonal data for the given pcurve
+    Handle(Poly_PolygonOnTriangulation) collectPolygon(
+      const IMeshData::IPCurveHandle& thePCurve,
+      const Standard_Real             theDeflection) const
+    {
+      TColStd_Array1OfInteger aNodes (1, thePCurve->ParametersNb());
+      TColStd_Array1OfReal    aParams(1, thePCurve->ParametersNb());
+      for (Standard_Integer i = 1; i <= thePCurve->ParametersNb(); ++i)
+      {
+        aNodes (i) = thePCurve->GetIndex    (i - 1);
+        aParams(i) = thePCurve->GetParameter(i - 1);
+      }
+
+      Handle(Poly_PolygonOnTriangulation) aPolygon = 
+        new Poly_PolygonOnTriangulation(aNodes, aParams);
+
+      aPolygon->Deflection(theDeflection);
+      return aPolygon;
+    }
+
+  private:
+
+    Handle(IMeshData_Model) myModel;
+  };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPostProcessor::BRepMesh_ModelPostProcessor()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelPostProcessor::Perform(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   /*theParameters*/)
+{
+  if (theModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  // TODO: Force single threaded solution due to data races on edges sharing the same TShape
+  OSD_Parallel::For(0, theModel->EdgesNb(), PolygonCommitter(theModel), Standard_True/*!theParameters.InParallel*/);
+  return Standard_True;
+}
diff --git a/src/BRepMesh/BRepMesh_ModelPostProcessor.hxx b/src/BRepMesh/BRepMesh_ModelPostProcessor.hxx
new file mode 100644 (file)
index 0000000..d475369
--- /dev/null
@@ -0,0 +1,43 @@
+// Created on: 2016-07-22
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ModelPostProcessor_HeaderFile
+#define _BRepMesh_ModelPostProcessor_HeaderFile
+
+#include <IMeshTools_ModelAlgo.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Class implements functionality of model post-processing tool.
+//! Stores polygons on triangulations to TopoDS_Edge.
+class BRepMesh_ModelPostProcessor : public IMeshTools_ModelAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ModelPostProcessor();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor();
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform(
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx b/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx
new file mode 100644 (file)
index 0000000..e963e3d
--- /dev/null
@@ -0,0 +1,172 @@
+// Created on: 2016-07-04
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ModelPreProcessor.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <BRep_Tool.hxx>
+#include <IMeshData_Model.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <OSD_Parallel.hxx>
+
+namespace
+{
+  //! Checks consistency of triangulation stored in topological face.
+  class TriangulationConsistency
+  {
+  public:
+    //! Constructor
+    TriangulationConsistency(const Handle(IMeshData_Model)& theModel)
+      : myModel (theModel)
+    {
+    }
+
+    //! Main functor.
+    void operator()(const Standard_Integer theFaceIndex) const
+    {
+      const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+      if (aDFace->IsSet(IMeshData_Outdated))
+      {
+        return;
+      }
+
+      TopLoc_Location aLoc;
+      const Handle(Poly_Triangulation)& aTriangulation =
+        BRep_Tool::Triangulation(aDFace->GetFace(), aLoc);
+
+      if (!aTriangulation.IsNull())
+      {
+        Standard_Boolean isTriangulationConsistent = Standard_False;
+        if (aTriangulation->Deflection() < 1.1 * aDFace->GetDeflection())
+        {
+          // #25080: check that indices of links forming triangles are in range.
+          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 aNode[3];
+            aTriangle.Get(aNode[0], aNode[1], aNode[2]);
+            for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
+            {
+              isTriangulationConsistent = (aNode[j] >= 1 && aNode[j] <= aNodesNb);
+            }
+          }
+        }
+
+        if (isTriangulationConsistent)
+        {
+          aDFace->SetStatus(IMeshData_Reused);
+          aDFace->SetDeflection(aTriangulation->Deflection());
+        }
+        else
+        {
+          aDFace->SetStatus(IMeshData_Outdated);
+        }
+      }
+    }
+
+  private:
+
+    Handle(IMeshData_Model) myModel;
+  };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPreProcessor::BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelPreProcessor::Perform(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   theParameters)
+{
+  if (theModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  OSD_Parallel::For(0, theModel->FacesNb(), TriangulationConsistency(theModel), !theParameters.InParallel);
+
+  // Clean edges and faces from outdated polygons.
+  Handle(NCollection_IncAllocator) aTmpAlloc(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));
+  NCollection_Map<IMeshData_Face*> aUsedFaces(1, aTmpAlloc);
+  for (Standard_Integer aEdgeIt = 0; aEdgeIt < theModel->EdgesNb(); ++aEdgeIt)
+  {
+    const IMeshData::IEdgeHandle& aDEdge = theModel->GetEdge(aEdgeIt);
+    if (aDEdge->IsFree())
+    {
+      if (aDEdge->IsSet(IMeshData_Outdated))
+      {
+        TopLoc_Location aLoc;
+        BRep_Tool::Polygon3D(aDEdge->GetEdge(), aLoc);
+        BRepMesh_ShapeTool::NullifyEdge(aDEdge->GetEdge(), aLoc);
+      }
+
+      continue;
+    }
+    
+    for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt)
+    {
+      // Find adjacent outdated face.
+      const IMeshData::IFaceHandle& aDFace = aDEdge->GetPCurve(aPCurveIt)->GetFace().lock();
+      if (!aUsedFaces.Contains(aDFace.get()))
+      {
+        aUsedFaces.Add(aDFace.get());
+        if (aDFace->IsSet(IMeshData_Outdated))
+        {
+          TopLoc_Location aLoc;
+          const Handle(Poly_Triangulation)& aTriangulation =
+            BRep_Tool::Triangulation(aDFace->GetFace(), aLoc);
+
+          // Clean all edges of oudated face.
+          for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+          {
+            const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
+            for (Standard_Integer aWireEdgeIt = 0; aWireEdgeIt < aDWire->EdgesNb(); ++aWireEdgeIt)
+            {
+              const IMeshData::IEdgeHandle& aTmpDEdge = aDWire->GetEdge(aWireEdgeIt).lock();
+              BRepMesh_ShapeTool::NullifyEdge(aTmpDEdge->GetEdge(), aTriangulation, aLoc);
+            }
+          }
+
+          BRepMesh_ShapeTool::NullifyFace(aDFace->GetFace());
+        }
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
diff --git a/src/BRepMesh/BRepMesh_ModelPreProcessor.hxx b/src/BRepMesh/BRepMesh_ModelPreProcessor.hxx
new file mode 100644 (file)
index 0000000..213d8f8
--- /dev/null
@@ -0,0 +1,44 @@
+// Created on: 2016-07-04
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ModelPreProcessor_HeaderFile
+#define _BRepMesh_ModelPreProcessor_HeaderFile
+
+#include <IMeshTools_ModelAlgo.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Class implements functionality of model pre-processing tool.
+//! Nullifies existing polygonal data in case if model elements
+//! have IMeshData_Outdated status.
+class BRepMesh_ModelPreProcessor : public IMeshTools_ModelAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ModelPreProcessor();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor();
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform(
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..e3e0d3d
--- /dev/null
@@ -0,0 +1,476 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_NURBSRangeSplitter.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <GeomAbs_IsoType.hxx>
+#include <BRepMesh_GeomTool.hxx>
+#include <NCollection_Handle.hxx>
+#include <algorithm>
+
+namespace
+{
+  class AnalyticalFilter
+  {
+  public:
+    //! Constructor.
+    AnalyticalFilter(
+      const IMeshData::IFaceHandle&             theDFace,
+      const GeomAbs_IsoType                     theIsoType,
+      const Handle(IMeshData::SequenceOfReal)&  theParams,
+      const Handle(IMeshData::SequenceOfReal)&  theControlParams,
+      const Handle(IMeshData::MapOfReal)&       theParamsForbiddenToRemove,
+      const Handle(IMeshData::MapOfReal)&       theControlParamsForbiddenToRemove)
+      : myDFace(theDFace),
+        mySurface(myDFace->GetSurface()->ChangeSurface().Surface().Surface()),
+        myIsoU(theIsoType == GeomAbs_IsoU),
+        myParams(theParams),
+        myControlParams(theControlParams),
+        myParamsForbiddenToRemove(theParamsForbiddenToRemove),
+        myControlParamsForbiddenToRemove(theControlParamsForbiddenToRemove),
+        myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+        myControlParamsToRemove(new IMeshData::MapOfReal(1, myAllocator))
+    {
+    }
+
+    //! Returns map of parameters supposed to be removed.
+    const Handle(IMeshData::MapOfReal)& GetControlParametersToRemove(
+      const IMeshTools_Parameters& theParameters)
+    {
+      myParameters = theParameters;
+
+      Standard_Integer aStartIndex, aEndIndex;
+      if (myIsoU)
+      {
+        aStartIndex = 1;
+        aEndIndex = myParams->Length();
+      }
+      else
+      {
+        aStartIndex = 2;
+        aEndIndex = myParams->Length() - 1;
+      }
+
+      for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i)
+      {
+        myCurrParam = myParams->Value(i);
+        myIso = new GeomAdaptor_Curve(myIsoU ? mySurface->UIso(myCurrParam) : mySurface->VIso(myCurrParam));
+
+        myPrevControlParam = myControlParams->Value(1);
+        myIso->D1(myPrevControlParam, myPrevControlPnt, myPrevControlVec);
+        for (Standard_Integer j = 2; j <= myControlParams->Length();)
+        {
+          j += checkControlPointAndMoveOn(j);
+        }
+      }
+
+      return myControlParamsToRemove;
+    }
+
+  private:
+
+    //! Checks the given control point for deviation.
+    //! Returns number of steps to be used to move point iterator.
+    Standard_Integer checkControlPointAndMoveOn(const Standard_Integer theIndex)
+    {
+      Standard_Integer aMoveSteps = 0;
+      myCurrControlParam = myControlParams->Value(theIndex);
+      myIso->D1(myCurrControlParam, myCurrControlPnt, myCurrControlVec);
+
+      const Standard_Real aMidParam = 0.5 * (myPrevControlParam + myCurrControlParam);
+      const gp_Pnt aMidPnt = myIso->Value(aMidParam);
+
+      const Standard_Real aSqDist = BRepMesh_GeomTool::SquareDeflectionOfSegment(
+        myPrevControlPnt, myCurrControlPnt, aMidPnt);
+
+      const Standard_Real aSqMaxDeflection = myDFace->GetDeflection() * myDFace->GetDeflection();
+      if (aSqDist > aSqMaxDeflection &&
+          aSqDist > myParameters.MinSize * myParameters.MinSize)
+      {
+        // insertion 
+        myControlParams->InsertBefore(theIndex, aMidParam);
+      }
+      else
+      {
+        // Here we should leave at least 3 parameters as far as
+        // we must have at least one parameter related to surface
+        // internals in order to prevent movement of triangle body
+        // outside the surface in case of highly curved ones, e.g.
+        // BSpline springs.
+        if (aSqDist < aSqMaxDeflection &&
+            myControlParams->Length() > 3 &&
+            theIndex < myControlParams->Length())
+        {
+          // Remove too dense points
+          const Standard_Real aTmpParam = myControlParams->Value(theIndex + 1);
+          if (checkParameterForDeflectionAndUpdateCache(aTmpParam))
+          {
+            ++aMoveSteps;
+          }
+        }
+
+        myPrevControlParam = myCurrControlParam;
+        myPrevControlPnt   = myCurrControlPnt;
+        myPrevControlVec   = myCurrControlVec;
+
+        ++aMoveSteps;
+      }
+
+      return aMoveSteps;
+    }
+
+    //! Checks whether the given param suits specified deflection. Updates cache.
+    Standard_Boolean checkParameterForDeflectionAndUpdateCache(const Standard_Real theParam)
+    {
+      gp_Pnt aTmpPnt;
+      gp_Vec aTmpVec;
+      myIso->D1(theParam, aTmpPnt, aTmpVec);
+
+      const Standard_Real aTmpMidParam = 0.5 * (myPrevControlParam + theParam);
+      const gp_Pnt        aTmpMidPnt = myIso->Value(aTmpMidParam);
+
+      // Lets check next parameter.
+      // If it also fits deflection, we can remove previous parameter.
+      const Standard_Real aSqDist = BRepMesh_GeomTool::SquareDeflectionOfSegment(
+        myPrevControlPnt, aTmpPnt, aTmpMidPnt);
+
+      if (aSqDist < myDFace->GetDeflection() * myDFace->GetDeflection())
+      {
+        // Lets check parameters for angular deflection.
+        if (myPrevControlVec.SquareMagnitude() < gp::Resolution() ||
+            aTmpVec.SquareMagnitude()          < gp::Resolution() ||
+            myPrevControlVec.Angle(aTmpVec)    < myParameters.Angle)
+        {
+          // For current Iso line we can remove this parameter.
+          myControlParamsToRemove->Add(myCurrControlParam);
+          myCurrControlParam = theParam;
+          myCurrControlPnt   = aTmpPnt;
+          myCurrControlVec   = aTmpVec;
+          return Standard_True;
+        }
+        else
+        {
+          // We have found a place on the surface refusing 
+          // removement of this parameter.
+          myParamsForbiddenToRemove       ->Add(myCurrParam);
+          myControlParamsForbiddenToRemove->Add(myCurrControlParam);
+        }
+      }
+
+      return Standard_False;
+    }
+
+  private:
+
+    IMeshData::IFaceHandle                myDFace;
+    Handle(Geom_Surface)                  mySurface;
+    Standard_Boolean                      myIsoU;
+    Handle(IMeshData::SequenceOfReal)     myParams;
+    Handle(IMeshData::SequenceOfReal)     myControlParams;
+
+    Handle(IMeshData::MapOfReal)          myParamsForbiddenToRemove;
+    Handle(IMeshData::MapOfReal)          myControlParamsForbiddenToRemove;
+
+    Handle(NCollection_IncAllocator)      myAllocator;
+    Handle(IMeshData::MapOfReal)          myControlParamsToRemove;
+
+
+    IMeshTools_Parameters                 myParameters;
+    NCollection_Handle<GeomAdaptor_Curve> myIso;
+
+    Standard_Real                         myCurrParam;
+
+    Standard_Real                         myCurrControlParam;
+    gp_Pnt                                myCurrControlPnt;
+    gp_Vec                                myCurrControlVec;
+
+    Standard_Real                         myPrevControlParam;
+    gp_Pnt                                myPrevControlPnt;
+    gp_Vec                                myPrevControlVec;
+  };
+
+  //! Adds param to map if it fits specified range.
+  inline void addParam(
+    const Standard_Real&                           theParam,
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    IMeshData::IMapOfReal&                         theParams)
+  {
+    if (theParam < theRange.first ||
+        theParam > theRange.second)
+    {
+      return;
+    }
+
+    theParams.Add(theParam);
+  }
+
+  //! Initializes parameters map using CN intervals.
+  inline void initParamsFromIntervals(
+    const TColStd_Array1OfReal&                    theIntervals,
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    const Standard_Boolean                         isSplitIntervals,
+    IMeshData::IMapOfReal&                         theParams)
+  {
+    for (Standard_Integer i = theIntervals.Lower(); i <= theIntervals.Upper(); ++i)
+    {
+      const Standard_Real& aStartParam = theIntervals.Value(i);
+      addParam(aStartParam, theRange, theParams);
+
+      if (isSplitIntervals && i < theIntervals.Upper())
+      {
+        const Standard_Real aMidParam = (aStartParam + theIntervals.Value(i + 1)) / 2.;
+        addParam(aMidParam, theRange, theParams);
+      }
+    }
+  }
+}
+
+//=======================================================================
+// Function: AdjustRange
+// Purpose : 
+//=======================================================================
+void BRepMesh_NURBSRangeSplitter::AdjustRange()
+{
+  BRepMesh_DefaultRangeSplitter::AdjustRange();
+  mySurfaceType = GetSurface()->GetType();
+
+  if (mySurfaceType == GeomAbs_BezierSurface ||
+      mySurfaceType == GeomAbs_BSplineSurface)
+  {
+    const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+    const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+    if (mySurfaceType == GeomAbs_BezierSurface)
+    {
+      myIsValid = !(aRangeU.first  < -0.5 ||
+                    aRangeU.second >  1.5 ||
+                    aRangeV.first  < -0.5 ||
+                    aRangeV.second >  1.5);
+
+      if (!myIsValid)
+      {
+        return;
+      }
+    }
+  }
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_NURBSRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& theParameters) const
+{
+  initParameters();
+
+  const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+  const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+  const std::pair<Standard_Real, Standard_Real>& aDelta  = GetDelta ();
+
+  const Standard_Real                 aDefFace = GetDFace()->GetDeflection();
+  const Handle(BRepAdaptor_HSurface)& gFace    = GetSurface();
+  Handle(Geom_Surface)                aSurface = gFace->ChangeSurface().Surface().Surface();
+
+  const Handle(NCollection_IncAllocator) aTmpAlloc =
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+  const Handle(IMeshData::SequenceOfReal) aParams[2] = {
+    computeGrainAndFilterParameters(GetParametersU(), gFace->UResolution(aDefFace),
+      (aRangeU.second - aRangeU.first), aDelta.first,  theParameters, aTmpAlloc),
+
+    computeGrainAndFilterParameters(GetParametersV(), gFace->VResolution(aDefFace),
+      (aRangeV.second - aRangeV.first), aDelta.second, theParameters, aTmpAlloc)
+  };
+
+  // check intermediate isolines
+  Handle(IMeshData::MapOfReal) aFixedParams[2] = {
+    new IMeshData::MapOfReal(1, aTmpAlloc),
+    new IMeshData::MapOfReal(1, aTmpAlloc)
+  };
+
+  const Handle(IMeshData::MapOfReal) aParamsToRemove[2] = {
+    AnalyticalFilter(GetDFace(), GeomAbs_IsoV, aParams[1], aParams[0],
+      aFixedParams[1], aFixedParams[0]).GetControlParametersToRemove(theParameters),
+
+    AnalyticalFilter(GetDFace(), GeomAbs_IsoU, aParams[0], aParams[1],
+      aFixedParams[0], aFixedParams[1]).GetControlParametersToRemove(theParameters),
+  };
+
+  aParamsToRemove[0]->Subtract(*aFixedParams[0]);
+  aParamsToRemove[1]->Subtract(*aFixedParams[1]);
+
+  // insert nodes of the regular grid
+  Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));
+
+  // insert nodes of the regular grid
+  for (Standard_Integer i = 1; i <= aParams[0]->Length(); ++i)
+  {
+    const Standard_Real aParam1 = aParams[0]->Value(i);
+    if (aParamsToRemove[0]->Contains(aParam1))
+    {
+      continue;
+    }
+
+    for (Standard_Integer j = 1; j <= aParams[1]->Length(); ++j)
+    {
+      const Standard_Real aParam2 = aParams[1]->Value(j);
+      if (aParamsToRemove[1]->Contains(aParam2))
+      {
+        continue;
+      }
+
+      aNodes->Append(gp_Pnt2d(aParam1, aParam2));
+    }
+  }
+
+  return aNodes;
+}
+
+//=======================================================================
+// Function: initParameters
+// Purpose : 
+//=======================================================================
+void BRepMesh_NURBSRangeSplitter::initParameters() const
+{
+  const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
+
+  const GeomAbs_Shape aContinuity = GeomAbs_CN;
+  const std::pair<Standard_Integer, Standard_Integer> aIntervalsNb(
+    aSurface->NbUIntervals(aContinuity),
+    aSurface->NbVIntervals(aContinuity)
+  );
+
+  TColStd_Array1OfReal aIntervals[2] = {
+    TColStd_Array1OfReal(1, aIntervalsNb.first  + 1),
+    TColStd_Array1OfReal(1, aIntervalsNb.second + 1)
+  };
+
+  aSurface->UIntervals(aIntervals[0], aContinuity);
+  aSurface->VIntervals(aIntervals[1], aContinuity);
+
+  Standard_Boolean isSplitIntervals =
+    (aIntervalsNb.first > 1 || aIntervalsNb.second > 1);
+
+  if (!isSplitIntervals &&
+      (aSurface->GetType() == GeomAbs_BezierSurface ||
+       aSurface->GetType() == GeomAbs_BSplineSurface))
+  {
+    isSplitIntervals = (aSurface->NbUPoles() > 2 && aSurface->NbVPoles() > 2);
+  }
+
+  initParamsFromIntervals(aIntervals[0], GetRangeU(), isSplitIntervals,
+                          const_cast<IMeshData::IMapOfReal&>(GetParametersU()));
+
+  initParamsFromIntervals(aIntervals[1], GetRangeV(), isSplitIntervals,
+                          const_cast<IMeshData::IMapOfReal&>(GetParametersV()));
+}
+
+//=======================================================================
+//function : computeGrainAndFilterParameters
+//purpose  : 
+//=======================================================================
+Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::computeGrainAndFilterParameters(
+  const IMeshData::IMapOfReal&            theSourceParams,
+  const Standard_Real                     theTol2d,
+  const Standard_Real                     theRangeDiff,
+  const Standard_Real                     theDelta,
+  const IMeshTools_Parameters&            theParameters,
+  const Handle(NCollection_IncAllocator)& theAllocator) const
+{
+  // Sort and filter sequence of parameters
+  Standard_Real aMinDiff = Precision::PConfusion();
+  if (theDelta < 1.)
+  {
+    aMinDiff /= theDelta;
+  }
+
+  aMinDiff = Max(theParameters.MinSize, aMinDiff);
+
+  const Standard_Real aDiffMaxLim = 0.1 * theRangeDiff;
+  const Standard_Real aDiffMinLim = Max(0.005 * theRangeDiff, 2. * theTol2d);
+  const Standard_Real aDiff = Max(theParameters.MinSize, Min(aDiffMaxLim, aDiffMinLim));
+  return filterParameters(theSourceParams, aMinDiff, aDiff, theAllocator);
+}
+
+//=======================================================================
+//function : filterParameters
+//purpose  : 
+//=======================================================================
+Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::filterParameters(
+  const IMeshData::IMapOfReal&            theParams,
+  const Standard_Real                     theMinDist,
+  const Standard_Real                     theFilterDist,
+  const Handle(NCollection_IncAllocator)& theAllocator) const
+{
+  Handle(IMeshData::SequenceOfReal) aResult = new IMeshData::SequenceOfReal(theAllocator);
+
+  // Sort sequence of parameters
+  const Standard_Integer anInitLen = theParams.Extent();
+
+  TColStd_Array1OfReal aParamArray(1, anInitLen);
+  Standard_Integer j;
+  for (j = 1; j <= anInitLen; j++)
+    aParamArray(j) = theParams(j);
+
+  std::sort(aParamArray.begin(), aParamArray.end());
+
+  // mandatory pre-filtering using the first (minimal) filter value
+  Standard_Integer aParamLength = 1;
+  for (j = 2; j <= anInitLen; j++)
+  {
+    if ((aParamArray(j) - aParamArray(aParamLength)) > theMinDist)
+    {
+      if (++aParamLength < j)
+        aParamArray(aParamLength) = aParamArray(j);
+    }
+  }
+
+  //perform filtering on series
+  Standard_Real aLastAdded, aLastCandidate;
+  Standard_Boolean isCandidateDefined = Standard_False;
+  aLastAdded = aParamArray(1);
+  aLastCandidate = aLastAdded;
+  aResult->Append(aLastAdded);
+
+  for (j = 2; j < aParamLength; j++)
+  {
+    Standard_Real aVal = aParamArray(j);
+    if (aVal - aLastAdded > theFilterDist)
+    {
+      //adds the parameter
+      if (isCandidateDefined)
+      {
+        aLastAdded = aLastCandidate;
+        isCandidateDefined = Standard_False;
+        j--;
+      }
+      else
+      {
+        aLastAdded = aVal;
+      }
+      aResult->Append(aLastAdded);
+      continue;
+    }
+
+    aLastCandidate = aVal;
+    isCandidateDefined = Standard_True;
+  }
+  aResult->Append(aParamArray(aParamLength));
+
+  return aResult;
+}
diff --git a/src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..f808e3b
--- /dev/null
@@ -0,0 +1,74 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_NURBSRangeSplitter_HeaderFile
+#define _BRepMesh_NURBSRangeSplitter_HeaderFile
+
+#include <BRepMesh_UVParamRangeSplitter.hxx>
+#include <IMeshData_Types.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending UV range splitter in order to generate
+//! internal nodes for NURBS surface.
+class BRepMesh_NURBSRangeSplitter : public BRepMesh_UVParamRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_NURBSRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_NURBSRangeSplitter()
+  {
+  }
+
+  //! Updates discrete range of surface according to its geometric range.
+  Standard_EXPORT virtual void AdjustRange() Standard_OVERRIDE;
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
+
+protected:
+
+  //! Initializes U and V parameters lists using CN continuity intervals.
+  Standard_EXPORT virtual void initParameters() const;
+
+private:
+
+  //! Computes parameters of filter and applies it to the source parameters.
+  Handle(IMeshData::SequenceOfReal) computeGrainAndFilterParameters(
+    const IMeshData::IMapOfReal&            theSourceParams,
+    const Standard_Real                     theTol2d,
+    const Standard_Real                     theRangeDiff,
+    const Standard_Real                     theDelta,
+    const IMeshTools_Parameters&            theParameters,
+    const Handle(NCollection_IncAllocator)& theAllocator) const;
+
+  //! Filters parameters in order to avoid too dence distribution.
+  Handle(IMeshData::SequenceOfReal) filterParameters(
+    const IMeshData::IMapOfReal&            theParams,
+    const Standard_Real                     theMinDist,
+    const Standard_Real                     theFilterDist,
+    const Handle(NCollection_IncAllocator)& theAllocator) const;
+
+private:
+
+  GeomAbs_SurfaceType mySurfaceType;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx b/src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..dce2103
--- /dev/null
@@ -0,0 +1,230 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_NodeInsertionMeshAlgo_HeaderFile
+#define _BRepMesh_NodeInsertionMeshAlgo_HeaderFile
+
+#include <BRepMesh_Classifier.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <BRepMesh_Vertex.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <BRepMesh_Delaun.hxx>
+
+//! Extends base meshing algo in order to enable possibility 
+//! of addition of free vertices into the mesh.
+template<class RangeSplitter, class BaseAlgo>
+class BRepMesh_NodeInsertionMeshAlgo : public BaseAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_NodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_NodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Performs processing of the given face.
+  Standard_EXPORT virtual void Perform(
+    const IMeshData::IFaceHandle& theDFace,
+    const IMeshTools_Parameters&  theParameters) Standard_OVERRIDE
+  {
+    myRangeSplitter.Reset(theDFace, theParameters);
+    myClassifier = new BRepMesh_Classifier;
+    BaseAlgo::Perform(theDFace, theParameters);
+    myClassifier.Nullify();
+  }
+
+protected:
+
+  typedef NCollection_Shared<NCollection_Sequence<const gp_Pnt2d*> > SequenceOfPnt2d;
+
+  //! Performs initialization of data structure using existing model data.
+  Standard_EXPORT virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
+  {
+    Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+    const IMeshData::IFaceHandle& aDFace = this->getDFace();
+    NCollection_Array1<Handle(SequenceOfPnt2d)> aWires(0, aDFace->WiresNb());
+    for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+    {
+      const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
+      if (aDWire->IsSet(IMeshData_SelfIntersectingWire) ||
+         (aDWire->IsSet(IMeshData_OpenWire) && aWireIt != 0))
+      {
+        continue;
+      }
+
+      aWires(aWireIt) = collectWirePoints(aDWire, aTmpAlloc);
+    }
+
+    myRangeSplitter.AdjustRange();
+    if (!myRangeSplitter.IsValid())
+    {
+      aDFace->SetStatus(IMeshData_Failure);
+      return Standard_False;
+    }
+
+    const std::pair<Standard_Real, Standard_Real>& aDelta = myRangeSplitter.GetDelta();
+    const std::pair<Standard_Real, Standard_Real>& aTolUV = myRangeSplitter.GetToleranceUV();
+    const Standard_Real uCellSize = 14.0 * aTolUV.first;
+    const Standard_Real vCellSize = 14.0 * aTolUV.second;
+
+    this->getStructure()->Data()->SetCellSize (uCellSize    / aDelta.first, vCellSize     / aDelta.second);
+    this->getStructure()->Data()->SetTolerance(aTolUV.first / aDelta.first, aTolUV.second / aDelta.second);
+
+    for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+    {
+      const Handle(SequenceOfPnt2d)& aWire = aWires(aWireIt);
+      if (!aWire.IsNull() && !aWire->IsEmpty())
+      {
+        myClassifier->RegisterWire(*aWire, aTolUV,
+                                   myRangeSplitter.GetRangeU(),
+                                   myRangeSplitter.GetRangeV());
+      }
+    }
+
+    if (this->getParameters().InternalVerticesMode)
+    {
+      insertInternalVertices();
+    }
+
+    return BaseAlgo::initDataStructure();
+  }
+
+  //! Adds the given 2d point to mesh data structure.
+  //! Returns index of node in the structure.
+  Standard_EXPORT virtual Standard_Integer addNodeToStructure(
+    const gp_Pnt2d&                thePoint,
+    const Standard_Integer         theLocation3d,
+    const BRepMesh_DegreeOfFreedom theMovability,
+    const Standard_Boolean         isForceAdd) Standard_OVERRIDE
+  {
+    return BaseAlgo::addNodeToStructure(
+      myRangeSplitter.Scale(thePoint, Standard_True),
+      theLocation3d, theMovability, isForceAdd);
+  }
+
+  //! Returns 2d point associated to the given vertex.
+  Standard_EXPORT virtual gp_Pnt2d getNodePoint2d(
+    const BRepMesh_Vertex& theVertex) const Standard_OVERRIDE
+  {
+    return myRangeSplitter.Scale(theVertex.Coord(), Standard_False);
+  }
+
+  //! Returns range splitter.
+  const RangeSplitter& getRangeSplitter() const
+  {
+    return myRangeSplitter;
+  }
+
+  //! Returns classifier.
+  const Handle(BRepMesh_Classifier)& getClassifier() const
+  {
+    return myClassifier;
+  }
+
+private:
+
+  //! Creates collection of points representing discrete wire.
+  Handle(SequenceOfPnt2d) collectWirePoints(
+    const IMeshData::IWireHandle&           theDWire,
+    const Handle(NCollection_IncAllocator)& theAllocator)
+  {
+    Handle(SequenceOfPnt2d) aWirePoints = new SequenceOfPnt2d(theAllocator);
+    for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
+    {
+      const IMeshData::IEdgeHandle&   aDEdge = theDWire->GetEdge(aEdgeIt).lock();
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+        this->getDFace(), theDWire->GetEdgeOrientation(aEdgeIt));
+
+      Standard_Integer aPointIt, aEndIndex, aInc;
+      if (aPCurve->IsForward())
+      {
+        aPointIt = 0;
+        aEndIndex = aPCurve->ParametersNb() - 1;
+        aInc = 1;
+      }
+      else
+      {
+        aPointIt = aPCurve->ParametersNb() - 1;
+        aEndIndex = 0;
+        aInc = -1;
+      }
+
+      for (; aPointIt != aEndIndex; aPointIt += aInc)
+      {
+        const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
+        aWirePoints->Append(&aPnt2d);
+        myRangeSplitter.AddPoint(aPnt2d);
+      }
+    }
+
+    return aWirePoints;
+  }
+
+  //! Iterates over internal vertices of a face and 
+  //! creates corresponding nodes in data structure.
+  void insertInternalVertices()
+  {
+    TopExp_Explorer aExplorer(this->getDFace()->GetFace(), TopAbs_VERTEX, TopAbs_EDGE);
+    for (; aExplorer.More(); aExplorer.Next())
+    {
+      const TopoDS_Vertex& aVertex = TopoDS::Vertex(aExplorer.Current());
+      if (aVertex.Orientation() != TopAbs_INTERNAL)
+      {
+        continue;
+      }
+
+      insertInternalVertex(aVertex);
+    }
+  }
+
+  //! Inserts the given vertex into mesh.
+  void insertInternalVertex(const TopoDS_Vertex& theVertex)
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+        gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, this->getDFace()->GetFace());
+      // check UV values for internal vertices
+      if (myClassifier->Perform(aPnt2d) != TopAbs_IN)
+        return;
+
+      this->registerNode(BRep_Tool::Pnt(theVertex), aPnt2d,
+                         BRepMesh_Fixed, Standard_False);
+    }
+    catch (Standard_Failure)
+    {
+    }
+  }
+
+private:
+
+  RangeSplitter               myRangeSplitter;
+  Handle(BRepMesh_Classifier) myClassifier;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ShapeExplorer.cxx b/src/BRepMesh/BRepMesh_ShapeExplorer.cxx
new file mode 100644 (file)
index 0000000..b606d61
--- /dev/null
@@ -0,0 +1,97 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ShapeExplorer.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <BRepLib.hxx>
+#include <BRep_Tool.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <Geom_Surface.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ShapeExplorer::BRepMesh_ShapeExplorer (
+  const TopoDS_Shape& theShape)
+  : IMeshTools_ShapeExplorer (theShape)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ShapeExplorer::~BRepMesh_ShapeExplorer ()
+{
+}
+
+//=======================================================================
+// Function: Accept
+// Purpose : 
+//=======================================================================
+void BRepMesh_ShapeExplorer::Accept (
+  const Handle (IMeshTools_ShapeVisitor)& theVisitor)
+{
+  // Explore all edges in shape - either free or related to some face.
+  TopTools_IndexedMapOfShape aEdges;
+  TopExp::MapShapes (GetShape (), TopAbs_EDGE, aEdges);
+
+  TopTools_IndexedMapOfShape::Iterator aEdgeIt (aEdges);
+  for (; aEdgeIt.More (); aEdgeIt.Next ())
+  {
+    const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Value ());
+    if (!BRep_Tool::IsGeometric(aEdge))
+    {
+      continue;
+    }
+
+    theVisitor->Visit (aEdge);
+  }
+
+  // Explore faces
+  TopTools_ListOfShape aFaceList;
+  BRepLib::ReverseSortFaces (GetShape (), aFaceList);
+  TopTools_MapOfShape aFaceMap;
+
+  // make array of faces suitable for processing (excluding faces without surface)
+  TopLoc_Location aDummyLoc;
+  const TopLoc_Location aEmptyLoc;
+  TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList);
+  for (; aFaceIter.More (); aFaceIter.Next ())
+  {
+    TopoDS_Shape aFaceNoLoc = aFaceIter.Value ();
+    aFaceNoLoc.Location (aEmptyLoc);
+    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;
+    }
+
+    // Store only forward faces in order to prevent inverse issue.
+    theVisitor->Visit (TopoDS::Face (aFace.Oriented (TopAbs_FORWARD)));
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_ShapeExplorer.hxx b/src/BRepMesh/BRepMesh_ShapeExplorer.hxx
new file mode 100644 (file)
index 0000000..351acaa
--- /dev/null
@@ -0,0 +1,41 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ShapeExplorer_HeaderFile
+#define _BRepMesh_ShapeExplorer_HeaderFile
+
+#include <IMeshTools_ShapeExplorer.hxx>
+#include <IMeshTools_ShapeVisitor.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Explores TopoDS_Shape for parts to be meshed - faces and free edges.
+class BRepMesh_ShapeExplorer : public IMeshTools_ShapeExplorer
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ShapeExplorer (const TopoDS_Shape& theShape);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ShapeExplorer ();
+
+  //! Explores shape for edges to be disretized and faces to be meshed (edges first).
+  //! All faces passed to visitor are forced to be forward.
+  Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeExplorer, IMeshTools_ShapeExplorer)
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_ShapeVisitor.cxx b/src/BRepMesh/BRepMesh_ShapeVisitor.cxx
new file mode 100644 (file)
index 0000000..07accb4
--- /dev/null
@@ -0,0 +1,148 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_ShapeVisitor.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopExp.hxx>
+#include <ShapeAnalysis.hxx>
+#include <TopExp_Explorer.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Face.hxx>
+#include <ShapeAnalysis_Wire.hxx>
+#include <ShapeAnalysis_WireOrder.hxx>
+#include <ShapeExtend_WireData.hxx>
+#include <Precision.hxx>
+#include <IMeshData_Status.hxx>
+#include <IMeshTools_Context.hxx>
+#include <BRepTools.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ShapeVisitor::BRepMesh_ShapeVisitor (const Handle (IMeshData_Model)& theModel)
+: myModel (theModel),
+  myDEdgeMap(1, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ShapeVisitor::~BRepMesh_ShapeVisitor ()
+{
+}
+
+//=======================================================================
+// Function: Visit (edge)
+// Purpose : 
+//=======================================================================
+void BRepMesh_ShapeVisitor::Visit(const TopoDS_Edge& theEdge)
+{
+  myModel->AddEdge(theEdge);
+  myDEdgeMap.Bind(theEdge, myModel->EdgesNb() - 1);
+}
+
+//=======================================================================
+// Function: Visit (face)
+// Purpose : 
+//=======================================================================
+void BRepMesh_ShapeVisitor::Visit (const TopoDS_Face& theFace)
+{
+  BRepTools::Update(theFace);
+  const IMeshData::IFaceHandle& aDFace = myModel->AddFace (theFace);
+
+  // Outer wire should always be the first in the model. 
+  TopoDS_Wire aOuterWire = ShapeAnalysis::OuterWire (theFace);
+  if (!addWire (aOuterWire, aDFace))
+  {
+    aDFace->SetStatus (IMeshData_Failure);
+    return;
+  }
+  
+  TopExp_Explorer aWireIt (theFace, TopAbs_WIRE);
+  for (; aWireIt.More (); aWireIt.Next ())
+  {
+    const TopoDS_Wire& aWire = TopoDS::Wire (aWireIt.Current ());
+    if (aWire.IsSame(aOuterWire))
+    {
+      continue;
+    }
+
+    if (!addWire (aWire, aDFace))
+    {
+      // If there is a failure on internal wire, just skip it.
+      // The most significant is an outer wire.
+      aDFace->SetStatus (IMeshData_UnorientedWire);
+    }
+  }
+}
+
+//=======================================================================
+// Function: addWire
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ShapeVisitor::addWire (
+  const TopoDS_Wire&            theWire,
+  const IMeshData::IFaceHandle& theDFace)
+{
+  if (theWire.IsNull())
+  {
+    return Standard_False;
+  }
+
+  Handle(ShapeExtend_WireData) aWireData = new ShapeExtend_WireData(theWire, Standard_True, Standard_False);
+  ShapeAnalysis_Wire aWireTool (aWireData, theDFace->GetFace (), Precision::Confusion ());
+
+  ShapeAnalysis_WireOrder aOrderTool;
+  aWireTool.CheckOrder (aOrderTool, Standard_True, Standard_False);
+  if (aWireTool.LastCheckStatus(ShapeExtend_FAIL))
+  {
+    return Standard_False;
+  }
+
+  if (aWireTool.LastCheckStatus(ShapeExtend_DONE3))
+  {
+    theDFace->SetStatus(IMeshData_UnorientedWire);
+  }
+
+  const Standard_Integer aEdgesNb = aOrderTool.NbEdges ();
+  if (aEdgesNb != aWireData->NbEdges())
+  {
+    return Standard_False;
+  }
+
+  const IMeshData::IWireHandle& aDWire = theDFace->AddWire (theWire, aEdgesNb);
+  for (Standard_Integer i = 1; i <= aEdgesNb; ++i)
+  {
+    const Standard_Integer aEdgeIndex = aOrderTool.Ordered (i);
+    const TopoDS_Edge& aEdge = aWireData->Edge (aEdgeIndex);
+    if (aEdge.Orientation() != TopAbs_EXTERNAL)
+    {
+      const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (myDEdgeMap.Find (aEdge));
+
+      aDEdge->AddPCurve (theDFace, aEdge.Orientation());
+      aDWire->AddEdge   (aDEdge,   aEdge.Orientation());
+    }
+  }
+
+  return Standard_True;
+}
diff --git a/src/BRepMesh/BRepMesh_ShapeVisitor.hxx b/src/BRepMesh/BRepMesh_ShapeVisitor.hxx
new file mode 100644 (file)
index 0000000..171f49c
--- /dev/null
@@ -0,0 +1,67 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_ShapeVisitor_HeaderFile
+#define _BRepMesh_ShapeVisitor_HeaderFile
+
+#include <IMeshTools_ShapeVisitor.hxx>
+#include <IMeshData_Model.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Types.hxx>
+
+class TopoDS_Face;
+class TopoDS_Edge;
+class TopoDS_Wire;
+class IMeshTools_Context;
+class IMeshData_Wire;
+
+//! Builds discrete model of a shape by adding faces and free edges.
+//! Computes deflection for corresponded shape and checks whether it
+//! fits existing polygonal representation. If not, cleans shape from
+//! outdated info.
+class BRepMesh_ShapeVisitor : public IMeshTools_ShapeVisitor
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_ShapeVisitor (const Handle (IMeshData_Model)& theModel);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_ShapeVisitor ();
+
+  //! Handles TopoDS_Face object.
+  Standard_EXPORT virtual void Visit (const TopoDS_Face& theFace) Standard_OVERRIDE;
+
+  //! Handles TopoDS_Edge object.
+  Standard_EXPORT virtual void Visit (const TopoDS_Edge& theEdge) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeVisitor, IMeshTools_ShapeVisitor)
+
+private:
+
+  //! Adds wire to face discrete model.
+  Standard_Boolean addWire (
+    const TopoDS_Wire&            theWire,
+    const IMeshData::IFaceHandle& theDFace);
+
+private:
+
+  Handle (IMeshData_Model)      myModel;
+  IMeshData::DMapOfShapeInteger myDEdgeMap;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx b/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..edd952c
--- /dev/null
@@ -0,0 +1,92 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_SphereRangeSplitter_HeaderFile
+#define _BRepMesh_SphereRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for spherical surface.
+class BRepMesh_SphereRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_SphereRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_SphereRangeSplitter()
+  {
+  }
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+  {
+    // Calculate parameters for iteration in V direction
+    Standard_Real aStep = 0.7 * GCPnts_TangentialDeflection::ArcAngularStep(
+      GetDFace()->GetSurface()->Sphere().Radius(), GetDFace()->GetDeflection(),
+      theParameters.Angle, theParameters.MinSize);
+
+    const std::pair<Standard_Real, Standard_Real>* aRange[2] = {
+      &GetRangeV(),
+      &GetRangeU()
+    };
+
+    std::pair<Standard_Real, Standard_Real> aStepAndOffset[2];
+    computeStep(*aRange[0], aStep, aStepAndOffset[0]);
+    computeStep(*aRange[1], aStep, aStepAndOffset[1]);
+
+    const Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+    Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+    const Standard_Real aHalfDu = aStepAndOffset[1].first * 0.5;
+    Standard_Boolean Shift = Standard_False;
+    Standard_Real aPasV = aRange[0]->first + aStepAndOffset[0].first;
+    for (; aPasV < aStepAndOffset[0].second; aPasV += aStepAndOffset[0].first)
+    {
+      Shift = !Shift;
+      const Standard_Real d = (Shift) ? aHalfDu : 0.;
+      Standard_Real aPasU = aRange[1]->first + d;
+      for (; aPasU < aStepAndOffset[1].second; aPasU += aStepAndOffset[1].first)
+      {
+        aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+      }
+    }
+
+    return aNodes;
+  }
+
+private:
+
+  //! Computes step for the given range.
+  inline void computeStep(
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    const Standard_Real                            theDefaultStep,
+    std::pair<Standard_Real, Standard_Real>&       theStepAndOffset) const
+  {
+    const Standard_Real aDiff = theRange.second - theRange.first;
+    theStepAndOffset.first  = aDiff / ((Standard_Integer) (aDiff / theDefaultStep) + 1);
+    theStepAndOffset.second = theRange.second - Precision::PConfusion();
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx b/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..5156f21
--- /dev/null
@@ -0,0 +1,228 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_TorusRangeSplitter_HeaderFile
+#define _BRepMesh_TorusRangeSplitter_HeaderFile
+
+#include <BRepMesh_UVParamRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending UV range splitter in order to generate
+//! internal nodes for NURBS surface.
+class BRepMesh_TorusRangeSplitter : public BRepMesh_UVParamRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_TorusRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_TorusRangeSplitter()
+  {
+  }
+
+  //! Returns list of nodes generated using surface data and specified parameters.
+  Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+    const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+  {
+    const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+    const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+    const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
+    const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
+
+    const gp_Torus aTorus = GetDFace()->GetSurface()->Torus();
+    const Standard_Real r = aTorus.MinorRadius();
+    const Standard_Real R = aTorus.MajorRadius();
+
+    const Standard_Real oldDv = GCPnts_TangentialDeflection::ArcAngularStep(
+      r, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+    Standard_Real Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
+    Dv = oldDv;
+
+    const Standard_Integer nbV = Max((Standard_Integer) (aDiffV / Dv), 2);
+    Dv = aDiffV / (nbV + 1);
+
+    Standard_Real Du;
+    const Standard_Real ru = R + r;
+    if (ru > 1.e-16)
+    {
+      Du = GCPnts_TangentialDeflection::ArcAngularStep(ru,
+        GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+      const Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
+      if (aa < gp::Resolution())
+      {
+        return Handle(IMeshData::ListOfPnt2d)();
+      }
+
+      Du *= Min(oldDv, Du) / aa;
+    }
+    else
+    {
+      Du = Dv;
+    }
+
+    Standard_Integer nbU = Max((Standard_Integer) (aDiffU / Du), 2);
+    nbU = Max(nbU, (Standard_Integer) (nbV * aDiffU * R / (aDiffV * r) / 5.));
+    Du = aDiffU / (nbU + 1);
+
+    const Handle(NCollection_IncAllocator) aTmpAlloc =
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+    Handle(IMeshData::SequenceOfReal) aParamU, aParamV;
+    if (R < r)
+    {
+      // As the points of edges are returned.
+      // in this case, the points are not representative.
+
+      //-- Choose DeltaX and DeltaY so that to avoid skipping points on the grid
+      aParamU = new IMeshData::SequenceOfReal(aTmpAlloc);
+      for (Standard_Integer i = 0; i <= nbU; i++)
+      {
+        aParamU->Append(aRangeU.first + i * Du);
+      }
+    }//R<r
+    else //U if R > r
+    {
+      aParamU = fillParams(GetParametersU(), GetRangeU(), nbU, 0.5, aTmpAlloc);
+    }
+
+    aParamV = fillParams(GetParametersV(), GetRangeV(), nbV, 2. / 3., aTmpAlloc);
+
+    const std::pair<Standard_Real, Standard_Real> aNewRangeU(aRangeU.first  + Du * 0.1,
+                                                             aRangeU.second - Dv * 0.1);
+
+    const std::pair<Standard_Real, Standard_Real> aNewRangeV(aRangeV.first  + Dv * 0.1,
+                                                             aRangeV.second - Dv * 0.1);
+
+    Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+    for (Standard_Integer i = 1; i <= aParamU->Length(); ++i)
+    {
+      const Standard_Real aPasU = aParamU->Value(i);
+      if (aPasU >= aNewRangeU.first && aPasU < aNewRangeU.second)
+      {
+        for (Standard_Integer j = 1; j <= aParamV->Length(); ++j)
+        {
+          const Standard_Real aPasV = aParamV->Value(j);
+          if (aPasV >= aNewRangeV.first && aPasV < aNewRangeV.second)
+          {
+            aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+          }
+        }
+      }
+    }
+
+    return aNodes;
+  }
+
+  //! Registers border point.
+  Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint) Standard_OVERRIDE
+  {
+    BRepMesh_DefaultRangeSplitter::AddPoint(thePoint);
+    GetParametersU().Add(thePoint.X());
+    GetParametersV().Add(thePoint.Y());
+  }
+
+private:
+
+  Handle(IMeshData::SequenceOfReal) fillParams(
+    const IMeshData::IMapOfReal&                   theParams,
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    const Standard_Integer                         theStepsNb,
+    const Standard_Real                            theScale,
+    const Handle(NCollection_IncAllocator)&        theAllocator) const
+  {
+    Handle(IMeshData::SequenceOfReal) aParams =
+      new IMeshData::SequenceOfReal(theAllocator);
+
+    const Standard_Integer aLength = theParams.Size();
+    TColStd_Array1OfReal aParamArray(1, aLength);
+
+    for (Standard_Integer j = 1; j <= aLength; ++j)
+    {
+      aParamArray(j) = theParams(j);
+    }
+
+    // Calculate DU, leave array of parameters
+    const Standard_Real aDiff = Abs(theRange.second - theRange.first);
+    Standard_Real aStep = FUN_CalcAverageDUV(aParamArray, aLength);
+    aStep = Max(aStep, aDiff / (Standard_Real) theStepsNb / 2.);
+
+    Standard_Real aStdStep = aDiff / (Standard_Real) aLength;
+    if (aStep > aStdStep)
+    {
+      aStdStep = aStep;
+    }
+    aStdStep *= theScale;
+
+    // Add parameters
+    for (Standard_Integer j = 1; j <= aLength; ++j)
+    {
+      const Standard_Real pp = aParamArray(j);
+
+      Standard_Boolean isToInsert = Standard_True;
+      const Standard_Integer aParamsLength = aParams->Length();
+      for (Standard_Integer i = 1; i <= aParamsLength && isToInsert; ++i)
+      {
+        isToInsert = (Abs(aParams->Value(i) - pp) > aStdStep);
+      }
+
+      if (isToInsert)
+      {
+        aParams->Append(pp);
+      }
+    }
+
+    return aParams;
+  }
+
+  inline Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen) const
+  {
+    Standard_Integer i, j, n = 0;
+    Standard_Real p, result = 0.;
+
+    for (i = 1; i <= PLen; i++)
+    {
+      // Sort
+      for (j = i + 1; j <= PLen; j++)
+      {
+        if (P(i) > P(j))
+        {
+          p = P(i);
+          P(i) = P(j);
+          P(j) = p;
+        }
+      }
+      // Accumulate
+      if (i != 1)
+      {
+        p = Abs(P(i) - P(i - 1));
+        if (p > 1.e-7)
+        {
+          result += p;
+          n++;
+        }
+      }
+    }
+    return (n ? (result / (Standard_Real) n) : -1.);
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx b/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..c7679cf
--- /dev/null
@@ -0,0 +1,81 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_UVParamRangeSplitter_HeaderFile
+#define _BRepMesh_UVParamRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Intended to generate internal mesh nodes using UV parameters of bounday discrete points.
+class BRepMesh_UVParamRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_UVParamRangeSplitter()
+    : myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+      myUParams(1, myAllocator),
+      myVParams(1, myAllocator)
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_UVParamRangeSplitter()
+  {
+  }
+
+  //! Resets this splitter.
+  Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+                                     const IMeshTools_Parameters&  theParameters)
+  {
+    BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters);
+    myUParams.Clear();
+    myVParams.Clear();
+    myAllocator->Reset(Standard_False);
+  }
+
+public:
+  //! Returns U parameters.
+  inline const IMeshData::IMapOfReal& GetParametersU() const
+  {
+    return myUParams;
+  }
+
+  //! Returns U parameters.
+  inline IMeshData::IMapOfReal& GetParametersU()
+  {
+    return myUParams;
+  }
+
+  //! Returns V parameters.
+  inline const IMeshData::IMapOfReal& GetParametersV() const
+  {
+    return myVParams;
+  }
+
+  //! Returns V parameters.
+  inline IMeshData::IMapOfReal& GetParametersV()
+  {
+    return myVParams;
+  }
+
+private:
+  Handle(NCollection_IncAllocator) myAllocator;
+  IMeshData::IMapOfReal            myUParams;
+  IMeshData::IMapOfReal            myVParams;
+};
+
+#endif
diff --git a/src/BRepMeshData/BRepMeshData_Curve.cxx b/src/BRepMeshData/BRepMeshData_Curve.cxx
new file mode 100644 (file)
index 0000000..ac427f9
--- /dev/null
@@ -0,0 +1,126 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_Curve.hxx>
+#include <gp_Pnt.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Curve::BRepMeshData_Curve (const Handle (NCollection_IncAllocator)& theAllocator)
+: myPoints     (NCollection_StdAllocator<gp_Pnt>(theAllocator)),
+  myParameters (NCollection_StdAllocator<Standard_Real>(theAllocator))
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Curve::~BRepMeshData_Curve ()
+{
+}
+
+//=======================================================================
+// Function: InsertPoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_Curve::InsertPoint(
+  const Standard_Integer thePosition,
+  const gp_Pnt&          thePoint,
+  const Standard_Real    theParamOnPCurve)
+{
+  myPoints    .insert(myPoints    .begin() + thePosition, thePoint);
+  myParameters.insert(myParameters.begin() + thePosition, theParamOnPCurve);
+}
+
+//=======================================================================
+// Function: AddPoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_Curve::AddPoint (
+  const gp_Pnt&       thePoint,
+  const Standard_Real theParamOnPCurve)
+{
+  myPoints    .push_back(thePoint);
+  myParameters.push_back(theParamOnPCurve);
+}
+
+//=======================================================================
+// Function: GetPoint
+// Purpose : 
+//=======================================================================
+gp_Pnt& BRepMeshData_Curve::GetPoint (const Standard_Integer theIndex)
+{
+  return myPoints[theIndex];
+}
+
+//=======================================================================
+// Function: GetParameter
+// Purpose : 
+//=======================================================================
+Standard_Real& BRepMeshData_Curve::GetParameter (const Standard_Integer theIndex)
+{
+  return myParameters[theIndex];
+}
+
+//=======================================================================
+// Function: ParameterNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Curve::ParametersNb() const
+{
+  return static_cast<Standard_Integer>(myParameters.size());
+}
+
+//=======================================================================
+// Function: RemovePoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_Curve::RemovePoint (const Standard_Integer theIndex)
+{
+  myPoints.erase(myPoints.begin() + theIndex);
+  removeParameter (theIndex);
+}
+
+//=======================================================================
+// Function: removeParameter
+// Purpose : 
+//=======================================================================
+void BRepMeshData_Curve::removeParameter (const Standard_Integer theIndex)
+{
+  myParameters.erase(myParameters.begin() + theIndex);
+}
+
+//=======================================================================
+// Function: Clear
+// Purpose : 
+//=======================================================================
+void BRepMeshData_Curve::Clear(const Standard_Boolean isKeepEndPoints)
+{
+  if (!isKeepEndPoints)
+  {
+    myPoints    .clear();
+    myParameters.clear();
+  }
+  else if (ParametersNb() > 2)
+  {
+    myPoints    .erase(myPoints    .begin() + 1, myPoints    .begin() + (myPoints    .size() - 1));
+    myParameters.erase(myParameters.begin() + 1, myParameters.begin() + (myParameters.size() - 1));
+  }
+}
diff --git a/src/BRepMeshData/BRepMeshData_Curve.hxx b/src/BRepMeshData/BRepMeshData_Curve.hxx
new file mode 100644 (file)
index 0000000..1566a4d
--- /dev/null
@@ -0,0 +1,76 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_Curve_HeaderFile
+#define _BRepMeshData_Curve_HeaderFile
+
+#include <IMeshData_Curve.hxx>
+#include <Standard_Type.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Default implementation of curve data model entity.
+class BRepMeshData_Curve : public IMeshData_Curve
+{
+public:
+
+  DEFINE_INC_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT BRepMeshData_Curve (const Handle (NCollection_IncAllocator)& theAllocator);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_Curve ();
+
+  //! Inserts new discretization point at the given position.
+  Standard_EXPORT virtual void InsertPoint(
+    const Standard_Integer thePosition,
+    const gp_Pnt&          thePoint,
+    const Standard_Real    theParamOnPCurve) Standard_OVERRIDE;
+
+  //! Adds new discretization point to pcurve.
+  Standard_EXPORT virtual void AddPoint (
+    const gp_Pnt&       thePoint,
+    const Standard_Real theParamOnCurve) Standard_OVERRIDE;
+
+  //! Returns discretization point with the given index.
+  Standard_EXPORT virtual gp_Pnt& GetPoint (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Removes point with the given index.
+  Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Returns parameter with the given index.
+  Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Returns number of parameters stored in curve.
+  Standard_EXPORT virtual Standard_Integer ParametersNb() const Standard_OVERRIDE;
+
+  //! Clears parameters list.
+  Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Curve, IMeshData_Curve)
+
+protected:
+
+  //! Removes parameter with the given index.
+  Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+private:
+
+  IMeshData::Model::SequenceOfPnt  myPoints;
+  IMeshData::Model::SequenceOfReal myParameters;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/BRepMeshData_Edge.cxx b/src/BRepMeshData/BRepMeshData_Edge.cxx
new file mode 100644 (file)
index 0000000..67ce822
--- /dev/null
@@ -0,0 +1,102 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_Edge.hxx>
+#include <BRepMeshData_PCurve.hxx>
+#include <BRepMeshData_Curve.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Edge::BRepMeshData_Edge (
+  const TopoDS_Edge&                       theEdge,
+  const Handle (NCollection_IncAllocator)& theAllocator)
+  : IMeshData_Edge (theEdge),
+    myAllocator (theAllocator),
+    myPCurves (256, myAllocator),
+    myPCurvesMap(1, myAllocator)
+{
+  SetCurve (IMeshData::ICurveHandle (new (myAllocator) BRepMeshData_Curve (myAllocator)));
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Edge::~BRepMeshData_Edge ()
+{
+}
+
+//=======================================================================
+// Function: AddPCurve
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Edge::PCurvesNb () const
+{
+  return myPCurves.Size ();
+}
+
+//=======================================================================
+// Function: AddPCurve
+// Purpose : 
+//=======================================================================
+const IMeshData::IPCurveHandle& BRepMeshData_Edge::AddPCurve (
+  const IMeshData::IFacePtr& theDFace,
+  const TopAbs_Orientation   theOrientation)
+{
+  const Standard_Integer aPCurveIndex = PCurvesNb ();
+  // Add pcurve to list of pcurves
+  IMeshData::IPCurveHandle aPCurve (new (myAllocator) BRepMeshData_PCurve (theDFace, theOrientation, myAllocator));
+  myPCurves.Append (aPCurve);
+
+  // Map pcurve to faces.
+  if (!myPCurvesMap.IsBound(theDFace))
+  {
+    myPCurvesMap.Bind(theDFace, IMeshData::ListOfInteger(myAllocator));
+  }
+
+  IMeshData::ListOfInteger& aListOfPCurves = myPCurvesMap.ChangeFind(theDFace);
+  aListOfPCurves.Append (aPCurveIndex);
+
+  return GetPCurve (aPCurveIndex);
+}
+
+//=======================================================================
+// Function: GetPCurve
+// Purpose : 
+//=======================================================================
+const IMeshData::IPCurveHandle& BRepMeshData_Edge::GetPCurve (
+  const IMeshData::IFacePtr& theDFace,
+  const TopAbs_Orientation   theOrientation) const
+{
+  const IMeshData::ListOfInteger& aListOfPCurves = myPCurvesMap.Find (theDFace);
+  const IMeshData::IPCurveHandle& aPCurve1 = myPCurves (aListOfPCurves.First ());
+  return (aPCurve1->GetOrientation () == theOrientation) ?
+    aPCurve1 :
+    myPCurves (aListOfPCurves.Last ());
+}
+
+//=======================================================================
+// Function: GetPCurve
+// Purpose : 
+//=======================================================================
+const IMeshData::IPCurveHandle& BRepMeshData_Edge::GetPCurve (
+  const Standard_Integer theIndex) const
+{
+  return myPCurves (theIndex);
+}
diff --git a/src/BRepMeshData/BRepMeshData_Edge.hxx b/src/BRepMeshData/BRepMeshData_Edge.hxx
new file mode 100644 (file)
index 0000000..d30e550
--- /dev/null
@@ -0,0 +1,65 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_Edge_HeaderFile
+#define _BRepMeshData_Edge_HeaderFile
+
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Curve.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Default implementation of edge data model entity.
+class BRepMeshData_Edge : public IMeshData_Edge
+{
+public:
+
+  DEFINE_INC_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT BRepMeshData_Edge (
+    const TopoDS_Edge&                       theEdge,
+    const Handle (NCollection_IncAllocator)& theAllocator);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_Edge ();
+
+  //! Returns number of pcurves assigned to current edge.
+  Standard_EXPORT virtual Standard_Integer PCurvesNb () const Standard_OVERRIDE;
+
+  //! Adds disrete pcurve for the specifed discrete face.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& AddPCurve (
+    const IMeshData::IFacePtr& theDFace,
+    const TopAbs_Orientation   theOrientation) Standard_OVERRIDE;
+
+  //! Returns pcurve for the specified discrete face.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve (
+    const IMeshData::IFacePtr& theDFace,
+    const TopAbs_Orientation   theOrientation) const Standard_OVERRIDE;
+
+  //! Returns pcurve with the given index.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve (
+    const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Edge, IMeshData_Edge)
+
+private:
+
+  Handle (NCollection_IncAllocator)       myAllocator;
+  IMeshData::VectorOfIPCurveHandles       myPCurves;
+  IMeshData::DMapOfIFacePtrsListOfInteger myPCurvesMap;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/BRepMeshData_Face.cxx b/src/BRepMeshData/BRepMeshData_Face.cxx
new file mode 100644 (file)
index 0000000..2dca22c
--- /dev/null
@@ -0,0 +1,72 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_Face.hxx>
+#include <BRepMeshData_Wire.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Face::BRepMeshData_Face (
+  const TopoDS_Face&                       theFace,
+  const Handle (NCollection_IncAllocator)& theAllocator)
+  : IMeshData_Face (theFace),
+    myAllocator (theAllocator),
+    myDWires (256, myAllocator)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Face::~BRepMeshData_Face ()
+{
+}
+
+//=======================================================================
+// Function: WiresNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Face::WiresNb () const
+{
+  return myDWires.Size ();
+}
+
+//=======================================================================
+// Function: AddWire
+// Purpose : 
+//=======================================================================
+const IMeshData::IWireHandle& BRepMeshData_Face::AddWire (
+  const TopoDS_Wire&     theWire,
+  const Standard_Integer theEdgeNb)
+{
+  IMeshData::IWireHandle aWire (new (myAllocator) BRepMeshData_Wire (theWire, theEdgeNb, myAllocator));
+  myDWires.Append (aWire);
+  return GetWire (WiresNb () - 1);
+}
+
+//=======================================================================
+// Function: GetWire
+// Purpose : 
+//=======================================================================
+const IMeshData::IWireHandle& BRepMeshData_Face::GetWire (
+  const Standard_Integer theIndex) const
+{
+  return myDWires (theIndex);
+}
diff --git a/src/BRepMeshData/BRepMeshData_Face.hxx b/src/BRepMeshData/BRepMeshData_Face.hxx
new file mode 100644 (file)
index 0000000..1f187f7
--- /dev/null
@@ -0,0 +1,58 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_Face_HeaderFile
+#define _BRepMeshData_Face_HeaderFile
+
+#include <IMeshData_Types.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Wire.hxx>
+
+//! Default implementation of face data model entity.
+class BRepMeshData_Face : public IMeshData_Face
+{
+public:
+
+  DEFINE_INC_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT BRepMeshData_Face (
+    const TopoDS_Face&                       theFace,
+    const Handle (NCollection_IncAllocator)& theAllocator);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_Face ();
+
+  //! Gets number of children.
+  Standard_EXPORT virtual Standard_Integer WiresNb () const Standard_OVERRIDE;
+
+  //! Gets wire with the given index.
+  Standard_EXPORT virtual const IMeshData::IWireHandle& GetWire (
+    const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+  //! Adds wire to discrete model of face.
+  Standard_EXPORT virtual const IMeshData::IWireHandle& AddWire (
+    const TopoDS_Wire&     theWire,
+    const Standard_Integer theEdgeNb = 0) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Face, IMeshData_Face)
+
+private:
+
+  Handle (NCollection_IncAllocator) myAllocator;
+  IMeshData::VectorOfIWireHandles   myDWires;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/BRepMeshData_Model.cxx b/src/BRepMeshData/BRepMeshData_Model.cxx
new file mode 100644 (file)
index 0000000..bd2e74c
--- /dev/null
@@ -0,0 +1,100 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_Model.hxx>
+#include <BRepMeshData_Face.hxx>
+#include <BRepMeshData_Edge.hxx>
+#include <BRepMesh_IncAllocator.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Model::BRepMeshData_Model (const TopoDS_Shape& theShape)
+  : IMeshData_Model (theShape),
+    myMaxSize (0.),
+    myAllocator (new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+    myDFaces (256, myAllocator),
+    myDEdges (256, myAllocator)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Model::~BRepMeshData_Model ()
+{
+}
+
+//=======================================================================
+// Function: FacesNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Model::FacesNb () const
+{
+  return myDFaces.Size ();
+}
+
+//=======================================================================
+// Function: AddFace
+// Purpose : 
+//=======================================================================
+const IMeshData::IFaceHandle& BRepMeshData_Model::AddFace (const TopoDS_Face& theFace)
+{
+  IMeshData::IFaceHandle aFace (new (myAllocator) BRepMeshData_Face (theFace, myAllocator));
+  myDFaces.Append (aFace);
+  return myDFaces (FacesNb () - 1);
+}
+
+//=======================================================================
+// Function: GetFace
+// Purpose : 
+//=======================================================================
+const IMeshData::IFaceHandle& BRepMeshData_Model::GetFace (const Standard_Integer theIndex) const
+{
+  return myDFaces (theIndex);
+}
+
+//=======================================================================
+// Function: EdgesNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Model::EdgesNb () const
+{
+  return myDEdges.Size ();
+}
+
+//=======================================================================
+// Function: AddEdge
+// Purpose : 
+//=======================================================================
+const IMeshData::IEdgeHandle& BRepMeshData_Model::AddEdge (const TopoDS_Edge& theEdge)
+{
+  IMeshData::IEdgeHandle aEdge (new (myAllocator) BRepMeshData_Edge (theEdge, myAllocator));
+  myDEdges.Append (aEdge);
+  return myDEdges (EdgesNb () - 1);
+}
+
+//=======================================================================
+// Function: GetEdge
+// Purpose : 
+//=======================================================================
+const IMeshData::IEdgeHandle& BRepMeshData_Model::GetEdge (const Standard_Integer theIndex) const
+{
+  return myDEdges (theIndex);
+}
diff --git a/src/BRepMeshData/BRepMeshData_Model.hxx b/src/BRepMeshData/BRepMeshData_Model.hxx
new file mode 100644 (file)
index 0000000..2b19684
--- /dev/null
@@ -0,0 +1,81 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_Model_HeaderFile
+#define _BRepMeshData_Model_HeaderFile
+
+#include <IMeshData_Model.hxx>
+#include <IMeshData_Types.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Edge.hxx>
+
+//! Default implementation of model entity.
+class BRepMeshData_Model : public IMeshData_Model
+{
+public:
+
+  //! Constructor.
+  //! Initializes empty model.
+  Standard_EXPORT BRepMeshData_Model (const TopoDS_Shape& theShape);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_Model ();
+
+  //! Returns maximum size of shape's bounding box.
+  Standard_EXPORT virtual Standard_Real GetMaxSize () const Standard_OVERRIDE
+  {
+    return myMaxSize;
+  }
+
+  //! Sets maximum size of shape's bounding box.
+  inline void SetMaxSize (const Standard_Real theValue)
+  {
+    myMaxSize = theValue;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Model, IMeshData_Model)
+
+public: //! @name discrete faces
+
+  //! Returns number of faces in discrete model.
+  Standard_EXPORT virtual Standard_Integer FacesNb () const Standard_OVERRIDE;
+
+  //! Adds new face to shape model.
+  Standard_EXPORT virtual const IMeshData::IFaceHandle& AddFace (const TopoDS_Face& theFace) Standard_OVERRIDE;
+
+  //! Gets model's face with the given index.
+  Standard_EXPORT virtual const IMeshData::IFaceHandle& GetFace (const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+public: //! @name discrete edges
+
+  //! Returns number of edges in discrete model.
+  Standard_EXPORT virtual Standard_Integer EdgesNb () const Standard_OVERRIDE;
+
+  //! Adds new edge to shape model.
+  Standard_EXPORT virtual const IMeshData::IEdgeHandle& AddEdge (const TopoDS_Edge& theEdge) Standard_OVERRIDE;
+
+  //! Gets model's edge with the given index.
+  Standard_EXPORT virtual const IMeshData::IEdgeHandle& GetEdge (const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+private:
+
+  Standard_Real                     myMaxSize;
+  Handle (NCollection_IncAllocator) myAllocator;
+  IMeshData::VectorOfIFaceHandles   myDFaces;
+  IMeshData::VectorOfIEdgeHandles   myDEdges;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/BRepMeshData_PCurve.cxx b/src/BRepMeshData/BRepMeshData_PCurve.cxx
new file mode 100644 (file)
index 0000000..53608a7
--- /dev/null
@@ -0,0 +1,145 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_PCurve.hxx>
+#include <gp_Pnt2d.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_PCurve::BRepMeshData_PCurve (
+  const IMeshData::IFacePtr&               theDFace,
+  const TopAbs_Orientation                 theOrientation,
+  const Handle (NCollection_IncAllocator)& theAllocator)
+  : IMeshData_PCurve (theDFace, theOrientation),
+    myPoints2d   (NCollection_StdAllocator<gp_Pnt2d>(theAllocator)),
+    myParameters (NCollection_StdAllocator<Standard_Real>(theAllocator)),
+    myIndices    (NCollection_StdAllocator<Standard_Integer>(theAllocator))
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_PCurve::~BRepMeshData_PCurve ()
+{
+}
+
+//=======================================================================
+// Function: InsertPoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_PCurve::InsertPoint(
+  const Standard_Integer thePosition,
+  const gp_Pnt2d&        thePoint,
+  const Standard_Real    theParamOnPCurve)
+{
+  myPoints2d  .insert(myPoints2d  .begin() + thePosition, thePoint);
+  myParameters.insert(myParameters.begin() + thePosition, theParamOnPCurve);
+  myIndices   .insert(myIndices   .begin() + thePosition, 0);
+}
+
+//=======================================================================
+// Function: AddPoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_PCurve::AddPoint (
+  const gp_Pnt2d&     thePoint,
+  const Standard_Real theParamOnPCurve)
+{
+  myPoints2d  .push_back(thePoint);
+  myParameters.push_back(theParamOnPCurve);
+  myIndices   .push_back(0);
+}
+
+//=======================================================================
+// Function: GetPoint
+// Purpose : 
+//=======================================================================
+gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
+{
+  return myPoints2d[theIndex];
+}
+
+//=======================================================================
+// Function: GetIndex
+// Purpose : 
+//=======================================================================
+Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
+{
+  return myIndices[theIndex];
+}
+
+//=======================================================================
+// Function: GetParameter
+// Purpose : 
+//=======================================================================
+Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
+{
+  return myParameters[theIndex];
+}
+
+//=======================================================================
+// Function: ParameterNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_PCurve::ParametersNb() const
+{
+  return static_cast<Standard_Integer>(myParameters.size());
+}
+
+//=======================================================================
+// Function: RemovePoint
+// Purpose : 
+//=======================================================================
+void BRepMeshData_PCurve::RemovePoint (const Standard_Integer theIndex)
+{
+  myPoints2d.erase(myPoints2d.begin() + theIndex);
+  myIndices .erase(myIndices .begin() + theIndex);
+  removeParameter (theIndex);
+}
+
+//=======================================================================
+// Function: removeParameter
+// Purpose : 
+//=======================================================================
+void BRepMeshData_PCurve::removeParameter (const Standard_Integer theIndex)
+{
+  myParameters.erase(myParameters.begin() + theIndex);
+}
+
+//=======================================================================
+// Function: Clear
+// Purpose : 
+//=======================================================================
+void BRepMeshData_PCurve::Clear(const Standard_Boolean isKeepEndPoints)
+{
+  if (!isKeepEndPoints)
+  {
+    myPoints2d  .clear();
+    myParameters.clear();
+    myIndices   .clear();
+  }
+  else if (ParametersNb() > 2)
+  {
+    myPoints2d  .erase(myPoints2d  .begin() + 1, myPoints2d  .begin() + (myPoints2d  .size() - 1));
+    myParameters.erase(myParameters.begin() + 1, myParameters.begin() + (myParameters.size() - 1));
+    myIndices   .erase(myIndices   .begin() + 1, myIndices   .begin() + (myIndices   .size() - 1));
+  }
+}
diff --git a/src/BRepMeshData/BRepMeshData_PCurve.hxx b/src/BRepMeshData/BRepMeshData_PCurve.hxx
new file mode 100644 (file)
index 0000000..1189f92
--- /dev/null
@@ -0,0 +1,82 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_PCurve_HeaderFile
+#define _BRepMeshData_PCurve_HeaderFile
+
+#include <IMeshData_PCurve.hxx>
+#include <Standard_Type.hxx>
+#include <NCollection_IncAllocator.hxx>
+
+//! Default implementation of pcurve data model entity.
+class BRepMeshData_PCurve : public IMeshData_PCurve
+{
+public:
+
+  DEFINE_INC_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT BRepMeshData_PCurve (
+    const IMeshData::IFacePtr&               theDFace,
+    const TopAbs_Orientation                 theOrientation,
+    const Handle (NCollection_IncAllocator)& theAllocator);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_PCurve ();
+
+  //! Inserts new discretization point at the given position.
+  Standard_EXPORT virtual void InsertPoint(
+    const Standard_Integer thePosition,
+    const gp_Pnt2d&        thePoint,
+    const Standard_Real    theParamOnPCurve) Standard_OVERRIDE;
+
+  //! Adds new discretization point to pcurve.
+  Standard_EXPORT virtual void AddPoint (
+    const gp_Pnt2d&     thePoint,
+    const Standard_Real theParamOnPCurve) Standard_OVERRIDE;
+
+  //! Returns discretization point with the given index.
+  Standard_EXPORT virtual gp_Pnt2d& GetPoint (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Returns index in mesh corresponded to discretization point with the given index.
+  Standard_EXPORT virtual Standard_Integer& GetIndex(const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Removes point with the given index.
+  Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Returns parameter with the given index.
+  Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+  //! Returns number of parameters stored in pcurve.
+  Standard_EXPORT virtual Standard_Integer ParametersNb() const Standard_OVERRIDE;
+
+  //! Clears parameters list.
+  Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_PCurve, IMeshData_PCurve)
+
+protected:
+
+  //! Removes parameter with the given index.
+  Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) Standard_OVERRIDE;
+
+private:
+
+  IMeshData::Model::SequenceOfPnt2d   myPoints2d;
+  IMeshData::Model::SequenceOfReal    myParameters;
+  IMeshData::Model::SequenceOfInteger myIndices;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/BRepMeshData_Wire.cxx b/src/BRepMeshData/BRepMeshData_Wire.cxx
new file mode 100644 (file)
index 0000000..8139f6a
--- /dev/null
@@ -0,0 +1,86 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMeshData_Wire.hxx>
+#include <IMeshData_Edge.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Wire::BRepMeshData_Wire (
+  const TopoDS_Wire&                       theWire,
+  const Standard_Integer                   theEdgeNb,
+  const Handle (NCollection_IncAllocator)& theAllocator)
+  : IMeshData_Wire (theWire),
+    myDEdges    (theEdgeNb > 0 ? theEdgeNb : 256, theAllocator),
+    myDEdgesOri (theEdgeNb > 0 ? theEdgeNb : 256, theAllocator)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Wire::~BRepMeshData_Wire ()
+{
+}
+
+//=======================================================================
+// Function: EdgesNb
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Wire::EdgesNb () const
+{
+  return myDEdges.Size ();
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+Standard_Integer BRepMeshData_Wire::AddEdge (
+  const IMeshData::IEdgePtr& theDEdge,
+  const TopAbs_Orientation   theOrientation)
+{
+  const Standard_Integer aIndex = EdgesNb ();
+
+  myDEdges   .Append (theDEdge);
+  myDEdgesOri.Append (theOrientation);
+
+  return aIndex;
+}
+
+//=======================================================================
+// Function: GetEdge
+// Purpose : 
+//=======================================================================
+const IMeshData::IEdgePtr& BRepMeshData_Wire::GetEdge (
+  const Standard_Integer theIndex) const
+{
+  return myDEdges (theIndex);
+}
+
+//=======================================================================
+// Function: GetEdgeOrientation
+// Purpose : 
+//=======================================================================
+TopAbs_Orientation BRepMeshData_Wire::GetEdgeOrientation (
+  const Standard_Integer theIndex) const
+{
+  return myDEdgesOri (theIndex);
+}
diff --git a/src/BRepMeshData/BRepMeshData_Wire.hxx b/src/BRepMeshData/BRepMeshData_Wire.hxx
new file mode 100644 (file)
index 0000000..bf55509
--- /dev/null
@@ -0,0 +1,63 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMeshData_Wire_HeaderFile
+#define _BRepMeshData_Wire_HeaderFile
+
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Types.hxx>
+
+//! Default implementation of wire data model entity.
+class BRepMeshData_Wire : public IMeshData_Wire
+{
+public:
+
+  DEFINE_INC_ALLOC
+
+  //! Constructor.
+  Standard_EXPORT BRepMeshData_Wire (
+    const TopoDS_Wire&                       theWire,
+    const Standard_Integer                   theEdgeNb, 
+    const Handle (NCollection_IncAllocator)& theAllocator);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMeshData_Wire ();
+
+  //! Gets number of children.
+  Standard_EXPORT virtual Standard_Integer EdgesNb () const Standard_OVERRIDE;
+
+  //! Adds new discrete edge with specified orientation to wire chain.
+  //! @return index of added edge in wire chain.
+  Standard_EXPORT virtual Standard_Integer AddEdge (
+    const IMeshData::IEdgePtr& theDEdge,
+    const TopAbs_Orientation   theOrientation) Standard_OVERRIDE;
+
+  //! Gets edge with the given index.
+  Standard_EXPORT virtual const IMeshData::IEdgePtr& GetEdge (
+    const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+  //! Returns True if orientation of discrete edge with the given index is forward.
+  Standard_EXPORT virtual TopAbs_Orientation GetEdgeOrientation (
+    const Standard_Integer theIndex) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Wire, IMeshData_Wire)
+
+private:
+
+  IMeshData::VectorOfIEdgePtrs    myDEdges;
+  IMeshData::VectorOfOrientation  myDEdgesOri;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/BRepMeshData/FILES b/src/BRepMeshData/FILES
new file mode 100644 (file)
index 0000000..eb27095
--- /dev/null
@@ -0,0 +1,12 @@
+BRepMeshData_Curve.cxx
+BRepMeshData_Curve.hxx
+BRepMeshData_Edge.cxx
+BRepMeshData_Edge.hxx
+BRepMeshData_Face.cxx
+BRepMeshData_Face.hxx
+BRepMeshData_Model.cxx
+BRepMeshData_Model.hxx
+BRepMeshData_PCurve.cxx
+BRepMeshData_PCurve.hxx
+BRepMeshData_Wire.cxx
+BRepMeshData_Wire.hxx
diff --git a/src/IMeshData/FILES b/src/IMeshData/FILES
new file mode 100644 (file)
index 0000000..1af663a
--- /dev/null
@@ -0,0 +1,13 @@
+IMeshData_Curve.hxx
+IMeshData_Edge.hxx
+IMeshData_Face.hxx
+IMeshData_Model.hxx
+IMeshData_ParametersList.hxx
+IMeshData_ParametersListArrayAdaptor.hxx
+IMeshData_PCurve.hxx
+IMeshData_Shape.hxx
+IMeshData_Status.hxx
+IMeshData_StatusOwner.hxx
+IMeshData_TessellatedShape.hxx
+IMeshData_Types.hxx
+IMeshData_Wire.hxx
diff --git a/src/IMeshData/IMeshData_Curve.hxx b/src/IMeshData/IMeshData_Curve.hxx
new file mode 100644 (file)
index 0000000..505efad
--- /dev/null
@@ -0,0 +1,62 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Curve_HeaderFile
+#define _IMeshData_Curve_HeaderFile
+
+#include <IMeshData_ParametersList.hxx>
+#include <Standard_Type.hxx>
+
+class gp_Pnt;
+
+//! Interface class representing discrete 3d curve of edge.
+//! Indexation of points starts from zero.
+class IMeshData_Curve : public IMeshData_ParametersList
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Curve()
+  {
+  }
+
+  //! Inserts new discretization point at the given position.
+  Standard_EXPORT virtual void InsertPoint(
+    const Standard_Integer thePosition,
+    const gp_Pnt&          thePoint,
+    const Standard_Real    theParamOnPCurve) = 0;
+
+  //! Adds new discretization point to curve.
+  Standard_EXPORT virtual void AddPoint (
+    const gp_Pnt&       thePoint,
+    const Standard_Real theParamOnCurve) = 0;
+
+  //! Returns discretization point with the given index.
+  Standard_EXPORT virtual gp_Pnt& GetPoint (const Standard_Integer theIndex) = 0;
+
+  //! Removes point with the given index.
+  Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Curve, IMeshData_ParametersList)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_Curve()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Edge.hxx b/src/IMeshData/IMeshData_Edge.hxx
new file mode 100644 (file)
index 0000000..162d2a2
--- /dev/null
@@ -0,0 +1,167 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Edge_HeaderFile
+#define _IMeshData_Edge_HeaderFile
+
+#include <IMeshData_TessellatedShape.hxx>
+#include <IMeshData_StatusOwner.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <IMeshData_Curve.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <IMeshData_Types.hxx>
+#include <BRep_Tool.hxx>
+
+class IMeshData_Face;
+
+//! Interface class representing discrete model of an edge.
+class IMeshData_Edge : public IMeshData_TessellatedShape, public IMeshData_StatusOwner
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Edge()
+  {
+  }
+
+  //! Returns TopoDS_Edge attached to model.
+  inline const TopoDS_Edge& GetEdge () const
+  {
+    return TopoDS::Edge (GetShape ());
+  }
+
+  //! Returns number of pcurves assigned to current edge.
+  Standard_EXPORT virtual Standard_Integer PCurvesNb () const = 0;
+
+  //! Adds discrete pcurve for the specifed discrete face.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& AddPCurve (
+    const IMeshData::IFacePtr& theDFace,
+    const TopAbs_Orientation   theOrientation) = 0;
+
+  //! Returns pcurve for the specified discrete face.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve (
+    const IMeshData::IFacePtr& theDFace,
+    const TopAbs_Orientation   theOrientation) const = 0;
+
+  //! Returns pcurve with the given index.
+  Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve (
+    const Standard_Integer theIndex) const = 0;
+
+  //! Clears curve and all pcurves assigned to the edge from discretization.
+  inline void Clear(const Standard_Boolean isKeepEndPoints)
+  {
+    myCurve->Clear(isKeepEndPoints);
+    for (Standard_Integer aPCurveIt = 0; aPCurveIt < PCurvesNb(); ++aPCurveIt)
+    {
+      GetPCurve(aPCurveIt)->Clear(isKeepEndPoints);
+    }
+  }
+
+  //! Returns true in case if the edge is free one, i.e. it does not have pcurves.
+  inline Standard_Boolean IsFree () const
+  {
+    return (PCurvesNb () == 0);
+  }
+
+  //! Sets 3d curve associated with current edge.
+  inline void SetCurve (const IMeshData::ICurveHandle& theCurve)
+  {
+    myCurve = theCurve;
+  }
+
+  //! Returns 3d curve associated with current edge.
+  inline const IMeshData::ICurveHandle& GetCurve () const
+  {
+    return myCurve;
+  }
+
+  //! Gets value of angular deflection for the discrete model.
+  inline Standard_Real GetAngularDeflection () const
+  {
+    return myAngDeflection;
+  }
+
+  //! Sets value of angular deflection for the discrete model.
+  inline void SetAngularDeflection (const Standard_Real theValue)
+  {
+    myAngDeflection = theValue;
+  }
+
+  //! Returns same param flag.
+  //! By default equals to flag stored in topological shape.
+  inline Standard_Boolean GetSameParam () const
+  {
+    return mySameParam;
+  }
+
+  //! Updates same param flag.
+  inline void SetSameParam (const Standard_Boolean theValue)
+  {
+    mySameParam = theValue;
+  }
+
+  //! Returns same range flag.
+  //! By default equals to flag stored in topological shape.
+  inline Standard_Boolean GetSameRange () const
+  {
+    return mySameRange;
+  }
+
+  //! Updates same range flag.
+  inline void SetSameRange (const Standard_Boolean theValue)
+  {
+    mySameRange = theValue;
+  }
+
+  //! Returns degenerative flag.
+  //! By default equals to flag stored in topological shape.
+  inline Standard_Boolean GetDegenerated () const
+  {
+    return myDegenerated;
+  }
+
+  //! Updates degenerative flag.
+  inline void SetDegenerated (const Standard_Boolean theValue)
+  {
+    myDegenerated = theValue;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Edge, IMeshData_TessellatedShape)
+
+protected:
+
+  //! Constructor.
+  //! Initializes empty model.
+  Standard_EXPORT IMeshData_Edge (const TopoDS_Edge& theEdge)
+    : IMeshData_TessellatedShape(theEdge),
+      mySameParam  (BRep_Tool::SameParameter(theEdge)),
+      mySameRange  (BRep_Tool::SameRange    (theEdge)),
+      myDegenerated(BRep_Tool::Degenerated  (theEdge)),
+      myAngDeflection(RealLast())
+  {
+  }
+
+private:
+
+  Standard_Boolean        mySameParam;
+  Standard_Boolean        mySameRange;
+  Standard_Boolean        myDegenerated;
+  Standard_Real           myAngDeflection;
+  IMeshData::ICurveHandle myCurve;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Face.hxx b/src/IMeshData/IMeshData_Face.hxx
new file mode 100644 (file)
index 0000000..4db215d
--- /dev/null
@@ -0,0 +1,93 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Face_HeaderFile
+#define _IMeshData_Face_HeaderFile
+
+#include <IMeshData_TessellatedShape.hxx>
+#include <IMeshData_StatusOwner.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS.hxx>
+#include <IMeshData_Status.hxx>
+#include <IMeshData_Types.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+
+class IMeshData_Wire;
+class TopoDS_Wire;
+
+//! Interface class representing discrete model of a face.
+//! Face model contains one or several wires.
+//! First wire is always outer one.
+class IMeshData_Face : public IMeshData_TessellatedShape, public IMeshData_StatusOwner
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Face()
+  {
+  }
+
+  //! Returns number of wires.
+  Standard_EXPORT virtual Standard_Integer WiresNb () const = 0;
+
+  //! Adds wire to discrete model of face.
+  Standard_EXPORT virtual const IMeshData::IWireHandle& AddWire (
+    const TopoDS_Wire&     theWire,
+    const Standard_Integer theEdgeNb = 0) = 0;
+
+  //! Returns discrete edge with the given index.
+  Standard_EXPORT virtual const IMeshData::IWireHandle& GetWire (
+    const Standard_Integer theIndex) const = 0;
+
+  //! Returns face's surface.
+  inline const Handle(BRepAdaptor_HSurface)& GetSurface() const
+  {
+    return mySurface;
+  }
+
+  //! Returns TopoDS_Face attached to model.
+  inline const TopoDS_Face& GetFace () const
+  {
+    return TopoDS::Face (GetShape ());
+  }
+
+  //! Returns whether the face discrete model is valid.
+  inline Standard_Boolean IsValid () const
+  {
+    return (IsEqual(IMeshData_NoError) ||
+            IsEqual(IMeshData_ReMesh)  ||
+            IsEqual(IMeshData_UnorientedWire));
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Face, IMeshData_TessellatedShape)
+
+protected:
+
+  //! Constructor.
+  //! Initializes empty model.
+  Standard_EXPORT IMeshData_Face (const TopoDS_Face& theFace)
+    : IMeshData_TessellatedShape(theFace)
+  {
+    BRepAdaptor_Surface aSurfAdaptor(GetFace(), Standard_False);
+    mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
+  }
+
+private:
+
+  mutable Handle(BRepAdaptor_HSurface)  mySurface;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Model.hxx b/src/IMeshData/IMeshData_Model.hxx
new file mode 100644 (file)
index 0000000..773ab6e
--- /dev/null
@@ -0,0 +1,76 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Model_HeaderFile
+#define _IMeshData_Model_HeaderFile
+
+#include <IMeshData_Shape.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Shape.hxx>
+#include <IMeshData_Types.hxx>
+
+class TopoDS_Face;
+class TopoDS_Edge;
+class IMeshData_Face;
+class IMeshData_Edge;
+
+//! Interface class representing discrete model of a shape.
+class IMeshData_Model : public IMeshData_Shape
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Model()
+  {
+  }
+
+  //! Returns maximum size of shape model.
+  Standard_EXPORT virtual Standard_Real GetMaxSize () const = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Model, IMeshData_Shape)
+
+public: //! @name discrete faces
+
+  //! Returns number of faces in discrete model.
+  Standard_EXPORT virtual Standard_Integer FacesNb () const = 0;
+
+  //! Adds new face to shape model.
+  Standard_EXPORT virtual const IMeshData::IFaceHandle& AddFace (const TopoDS_Face& theFace) = 0;
+
+  //! Gets model's face with the given index.
+  Standard_EXPORT virtual const IMeshData::IFaceHandle& GetFace (const Standard_Integer theIndex) const = 0;
+
+public: //! @name discrete edges
+
+  //! Returns number of edges in discrete model.
+  Standard_EXPORT virtual Standard_Integer EdgesNb () const = 0;
+
+  //! Adds new edge to shape model.
+  Standard_EXPORT virtual const IMeshData::IEdgeHandle& AddEdge (const TopoDS_Edge& theEdge) = 0;
+
+  //! Gets model's edge with the given index.
+  Standard_EXPORT virtual const IMeshData::IEdgeHandle& GetEdge (const Standard_Integer theIndex) const = 0;
+
+protected:
+
+  //! Constructor.
+  //! Initializes empty model.
+  Standard_EXPORT IMeshData_Model (const TopoDS_Shape& theShape)
+    : IMeshData_Shape(theShape)
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_PCurve.hxx b/src/IMeshData/IMeshData_PCurve.hxx
new file mode 100644 (file)
index 0000000..4c6530c
--- /dev/null
@@ -0,0 +1,99 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_PCurve_HeaderFile
+#define _IMeshData_PCurve_HeaderFile
+
+#include <IMeshData_ParametersList.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshData_Face.hxx>
+
+class gp_Pnt2d;
+
+//! Interface class representing pcurve of edge associated with discrete face.
+//! Indexation of points starts from zero.
+class IMeshData_PCurve : public IMeshData_ParametersList
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_PCurve()
+  {
+  }
+
+  //! Inserts new discretization point at the given position.
+  Standard_EXPORT virtual void InsertPoint(
+    const Standard_Integer thePosition,
+    const gp_Pnt2d&        thePoint,
+    const Standard_Real    theParamOnPCurve) = 0;
+
+  //! Adds new discretization point to pcurve.
+  Standard_EXPORT virtual void AddPoint (
+    const gp_Pnt2d&     thePoint,
+    const Standard_Real theParamOnPCurve) = 0;
+
+  //! Returns discretization point with the given index.
+  Standard_EXPORT virtual gp_Pnt2d& GetPoint (const Standard_Integer theIndex) = 0;
+
+  //! Returns index in mesh corresponded to discretization point with the given index.
+  Standard_EXPORT virtual Standard_Integer& GetIndex(const Standard_Integer theIndex) = 0;
+
+  //! Removes point with the given index.
+  Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) = 0;
+
+  //! Returns forward flag of this pcurve.
+  inline Standard_Boolean IsForward () const
+  {
+    return (myOrientation != TopAbs_REVERSED);
+  }
+
+  //! Returns internal flag of this pcurve.
+  inline Standard_Boolean IsInternal() const
+  {
+    return (myOrientation == TopAbs_INTERNAL);
+  }
+
+  //! Returns orientation of the edge associated with current pcurve.
+  inline TopAbs_Orientation GetOrientation() const
+  {
+    return myOrientation;
+  }
+
+  //! Returns discrete face pcurve is associated to.
+  inline const IMeshData::IFacePtr& GetFace () const
+  {
+    return myDFace;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_PCurve, IMeshData_ParametersList)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_PCurve (
+    const IMeshData::IFacePtr& theDFace,
+    const TopAbs_Orientation   theOrientation)
+    : myDFace(theDFace),
+      myOrientation(theOrientation)
+  {
+  }
+
+private:
+
+  IMeshData::IFacePtr myDFace;
+  TopAbs_Orientation  myOrientation;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_ParametersList.hxx b/src/IMeshData/IMeshData_ParametersList.hxx
new file mode 100644 (file)
index 0000000..8190fd2
--- /dev/null
@@ -0,0 +1,54 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_ParametersList_HeaderFile
+#define _IMeshData_ParametersList_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+//! Interface class representing list of parameters on curve.
+class IMeshData_ParametersList : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_ParametersList()
+  {
+  }
+
+  //! Returns parameter with the given index.
+  Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) = 0;
+
+  //! Returns number of parameters.
+  Standard_EXPORT virtual Standard_Integer ParametersNb() const = 0;
+
+  //! Clears parameters list.
+  Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_ParametersList, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_ParametersList()
+  {
+  }
+
+  //! Removes parameter with the given index.
+  Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) = 0;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx b/src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx
new file mode 100644 (file)
index 0000000..4356961
--- /dev/null
@@ -0,0 +1,70 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_ParametersListArrayAdaptor_HeaderFile
+#define _IMeshData_ParametersListArrayAdaptor_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshData_ParametersList.hxx>
+
+//! Auxiliary tool representing adaptor interface for child classes of 
+//! IMeshData_ParametersList to be used in tools working on NCollection_Array structure.
+template<class ParametersListPtrType>
+class IMeshData_ParametersListArrayAdaptor : public Standard_Transient
+{
+public:
+
+  //! Constructor. Initializes tool by the given parameters.
+  Standard_EXPORT IMeshData_ParametersListArrayAdaptor(
+    const ParametersListPtrType& theParameters)
+    : myParameters (theParameters)
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_ParametersListArrayAdaptor()
+  {
+  }
+
+  //! Returns lower index in parameters array.
+  Standard_EXPORT Standard_Integer Lower() const
+  {
+    return 0;
+  }
+
+  //! Returns upper index in parameters array.
+  Standard_EXPORT Standard_Integer Upper() const
+  {
+    return myParameters->ParametersNb() - 1;
+  }
+
+  //! Returns value of the given index.
+  Standard_EXPORT Standard_Real Value(const Standard_Integer theIndex) const
+  {
+    return myParameters->GetParameter(theIndex);
+  }
+
+private:
+
+  IMeshData_ParametersListArrayAdaptor (
+    const IMeshData_ParametersListArrayAdaptor<ParametersListPtrType>& theOther);
+
+  void operator=(const IMeshData_ParametersListArrayAdaptor<ParametersListPtrType>& theOther);
+
+  const ParametersListPtrType myParameters;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Shape.hxx b/src/IMeshData/IMeshData_Shape.hxx
new file mode 100644 (file)
index 0000000..eb5100a
--- /dev/null
@@ -0,0 +1,66 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Shape_HeaderFile
+#define _IMeshData_Shape_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Interface class representing model with associated TopoDS_Shape.
+//! Intended for inheritance by structures and algorithms keeping 
+//! reference TopoDS_Shape.
+class IMeshData_Shape : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Shape()
+  {
+  }
+
+  //! Assigns shape to discrete shape.
+  inline void SetShape (const TopoDS_Shape& theShape)
+  {
+    myShape = theShape;
+  }
+
+  //! Returns shape assigned to discrete shape.
+  const TopoDS_Shape& GetShape () const
+  {
+    return myShape;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Shape, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_Shape()
+  {
+  }
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_Shape (const TopoDS_Shape& theShape)
+    : myShape(theShape)
+  {
+  }
+
+private:
+
+  TopoDS_Shape myShape;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Status.hxx b/src/IMeshData/IMeshData_Status.hxx
new file mode 100644 (file)
index 0000000..89f948f
--- /dev/null
@@ -0,0 +1,33 @@
+// Created on: 2011-05-17
+// Created by: Oleg AGASHIN
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Status_HeaderFile
+#define _IMeshData_Status_HeaderFile
+
+//! Enumerates statuses used to notify state of discrete model.
+enum IMeshData_Status
+{
+  IMeshData_NoError               = 0x0,
+  IMeshData_OpenWire              = 0x1,
+  IMeshData_SelfIntersectingWire  = 0x2,
+  IMeshData_Failure               = 0x4,
+  IMeshData_ReMesh                = 0x8,
+  IMeshData_UnorientedWire        = 0x10,
+  IMeshData_TooFewPoints          = 0x20,
+  IMeshData_Outdated              = 0x40,
+  IMeshData_Reused                = 0x80
+};
+
+#endif
diff --git a/src/IMeshData/IMeshData_StatusOwner.hxx b/src/IMeshData/IMeshData_StatusOwner.hxx
new file mode 100644 (file)
index 0000000..d1b54b0
--- /dev/null
@@ -0,0 +1,76 @@
+// Created on: 2016-06-23
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_StatusOwner_HeaderFile
+#define _IMeshData_StatusOwner_HeaderFile
+
+#include <IMeshData_Status.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+//! Extension interface class providing status functionality.
+class IMeshData_StatusOwner
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_StatusOwner()
+  {
+  }
+
+  //! Returns true in case if status is strictly equal to the given value.
+  inline Standard_Boolean IsEqual(const IMeshData_Status theValue) const
+  {
+    return (myStatus == theValue);
+  }
+
+  //! Returns true in case if status is set.
+  inline Standard_Boolean IsSet(const IMeshData_Status theValue) const
+  {
+    return (myStatus & theValue) != 0;
+  }
+
+  //! Adds status to status flags of a face.
+  inline void SetStatus(const IMeshData_Status theValue)
+  {
+    myStatus |= theValue;
+  }
+
+  //! Adds status to status flags of a face.
+  inline void UnsetStatus(const IMeshData_Status theValue)
+  {
+    myStatus &= ~theValue;
+  }
+
+  //! Returns complete status mask.
+  inline Standard_Integer GetStatusMask() const
+  {
+    return myStatus;
+  }
+
+protected:
+
+  //! Constructor. Initializes default status.
+  Standard_EXPORT IMeshData_StatusOwner()
+    : myStatus(IMeshData_NoError)
+  {
+  }
+
+private:
+
+  Standard_Integer myStatus;
+};
+
+#endif
diff --git a/src/IMeshData/IMeshData_TessellatedShape.hxx b/src/IMeshData/IMeshData_TessellatedShape.hxx
new file mode 100644 (file)
index 0000000..94001b0
--- /dev/null
@@ -0,0 +1,67 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_TessellatedShape_HeaderFile
+#define _IMeshData_TessellatedShape_HeaderFile
+
+#include <IMeshData_Shape.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Interface class representing shaped model with deflection.
+class IMeshData_TessellatedShape : public IMeshData_Shape
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_TessellatedShape()
+  {
+  }
+
+  //! Gets deflection value for the discrete model.
+  inline Standard_Real GetDeflection () const
+  {
+    return myDeflection;
+  }
+
+  //! Sets deflection value for the discrete model.
+  inline void SetDeflection (const Standard_Real theValue)
+  {
+    myDeflection = theValue;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_TessellatedShape, IMeshData_Shape)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_TessellatedShape ()
+    : myDeflection(RealLast())
+  {
+  }
+
+  //! Constructor.
+  Standard_EXPORT IMeshData_TessellatedShape (const TopoDS_Shape& theShape)
+    : IMeshData_Shape(theShape),
+      myDeflection(RealLast())
+  {
+  }
+
+private:
+
+  Standard_Real myDeflection;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Types.hxx b/src/IMeshData/IMeshData_Types.hxx
new file mode 100644 (file)
index 0000000..26c9eb4
--- /dev/null
@@ -0,0 +1,175 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Types_HeaderFile
+#define _IMeshData_Types_HeaderFile
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Vector.hxx>
+#include <NCollection_Sequence.hxx>
+#include <NCollection_List.hxx>
+#include <NCollection_Shared.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+#include <TopoDS_Shape.hxx>
+#include <NCollection_DefineAlloc.hxx>
+#include <NCollection_StdAllocator.hxx>
+#include <IMeshData_ParametersListArrayAdaptor.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+#include <Precision.hxx>
+#include <NCollection_EBTree.hxx>
+#include <Bnd_Box2d.hxx>
+#include <NCollection_CellFilter.hxx>
+#include <NCollection_IndexedDataMap.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+#include <Bnd_B2d.hxx>
+
+#include <memory>
+#include <queue>
+#include <list>
+
+class IMeshData_Shape;
+class IMeshData_Face;
+class IMeshData_Wire;
+class IMeshData_Edge;
+class IMeshData_Curve;
+class IMeshData_PCurve;
+class IMeshData_Model;
+class BRepMesh_VertexInspector;
+class BRepMesh_Triangle;
+class BRepMesh_Edge;
+class BRepMesh_PairOfIndex;
+class BRepMesh_Circle;
+class BRepMesh_CircleInspector;
+
+#define DEFINE_INC_ALLOC                      \
+  DEFINE_NCOLLECTION_ALLOC                    \
+  void operator delete (void* /*theAddress*/) \
+  {                                           \
+    /*it's inc allocator, nothing to do*/     \
+  }
+
+namespace IMeshData
+{
+  //! Default size for memory block allocated by IncAllocator. 
+  /**
+  * The idea here is that blocks of the given size are returned to the system
+  * rather than retained in the malloc heap, at least on WIN32 and WIN64 platforms.
+  */
+#ifdef _WIN64
+  const size_t MEMORY_BLOCK_SIZE_HUGE = 1024 * 1024;
+#else
+  const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
+#endif
+
+  typedef std::weak_ptr<IMeshData_Shape>  IShapePtr;
+  typedef std::weak_ptr<IMeshData_Edge>   IEdgePtr;
+  typedef std::weak_ptr<IMeshData_Wire>   IWirePtr;
+  typedef std::weak_ptr<IMeshData_Face>   IFacePtr;
+  typedef std::weak_ptr<IMeshData_Curve>  ICurvePtr;
+  typedef std::weak_ptr<IMeshData_PCurve> IPCurvePtr;
+  typedef std::weak_ptr<IMeshData_Model>  IModelPtr;
+
+  typedef std::shared_ptr<IMeshData_Shape>    IShapeHandle;
+  typedef std::shared_ptr<IMeshData_Edge>     IEdgeHandle;
+  typedef std::shared_ptr<IMeshData_Wire>     IWireHandle;
+  typedef std::shared_ptr<IMeshData_Face>     IFaceHandle;
+  typedef std::shared_ptr<IMeshData_Curve>    ICurveHandle;
+  typedef std::shared_ptr<IMeshData_PCurve>   IPCurveHandle;
+  typedef std::shared_ptr<IMeshData_Model>    IModelHandle;
+
+  typedef IMeshData_ParametersListArrayAdaptor<ICurveHandle> ICurveArrayAdaptor;
+  typedef std::shared_ptr<ICurveArrayAdaptor>                ICurveArrayAdaptorHandle;
+
+  typedef NCollection_Shared<NCollection_EBTree<Standard_Integer, Bnd_Box2d> > BndBox2dTree;
+  typedef NCollection_UBTreeFiller<Standard_Integer, Bnd_Box2d>                BndBox2dTreeFiller;
+
+  // Vectors
+  typedef NCollection_Vector<IFaceHandle>        VectorOfIFaceHandles;
+  typedef NCollection_Vector<IWireHandle>        VectorOfIWireHandles;
+  typedef NCollection_Vector<IEdgeHandle>        VectorOfIEdgeHandles;
+  typedef NCollection_Vector<IPCurveHandle>      VectorOfIPCurveHandles;
+  typedef NCollection_Vector<IEdgePtr>           VectorOfIEdgePtrs;
+  typedef NCollection_Vector<IShapeHandle>       VectorOfIShapesHandles;
+  typedef NCollection_Vector<Standard_Boolean>   VectorOfBoolean;
+  typedef NCollection_Vector<Standard_Integer>   VectorOfInteger;
+  typedef NCollection_Vector<TopAbs_Orientation> VectorOfOrientation;
+  typedef NCollection_Vector<Handle(BndBox2dTree)>  VectorOfHBndBox2dTree;
+  typedef NCollection_Vector<BRepMesh_Triangle>     VectorOfElements;
+  typedef NCollection_Vector<BRepMesh_Circle>       VectorOfCircle;
+
+  typedef NCollection_Array1<BRepMesh_Vertex>                       Array1OfVertexOfDelaun;
+  typedef NCollection_Shared<NCollection_Vector<BRepMesh_Vertex> >  VectorOfVertex;
+
+  // Sequences
+  typedef NCollection_Shared<NCollection_Sequence<Bnd_B2d> >          SequenceOfBndB2d;
+  typedef NCollection_Shared<NCollection_Sequence<Standard_Integer> > SequenceOfInteger;
+  typedef NCollection_Shared<NCollection_Sequence<Standard_Real> >    SequenceOfReal;
+
+  namespace Model
+  {
+    typedef std::deque<gp_Pnt, NCollection_StdAllocator<gp_Pnt> >                     SequenceOfPnt;
+    typedef std::deque<gp_Pnt2d, NCollection_StdAllocator<gp_Pnt2d> >                 SequenceOfPnt2d;
+    typedef std::deque<Standard_Real, NCollection_StdAllocator<Standard_Real> >       SequenceOfReal;
+    typedef std::deque<Standard_Integer, NCollection_StdAllocator<Standard_Integer> > SequenceOfInteger;
+  }
+
+  // Lists
+  typedef NCollection_Shared<NCollection_List<Standard_Integer> > ListOfInteger;
+  typedef NCollection_Shared<NCollection_List<gp_Pnt2d> >         ListOfPnt2d;
+  typedef NCollection_List<IPCurveHandle>                         ListOfIPCurves;
+
+  typedef NCollection_Shared<TColStd_PackedMapOfInteger>          MapOfInteger;
+  typedef TColStd_MapIteratorOfPackedMapOfInteger                 IteratorOfMapOfInteger;
+
+  typedef NCollection_CellFilter<BRepMesh_CircleInspector>   CircleCellFilter;
+  typedef NCollection_CellFilter<BRepMesh_VertexInspector>   VertexCellFilter;
+
+  // Data Maps
+  template<typename Type>
+  struct WeakEqual
+  {
+    static Standard_Boolean IsEqual(const std::weak_ptr<Type>& theFirst,
+                                    const std::weak_ptr<Type>& theSecond)
+    {
+      return (theFirst.lock().get() == theSecond.lock().get());
+    }
+
+    static Standard_Integer HashCode(const std::weak_ptr<Type>& thePtr, Standard_Integer theUpper)
+    {
+      return ::HashCode(thePtr.lock().get(), theUpper);
+    }
+  };
+
+  typedef NCollection_Shared<NCollection_DataMap<TopoDS_Shape, Standard_Integer, TopTools_ShapeMapHasher> >     DMapOfShapeInteger;
+  typedef NCollection_Shared<NCollection_DataMap<IFacePtr, ListOfInteger, WeakEqual<IMeshData_Face> > >         DMapOfIFacePtrsListOfInteger;
+  typedef NCollection_Shared<NCollection_Map<IEdgePtr, WeakEqual<IMeshData_Edge> > >                            MapOfIEdgePtr;
+  typedef NCollection_Shared<NCollection_Map<IFacePtr, WeakEqual<IMeshData_Face> > >                            MapOfIFacePtr;
+  typedef NCollection_Shared<NCollection_Map<BRepMesh_OrientedEdge> >                                           MapOfOrientedEdges;
+  typedef NCollection_Shared<NCollection_Map<Standard_Real> >                                                   MapOfReal;
+  typedef NCollection_Shared<NCollection_IndexedDataMap<IFacePtr, ListOfIPCurves, WeakEqual<IMeshData_Face> > > IDMapOfIFacePtrsListOfIPCurves;
+  typedef NCollection_Shared<NCollection_DataMap<IFacePtr, Handle(MapOfIEdgePtr), WeakEqual<IMeshData_Face> > > DMapOfIFacePtrsMapOfIEdgePtrs;
+  typedef NCollection_IndexedDataMap<BRepMesh_Edge, BRepMesh_PairOfIndex>                                       IDMapOfLink;
+  typedef NCollection_DataMap<Standard_Integer, ListOfInteger>                                                  DMapOfIntegerListOfInteger;
+  typedef NCollection_DataMap<Standard_Integer, Standard_Integer>                                               MapOfIntegerInteger;
+  typedef NCollection_IndexedMap<Standard_Real>                                                                 IMapOfReal;
+
+  typedef NCollection_Array1<Standard_Integer>                                                                  Array1OfInteger;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshData/IMeshData_Wire.hxx b/src/IMeshData/IMeshData_Wire.hxx
new file mode 100644 (file)
index 0000000..e2c2634
--- /dev/null
@@ -0,0 +1,74 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshData_Wire_HeaderFile
+#define _IMeshData_Wire_HeaderFile
+
+#include <IMeshData_TessellatedShape.hxx>
+#include <IMeshData_StatusOwner.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS.hxx>
+#include <IMeshData_Types.hxx>
+
+class IMeshData_Edge;
+
+//! Interface class representing discrete model of a wire.
+//! Wire should represent an ordered set of edges.
+class IMeshData_Wire : public IMeshData_TessellatedShape, public IMeshData_StatusOwner
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshData_Wire()
+  {
+  }
+
+  //! Returns TopoDS_Face attached to model.
+  inline const TopoDS_Wire& GetWire () const
+  {
+    return TopoDS::Wire (GetShape ());
+  }
+
+  //! Returns number of edges.
+  Standard_EXPORT virtual Standard_Integer EdgesNb () const = 0;
+
+  //! Adds new discrete edge with specified orientation to wire chain.
+  //! @return index of added edge in wire chain.
+  Standard_EXPORT virtual Standard_Integer AddEdge (
+    const IMeshData::IEdgePtr& theDEdge,
+    const TopAbs_Orientation   theOrientation) = 0;
+
+  //! Returns discrete edge with the given index.
+  Standard_EXPORT virtual const IMeshData::IEdgePtr& GetEdge (
+    const Standard_Integer theIndex) const = 0;
+
+  //! Returns True if orientation of discrete edge with the given index is forward.
+  Standard_EXPORT virtual TopAbs_Orientation GetEdgeOrientation (
+    const Standard_Integer theIndex) const = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshData_Wire, IMeshData_TessellatedShape)
+
+protected:
+
+  //! Constructor.
+  //! Initializes empty model.
+  Standard_EXPORT IMeshData_Wire(const TopoDS_Wire& theWire)
+    : IMeshData_TessellatedShape(theWire)
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/FILES b/src/IMeshTools/FILES
new file mode 100644 (file)
index 0000000..a5ba04e
--- /dev/null
@@ -0,0 +1,10 @@
+IMeshTools_Context.hxx
+IMeshTools_CurveTessellator.hxx
+IMeshTools_MeshAlgo.hxx
+IMeshTools_MeshAlgoFactory.hxx
+IMeshTools_MeshBuilder.hxx
+IMeshTools_ModelAlgo.hxx
+IMeshTools_ModelBuilder.hxx
+IMeshTools_Parameters.hxx
+IMeshTools_ShapeExplorer.hxx
+IMeshTools_ShapeVisitor.hxx
diff --git a/src/IMeshTools/IMeshTools_Context.hxx b/src/IMeshTools/IMeshTools_Context.hxx
new file mode 100644 (file)
index 0000000..fe77996
--- /dev/null
@@ -0,0 +1,240 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_Context_HeaderFile
+#define _IMeshTools_Context_HeaderFile
+
+#include <IMeshData_Shape.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshTools_ModelBuilder.hxx>
+#include <IMeshData_Model.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshTools_ModelAlgo.hxx>
+
+//! Interface class representing context of BRepMesh algorithm.
+//! Intended to cache discrete model and instances of tools for 
+//! its processing.
+class IMeshTools_Context : public IMeshData_Shape
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_Context()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_Context()
+  {
+  }
+
+  //! Builds model using assined model builder.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean BuildModel ()
+  {
+    if (myModelBuilder.IsNull())
+    {
+      return Standard_False;
+    }
+
+    myModel = myModelBuilder->Perform(GetShape(), myParameters);
+
+    return !myModel.IsNull();
+  }
+
+  //! Performs discretization of model edges using assigned edge discret algorithm.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean DiscretizeEdges()
+  {
+    if (myModel.IsNull() || myEdgeDiscret.IsNull())
+    {
+      return Standard_False;
+    }
+
+    // Discretize edges of a model.
+    return myEdgeDiscret->Perform(myModel, myParameters);
+  }
+
+  //! Performs healing of discrete model built by DiscretizeEdges() method
+  //! using assigned healing algorithm.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean HealModel()
+  {
+    if (myModel.IsNull())
+    {
+      return Standard_False;
+    }
+
+    return myModelHealer.IsNull() ?
+      Standard_True :
+      myModelHealer->Perform(myModel, myParameters);
+  }
+
+  //! Performs pre-processing of discrete model using assigned algorithm.
+  //! Performs auxiliary actions such as cleaning shape from old triangulation.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean PreProcessModel()
+  {
+    if (myModel.IsNull())
+    {
+      return Standard_False;
+    }
+
+    return myPreProcessor.IsNull() ? 
+      Standard_True :
+      myPreProcessor->Perform(myModel, myParameters);
+  }
+
+  //! Performs meshing of faces of discrete model using assigned meshing algorithm.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean DiscretizeFaces()
+  {
+    if (myModel.IsNull() || myFaceDiscret.IsNull())
+    {
+      return Standard_False;
+    }
+
+    // Discretize faces of a model.
+    return myFaceDiscret->Perform(myModel, myParameters);
+  }
+
+  //! Performs post-processing of discrete model using assigned algorithm.
+  //! @return True on success, False elsewhere.
+  Standard_EXPORT virtual Standard_Boolean PostProcessModel()
+  {
+    if (myModel.IsNull())
+    {
+      return Standard_False;
+    }
+
+    return myPostProcessor.IsNull() ?
+      Standard_True :
+      myPostProcessor->Perform(myModel, myParameters);
+  }
+
+  //! Cleans temporary context data.
+  Standard_EXPORT virtual void Clean()
+  {
+    if (myParameters.CleanModel)
+    {
+      myModel.Nullify();
+    }
+  }
+
+  //! Gets instance of a tool to be used to build discrete model.
+  inline const Handle (IMeshTools_ModelBuilder)& GetModelBuilder () const
+  {
+    return myModelBuilder;
+  }
+
+  //! Sets instance of a tool to be used to build discrete model.
+  inline void SetModelBuilder (const Handle (IMeshTools_ModelBuilder)& theBuilder)
+  {
+    myModelBuilder = theBuilder;
+  }
+
+  //! Gets instance of a tool to be used to discretize edges of a model.
+  inline const Handle (IMeshTools_ModelAlgo)& GetEdgeDiscret () const
+  {
+    return myEdgeDiscret;
+  }
+
+  //! Sets instance of a tool to be used to discretize edges of a model.
+  inline void SetEdgeDiscret (const Handle (IMeshTools_ModelAlgo)& theEdgeDiscret)
+  {
+    myEdgeDiscret = theEdgeDiscret;
+  }
+
+  //! Gets instance of a tool to be used to heal discrete model.
+  inline const Handle(IMeshTools_ModelAlgo)& GetModelHealer() const
+  {
+    return myModelHealer;
+  }
+
+  //! Sets instance of a tool to be used to heal discrete model.
+  inline void SetModelHealer(const Handle(IMeshTools_ModelAlgo)& theModelHealer)
+  {
+    myModelHealer = theModelHealer;
+  }
+
+  //! Gets instance of pre-processing algorithm.
+  inline const Handle(IMeshTools_ModelAlgo)& GetPreProcessor() const
+  {
+    return myPreProcessor;
+  }
+
+  //! Sets instance of pre-processing algorithm.
+  inline void SetPreProcessor(const Handle(IMeshTools_ModelAlgo)& thePreProcessor)
+  {
+    myPreProcessor = thePreProcessor;
+  }
+
+  //! Gets instance of meshing algorithm.
+  inline const Handle(IMeshTools_ModelAlgo)& GetFaceDiscret() const
+  {
+    return myFaceDiscret;
+  }
+
+  //! Sets instance of meshing algorithm.
+  inline void SetFaceDiscret(const Handle(IMeshTools_ModelAlgo)& theFaceDiscret)
+  {
+    myFaceDiscret = theFaceDiscret;
+  }
+
+  //! Gets instance of post-processing algorithm.
+  inline const Handle(IMeshTools_ModelAlgo)& GetPostProcessor() const
+  {
+    return myPostProcessor;
+  }
+
+  //! Sets instance of post-processing algorithm.
+  inline void SetPostProcessor(const Handle(IMeshTools_ModelAlgo)& thePostProcessor)
+  {
+    myPostProcessor = thePostProcessor;
+  }
+
+  //! Gets parameters to be used for meshing.
+  inline const IMeshTools_Parameters& GetParameters () const 
+  {
+    return myParameters;
+  }
+
+  //! Gets reference to parameters to be used for meshing.
+  inline IMeshTools_Parameters& ChangeParameters ()
+  {
+    return myParameters;
+  }
+
+  //! Returns discrete model of a shape.
+  inline const Handle (IMeshData_Model)& GetModel () const
+  {
+    return myModel;
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_Context, IMeshData_Shape)
+
+private:
+
+  Handle (IMeshTools_ModelBuilder) myModelBuilder;
+  Handle (IMeshData_Model)         myModel;
+  Handle (IMeshTools_ModelAlgo)    myEdgeDiscret;
+  Handle (IMeshTools_ModelAlgo)    myModelHealer;
+  Handle (IMeshTools_ModelAlgo)    myPreProcessor;
+  Handle (IMeshTools_ModelAlgo)    myFaceDiscret;
+  Handle (IMeshTools_ModelAlgo)    myPostProcessor;
+  IMeshTools_Parameters            myParameters;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_CurveTessellator.hxx b/src/IMeshTools/IMeshTools_CurveTessellator.hxx
new file mode 100644 (file)
index 0000000..2cbd66b
--- /dev/null
@@ -0,0 +1,57 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_EdgeTessellator_HeaderFile
+#define _IMeshTools_EdgeTessellator_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+class gp_Pnt;
+
+//! Interface class providing API for edge tessellation tools.
+class IMeshTools_CurveTessellator : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_CurveTessellator()
+  {
+  }
+
+  //! Returns number of tessellation points.
+  Standard_EXPORT virtual Standard_Integer PointsNb () const = 0;
+
+  //! Returns parameters of solution with the given index.
+  //! @param theIndex index of tessellation point.
+  //! @param thePoint tessellation point.
+  //! @param theParameter parameters on PCurve corresponded to the solution.
+  //! @return True in case of valid result, false elewhere.
+  Standard_EXPORT virtual Standard_Boolean Value (
+    const Standard_Integer theIndex,
+    gp_Pnt&                thePoint,
+    Standard_Real&         theParameter) const = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_CurveTessellator, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_CurveTessellator()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_MeshAlgo.hxx b/src/IMeshTools/IMeshTools_MeshAlgo.hxx
new file mode 100644 (file)
index 0000000..fb8e0b6
--- /dev/null
@@ -0,0 +1,50 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_MeshAlgo_HeaderFile
+#define _IMeshTools_MeshAlgo_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshData_Types.hxx>
+
+struct IMeshTools_Parameters;
+
+//! Interface class providing API for algorithms intended to create mesh for discrete face.
+class IMeshTools_MeshAlgo : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_MeshAlgo()
+  {
+  }
+
+  //! Performs processing of the given face.
+  Standard_EXPORT virtual void Perform(
+    const IMeshData::IFaceHandle& theDFace,
+    const IMeshTools_Parameters&  theParameters) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshAlgo, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshAlgo()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx b/src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx
new file mode 100644 (file)
index 0000000..4700875
--- /dev/null
@@ -0,0 +1,52 @@
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_MeshAlgoFactory_HeaderFile
+#define _IMeshTools_MeshAlgoFactory_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+#include <GeomAbs_SurfaceType.hxx>
+#include <IMeshTools_MeshAlgo.hxx>
+
+struct IMeshTools_Parameters;
+
+//! Base interface for factories producing instances of triangulation
+//! algorithms taking into account type of surface of target face.
+class IMeshTools_MeshAlgoFactory : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_MeshAlgoFactory()
+  {
+  }
+
+  //! Creates instance of meshing algorithm for the given type of surface.
+  Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo(
+    const GeomAbs_SurfaceType    theSurfaceType,
+    const IMeshTools_Parameters& theParameters) const = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshAlgoFactory, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshAlgoFactory()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_MeshBuilder.hxx b/src/IMeshTools/IMeshTools_MeshBuilder.hxx
new file mode 100644 (file)
index 0000000..dc7bc8c
--- /dev/null
@@ -0,0 +1,68 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_MeshBuilder_HeaderFile
+#define _IMeshTools_MeshBuilder_HeaderFile
+
+#include <Message_Algorithm.hxx>
+#include <IMeshTools_Context.hxx>
+#include <Standard_Type.hxx>
+
+//! Interface class providing API for mesh builder tool.
+class IMeshTools_MeshBuilder : public Message_Algorithm
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_MeshBuilder()
+  {
+  }
+
+  //! Sets context for algorithm.
+  inline void SetContext (const Handle (IMeshTools_Context)& theContext)
+  {
+    myContext = theContext;
+  }
+
+  //! Gets context of algorithm.
+  inline const Handle (IMeshTools_Context)& GetContext () const
+  {
+    return myContext;
+  }
+
+  //! Performs meshing ot the shape using current context.
+  Standard_EXPORT virtual void Perform () = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshBuilder, Message_Algorithm)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshBuilder()
+  {
+  }
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshBuilder (const Handle (IMeshTools_Context)& theContext)
+    : myContext(theContext)
+  {
+  }
+
+private:
+
+  Handle (IMeshTools_Context) myContext;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_ModelAlgo.hxx b/src/IMeshTools/IMeshTools_ModelAlgo.hxx
new file mode 100644 (file)
index 0000000..7e378dc
--- /dev/null
@@ -0,0 +1,50 @@
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_ModelAlgo_HeaderFile
+#define _IMeshTools_ModelAlgo_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+class IMeshData_Model;
+struct IMeshTools_Parameters;
+
+//! Interface class providing API for algorithms intended to update or modify discrete model.
+class IMeshTools_ModelAlgo : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_ModelAlgo()
+  {
+  }
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean Perform (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ModelAlgo()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_ModelBuilder.hxx b/src/IMeshTools/IMeshTools_ModelBuilder.hxx
new file mode 100644 (file)
index 0000000..1dcdc3d
--- /dev/null
@@ -0,0 +1,57 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_ModelBuilder_HeaderFile
+#define _IMeshTools_ModelBuilder_HeaderFile
+
+#include <Message_Algorithm.hxx>
+#include <Standard_Type.hxx>
+#include <TopoDS_Shape.hxx>
+
+class IMeshData_Model;
+struct IMeshTools_Parameters;
+
+//! Interface class represents API for tool building discrete model.
+//! 
+//! The following statuses should be used by default:
+//! Message_Done1 - model has been sucessfully built.
+//! Message_Fail1 - empty shape.
+//! Message_Fail2 - model has not been build due to unexpected reason.
+class IMeshTools_ModelBuilder : public Message_Algorithm
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_ModelBuilder()
+  {
+  }
+
+  //! Creates discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ModelBuilder()
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_Parameters.hxx b/src/IMeshTools/IMeshTools_Parameters.hxx
new file mode 100644 (file)
index 0000000..60acf8e
--- /dev/null
@@ -0,0 +1,68 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_Parameters_HeaderFile
+#define _IMeshTools_Parameters_HeaderFile
+
+#include <Precision.hxx>
+
+//! Structure storing meshing parameters
+struct IMeshTools_Parameters {
+
+  //! Default constructor
+  IMeshTools_Parameters ()
+    :
+    Angle (0.5),
+    Deflection (0.001),
+    MinSize (Precision::Confusion ()),
+    InParallel (Standard_False),
+    Relative (Standard_False),
+    InternalVerticesMode (Standard_True),
+    ControlSurfaceDeflection (Standard_True),
+    CleanModel(Standard_True)
+  {
+  }
+
+  //! Angular deflection
+  Standard_Real                                    Angle;
+
+  //! Deflection
+  Standard_Real                                    Deflection;
+
+  //! Minimal allowed size of mesh element
+  Standard_Real                                    MinSize;
+
+  //! Switches on/off multi-thread computation
+  Standard_Boolean                                 InParallel;
+
+  //! Switches on/off relative computation of edge tolerance<br>
+  //! If true, deflection used for the polygonalisation of each edge will be 
+  //! <defle> * Size of Edge. The deflection used for the faces will be the 
+  //! maximum deflection of their edges.
+  Standard_Boolean                                 Relative;
+
+  //! Mode to take or not to take internal face vertices into account
+  //! in triangulation process
+  Standard_Boolean                                 InternalVerticesMode;
+
+  //! Parameter to check the deviation of triangulation and interior of
+  //! the face
+  Standard_Boolean                                 ControlSurfaceDeflection;
+
+  //! Cleans temporary data model when algorithm is finished.
+  Standard_Boolean                                 CleanModel;
+};
+
+#endif
diff --git a/src/IMeshTools/IMeshTools_ShapeExplorer.hxx b/src/IMeshTools/IMeshTools_ShapeExplorer.hxx
new file mode 100644 (file)
index 0000000..a6ee59e
--- /dev/null
@@ -0,0 +1,48 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_ShapeExplorer_HeaderFile
+#define _IMeshTools_ShapeExplorer_HeaderFile
+
+#include <IMeshData_Shape.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshTools_ShapeVisitor.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Interface class for tools exploring TopoDS_Shape.
+class IMeshTools_ShapeExplorer : public IMeshData_Shape
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_ShapeExplorer()
+  {
+  }
+
+  //! Starts exploring of a shape.
+  Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ShapeExplorer, IMeshData_Shape)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ShapeExplorer (const TopoDS_Shape& theShape)
+    : IMeshData_Shape(theShape)
+  {
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/src/IMeshTools/IMeshTools_ShapeVisitor.hxx b/src/IMeshTools/IMeshTools_ShapeVisitor.hxx
new file mode 100644 (file)
index 0000000..50ee23d
--- /dev/null
@@ -0,0 +1,51 @@
+// Created on: 2016-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _IMeshTools_ShapeVisitor_HeaderFile
+#define _IMeshTools_ShapeVisitor_HeaderFile
+
+#include <Standard_Transient.hxx>
+#include <Standard_Type.hxx>
+
+class TopoDS_Face;
+class TopoDS_Edge;
+
+//! Interface class for shape visitor.
+class IMeshTools_ShapeVisitor : public Standard_Transient
+{
+public:
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_ShapeVisitor()
+  {
+  }
+
+  //! Handles TopoDS_Face object.
+  Standard_EXPORT virtual void Visit (const TopoDS_Face& theFace) = 0;
+
+  //! Handles TopoDS_Edge object.
+  Standard_EXPORT virtual void Visit (const TopoDS_Edge& theEdge) = 0;
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ShapeVisitor, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ShapeVisitor()
+  {
+  }
+};
+
+#endif
\ No newline at end of file