]> OCCT Git - occt.git/commitdiff
Update BRepMesh component according to OCCT's 7.4.0
authoroan <oan@opencascade.com>
Mon, 16 Jan 2023 11:57:12 +0000 (14:57 +0300)
committeroan <oan@opencascade.com>
Mon, 16 Jan 2023 11:57:12 +0000 (14:57 +0300)
Includes #26106 patch

151 files changed:
adm/UDLIST
src/AIS/AIS_RubberBand.cxx
src/BRepMesh/BRepMesh.hxx [deleted file]
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_CircleInspector.hxx
src/BRepMesh/BRepMesh_CircleTool.cxx
src/BRepMesh/BRepMesh_CircleTool.hxx
src/BRepMesh/BRepMesh_Classifier.cxx
src/BRepMesh/BRepMesh_Classifier.hxx
src/BRepMesh/BRepMesh_ConeRangeSplitter.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ConstrainedBaseMeshAlgo.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_CustomBaseMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CustomDelaunayBaseMeshAlgo.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CylinderRangeSplitter.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_DataStructureOfDelaun.cxx
src/BRepMesh/BRepMesh_DataStructureOfDelaun.hxx
src/BRepMesh/BRepMesh_DefaultRangeSplitter.cxx [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_Delaun.cxx
src/BRepMesh/BRepMesh_Delaun.hxx
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_DiscretFactory.hxx
src/BRepMesh/BRepMesh_DiscretRoot.hxx
src/BRepMesh/BRepMesh_Edge.hxx
src/BRepMesh/BRepMesh_EdgeDiscret.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_EdgeDiscret.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_EdgeParameterProvider.cxx [deleted file]
src/BRepMesh/BRepMesh_EdgeParameterProvider.hxx
src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx
src/BRepMesh/BRepMesh_EdgeTessellationExtractor.hxx
src/BRepMesh/BRepMesh_EdgeTessellator.cxx [deleted file]
src/BRepMesh/BRepMesh_EdgeTessellator.hxx [deleted file]
src/BRepMesh/BRepMesh_FaceAttribute.cxx [deleted file]
src/BRepMesh/BRepMesh_FaceAttribute.hxx [deleted file]
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_FastDiscret.cxx [deleted file]
src/BRepMesh/BRepMesh_FastDiscret.hxx
src/BRepMesh/BRepMesh_FastDiscretFace.cxx [deleted file]
src/BRepMesh/BRepMesh_FastDiscretFace.hxx [deleted file]
src/BRepMesh/BRepMesh_GeomTool.cxx
src/BRepMesh/BRepMesh_GeomTool.hxx
src/BRepMesh/BRepMesh_IEdgeTool.cxx [deleted file]
src/BRepMesh/BRepMesh_IEdgeTool.hxx [deleted file]
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_IncrementalMesh.hxx
src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_MeshAlgoFactory.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_OrientedEdge.hxx
src/BRepMesh/BRepMesh_PairOfPolygon.hxx [deleted file]
src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.cxx
src/BRepMesh/BRepMesh_SelectorOfDataStructureOfDelaun.hxx
src/BRepMesh/BRepMesh_ShapeTool.cxx
src/BRepMesh/BRepMesh_ShapeTool.hxx
src/BRepMesh/BRepMesh_ShapeVisitor.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_ShapeVisitor.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_SphereRangeSplitter.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Status.hxx [deleted file]
src/BRepMesh/BRepMesh_TorusRangeSplitter.cxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Triangle.hxx
src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx [new file with mode: 0644]
src/BRepMesh/BRepMesh_Vertex.hxx
src/BRepMesh/BRepMesh_VertexInspector.hxx
src/BRepMesh/BRepMesh_VertexTool.cxx
src/BRepMesh/BRepMesh_VertexTool.hxx
src/BRepMesh/BRepMesh_WireChecker.cxx [deleted file]
src/BRepMesh/BRepMesh_WireChecker.hxx [deleted file]
src/BRepMesh/BRepMesh_WireInterferenceChecker.cxx [deleted file]
src/BRepMesh/BRepMesh_WireInterferenceChecker.hxx [deleted file]
src/BRepMesh/FILES
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/DBRep/DBRep_DrawableShape.cxx
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.cxx [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.cxx [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]
src/MeshTest/MeshTest.cxx
src/MeshTest/MeshTest_Debug.cxx
src/MeshTest/MeshTest_DrawableMesh.cxx
src/QABugs/QABugs_11.cxx
src/SelectMgr/SelectMgr_TriangularFrustumSet.cxx
src/StdPrs/StdPrs_HLRPolyShape.cxx
src/TKMesh/EXTERNLIB
src/TKMesh/PACKAGES
tests/bugs/grids.list
tests/lowalgos/grids.list

index 39ffb0ba8a3d21b78afbb5c194faa9a8d3a28209..42d740c06af142bcd1985e345c24d372cd321f8b 100644 (file)
@@ -105,6 +105,7 @@ n BRepIntCurveSurface
 n BRepLib
 n BRepMAT2d
 n BRepMesh
+n BRepMeshData
 n BRepOffset
 n BRepOffsetAPI
 n BRepPrim
@@ -141,6 +142,8 @@ n HLRTopoBRep
 n HLRAppli
 n Hatch
 n HatchGen
+n IMeshData
+n IMeshTools
 n IntCurve
 n IntCurveSurface
 n IntCurvesFace
index 1d7f1ab9d17cb08a648b7c7198c073729deef8e8..6de1394d36c1686e8389fc308937031718bd8bad 100644 (file)
@@ -296,13 +296,13 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
   Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
   Standard_Integer aPtsLower = myPoints.Lower();
   Standard_Integer aPtsUpper = myPoints.Upper();
-  BRepMesh::Array1OfInteger anIndexes (0, myPoints.Length() - 1);
+  IMeshData::VectorOfInteger anIndexes (myPoints.Length());
   for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
   {
     gp_XY aP ((Standard_Real)myPoints.Value (aPtIdx).x(),
               (Standard_Real)myPoints.Value (aPtIdx).y());
     BRepMesh_Vertex aVertex (aP, aPtIdx, BRepMesh_Frontier);
-    anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
+    anIndexes.Append (aMeshStructure->AddNode (aVertex));
   }
 
   Standard_Real aPtSum = 0;
@@ -325,7 +325,7 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
   }
 
   BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
-  const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
+  const IMeshData::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
   if (aTriangles.Extent() < 1)
     return Standard_False;
 
@@ -338,7 +338,7 @@ Standard_Boolean AIS_RubberBand::fillTriangles()
   }
 
   Standard_Integer aVertexIndex = 1;
-  BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
+  IMeshData::IteratorOfMapOfInteger aTriangleIt (aTriangles);
   for (; aTriangleIt.More(); aTriangleIt.Next())
   {
     const Standard_Integer aTriangleId = aTriangleIt.Key();
diff --git a/src/BRepMesh/BRepMesh.hxx b/src/BRepMesh/BRepMesh.hxx
deleted file mode 100644 (file)
index 8d503f6..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 1999-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 _BRepMesh_HeaderFile
-#define _BRepMesh_HeaderFile
-
-#include <gp_Pnt.hxx>
-#include <gp_XYZ.hxx>
-#include <gp_XY.hxx>
-#include <Bnd_B2d.hxx>
-#include <Bnd_Box2d.hxx>
-#include <Standard.hxx>
-#include <NCollection_List.hxx>
-#include <NCollection_Map.hxx>
-#include <NCollection_Vector.hxx>
-#include <NCollection_Handle.hxx>
-#include <NCollection_DataMap.hxx>
-#include <NCollection_IndexedMap.hxx>
-#include <NCollection_IndexedDataMap.hxx>
-#include <NCollection_Array1.hxx>
-#include <NCollection_Sequence.hxx>
-#include <NCollection_CellFilter.hxx>
-#include <NCollection_IncAllocator.hxx>
-#include <NCollection_EBTree.hxx>
-#include <NCollection_UBTreeFiller.hxx>
-#include <BRepMesh_Edge.hxx>
-#include <BRepMesh_Triangle.hxx>
-#include <BRepMesh_PairOfPolygon.hxx>
-#include <BRepMesh_PairOfIndex.hxx>
-#include <BRepMesh_Circle.hxx>
-#include <TopTools_ShapeMapHasher.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-
-#include <vector>
-
-class BRepMesh_Vertex;
-class TopoDS_Edge;
-class TopoDS_Vertex;
-class BRepMesh_FaceAttribute;
-class BRepMesh_VertexInspector;
-class BRepMesh_CircleInspector;
-class BRepMesh_Classifier;
-class Poly_Triangulation;
-class BRepMesh_VertexTool;
-
-namespace BRepMesh
-{
-  //! 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
-
-  //! Structure keeping parameters of segment.
-  struct Segment
-  {
-    gp_XY StartPnt;
-    gp_XY EndPnt;
-  };
-
-  //! Sequences
-  typedef NCollection_Sequence<Bnd_B2d>                                                             SequenceOfBndB2d;
-  typedef NCollection_Sequence<Standard_Integer>                                                    SequenceOfInteger;
-  typedef NCollection_Sequence<Standard_Real>                                                       SequenceOfReal;
-
-  //! Vectors
-  typedef NCollection_Vector<BRepMesh_Vertex>                                                       VectorOfVertex;
-  typedef NCollection_Vector<Standard_Integer>                                                      VectorOfInteger;
-  typedef NCollection_Vector<BRepMesh_Circle>                                                       VectorOfCircle;
-
-  //! Trees
-  typedef NCollection_EBTree<Standard_Integer, Bnd_Box2d>                                           BndBox2dTree;
-  typedef NCollection_UBTreeFiller<Standard_Integer, Bnd_Box2d>                                     BndBox2dTreeFiller;
-
-  //! Arrays
-  typedef NCollection_Array1<BRepMesh_Vertex>                                                       Array1OfVertexOfDelaun;
-  typedef NCollection_Array1<Standard_Integer>                                                      Array1OfInteger;
-  typedef NCollection_Array1<Standard_Real>                                                         Array1OfReal;
-  typedef NCollection_Array1<Segment>                                                               Array1OfSegments;
-
-  //! Lists
-  typedef NCollection_List<gp_XY>                                                                   ListOfXY;
-  typedef NCollection_List<BRepMesh_Vertex>                                                         ListOfVertex;
-  typedef NCollection_List<Standard_Integer>                                                        ListOfInteger;
-
-  //! Maps
-  typedef NCollection_Map<Standard_Real>                                                            MapOfReal;
-  typedef NCollection_Map<Standard_Integer>                                                         MapOfInteger;
-  typedef NCollection_DataMap<Handle(Poly_Triangulation), Standard_Boolean>                         DMapOfTriangulationBool;
-  typedef NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher>                                    MapOfShape;
-
-  typedef NCollection_DataMap<Standard_Integer, Standard_Integer>                                   MapOfIntegerInteger;
-  typedef NCollection_DataMap<TopoDS_Vertex, Standard_Integer, TopTools_ShapeMapHasher>             DMapOfVertexInteger;
-  typedef NCollection_DataMap<TopoDS_Face, Handle(BRepMesh_FaceAttribute), TopTools_ShapeMapHasher>  DMapOfFaceAttribute;
-  typedef NCollection_DataMap<TopoDS_Shape, BRepMesh_PairOfPolygon, TopTools_ShapeMapHasher>        DMapOfShapePairOfPolygon;
-  typedef NCollection_DataMap<Standard_Integer, gp_Pnt>                                             DMapOfIntegerPnt;
-  typedef NCollection_DataMap<Standard_Integer, ListOfXY>                                           DMapOfIntegerListOfXY;
-  typedef NCollection_DataMap<Standard_Integer, ListOfInteger>                                      DMapOfIntegerListOfInteger;
-  typedef NCollection_DataMap<TopoDS_Edge, DMapOfTriangulationBool, TopTools_ShapeMapHasher>        DMapOfEdgeListOfTriangulationBool;
-
-  typedef NCollection_IndexedMap<Standard_Integer>                                                  IMapOfInteger;
-  typedef NCollection_IndexedMap<Standard_Real>                                                     IMapOfReal;
-  typedef NCollection_IndexedMap<BRepMesh_Triangle>                                                 IMapOfElement;
-  typedef NCollection_IndexedDataMap<BRepMesh_Edge, BRepMesh_PairOfIndex>                           IDMapOfLink;
-
-  //! CellFilters
-  typedef NCollection_CellFilter<BRepMesh_CircleInspector>                                          CircleCellFilter;
-  typedef NCollection_CellFilter<BRepMesh_VertexInspector>                                          VertexCellFilter;
-
-  //! Handles
-  typedef NCollection_Handle<VectorOfVertex>                                                        HVectorOfVertex;
-  typedef NCollection_Handle<MapOfInteger>                                                          HMapOfInteger;
-  typedef NCollection_Handle<IMapOfInteger>                                                         HIMapOfInteger;
-  typedef NCollection_Handle<DMapOfShapePairOfPolygon>                                              HDMapOfShapePairOfPolygon;
-  typedef NCollection_Handle<DMapOfIntegerPnt>                                                      HDMapOfIntegerPnt;
-  typedef NCollection_Handle<BRepMesh_Classifier>                                                   HClassifier;
-  typedef NCollection_Handle<BndBox2dTree>                                                          HBndBox2dTree;
-  typedef NCollection_Handle<Array1OfSegments>                                                      HArray1OfSegments;
-  typedef NCollection_Handle<DMapOfVertexInteger>                                                   HDMapOfVertexInteger;
-  typedef NCollection_Handle<DMapOfIntegerListOfXY>                                                 HDMapOfIntegerListOfXY;
-  typedef NCollection_Handle<BRepMesh_VertexTool>                                                   HVertexTool;
-  typedef NCollection_Handle<SequenceOfBndB2d>                                                      HSequenceOfBndB2d;
-  typedef NCollection_Handle<SequenceOfInteger>                                                     HSequenceOfInteger;
-
-  //! Other data structures
-  typedef std::pair<HArray1OfSegments, HBndBox2dTree>                                               SegmentsTree;
-  typedef NCollection_Array1<SegmentsTree>                                                          Array1OfSegmentsTree;
-
-} // namespace BRepMesh
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx
new file mode 100644 (file)
index 0000000..dce927a
--- /dev/null
@@ -0,0 +1,316 @@
+// 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 const& /*theExeption*/)
+  {
+  }
+
+  myDFace.Nullify(); // Do not hold link to face.
+  myStructure.Nullify();
+  myNodesMap .Nullify();
+  myUsedNodes.Nullify();
+  myAllocator.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);
+      const IMeshData::ICurveHandle&  aCurve = aDEdge->GetCurve();
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+        myDFace.get(), 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() == 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..5006e1b
--- /dev/null
@@ -0,0 +1,54 @@
+// 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.
+  BRepMesh_BoundaryParamsRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_BoundaryParamsRangeSplitter()
+  {
+  }
+
+  //! Registers border point.
+  virtual void AddPoint(const gp_Pnt2d& thePoint) Standard_OVERRIDE
+  {
+    BRepMesh_NURBSRangeSplitter::AddPoint(thePoint);
+    GetParametersU().Add(thePoint.X());
+    GetParametersV().Add(thePoint.Y());
+  }
+
+protected:
+
+  //! Initializes U and V parameters lists using CN continuity intervals.
+  virtual Standard_Boolean initParameters() const Standard_OVERRIDE
+  {
+    return Standard_True;
+  }
+};
+
+#endif
index 509f37682617c4d2c640610fb03f75e2ba0e8f25..c954d7d50ce8415795482cd256859abca21d2a23 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef BRepMesh_CircleInspector_Header
 #define BRepMesh_CircleInspector_Header
 
-#include <BRepMesh.hxx>
+#include <IMeshData_Types.hxx>
 #include <BRepMesh_Circle.hxx>
 #include <Precision.hxx>
 #include <gp_XY.hxx>
@@ -37,9 +37,9 @@ public:
     const Standard_Real                     theTolerance,
     const Standard_Integer                  theReservedSize,
     const Handle(NCollection_IncAllocator)& theAllocator)
-  : myTolerance(theTolerance*theTolerance),
+  : mySqTolerance(theTolerance*theTolerance),
     myResIndices(theAllocator),
-    myCircles(theReservedSize)
+    myCircles(theReservedSize, theAllocator)
   {
   }
 
@@ -53,7 +53,7 @@ public:
   }
 
   //! Resutns vector of registered circles.
-  inline const BRepMesh::VectorOfCircle& Circles() const
+  inline const IMeshData::VectorOfCircle& Circles() const
   {
     return myCircles; 
   }
@@ -75,7 +75,7 @@ public:
   }
 
   //! Returns list of circles shot by the reference point.
-  inline BRepMesh::ListOfInteger& GetShotCircles()
+  inline IMeshData::ListOfInteger& GetShotCircles()
   {
     return myResIndices;
   }
@@ -83,8 +83,41 @@ public:
   //! Performs inspection of a circle with the given index.
   //! @param theTargetIndex index of a circle to be checked.
   //! @return status of the check.
-  Standard_EXPORT NCollection_CellFilter_Action Inspect(
-    const Standard_Integer theTargetIndex);
+  inline NCollection_CellFilter_Action Inspect(
+    const Standard_Integer theTargetIndex)
+  {
+    BRepMesh_Circle& aCircle = myCircles(theTargetIndex);
+    const Standard_Real& aRadius = aCircle.Radius();
+    if (aRadius < 0.)
+      return CellFilter_Purge;
+
+    gp_XY& aLoc = const_cast<gp_XY&>(aCircle.Location());
+
+    const Standard_Real aDX = myPoint.ChangeCoord(1) - aLoc.ChangeCoord(1);
+    const Standard_Real aDY = myPoint.ChangeCoord(2) - aLoc.ChangeCoord(2);
+
+    //This check is wrong. It is better to use 
+    //  
+    //  const Standard_Real aR = aRadius + aToler;
+    //  if ((aDX * aDX + aDY * aDY) <= aR * aR)
+    //  {
+    //    ...
+    //  }
+
+    //where aToler = sqrt(mySqTolerance). Taking into account the fact
+    //that the input parameter of the class (see constructor) is linear
+    //(not quadratic) tolerance there is no point in square root computation.
+    //Simply, we do not need to compute square of the input tolerance and to
+    //assign it to mySqTolerance. The input linear tolerance is needed to be used.
+
+    //However, this change leads to hangs the test case "perf mesh bug27119".
+    //So, this correction is better to be implemented in the future.
+
+    if ((aDX * aDX + aDY * aDY) - (aRadius * aRadius) <= mySqTolerance)
+      myResIndices.Append(theTargetIndex);
+
+    return CellFilter_Keep;
+  }
 
   //! Checks indices for equlity.
   static Standard_Boolean IsEqual(
@@ -95,10 +128,10 @@ public:
   }
 
 private:
-  Standard_Real            myTolerance;
-  BRepMesh::ListOfInteger  myResIndices;
-  BRepMesh::VectorOfCircle myCircles;
-  gp_XY                    myPoint;
+  Standard_Real             mySqTolerance;
+  IMeshData::ListOfInteger  myResIndices;
+  IMeshData::VectorOfCircle myCircles;
+  gp_XY                     myPoint;
 };
 
 #endif
index e0f76003d9b995edc714105506e7c11fa39b3b7b..67aa20ee60ae04c37379b8039f226f6c21426f5c 100644 (file)
 #include <BRepMesh_Circle.hxx>
 #include <BRepMesh_CircleInspector.hxx>
 
-//=======================================================================
-//function : Inspect
-//purpose  : 
-//=======================================================================
-NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect(
-  const Standard_Integer theTargetIndex)
-{
-  const BRepMesh_Circle& aCircle = myCircles(theTargetIndex);
-  Standard_Real aRadius = aCircle.Radius();
-  if(aRadius < 0.)
-    return CellFilter_Purge;
-
-  const gp_XY& aLoc = aCircle.Location();
-
-  if ((myPoint - aLoc).SquareModulus() - (aRadius * aRadius) <= myTolerance)
-    myResIndices.Append(theTargetIndex);
-
-  return CellFilter_Keep;
-}
-
-
 //=======================================================================
 //function : BRepMesh_CircleTool
 //purpose  : 
 //=======================================================================
 BRepMesh_CircleTool::BRepMesh_CircleTool(
   const Handle(NCollection_IncAllocator)& theAllocator)
-: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
+: myTolerance (Precision::PConfusion()),
   myAllocator (theAllocator),
   myCellFilter(10.0, theAllocator),
   mySelector  (myTolerance, 64, theAllocator)
@@ -62,7 +41,7 @@ BRepMesh_CircleTool::BRepMesh_CircleTool(
 BRepMesh_CircleTool::BRepMesh_CircleTool(
   const Standard_Integer                  theReservedSize,
   const Handle(NCollection_IncAllocator)& theAllocator)
-: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
+: myTolerance (Precision::PConfusion()),
   myAllocator (theAllocator),
   myCellFilter(10.0, theAllocator),
   mySelector  (myTolerance, Max(theReservedSize, 64), theAllocator)
@@ -117,42 +96,43 @@ Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY&   thePoint1,
   static const Standard_Real aPrecision   = Precision::PConfusion();
   static const Standard_Real aSqPrecision = aPrecision * aPrecision;
 
-  if ((thePoint1 - thePoint3).SquareModulus() < aSqPrecision)
-    return Standard_False;
-
-  gp_XY aLink1(thePoint2 - thePoint1);
+  gp_XY aLink1(const_cast<gp_XY&>(thePoint3).ChangeCoord(1) - const_cast<gp_XY&>(thePoint2).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint2).ChangeCoord(2) - const_cast<gp_XY&>(thePoint3).ChangeCoord(2));
   if (aLink1.SquareModulus() < aSqPrecision)
     return Standard_False;
 
-  gp_XY aLink2(thePoint3 - thePoint2);
+  gp_XY aLink2(const_cast<gp_XY&>(thePoint1).ChangeCoord(1) - const_cast<gp_XY&>(thePoint3).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint3).ChangeCoord(2) - const_cast<gp_XY&>(thePoint1).ChangeCoord(2));
   if (aLink2.SquareModulus() < aSqPrecision)
     return Standard_False;
 
-  gp_XY aMidPnt1 = (thePoint1 + thePoint2) / 2.;
-  gp_XY aNorm1   = gp_XY(aLink1.Y(), -aLink1.X());
-  aNorm1.Add(aMidPnt1);
-
-  if (aLink2.SquareModulus() < aSqPrecision)
+  gp_XY aLink3(const_cast<gp_XY&>(thePoint2).ChangeCoord(1) - const_cast<gp_XY&>(thePoint1).ChangeCoord(1),
+               const_cast<gp_XY&>(thePoint1).ChangeCoord(2) - const_cast<gp_XY&>(thePoint2).ChangeCoord(2));
+  if (aLink3.SquareModulus() < aSqPrecision)
     return Standard_False;
 
-  gp_XY aMidPnt2 = (thePoint2 + thePoint3) / 2.;
-  gp_XY aNorm2   = gp_XY(aLink2.Y(), -aLink2.X());
-  aNorm2.Add(aMidPnt2);
+  const Standard_Real aD = 2 * (const_cast<gp_XY&>(thePoint1).ChangeCoord(1) * aLink1.Y() +
+                                const_cast<gp_XY&>(thePoint2).ChangeCoord(1) * aLink2.Y() +
+                                const_cast<gp_XY&>(thePoint3).ChangeCoord(1) * aLink3.Y());
 
-  gp_XY aIntPnt;
-  Standard_Real aParam[2];
-  BRepMesh_GeomTool::IntFlag aIntFlag = 
-    BRepMesh_GeomTool::IntLinLin(aMidPnt1, aNorm1,
-      aMidPnt2, aNorm2, aIntPnt, aParam);
-
-  if (aIntFlag != BRepMesh_GeomTool::Cross)
+  if (Abs(aD) < gp::Resolution())
     return Standard_False;
 
-  theLocation = aIntPnt;
+  const Standard_Real aInvD = 1. / aD;
+  const Standard_Real aSqMod1 = thePoint1.SquareModulus();
+  const Standard_Real aSqMod2 = thePoint2.SquareModulus();
+  const Standard_Real aSqMod3 = thePoint3.SquareModulus();
+  theLocation.ChangeCoord(1) = (aSqMod1 * aLink1.Y() +
+                                aSqMod2 * aLink2.Y() +
+                                aSqMod3 * aLink3.Y()) * aInvD;
+
+  theLocation.ChangeCoord(2) = (aSqMod1 * aLink1.X() +
+                                aSqMod2 * aLink2.X() +
+                                aSqMod3 * aLink3.X()) * aInvD;
 
-  theRadius = Sqrt(Max(Max((thePoint1 - aIntPnt).SquareModulus(), 
-                           (thePoint2 - aIntPnt).SquareModulus()),
-                           (thePoint3 - aIntPnt).SquareModulus())) + 2 * RealEpsilon();
+  theRadius = Sqrt(Max(Max((thePoint1 - theLocation).SquareModulus(),
+                           (thePoint2 - theLocation).SquareModulus()),
+                           (thePoint3 - theLocation).SquareModulus())) + 2 * RealEpsilon();
 
   return Standard_True;
 }
@@ -190,7 +170,7 @@ void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
 //function : Select
 //purpose  : 
 //=======================================================================
-BRepMesh::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
+IMeshData::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
 {
   mySelector.SetPoint(thePoint);
   myCellFilter.Inspect(thePoint, mySelector);
index a81e739b63d885f601102ddb8fe45edc20142f65..3f5701d63dfb423dfbadaeac7d03a6243966c48e 100644 (file)
@@ -24,7 +24,7 @@
 #include <gp_XYZ.hxx>
 #include <Standard_Integer.hxx>
 #include <Standard_Boolean.hxx>
-#include <BRepMesh.hxx>
+#include <IMeshData_Types.hxx>
 #include <NCollection_Array1.hxx>
 
 class gp_Circ2d;
@@ -52,7 +52,7 @@ public:
   //! @param theReservedSize size to be reserved for vector of circles.
   inline void Init(const Standard_Integer /*theReservedSize*/)
   {
-    myTolerance = Precision::PConfusion() * Precision::PConfusion();
+    myTolerance = Precision::PConfusion();
   }
 
   //! Sets new size for cell filter.
@@ -83,6 +83,12 @@ public:
     myFaceMax = theMax;
   }
 
+  //! Retruns true if cell filter contains no circle.
+  inline Standard_Boolean IsEmpty () const
+  {
+    return mySelector.Circles ().IsEmpty ();
+  }
+
   //! Binds the circle to the tool.
   //! @param theIndex index a circle should be bound with.
   //! @param theCircle circle to be bound.
@@ -125,7 +131,7 @@ public:
 
   //! Select the circles shot by the given point.
   //! @param thePoint bullet point.
-  Standard_EXPORT BRepMesh::ListOfInteger& Select(const gp_XY& thePoint);
+  Standard_EXPORT IMeshData::ListOfInteger& Select(const gp_XY& thePoint);
 
 private:
 
@@ -141,7 +147,7 @@ private:
 
   Standard_Real                     myTolerance;
   Handle(NCollection_IncAllocator)  myAllocator;
-  BRepMesh::CircleCellFilter        myCellFilter;
+  IMeshData::CircleCellFilter       myCellFilter;
   BRepMesh_CircleInspector          mySelector;
   gp_XY                             myFaceMax;
   gp_XY                             myFaceMin;
index 09545b49ed4011952322ce28c2f72cb8fb9fbacd..9ec0ca51dd5122e7c52d0c73382d4ff1c044ae02 100644 (file)
@@ -1,7 +1,6 @@
-// Created on: 1997-06-26
-// Created by: Laurent PAINNOT
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// 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.
 //
@@ -29,6 +28,14 @@ BRepMesh_Classifier::BRepMesh_Classifier()
 {
 }
 
+//=======================================================================
+//function : Destructor
+//purpose  : 
+//=======================================================================
+BRepMesh_Classifier::~BRepMesh_Classifier()
+{
+}
+
 //=======================================================================
 //function : Perform
 //purpose  : 
@@ -38,19 +45,23 @@ TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const
   Standard_Boolean isOut = Standard_False;
   Standard_Integer aNb   = myTabClass.Length();
   
-  for (Standard_Integer i = 1; i <= aNb; i++)
+  for (Standard_Integer i = 0; i < aNb; i++)
   {
-    Standard_Integer aCur = ((CSLib_Class2d*)myTabClass(i))->SiDans(thePoint);
+    const Standard_Integer aCur = myTabClass(i)->SiDans(thePoint);
     if (aCur == 0)
     {
       // Point is ON, but mark it as OUT
       isOut = Standard_True;
     }
     else
+    {
       isOut = myTabOrient(i) ? (aCur == -1) : (aCur == 1);
+    }
     
     if (isOut)
+    {
       return TopAbs_OUT;
+    }
   }
 
   return TopAbs_IN;
@@ -61,23 +72,23 @@ TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const
 //purpose  : 
 //=======================================================================
 void BRepMesh_Classifier::RegisterWire(
-  const NCollection_Sequence<gp_Pnt2d>& theWire,
-  const Standard_Real                   theTolUV,
-  const Standard_Real                   theUmin,
-  const Standard_Real                   theUmax,
-  const Standard_Real                   theVmin,
-  const Standard_Real                   theVmax)
+  const NCollection_Sequence<const gp_Pnt2d*>&   theWire,
+  const std::pair<Standard_Real, Standard_Real>& theTolUV,
+  const std::pair<Standard_Real, Standard_Real>& theRangeU,
+  const std::pair<Standard_Real, Standard_Real>& theRangeV)
 {
   const Standard_Integer aNbPnts = theWire.Length();
   if (aNbPnts < 2)
+  {
     return;
+  }
 
   // Accumulate angle
   TColgp_Array1OfPnt2d aPClass(1, aNbPnts);
   Standard_Real anAngle = 0.0;
-  gp_Pnt2d p1 = theWire(1), p2 = theWire(2), p3;
-  aPClass(1) = p1;
-  aPClass(2) = p2;
+  const gp_Pnt2d *p1 = theWire(1), *p2 = theWire(2), *p3;
+  aPClass(1) = *p1;
+  aPClass(2) = *p2;
 
   const Standard_Real aAngTol = Precision::Angular();
   const Standard_Real aSqConfusion =
@@ -88,15 +99,15 @@ void BRepMesh_Classifier::RegisterWire(
     Standard_Integer ii = i + 2;
     if (ii > aNbPnts)
     {
-      p3 = aPClass(ii - aNbPnts);
+      p3 = &aPClass(ii - aNbPnts);
     }
     else
     {
       p3 = theWire.Value(ii);
-      aPClass(ii) = p3;
+      aPClass(ii) = *p3;
     }
 
-    gp_Vec2d A(p1,p2), B(p2,p3);
+    const gp_Vec2d A(*p1,*p2), B(*p2,*p3);
     if (A.SquareMagnitude() > aSqConfusion && 
         B.SquareMagnitude() > aSqConfusion)
     {
@@ -115,27 +126,10 @@ void BRepMesh_Classifier::RegisterWire(
   if (Abs(anAngle) < aAngTol)
     anAngle = 0.0;
 
-  myTabClass.Append( (void *)new CSLib_Class2d(aPClass, 
-    theTolUV, theTolUV, theUmin, theVmin, theUmax, theVmax) );
-  myTabOrient.Append( !(anAngle < 0.0) );
-}
-
-//=======================================================================
-//function : Destroy
-//purpose  : 
-//=======================================================================
-void BRepMesh_Classifier::Destroy()
-{
-  Standard_Integer aNb = myTabClass.Length();
-  for (Standard_Integer i = 1; i <= aNb; i++)
-  {
-    if (myTabClass(i))
-    {
-      delete ((CSLib_Class2d*)myTabClass(i));
-      myTabClass(i) = NULL;
-    }
-  }
+  myTabClass.Append(new CSLib_Class2d(
+                    aPClass, theTolUV.first, theTolUV.second,
+                    theRangeU.first, theRangeV.first,
+                    theRangeU.second, theRangeV.second));
 
-  myTabClass.Clear();
-  myTabOrient.Clear();
+  myTabOrient.Append( !(anAngle < 0.0) );
 }
index 4a87b84b61958f0c11d2f43ed928c1ed49c10508..d7ee6f57e5ce1b497cae6963ef479fccefacdf08 100644 (file)
@@ -1,7 +1,6 @@
-// Created on: 2014-06-03
+// Created on: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
 // Created by: Oleg AGASHIN
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 #define _BRepMesh_Classifier_HeaderFile
 
 #include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
 #include <Standard_Macro.hxx>
-#include <BRepTopAdaptor_SeqOfPtr.hxx>
-#include <TColStd_SequenceOfBoolean.hxx>
 #include <TopAbs_State.hxx>
-#include <NCollection_Sequence.hxx>
-#include <gp_Pnt2d.hxx>
+#include <IMeshData_Types.hxx>
+#include <NCollection_Handle.hxx>
 
-//! Auxilary class contains information about correctness of discretized 
-//! face and used for classification of points regarding face internals.
-class BRepMesh_Classifier
+#include <memory>
+
+class gp_Pnt2d;
+class CSLib_Class2d;
+
+//! Auxilary class intended for classification of points
+//! regarding internals of discrete face.
+class BRepMesh_Classifier : public Standard_Transient
 {
 public:
 
-  DEFINE_STANDARD_ALLOC
-
   //! Constructor.
   Standard_EXPORT BRepMesh_Classifier();
 
   //! Destructor.
-  Standard_EXPORT virtual ~BRepMesh_Classifier()
-  {
-    Destroy();
-  }
-
-  //! Method is called on destruction.
-  //! Clears internal data structures.
-  Standard_EXPORT void Destroy();
+  Standard_EXPORT virtual ~BRepMesh_Classifier();
   
   //! Performs classification of the given point regarding to face internals.
   //! @param thePoint Point in parametric space to be classified.
-  //! @return 
+  //! @return TopAbs_IN if point lies within face boundaries and TopAbs_OUT elsewhere.
   Standard_EXPORT TopAbs_State Perform(const gp_Pnt2d& thePoint) const;
 
   //! Registers wire specified by sequence of points for 
@@ -61,17 +53,17 @@ public:
   //! @param theVmin Lower V boundary of the face in parametric space.
   //! @param theVmax Upper V boundary of the face in parametric space.
   Standard_EXPORT void RegisterWire(
-    const NCollection_Sequence<gp_Pnt2d>& theWire,
-    const Standard_Real                   theTolUV,
-    const Standard_Real                   theUmin,
-    const Standard_Real                   theUmax,
-    const Standard_Real                   theVmin,
-    const Standard_Real                   theVmax);
+    const NCollection_Sequence<const gp_Pnt2d*>&   theWire,
+    const std::pair<Standard_Real, Standard_Real>& theTolUV,
+    const std::pair<Standard_Real, Standard_Real>& theRangeU,
+    const std::pair<Standard_Real, Standard_Real>& theRangeV);
+
+  DEFINE_STANDARD_RTTI_INLINE (BRepMesh_Classifier, Standard_Transient)
 
 private:
 
-  BRepTopAdaptor_SeqOfPtr       myTabClass;
-  TColStd_SequenceOfBoolean     myTabOrient;
+  NCollection_Vector<NCollection_Handle<CSLib_Class2d> > myTabClass;
+  IMeshData::VectorOfBoolean                             myTabOrient;
 };
 
 #endif
diff --git a/src/BRepMesh/BRepMesh_ConeRangeSplitter.cxx b/src/BRepMesh/BRepMesh_ConeRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..da28dd0
--- /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.
+
+#include <BRepMesh_ConeRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+
+//=======================================================================
+// Function: GetSplitSteps
+// Purpose : 
+//=======================================================================
+std::pair<Standard_Real, Standard_Real> BRepMesh_ConeRangeSplitter::GetSplitSteps(
+  const IMeshTools_Parameters&                   theParameters,    
+  std::pair<Standard_Integer, Standard_Integer>& theStepsNb) const
+{
+  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);
+
+  theStepsNb.first  = nbU;
+  theStepsNb.second = nbV;
+  return std::make_pair (Du, Dv);
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_ConeRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& theParameters) const
+{
+  const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+  const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+  std::pair<Standard_Integer, Standard_Integer> aStepsNb;
+  std::pair<Standard_Real, Standard_Real> aSteps = GetSplitSteps (theParameters, aStepsNb);
+
+  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 - aSteps.second*0.5;
+  const Standard_Real aPasMaxU = aRangeU.second - aSteps.first *0.5;
+  for (Standard_Real aPasV = aRangeV.first + aSteps.second; aPasV < aPasMaxV; aPasV += aSteps.second)
+  {
+    for (Standard_Real aPasU = aRangeU.first + aSteps.first; aPasU < aPasMaxU; aPasU += aSteps.first)
+    {
+      aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+    }
+  }
+
+  return aNodes;
+}
diff --git a/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx b/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..e9abf42
--- /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 _BRepMesh_ConeRangeSplitter_HeaderFile
+#define _BRepMesh_ConeRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.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.
+  BRepMesh_ConeRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_ConeRangeSplitter()
+  {
+  }
+
+  //! Returns split intervals along U and V direction.
+  //! @param theParameters meshing parameters.
+  //! @param[out] theStepsNb number of steps along corresponding direction. 
+  std::pair<Standard_Real, Standard_Real> GetSplitSteps(
+    const IMeshTools_Parameters&                   theParameters,    
+    std::pair<Standard_Integer, Standard_Integer>& theStepsNb) const;
+
+  //! 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;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ConstrainedBaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_ConstrainedBaseMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..7edd4aa
--- /dev/null
@@ -0,0 +1,60 @@
+// Created on: 2019-07-08
+// Copyright (c) 2019 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_ConstrainedBaseMeshAlgo_HeaderFile
+#define _BRepMesh_ConstrainedBaseMeshAlgo_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_ConstrainedBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
+{
+public:
+
+  //! Constructor.
+  BRepMesh_ConstrainedBaseMeshAlgo ()
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_ConstrainedBaseMeshAlgo ()
+  {
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ConstrainedBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
+
+protected:
+
+  //! Returns size of cell to be used by acceleration circles grid structure.
+  virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer /*theVerticesNb*/)
+  {
+    return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
+  }
+
+  //! Perfroms processing of generated mesh.
+  //! By default does nothing.
+  //! Expected to be called from method generateMesh() in successor classes.
+  virtual void postProcessMesh (BRepMesh_Delaun& /*theMesher*/)
+  {
+  }
+};
+
+#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..bb780d2
--- /dev/null
@@ -0,0 +1,342 @@
+// 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>
+#include <Standard_Failure.hxx>
+#include <GCPnts_AbscissaPoint.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()
+{
+  if (myParameters.MinSize <= 0.0)
+  {
+    Standard_Failure::Raise ("The structure \"myParameters\" is not initialized");
+  }
+
+  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;
+  }
+
+  aPreciseLinDef = Max (aPreciseLinDef, Precision::Confusion());
+  aPreciseAngDef = Max (aPreciseAngDef, Precision::Angular());
+
+  Standard_Real aMinSize = myParameters.MinSize;
+  if (myParameters.AdjustMinSize)
+  {
+    aMinSize = Min (aMinSize, myParameters.RelMinSize() * GCPnts_AbscissaPoint::Length (
+      myCurve, myCurve.FirstParameter(), myCurve.LastParameter(), aPreciseLinDef));
+  }
+
+  mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
+  mySquareMinSize = Max (mySquareEdgeDef, aMinSize * aMinSize);
+
+  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(), aMinSize);
+
+  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 ()->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;
+  }
+
+  if ((theCurve2d->FirstParameter() - theFirst > Precision::PConfusion()) ||
+      (theLast - theCurve2d->LastParameter() > Precision::PConfusion()))
+  {
+    // E.g. test bugs moddata_3 bug30133
+    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_CustomBaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_CustomBaseMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..e175091
--- /dev/null
@@ -0,0 +1,70 @@
+// Created on: 2019-06-07
+// Copyright (c) 2019 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_CustomBaseMeshAlgo_HeaderFile
+#define _BRepMesh_CustomBaseMeshAlgo_HeaderFile
+
+#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
+#include <NCollection_Shared.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+#include <BRepMesh_Delaun.hxx>
+#include <BRepMesh_MeshTool.hxx>
+
+class BRepMesh_DataStructureOfDelaun;
+
+//! Class provides base fuctionality to build face triangulation using custom triangulation algorithm.
+//! Performs generation of mesh using raw data from model.
+class BRepMesh_CustomBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_CustomBaseMeshAlgo ()
+  {
+  }
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_CustomBaseMeshAlgo ()
+  {
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_CustomBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
+
+protected:
+
+  //! Generates mesh for the contour stored in data structure.
+  Standard_EXPORT virtual void generateMesh () Standard_OVERRIDE
+  {
+    const Handle (BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure ();
+    buildBaseTriangulation ();
+
+    std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes ());
+    BRepMesh_Delaun aMesher (aStructure, aCellsCount.first, aCellsCount.second, Standard_False);
+    aMesher.ProcessConstraints ();
+
+    BRepMesh_MeshTool aCleaner (aStructure);
+    aCleaner.EraseFreeLinks ();
+
+    postProcessMesh (aMesher);
+  }
+
+protected:
+
+  //! Builds base triangulation using custom triangulation algorithm.
+  Standard_EXPORT virtual void buildBaseTriangulation() = 0;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_CustomDelaunayBaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..6bde7b9
--- /dev/null
@@ -0,0 +1,53 @@
+// Created on: 2019-06-07
+// Copyright (c) 2019 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_CustomDelaunayBaseMeshAlgo_HeaderFile
+#define _BRepMesh_CustomDelaunayBaseMeshAlgo_HeaderFile
+
+class BRepMesh_DataStructureOfDelaun;
+class BRepMesh_Delaun;
+
+//! Class provides base fuctionality to build face triangulation using custom
+//! triangulation algorithm with possibility to modify final mesh.
+//! Performs generation of mesh using raw data from model.
+template<class BaseAlgo>
+class BRepMesh_CustomDelaunayBaseMeshAlgo : public BaseAlgo
+{
+public:
+
+  //! Constructor.
+  BRepMesh_CustomDelaunayBaseMeshAlgo ()
+  {
+  } 
+
+  //! Destructor.
+  virtual ~BRepMesh_CustomDelaunayBaseMeshAlgo ()
+  {
+  }
+
+protected:
+
+  //! Perfroms processing of generated mesh.
+  virtual void postProcessMesh(BRepMesh_Delaun& theMesher)
+  {
+    BaseAlgo::postProcessMesh (theMesher);
+
+    const Handle(BRepMesh_DataStructureOfDelaun)& aStructure  = this->getStructure();
+    std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes());
+    theMesher.InitCirclesTool (aCellsCount.first, aCellsCount.second);
+  }
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_CylinderRangeSplitter.cxx b/src/BRepMesh/BRepMesh_CylinderRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..7016ad8
--- /dev/null
@@ -0,0 +1,98 @@
+// 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.
+
+#include <BRepMesh_CylinderRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+
+//=======================================================================
+// Function: Reset
+// Purpose : 
+//=======================================================================
+void BRepMesh_CylinderRangeSplitter::Reset(const IMeshData::IFaceHandle& theDFace,
+                                           const IMeshTools_Parameters&  theParameters)
+{
+  BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters);
+
+  const Standard_Real aRadius = GetDFace()->GetSurface()->Cylinder().Radius();
+  myDu = GCPnts_TangentialDeflection::ArcAngularStep(
+    aRadius, GetDFace()->GetDeflection(),
+    theParameters.Angle, theParameters.MinSize);
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_CylinderRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& /*theParameters*/) const
+{
+  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;
+}
+
+//=======================================================================
+// Function: computeDelta
+// Purpose : 
+//=======================================================================
+void BRepMesh_CylinderRangeSplitter::computeDelta(
+  const Standard_Real /*theLengthU*/,
+  const Standard_Real theLengthV)
+{
+  const std::pair<double, double>& aRangeV = GetRangeV();
+  myDelta.first  = myDu / Max(theLengthV, aRangeV.second - aRangeV.first);
+  myDelta.second = 1.;
+}
diff --git a/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx b/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..87a9457
--- /dev/null
@@ -0,0 +1,59 @@
+// 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 <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.
+  BRepMesh_CylinderRangeSplitter()
+    : myDu(1.)
+  {
+  }
+
+  //! Destructor.
+  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;
+
+  //! 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:
+
+  //! Computes parametric delta taking length along U and V into account.
+  Standard_EXPORT virtual void computeDelta(
+    const Standard_Real theLengthU,
+    const Standard_Real theLengthV) Standard_OVERRIDE;
+
+private:
+
+  Standard_Real myDu;
+};
+
+#endif
index b7d2adb1e0ce1f8167c5de88656a7783d4599328..7a49413c9567d876912ac3ac2bad1794b3de27bf 100644 (file)
 // commercial license or contractual agreement.
 
 #include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh_PairOfIndex.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepMesh_Edge.hxx>
 
 #include <TopoDS_Compound.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
 #include <Standard_ErrorHandler.hxx>
 
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_DataStructureOfDelaun,Standard_Transient)
-
 //=======================================================================
 //function : BRepMesh_DataStructureOfDelaun
 //purpose  : 
@@ -39,9 +36,7 @@ BRepMesh_DataStructureOfDelaun::BRepMesh_DataStructureOfDelaun(
     myNodeLinks       (theReservedNodeSize * 3, myAllocator),
     myLinks           (theReservedNodeSize * 3, myAllocator),
     myDelLinks        (myAllocator),
-    myElements        (theReservedNodeSize * 2, myAllocator),
-    myElementsOfDomain(theReservedNodeSize * 2, myAllocator),
-    myLinksOfDomain   (theReservedNodeSize * 2, myAllocator)
+    myElements        (theReservedNodeSize * 2, myAllocator)
 {
 }
 
@@ -55,7 +50,7 @@ Standard_Integer BRepMesh_DataStructureOfDelaun::AddNode(
 {
   const Standard_Integer aNodeId = myNodes->Add(theNode, isForceAdd);
   if (!myNodeLinks.IsBound(aNodeId))
-    myNodeLinks.Bind(aNodeId, BRepMesh::ListOfInteger(myAllocator));
+    myNodeLinks.Bind(aNodeId, IMeshData::ListOfInteger(myAllocator));
 
   return aNodeId;
 }
@@ -174,8 +169,8 @@ void BRepMesh_DataStructureOfDelaun::cleanLink(
     const Standard_Integer aNodeId = (i == 0) ?
       theLink.FirstNode() : theLink.LastNode();
 
-    BRepMesh::ListOfInteger& aLinkList = linksConnectedTo(aNodeId);
-    BRepMesh::ListOfInteger::Iterator aLinkIt(aLinkList);
+    IMeshData::ListOfInteger& aLinkList = linksConnectedTo(aNodeId);
+    IMeshData::ListOfInteger::Iterator aLinkIt(aLinkList);
     for(; aLinkIt.More(); aLinkIt.Next())
     {
       if (aLinkIt.Value() == theIndex)
@@ -194,16 +189,11 @@ void BRepMesh_DataStructureOfDelaun::cleanLink(
 Standard_Integer BRepMesh_DataStructureOfDelaun::AddElement(
   const BRepMesh_Triangle& theElement)
 {
-  Standard_Integer aElementIndex = IndexOf(theElement);
-  if (aElementIndex > 0)
-    return aElementIndex;
-
-  aElementIndex = myElements.Add(theElement);
+  myElements.Append(theElement);
+  Standard_Integer aElementIndex = myElements.Size();
   myElementsOfDomain.Add(aElementIndex);
 
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  theElement.Edges(e, o);
+  const Standard_Integer (&e)[3] = theElement.myEdges;
   for (Standard_Integer i = 0; i < 3; ++i)
     myLinks(e[i]).Append(aElementIndex);
 
@@ -237,10 +227,7 @@ void BRepMesh_DataStructureOfDelaun::cleanElement(
   if (theElement.Movability() != BRepMesh_Free)
     return;
 
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  theElement.Edges(e, o);
-
+  const Standard_Integer(&e)[3] = theElement.myEdges;
   for (Standard_Integer i = 0; i < 3; ++i)
     removeElementIndex(theIndex, myLinks(e[i]));
 }
@@ -274,20 +261,15 @@ Standard_Boolean BRepMesh_DataStructureOfDelaun::SubstituteElement(
   const BRepMesh_Triangle& aElement = GetElement(theIndex);
   if (aElement.Movability() == BRepMesh_Deleted) 
   {
-    myElements.Substitute(theIndex, theNewElement);
+    myElements(theIndex) = theNewElement;
     return Standard_True;
   }
 
-  if (IndexOf(theNewElement) != 0)
-    return Standard_False;
-
   cleanElement(theIndex, aElement);
   // Warning: here new element and old element should have different Hash code
-  myElements.Substitute(theIndex, theNewElement);
+  myElements(theIndex) = theNewElement;
 
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  theNewElement.Edges(e, o);
+  const Standard_Integer(&e)[3] = theNewElement.myEdges;
   for (Standard_Integer i = 0; i < 3; ++i)
     myLinks(e[i]).Append(theIndex);
 
@@ -302,9 +284,8 @@ void BRepMesh_DataStructureOfDelaun::ElementNodes(
     const BRepMesh_Triangle& theElement,
     Standard_Integer         (&theNodes)[3])
 {
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  theElement.Edges(e, o);
+  const Standard_Integer(&e)[3] = theElement.myEdges;
+  const Standard_Boolean(&o)[3] = theElement.myOrientations;
 
   const BRepMesh_Edge& aLink1 = GetLink(e[0]);
   if (o[0])
@@ -331,16 +312,14 @@ void BRepMesh_DataStructureOfDelaun::ElementNodes(
 //=======================================================================
 void BRepMesh_DataStructureOfDelaun::ClearDomain()
 {
-  BRepMesh::MapOfInteger aFreeEdges;
-  BRepMesh::MapOfInteger::Iterator aElementIt(myElementsOfDomain);
+  IMeshData::MapOfInteger aFreeEdges;
+  IMeshData::IteratorOfMapOfInteger aElementIt(myElementsOfDomain);
   for (; aElementIt.More(); aElementIt.Next())
   {
     const Standard_Integer aElementId = aElementIt.Key();
     BRepMesh_Triangle& aElement = (BRepMesh_Triangle&)GetElement(aElementId);
 
-    Standard_Integer e[3];
-    Standard_Boolean o[3];
-    aElement.Edges(e, o);
+    const Standard_Integer(&e)[3] = aElement.myEdges;
 
     for (Standard_Integer i = 0; i < 3; ++i)
       aFreeEdges.Add(e[i]);
@@ -350,7 +329,7 @@ void BRepMesh_DataStructureOfDelaun::ClearDomain()
   }
   myElementsOfDomain.Clear();
 
-  BRepMesh::MapOfInteger::Iterator aEdgeIt(aFreeEdges);
+  IMeshData::IteratorOfMapOfInteger aEdgeIt(aFreeEdges);
   for (; aEdgeIt.More(); aEdgeIt.Next())
     RemoveLink(aEdgeIt.Key());
 }
@@ -390,7 +369,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks()
     --aLastLiveItem;
 
     const Standard_Integer aLastLiveItemId = aLastLiveItem + 1;
-    BRepMesh::ListOfInteger::Iterator aLinkIt;
+    IMeshData::ListOfInteger::Iterator aLinkIt;
     // update link references
     for (Standard_Integer i = 0; i < 2; ++i)
     {
@@ -411,10 +390,9 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks()
     // update elements references
     for(Standard_Integer j = 1, jn = aPair.Extent(); j <= jn; ++j)
     {
-      const BRepMesh_Triangle& aElement = GetElement(aPair.Index(j));
-
       Standard_Integer e[3];
       Standard_Boolean o[3];
+      const BRepMesh_Triangle& aElement = GetElement(aPair.Index(j));
       aElement.Edges(e, o);
       for (Standard_Integer i = 0; i < 3; ++i)
       {
@@ -425,8 +403,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks()
         }
       }
 
-      myElements.Substitute(aLinkIt.Value(), 
-        BRepMesh_Triangle(e, o, aElement.Movability()));
+      myElements(aLinkIt.Value()) = BRepMesh_Triangle(e, o, aElement.Movability());
     }
   }
 }
@@ -437,8 +414,8 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedLinks()
 //=======================================================================
 void BRepMesh_DataStructureOfDelaun::clearDeletedNodes()
 {
-  BRepMesh::ListOfInteger& aDelNodes = 
-    (BRepMesh::ListOfInteger&)myNodes->GetListOfDelNodes();
+  IMeshData::ListOfInteger& aDelNodes =
+    (IMeshData::ListOfInteger&)myNodes->GetListOfDelNodes();
 
   Standard_Integer aLastLiveItem = NbNodes();
   while (!aDelNodes.IsEmpty())
@@ -459,7 +436,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedNodes()
       continue;
 
     BRepMesh_Vertex aNode = GetNode(aLastLiveItem);
-    BRepMesh::ListOfInteger& aLinkList = linksConnectedTo(aLastLiveItem);
+    IMeshData::ListOfInteger& aLinkList = linksConnectedTo(aLastLiveItem);
 
     myNodes->RemoveLast();
     --aLastLiveItem;
@@ -468,7 +445,7 @@ void BRepMesh_DataStructureOfDelaun::clearDeletedNodes()
     myNodeLinks.ChangeFind(aDelItem) = aLinkList;
 
     const Standard_Integer aLastLiveItemId = aLastLiveItem + 1;
-    BRepMesh::ListOfInteger::Iterator aLinkIt(aLinkList);
+    IMeshData::ListOfInteger::Iterator aLinkIt(aLinkList);
     for (; aLinkIt.More(); aLinkIt.Next())
     {
       const Standard_Integer aLinkId = aLinkIt.Value();
@@ -495,14 +472,14 @@ void BRepMesh_DataStructureOfDelaun::Statistics(Standard_OStream& theStream) con
 {
   theStream << " Map of nodes : \n";
   myNodes->Statistics(theStream);
-  theStream << "\n Deleted nodes : " << myNodes->GetListOfDelNodes().Extent() << endl;
+  theStream << "\n Deleted nodes : " << myNodes->GetListOfDelNodes().Extent() << std::endl;
 
   theStream << "\n\n Map of Links : \n";
   myLinks.Statistics(theStream);
-  theStream << "\n Deleted links : " << myDelLinks.Extent() << endl;
+  theStream << "\n Deleted links : " << myDelLinks.Extent() << std::endl;
 
   theStream << "\n\n Map of elements : \n";
-  myElements.Statistics(theStream);
+  theStream << "\n Elements : " << myElements.Size() << std::endl;
 }
 
 //=======================================================================
@@ -521,7 +498,7 @@ Standard_CString BRepMesh_Dump(void*            theMeshHandlePtr,
     return "Error: file name or mesh data is null";
   }
 
-  Handle(BRepMesh_DataStructureOfDelaun) aMeshData = 
+  Handle(BRepMesh_DataStructureOfDelaun) aMeshData =
     *(Handle(BRepMesh_DataStructureOfDelaun)*)theMeshHandlePtr;
 
   if (aMeshData.IsNull())
@@ -547,10 +524,10 @@ Standard_CString BRepMesh_Dump(void*            theMeshHandlePtr,
     }
     else
     {
-      BRepMesh::MapOfInteger::Iterator aLinksIt(aMeshData->LinksOfDomain());
+      IMeshData::IteratorOfMapOfInteger aLinksIt(aMeshData->LinksOfDomain());
       for (; aLinksIt.More(); aLinksIt.Next())
       {
-        const BRepMesh_Edge& aLink = aMeshData->GetLink(aLinksIt.Value());
+        const BRepMesh_Edge& aLink = aMeshData->GetLink(aLinksIt.Key());
         gp_Pnt aPnt[2];
         for (Standard_Integer i = 0; i < 2; ++i)
         {
@@ -578,3 +555,9 @@ Standard_CString BRepMesh_Dump(void*            theMeshHandlePtr,
 
   return theFileNameStr;
 }
+
+void BRepMesh_DataStructureOfDelaun::Dump(Standard_CString theFileNameStr)
+{
+  Handle(BRepMesh_DataStructureOfDelaun) aMeshData (this);
+  BRepMesh_Dump((void*)&aMeshData, theFileNameStr);
+}
index 60b98f230b771de8ac957e6c68a5f79d754735a1..cc6b714153a17fe8744dadfa0abc7d1b8926ab27 100644 (file)
 #ifndef _BRepMesh_DataStructureOfDelaun_HeaderFile
 #define _BRepMesh_DataStructureOfDelaun_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-#include <BRepMesh_VertexTool.hxx>
 #include <Standard_Transient.hxx>
 #include <BRepMesh_Triangle.hxx>
 #include <BRepMesh_PairOfIndex.hxx>
 #include <Standard_OStream.hxx>
-#include <BRepMesh.hxx>
+#include <IMeshData_Types.hxx>
+#include <BRepMesh_VertexTool.hxx>
 
 class BRepMesh_Vertex;
-class BRepMesh_VertexTool;
 class BRepMesh_Edge;
 
 //! Describes the data structure necessary for the mesh algorithms in 
@@ -101,14 +98,14 @@ public: //! @name API for accessing mesh nodes.
     if (isForce || myNodes->FindKey(theIndex).Movability() == BRepMesh_Free)
     {
       if (LinksConnectedTo(theIndex).Extent()==0)
-        myNodes->Delete(theIndex);
+        myNodes->DeleteVertex(theIndex);
     }
   }
 
   //! Get list of links attached to the node with the given index.
   //! @param theIndex index of node whose links should be retrieved.
   //! @return list of links attached to the node.
-  inline const BRepMesh::ListOfInteger& LinksConnectedTo(
+  inline const IMeshData::ListOfInteger& LinksConnectedTo(
     const Standard_Integer theIndex) const
   {
     return linksConnectedTo(theIndex);
@@ -145,7 +142,7 @@ public: //! @name API for accessing mesh links.
   }
 
   //! Returns map of indices of links registered in mesh.
-  inline const BRepMesh::MapOfInteger& LinksOfDomain() const
+  inline const IMeshData::MapOfInteger& LinksOfDomain() const
   {
     return myLinksOfDomain;
   }
@@ -181,7 +178,7 @@ public: //! @name API for accessing mesh elements.
   //! Returns number of links.
   inline Standard_Integer NbElements() const
   {
-    return myElements.Extent();
+    return myElements.Size();
   }
 
   //! Adds element to the mesh if it is not already in the mesh.
@@ -189,24 +186,16 @@ public: //! @name API for accessing mesh elements.
   //! @return index of the element in the structure.
   Standard_EXPORT Standard_Integer AddElement(const BRepMesh_Triangle& theElement);
 
-  //! Finds the index of the given element.
-  //! @param theElement element to find.
-  //! @return index of the given element of zero if element is not in the mesh.
-  Standard_Integer IndexOf(const BRepMesh_Triangle& theElement) const
-  {
-    return myElements.FindIndex(theElement);
-  }
-
   //! Get element by the index.
   //! @param theIndex index of an element.
   //! @return element with the given index.
   const BRepMesh_Triangle& GetElement(const Standard_Integer theIndex)
   {
-    return myElements.FindKey(theIndex);
+    return myElements.ChangeValue(theIndex - 1);
   }
 
   //! Returns map of indices of elements registered in mesh.
-  inline const BRepMesh::MapOfInteger& ElementsOfDomain() const
+  inline const IMeshData::MapOfInteger& ElementsOfDomain() const
   {
     return myElementsOfDomain;
   }
@@ -229,6 +218,8 @@ public: //! @name API for accessing mesh elements.
     const BRepMesh_Triangle& theElement,
     Standard_Integer         (&theNodes)[3]);
 
+  Standard_EXPORT void Dump(Standard_CString theFileNameStr);
+
 
 
 public: //! @name Auxilary API
@@ -244,7 +235,7 @@ public: //! @name Auxilary API
   }
 
   //! Gives the data structure for initialization of cell size and tolerance.
-  inline BRepMesh::HVertexTool& Data()
+  inline const Handle(BRepMesh_VertexTool)& Data()
   {
     return myNodes;
   }
@@ -260,17 +251,17 @@ public: //! @name Auxilary API
     clearDeletedNodes();
   }
 
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_DataStructureOfDelaun,Standard_Transient)
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DataStructureOfDelaun, Standard_Transient)
 
 private: 
 
   //! Get list of links attached to the node with the given index.
   //! @param theIndex index of node whose links should be retrieved.
   //! @return list of links attached to the node.
-  inline BRepMesh::ListOfInteger& linksConnectedTo(
+  inline IMeshData::ListOfInteger& linksConnectedTo(
     const Standard_Integer theIndex) const
   {
-    return (BRepMesh::ListOfInteger&)myNodeLinks.Find(theIndex);
+    return (IMeshData::ListOfInteger&)myNodeLinks.Find(theIndex);
   }
 
   //! Substitutes deleted links by the last one from corresponding map 
@@ -305,15 +296,13 @@ private:
 private:
 
   Handle(NCollection_IncAllocator)      myAllocator;
-  BRepMesh::HVertexTool                 myNodes;
-  BRepMesh::DMapOfIntegerListOfInteger  myNodeLinks;
-  BRepMesh::IDMapOfLink                 myLinks;
-  BRepMesh::ListOfInteger               myDelLinks;
-  BRepMesh::IMapOfElement               myElements;
-  BRepMesh::MapOfInteger                myElementsOfDomain;
-  BRepMesh::MapOfInteger                myLinksOfDomain;
+  Handle(BRepMesh_VertexTool)           myNodes;
+  IMeshData::DMapOfIntegerListOfInteger myNodeLinks;
+  IMeshData::IDMapOfLink                myLinks;
+  IMeshData::ListOfInteger              myDelLinks;
+  IMeshData::VectorOfElements           myElements;
+  IMeshData::MapOfInteger               myElementsOfDomain;
+  IMeshData::MapOfInteger               myLinksOfDomain;
 };
 
-DEFINE_STANDARD_HANDLE(BRepMesh_DataStructureOfDelaun,Standard_Transient)
-
 #endif
diff --git a/src/BRepMesh/BRepMesh_DefaultRangeSplitter.cxx b/src/BRepMesh/BRepMesh_DefaultRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..a72cdfe
--- /dev/null
@@ -0,0 +1,252 @@
+// 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.
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAbs_IsoType.hxx>
+
+//=======================================================================
+// Function: Reset
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::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();
+}
+
+//=======================================================================
+// Function: AddPoint
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::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);
+}
+
+//=======================================================================
+// Function: AdjustRange
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::AdjustRange()
+{
+  const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
+  updateRange(aSurface->FirstUParameter(), aSurface->LastUParameter(),
+              aSurface->IsUPeriodic(), myRangeU.first, myRangeU.second);
+
+  if (myRangeU.second < myRangeU.first)
+  {
+    myIsValid = Standard_False;
+    return;
+  }
+
+  updateRange(aSurface->FirstVParameter(), aSurface->LastVParameter(),
+              aSurface->IsVPeriodic(), myRangeV.first, myRangeV.second);
+
+  if (myRangeV.second < myRangeV.first)
+  {
+    myIsValid = Standard_False;
+    return;
+  }
+
+  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);
+  }
+}
+
+//=======================================================================
+// Function: IsValid
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_DefaultRangeSplitter::IsValid()
+{
+  return myIsValid;
+}
+
+//=======================================================================
+// Function: Scale
+// Purpose : 
+//=======================================================================
+gp_Pnt2d BRepMesh_DefaultRangeSplitter::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);
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_DefaultRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& /*theParameters*/) const
+{
+  return Handle(IMeshData::ListOfPnt2d)();
+}
+
+//=======================================================================
+// Function: computeTolerance
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::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(Min(aDeflectionUV, 0.1 * aDiffU), 1e-7 * aDiffU);
+  myTolerance.second = Max(Min(aDeflectionUV, 0.1 * aDiffV), 1e-7 * aDiffV);
+}
+
+//=======================================================================
+// Function: computeDelta
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::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);
+}
+
+//=======================================================================
+// Function: computeLengthU
+// Purpose : 
+//=======================================================================
+Standard_Real BRepMesh_DefaultRangeSplitter::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.;
+}
+
+//=======================================================================
+// Function: computeLengthV
+// Purpose : 
+//=======================================================================
+Standard_Real BRepMesh_DefaultRangeSplitter::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.;
+}
+
+//=======================================================================
+// Function: updateRange
+// Purpose : 
+//=======================================================================
+void BRepMesh_DefaultRangeSplitter::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 ((theDiscreteFirst < theGeomLast) && (theDiscreteLast > theGeomFirst))
+      {
+        //Protection against the faces whose pcurve is out of the surface's domain
+        //(see issue #23675 and test cases "bugs iges buc60820*")
+
+        if (theGeomFirst > theDiscreteFirst)
+        {
+          theDiscreteFirst = theGeomFirst;
+        }
+
+        if (theGeomLast < theDiscreteLast)
+        {
+          theDiscreteLast = theGeomLast;
+        }
+      }
+    }
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx b/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..db9229a
--- /dev/null
@@ -0,0 +1,150 @@
+// 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>
+
+struct IMeshTools_Parameters;
+
+//! Default tool to define range of discrete face model and 
+//! obtain grid points distributed within this range.
+class BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  BRepMesh_DefaultRangeSplitter()
+    : myIsValid (Standard_True)
+  {
+  }
+
+  //! Destructor.
+  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);
+
+  //! Registers border point.
+  Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint);
+
+  //! Updates discrete range of surface according to its geometric range.
+  Standard_EXPORT virtual void AdjustRange();
+
+  //! Returns True if computed range is valid.
+  Standard_EXPORT virtual Standard_Boolean IsValid();
+
+  //! 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;
+
+  //! 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;
+
+  //! 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);
+
+  //! 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);
+
+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.
+  Standard_Real computeLengthU();
+
+  //! Computes length along V direction.
+  Standard_Real computeLengthV();
+
+  //! Updates discrete range of surface according to its geometric range.
+  void updateRange(const Standard_Real     theGeomFirst,
+                   const Standard_Real     theGeomLast,
+                   const Standard_Boolean  isPeriodic,
+                   Standard_Real&          theDiscreteFirst,
+                   Standard_Real&          theDiscreteLast);
+
+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..9110114
--- /dev/null
@@ -0,0 +1,162 @@
+// 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 <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Vertex.hxx>
+
+//=======================================================================
+//function : RelativeEdgeDeflection
+//purpose  : 
+//=======================================================================
+Standard_Real BRepMesh_Deflection::ComputeAbsoluteDeflection(
+  const TopoDS_Shape& theShape,
+  const Standard_Real theRelativeDeflection,
+  const Standard_Real theMaxShapeSize)
+{
+  if (theShape.IsNull())
+  {
+    return theRelativeDeflection;
+  }
+
+  Bnd_Box aBox;
+  BRepBndLib::Add (theShape, aBox, Standard_False);
+
+  Standard_Real aShapeSize = theRelativeDeflection;
+  BRepMesh_ShapeTool::BoxMaxDimension (aBox, aShapeSize);
+
+  // Adjust resulting value in relation to the total size
+
+  Standard_Real aX1, aY1, aZ1, aX2, aY2, aZ2;
+  aBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);
+  const Standard_Real aMaxShapeSize = (theMaxShapeSize > 0.0) ? theMaxShapeSize :
+                                       Max(aX2 - aX1, Max(aY2 - aY1, aZ2 - aZ1));
+
+  Standard_Real anAdjustmentCoefficient = aMaxShapeSize / (2 * aShapeSize);
+  if (anAdjustmentCoefficient < 0.5)
+  {
+    anAdjustmentCoefficient = 0.5;
+  }
+  else if (anAdjustmentCoefficient > 2.)
+  {
+    anAdjustmentCoefficient = 2.;
+  }
+
+  return (anAdjustmentCoefficient * aShapeSize * theRelativeDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (edge)
+// Purpose : 
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+  const IMeshData::IEdgeHandle& theDEdge,
+  const Standard_Real           theMaxShapeSize,
+  const IMeshTools_Parameters&  theParameters)
+{
+  const Standard_Real aAngDeflection = theParameters.Angle;
+  Standard_Real aLinDeflection =
+    !theParameters.Relative ? theParameters.Deflection :
+    ComputeAbsoluteDeflection(theDEdge->GetEdge(),
+                              theParameters.Deflection,
+                              theMaxShapeSize);
+
+  const TopoDS_Edge& anEdge = theDEdge->GetEdge();
+
+  TopoDS_Vertex aFirstVertex, aLastVertex;
+  TopExp::Vertices(anEdge, aFirstVertex, aLastVertex);
+
+  Handle(Geom_Curve) aCurve;
+  Standard_Real aFirstParam, aLastParam;
+  if (BRepMesh_ShapeTool::Range(anEdge, aCurve, aFirstParam, aLastParam))
+  {
+    const Standard_Real aDistF = aFirstVertex.IsNull() ? -1.0 : 
+                        BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam));
+    const Standard_Real aDistL = aLastVertex.IsNull()  ? -1.0 :
+                        BRep_Tool::Pnt(aLastVertex).Distance(aCurve->Value(aLastParam));
+
+    const Standard_Real aVertexAdjustDistance = Max(aDistF, aDistL);
+
+    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)->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 aDeflection = theParameters.DeflectionInterior;
+  if (theParameters.Relative)
+  {
+    aDeflection = ComputeAbsoluteDeflection(theDFace->GetFace(),
+                                            aDeflection, -1.0);
+  }
+
+  Standard_Real aFaceDeflection = 0.0;
+  if (theDFace->WiresNb () > 0)
+  {
+    for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
+    {
+      aFaceDeflection += theDFace->GetWire(aWireIt)->GetDeflection();
+    }
+
+    aFaceDeflection /= theDFace->WiresNb ();
+  }
+
+  aFaceDeflection = Max(aDeflection, aFaceDeflection);
+
+  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..35998a8
--- /dev/null
@@ -0,0 +1,64 @@
+// 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 absolute deflection for theShape with respect to the 
+  //! relative deflection and theMaxShapeSize.
+  //! @param theShape shape for that the deflection should be computed.
+  //! @param theRelativeDeflection relative deflection.
+  //! @param theMaxShapeSize maximum size of the whole shape.
+  //! @return absolute deflection for the shape.
+  Standard_EXPORT static Standard_Real ComputeAbsoluteDeflection (
+    const TopoDS_Shape& theShape,
+    const Standard_Real theRelativeDeflection,
+    const Standard_Real theMaxShapeSize);
+
+  //! 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
index 26d3fce6eab4fa99a1b674dea2631b9b7181cb4d..c87bc6ce62121fe0e2d6e897048e26ec00f75c1b 100644 (file)
@@ -31,7 +31,6 @@
 #include <BRepMesh_Vertex.hxx>
 #include <BRepMesh_Triangle.hxx>
 
-#include <Message_ProgressSentry.hxx>
 #include <NCollection_Vector.hxx>
 
 #include <algorithm>
@@ -79,18 +78,37 @@ namespace {
   }
 } // anonymous namespace
 
+//=======================================================================
+//function : BRepMesh_Delaun
+//purpose  : 
+//=======================================================================
+BRepMesh_Delaun::BRepMesh_Delaun (
+  const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
+  const Standard_Integer                        theCellsCountU,
+  const Standard_Integer                        theCellsCountV,
+  const Standard_Boolean                        isFillCircles)
+: myMeshData ( theOldMesh ),
+  myCircles (new NCollection_IncAllocator(
+             IMeshData::MEMORY_BLOCK_SIZE_HUGE))
+{
+  if (isFillCircles)
+  {
+    InitCirclesTool (theCellsCountU, theCellsCountV);
+  }
+}
+
 //=======================================================================
 //function : BRepMesh_Delaun
 //purpose  : Creates the triangulation with an empty Mesh data structure
 //=======================================================================
-BRepMesh_Delaun::BRepMesh_Delaun(BRepMesh::Array1OfVertexOfDelaun& theVertices)
+BRepMesh_Delaun::BRepMesh_Delaun(IMeshData::Array1OfVertexOfDelaun& theVertices)
 : myCircles (theVertices.Length(), new NCollection_IncAllocator(
-             BRepMesh::MEMORY_BLOCK_SIZE_HUGE))
+             IMeshData::MEMORY_BLOCK_SIZE_HUGE))
 {
   if ( theVertices.Length() > 2 )
   {
     myMeshData = new BRepMesh_DataStructureOfDelaun(
-      new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE),
+      new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE),
       theVertices.Length() );
     Init( theVertices );
   }
@@ -101,13 +119,16 @@ BRepMesh_Delaun::BRepMesh_Delaun(BRepMesh::Array1OfVertexOfDelaun& theVertices)
 //purpose  : Creates the triangulation with and existent Mesh data structure
 //=======================================================================
 BRepMesh_Delaun::BRepMesh_Delaun(
-  const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh,
-  BRepMesh::Array1OfVertexOfDelaun&               theVertices)
+  const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
+  IMeshData::Array1OfVertexOfDelaun&            theVertices)
 : myMeshData( theOldMesh ),
-  myCircles ( theVertices.Length(), theOldMesh->Allocator() )
+  myCircles ( theVertices.Length(), new NCollection_IncAllocator(
+             IMeshData::MEMORY_BLOCK_SIZE_HUGE))
 {
   if ( theVertices.Length() > 2 )
+  {
     Init( theVertices );
+  }
 }
 
 //=======================================================================
@@ -115,93 +136,160 @@ BRepMesh_Delaun::BRepMesh_Delaun(
 //purpose  : Creates the triangulation with and existent Mesh data structure
 //=======================================================================
 BRepMesh_Delaun::BRepMesh_Delaun(
-  const Handle( BRepMesh_DataStructureOfDelaun )& theOldMesh, 
-  BRepMesh::Array1OfInteger&                      theVertexIndices)
+  const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
+  IMeshData::VectorOfInteger&                   theVertexIndices)
 : myMeshData( theOldMesh ),
-  myCircles ( theVertexIndices.Length(), theOldMesh->Allocator() )
+  myCircles ( theVertexIndices.Length(), new NCollection_IncAllocator(
+             IMeshData::MEMORY_BLOCK_SIZE_HUGE))
 {
-  if ( theVertexIndices.Length() > 2 )
-  {
-    Bnd_Box2d aBox;
-    Standard_Integer anIndex = theVertexIndices.Lower();
-    Standard_Integer anUpper = theVertexIndices.Upper();
-    for ( ; anIndex <= anUpper; ++anIndex )
-      aBox.Add( gp_Pnt2d( GetVertex( theVertexIndices( anIndex) ).Coord() ) );
+  perform(theVertexIndices);
+}
 
-    perform( aBox, theVertexIndices );
-  }
+//=======================================================================
+//function : BRepMesh_Delaun
+//purpose  : Creates the triangulation with and existent Mesh data structure
+//=======================================================================
+BRepMesh_Delaun::BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)& theOldMesh,
+                                  IMeshData::VectorOfInteger&                    theVertexIndices,
+                                  const Standard_Integer                         theCellsCountU,
+                                  const Standard_Integer                         theCellsCountV)
+: myMeshData (theOldMesh),
+  myCircles (theVertexIndices.Length (), new NCollection_IncAllocator(
+             IMeshData::MEMORY_BLOCK_SIZE_HUGE))
+{
+  perform (theVertexIndices, theCellsCountU, theCellsCountV);
 }
 
 //=======================================================================
 //function : Init
 //purpose  : Initializes the triangulation with an Array of Vertex
 //=======================================================================
-void BRepMesh_Delaun::Init(BRepMesh::Array1OfVertexOfDelaun& theVertices)
+void BRepMesh_Delaun::Init(IMeshData::Array1OfVertexOfDelaun& theVertices)
 {
-  Bnd_Box2d aBox;
   Standard_Integer aLowerIdx  = theVertices.Lower();
   Standard_Integer anUpperIdx = theVertices.Upper();
-  BRepMesh::Array1OfInteger aVertexIndexes( aLowerIdx, anUpperIdx );
+  IMeshData::VectorOfInteger aVertexIndexes(theVertices.Size());
   
   Standard_Integer anIndex = aLowerIdx;
   for ( ; anIndex <= anUpperIdx; ++anIndex )
   {
-    aBox.Add( gp_Pnt2d( theVertices( anIndex ).Coord() ) );
-    aVertexIndexes( anIndex ) = myMeshData->AddNode( theVertices( anIndex ) );
+    aVertexIndexes.Append(myMeshData->AddNode( theVertices( anIndex ) ));
   }
 
-  perform( aBox, aVertexIndexes );
+  perform( aVertexIndexes );
+}
+
+//=======================================================================
+//function : InitCirclesTool
+//purpose  : 
+//=======================================================================
+void BRepMesh_Delaun::InitCirclesTool (const Standard_Integer theCellsCountU,
+                                       const Standard_Integer theCellsCountV)
+{
+  Bnd_Box2d aBox;
+  for (Standard_Integer aNodeIt = 1; aNodeIt <= myMeshData->NbNodes(); ++aNodeIt)
+  {
+    aBox.Add (gp_Pnt2d (GetVertex (aNodeIt).Coord ()));
+  }
+  aBox.Enlarge (Precision);
+
+  initCirclesTool (aBox, theCellsCountU, theCellsCountV);
+
+  IMeshData::IteratorOfMapOfInteger aTriangleIt (myMeshData->ElementsOfDomain());
+  for (; aTriangleIt.More(); aTriangleIt.Next())
+  {
+    Standard_Integer aNodesIndices[3];
+    const BRepMesh_Triangle& aTriangle = myMeshData->GetElement (aTriangleIt.Key());
+    myMeshData->ElementNodes (aTriangle, aNodesIndices);
+    myCircles.Bind (aTriangleIt.Key(),
+                    GetVertex( aNodesIndices[0] ).Coord(), 
+                    GetVertex( aNodesIndices[1] ).Coord(),
+                    GetVertex( aNodesIndices[2] ).Coord());
+  }
+}
+
+//=======================================================================
+//function : initCirclesTool
+//purpose  : 
+//=======================================================================
+void BRepMesh_Delaun::initCirclesTool (const Bnd_Box2d&       theBox,
+                                       const Standard_Integer theCellsCountU,
+                                       const Standard_Integer theCellsCountV)
+{
+  Standard_Real aMinX, aMinY, aMaxX, aMaxY;
+  theBox.Get  ( aMinX, aMinY, aMaxX, aMaxY );
+  const Standard_Real aDeltaX = aMaxX - aMinX;
+  const Standard_Real aDeltaY = aMaxY - aMinY;
+
+  Standard_Integer aScaler = 2;
+  if ( myMeshData->NbNodes() > 100 )
+  {
+    aScaler = 5;
+  }
+  else if( myMeshData->NbNodes() > 1000 )
+  {
+    aScaler = 7;
+  }
+
+  myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
+  myCircles.SetCellSize  ( aDeltaX / Max (theCellsCountU, aScaler),
+                           aDeltaY / Max (theCellsCountV, aScaler));
 }
 
 //=======================================================================
 //function : perform
 //purpose  : Create super mesh and run triangulation procedure
 //=======================================================================
-void BRepMesh_Delaun::perform(Bnd_Box2d&                 theBndBox,
-                              BRepMesh::Array1OfInteger& theVertexIndexes)
+void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
+                              const Standard_Integer      theCellsCountU /* = -1 */,
+                              const Standard_Integer      theCellsCountV /* = -1 */)
 {
-  theBndBox.Enlarge( Precision );
-  superMesh( theBndBox );
+  if (theVertexIndices.Length () <= 2)
+  {
+    return;
+  }
+
+  Bnd_Box2d aBox;
+  Standard_Integer anIndex = theVertexIndices.Lower ();
+  Standard_Integer anUpper = theVertexIndices.Upper ();
+  for (; anIndex <= anUpper; ++anIndex)
+  {
+    aBox.Add (gp_Pnt2d (GetVertex (theVertexIndices (anIndex)).Coord ()));
+  }
+
+  aBox.Enlarge (Precision);
+
+  initCirclesTool (aBox, theCellsCountU, theCellsCountV);
+  superMesh       (aBox);
 
   ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
-  std::make_heap(theVertexIndexes.begin(), theVertexIndexes.end(), aCmp);
-  std::sort_heap(theVertexIndexes.begin(), theVertexIndexes.end(), aCmp);
+  std::make_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
+  std::sort_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
 
-  compute( theVertexIndexes );
+  compute( theVertexIndices );
 }
 
 //=======================================================================
 //function : superMesh
 //purpose  : Build the super mesh
 //=======================================================================
-void BRepMesh_Delaun::superMesh( const Bnd_Box2d& theBox )
+void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
 {
   Standard_Real aMinX, aMinY, aMaxX, aMaxY;
-  theBox.Get( aMinX, aMinY, aMaxX, aMaxY );
+  theBox.Get  ( aMinX, aMinY, aMaxX, aMaxY );
   Standard_Real aDeltaX = aMaxX - aMinX;
   Standard_Real aDeltaY = aMaxY - aMinY;
 
   Standard_Real aDeltaMin = Min( aDeltaX, aDeltaY );
   Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
   Standard_Real aDelta    = aDeltaX + aDeltaY;
-  
-  myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
-
-  Standard_Integer aScaler = 2;
-  if ( myMeshData->NbNodes() > 100 )
-    aScaler = 5;
-  else if( myMeshData->NbNodes() > 1000 )
-    aScaler = 7;
-
-  myCircles.SetCellSize( aDeltaX / aScaler,
-                         aDeltaY / aScaler );
 
   mySupVert[0] = myMeshData->AddNode(
     BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) );
-    
+
   mySupVert[1] = myMeshData->AddNode(
     BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
-    
+
   mySupVert[2] = myMeshData->AddNode(
     BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
 
@@ -211,13 +299,13 @@ void BRepMesh_Delaun::superMesh( const Bnd_Box2d& theBox )
   {
     Standard_Integer aFirstNode = aNodeId;
     Standard_Integer aLastNode  = (aNodeId + 1) % 3;
-    Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge( 
+    Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge(
       mySupVert[aFirstNode], mySupVert[aLastNode], BRepMesh_Free ) );
 
     e[aNodeId] = Abs(aLinkIndex);
     o[aNodeId] = (aLinkIndex > 0);
   }
-  
+
   mySupTrian = BRepMesh_Triangle(e, o, BRepMesh_Free);
 }
 
@@ -227,15 +315,18 @@ void BRepMesh_Delaun::superMesh( const Bnd_Box2d& theBox )
 //           edges into the map.
 //           When an edge is suppressed more than one time it is destroyed.
 //=======================================================================
-void BRepMesh_Delaun::deleteTriangle(const Standard_Integer         theIndex, 
-                                     BRepMesh::MapOfIntegerInteger& theLoopEdges )
+void BRepMesh_Delaun::deleteTriangle(const Standard_Integer          theIndex, 
+                                     IMeshData::MapOfIntegerInteger& theLoopEdges )
 {
-  myCircles.Delete( theIndex );
+  if (!myCircles.IsEmpty())
+  {
+    myCircles.Delete (theIndex);
+  }
+
+  const BRepMesh_Triangle& aElement = GetTriangle(theIndex);
+  const Standard_Integer(&e)[3] = aElement.myEdges;
+  const Standard_Boolean(&o)[3] = aElement.myOrientations;
 
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  GetTriangle( theIndex ).Edges( e, o );
-  
   myMeshData->RemoveElement( theIndex );
 
   for ( Standard_Integer i = 0; i < 3; ++i )
@@ -253,13 +344,14 @@ void BRepMesh_Delaun::deleteTriangle(const Standard_Integer         theIndex,
 //purpose  : Computes the triangulation and add the vertices edges and 
 //           triangles to the Mesh data structure
 //=======================================================================
-void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes)
+void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
 {
-  // Insertion of edges of super triangles in the list of free edges: 
-  BRepMesh::MapOfIntegerInteger aLoopEdges(10, myMeshData->Allocator());
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  mySupTrian.Edges( e, o );
+  // Insertion of edges of super triangles in the list of free edges:
+  Handle(NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator(
+    IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+  IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
+  const Standard_Integer(&e)[3] = mySupTrian.myEdges;
                     
   aLoopEdges.Bind( e[0], Standard_True );
   aLoopEdges.Bind( e[1], Standard_True );
@@ -281,13 +373,13 @@ void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes)
     aSelector.NeighboursOfNode( mySupVert[aSupVertId] );
   
   aLoopEdges.Clear();
-  BRepMesh::MapOfInteger::Iterator aFreeTriangles( aSelector.Elements() );
+  IMeshData::IteratorOfMapOfInteger aFreeTriangles( aSelector.Elements() );
   for ( ; aFreeTriangles.More(); aFreeTriangles.Next() )
     deleteTriangle( aFreeTriangles.Key(), aLoopEdges );
 
   // All edges that remain free are removed from aLoopEdges;
   // only the boundary edges of the triangulation remain there
-  BRepMesh::MapOfIntegerInteger::Iterator aFreeEdges( aLoopEdges );
+  IMeshData::MapOfIntegerInteger::Iterator aFreeEdges( aLoopEdges );
   for ( ; aFreeEdges.More(); aFreeEdges.Next() )
   {
     if ( myMeshData->ElementsConnectedTo( aFreeEdges.Key() ).IsEmpty() )
@@ -303,34 +395,19 @@ void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes)
 //function : createTriangles
 //purpose  : Creates the triangles beetween the node and the polyline.
 //=======================================================================
-void BRepMesh_Delaun::createTriangles(const Standard_Integer         theVertexIndex,  
-                                      BRepMesh::MapOfIntegerInteger& thePoly)
+void BRepMesh_Delaun::createTriangles(const Standard_Integer          theVertexIndex,  
+                                      IMeshData::MapOfIntegerInteger& thePoly)
 {
-  createTriangles (theVertexIndex, thePoly, NULL);
-}
-
-//=======================================================================
-//function : createTriangles
-//purpose  : Creates the triangles beetween the node and the polyline.
-//=======================================================================
-void BRepMesh_Delaun::createTriangles(const Standard_Integer         theVertexIndex,
-                                      BRepMesh::MapOfIntegerInteger& thePoly,
-                                      Message_ProgressSentry*        theProgressEntry)
-{
-  BRepMesh::ListOfInteger aLoopEdges, anExternalEdges;
+  IMeshData::ListOfInteger aLoopEdges, anExternalEdges;
   const gp_XY& aVertexCoord = myMeshData->GetNode( theVertexIndex ).Coord();
   
-  BRepMesh::MapOfIntegerInteger::Iterator anEdges( thePoly );
+  IMeshData::MapOfIntegerInteger::Iterator anEdges( thePoly );
   for ( ; anEdges.More(); anEdges.Next() )
   {
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return;
-    }
     Standard_Integer     anEdgeId = anEdges.Key();
     const BRepMesh_Edge& anEdge   = GetEdge( anEdgeId );
 
-    const Standard_Boolean isPositive = thePoly (anEdgeId) != 0;
+    Standard_Boolean isPositive = thePoly( anEdgeId ) != 0;
 
     Standard_Integer aNodes[3];
     if ( isPositive )
@@ -424,10 +501,6 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer         theVertexIn
 
   while ( !aLoopEdges.IsEmpty() )
   {
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return;
-    }
     const BRepMesh_Edge& anEdge = GetEdge( Abs( aLoopEdges.First() ) );
     if ( anEdge.Movability() != BRepMesh_Deleted )
     {
@@ -444,21 +517,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer         theVertexIn
 //purpose  : Creation of triangles from the new nodes
 //=======================================================================
 void BRepMesh_Delaun::createTrianglesOnNewVertices(
-  BRepMesh::Array1OfInteger& theVertexIndexes)
-{
-  createTrianglesOnNewVertices (theVertexIndexes, NULL);
-}
-
-//=======================================================================
-//function : createTrianglesOnNewVertices
-//purpose  : Creation of triangles from the new nodes
-//=======================================================================
-void BRepMesh_Delaun::createTrianglesOnNewVertices(
-  BRepMesh::Array1OfInteger& theVertexIndexes,
-  Message_ProgressSentry*    theProgressEntry)
+  IMeshData::VectorOfInteger& theVertexIndexes)
 {
   Handle(NCollection_IncAllocator) aAllocator =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
   Standard_Real aTolU, aTolV;
   myMeshData->Data()->GetTolerance(aTolU, aTolV);
@@ -471,22 +533,17 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
   Standard_Integer anUpper = theVertexIndexes.Upper();
   for( ; anIndex <= anUpper; ++anIndex ) 
   {
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return;
-    }
-
     aAllocator->Reset(Standard_False);
-    BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
+    IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
     
     Standard_Integer aVertexIdx = theVertexIndexes( anIndex );    
     const BRepMesh_Vertex& aVertex = GetVertex( aVertexIdx );
 
     // Iterator in the list of indexes of circles containing the node
-    BRepMesh::ListOfInteger& aCirclesList = myCircles.Select( aVertex.Coord() );
+    IMeshData::ListOfInteger& aCirclesList = myCircles.Select( aVertex.Coord() );
     
     Standard_Integer onEgdeId = 0, aTriangleId = 0;
-    BRepMesh::ListOfInteger::Iterator aCircleIt( aCirclesList );
+    IMeshData::ListOfInteger::Iterator aCircleIt( aCirclesList );
     for ( ; aCircleIt.More(); aCircleIt.Next() )
     {
       // To add a node in the mesh it is necessary to check conditions: 
@@ -519,18 +576,12 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
       isModify = Standard_True;    
       while ( isModify && !aCirclesList.IsEmpty() )
       {
-        if (theProgressEntry != NULL && !theProgressEntry->More())
-        {
-          return;
-        }
-
         isModify = Standard_False;
-        BRepMesh::ListOfInteger::Iterator aCircleIt1( aCirclesList );
+        IMeshData::ListOfInteger::Iterator aCircleIt1( aCirclesList );
         for ( ; aCircleIt1.More(); aCircleIt1.Next() )
         {
-          Standard_Integer e[3];
-          Standard_Boolean o[3];
-          GetTriangle( aCircleIt1.Value() ).Edges( e, o );
+          const BRepMesh_Triangle& aElement = GetTriangle(aCircleIt1.Value());
+          const Standard_Integer(&e)[3] = aElement.myEdges;
                                                    
           if ( aLoopEdges.IsBound( e[0] ) || 
                aLoopEdges.IsBound( e[1] ) || 
@@ -544,28 +595,13 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
         }
       }
 
-      if (theProgressEntry != NULL && !theProgressEntry->More())
-      {
-        return;
-      }
       // Creation of triangles with the current node and free edges
       // and removal of these edges from the list of free edges
-      createTriangles( aVertexIdx, aLoopEdges, theProgressEntry );
+      createTriangles( aVertexIdx, aLoopEdges );
     }
   }
-  if (theProgressEntry != NULL && !theProgressEntry->More())
-  {
-    return;
-  }
-
-  insertInternalEdges (theProgressEntry);
-  if (theProgressEntry != NULL && !theProgressEntry->More())
-  {
-    return;
-  }
 
-  // Adjustment of meshes to boundary edges
-  frontierAdjust();
+  ProcessConstraints();
 }
 
 //=======================================================================
@@ -574,29 +610,13 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
 //=======================================================================
 void BRepMesh_Delaun::insertInternalEdges()
 {
-  insertInternalEdges (NULL);
-}
-
-//=======================================================================
-//function : insertInternalEdges
-//purpose  : 
-//=======================================================================
-void BRepMesh_Delaun::insertInternalEdges (Message_ProgressSentry* theProgressEntry)
-{
-  BRepMesh::HMapOfInteger anInternalEdges = InternalEdges();
+  Handle(IMeshData::MapOfInteger) anInternalEdges = InternalEdges();;
 
   // Destruction of triancles intersecting internal edges 
   // and their replacement by makeshift triangles
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  BRepMesh::MapOfInteger::Iterator anInernalEdgesIt( *anInternalEdges );
+  IMeshData::IteratorOfMapOfInteger anInernalEdgesIt( *anInternalEdges );
   for ( ; anInernalEdgesIt.More(); anInernalEdgesIt.Next() )
   {
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return;
-    }
-
     const Standard_Integer aLinkIndex = anInernalEdgesIt.Key();
     const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(aLinkIndex);
 
@@ -604,7 +624,10 @@ void BRepMesh_Delaun::insertInternalEdges (Message_ProgressSentry* theProgressEn
     Standard_Boolean isGo[2] = { Standard_True, Standard_True };
     for (Standard_Integer aTriangleIt = 1; aTriangleIt <= aPair.Extent(); ++aTriangleIt)
     {
-      GetTriangle(aPair.Index(aTriangleIt)).Edges(e, o);
+      const BRepMesh_Triangle& aElement = GetTriangle(aPair.Index(aTriangleIt));
+      const Standard_Integer(&e)[3] = aElement.myEdges;
+      const Standard_Boolean(&o)[3] = aElement.myOrientations;
+
       for (Standard_Integer i = 0; i < 3; ++i)
       {
         if (e[i] == aLinkIndex)
@@ -653,9 +676,8 @@ Standard_Boolean BRepMesh_Delaun::isBoundToFrontier(
     if ( aTriId < 0 || aTriId == thePrevElementId )
       continue;
 
-    Standard_Integer anEdges[3];
-    Standard_Boolean anEdgesOri[3];
-    GetTriangle( aTriId ).Edges( anEdges, anEdgesOri );
+    const BRepMesh_Triangle& aElement = GetTriangle(aTriId);
+    const Standard_Integer(&anEdges)[3] = aElement.myEdges;
 
     for ( Standard_Integer anEdgeIt = 0; anEdgeIt < 3; ++anEdgeIt )
     {
@@ -690,16 +712,16 @@ Standard_Boolean BRepMesh_Delaun::isBoundToFrontier(
 void BRepMesh_Delaun::cleanupMesh()
 {
   Handle(NCollection_IncAllocator) aAllocator =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
   for(;;)
   {
     aAllocator->Reset(Standard_False);
-    BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
-    BRepMesh::MapOfInteger aDelTriangles(10, aAllocator);
+    IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
+    IMeshData::MapOfInteger aDelTriangles;
 
-    BRepMesh::HMapOfInteger aFreeEdges = FreeEdges();
-    BRepMesh::MapOfInteger::Iterator aFreeEdgesIt( *aFreeEdges );
+    Handle(IMeshData::MapOfInteger) aFreeEdges = FreeEdges();
+    IMeshData::IteratorOfMapOfInteger aFreeEdgesIt( *aFreeEdges );
     for ( ; aFreeEdgesIt.More(); aFreeEdgesIt.Next() )
     {
       const Standard_Integer& aFreeEdgeId = aFreeEdgesIt.Key();
@@ -718,9 +740,8 @@ void BRepMesh_Delaun::cleanupMesh()
       Standard_Integer aTriId = aPair.FirstIndex();
 
       // Check that the connected triangle is not surrounded by another triangles
-      Standard_Integer anEdges[3];
-      Standard_Boolean anEdgesOri[3];
-      GetTriangle( aTriId ).Edges( anEdges, anEdgesOri );
+      const BRepMesh_Triangle& aElement = GetTriangle(aTriId);
+      const Standard_Integer(&anEdges)[3] = aElement.myEdges;
 
       Standard_Boolean isCanNotBeRemoved = Standard_True;
       for ( Standard_Integer aCurEdgeIdx = 0; aCurEdgeIdx < 3; ++aCurEdgeIdx )
@@ -728,7 +749,7 @@ void BRepMesh_Delaun::cleanupMesh()
         if ( anEdges[aCurEdgeIdx] != aFreeEdgeId )
           continue;
 
-        for ( Standard_Integer anOtherEdgeIt = 1; anOtherEdgeIt <= 2; ++anOtherEdgeIt )
+        for ( Standard_Integer anOtherEdgeIt = 1; anOtherEdgeIt <= 2 && isCanNotBeRemoved; ++anOtherEdgeIt )
         {
           Standard_Integer anOtherEdgeId = ( aCurEdgeIdx + anOtherEdgeIt ) % 3;
           const BRepMesh_PairOfIndex& anOtherEdgePair = 
@@ -737,7 +758,27 @@ void BRepMesh_Delaun::cleanupMesh()
           if ( anOtherEdgePair.Extent() < 2 )
           {
             isCanNotBeRemoved = Standard_False;
-            break;
+          }
+          else
+          {
+            for (int aTriIdx = 1; aTriIdx <= anOtherEdgePair.Extent () && isCanNotBeRemoved; ++aTriIdx)
+            {
+              if (anOtherEdgePair.Index (aTriIdx) == aTriId)
+                continue;
+
+              Standard_Integer v[3];
+              const BRepMesh_Triangle& aCurTriangle = GetTriangle (anOtherEdgePair.Index (aTriIdx));
+              myMeshData->ElementNodes (aCurTriangle, v);
+              for (int aNodeIdx = 0; aNodeIdx < 3 && isCanNotBeRemoved; ++aNodeIdx)
+              {
+                if (v[aNodeIdx] == mySupVert[0] ||
+                    v[aNodeIdx] == mySupVert[1] ||
+                    v[aNodeIdx] == mySupVert[2])
+                {
+                  isCanNotBeRemoved = Standard_False;
+                }
+              }
+            }
           }
         }
 
@@ -761,7 +802,7 @@ void BRepMesh_Delaun::cleanupMesh()
 
     // Destruction of triangles :
     Standard_Integer aDeletedTrianglesNb = 0;
-    BRepMesh::MapOfInteger::Iterator aDelTrianglesIt( aDelTriangles );
+    IMeshData::IteratorOfMapOfInteger aDelTrianglesIt( aDelTriangles );
     for ( ; aDelTrianglesIt.More(); aDelTrianglesIt.Next() )
     {
       deleteTriangle( aDelTrianglesIt.Key(), aLoopEdges );
@@ -769,7 +810,7 @@ void BRepMesh_Delaun::cleanupMesh()
     }
 
     // Destruction of remaining hanging edges
-    BRepMesh::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
+    IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
     for ( ; aLoopEdgesIt.More(); aLoopEdgesIt.Next() )
     {
       if ( myMeshData->ElementsConnectedTo( aLoopEdgesIt.Key() ).IsEmpty() )
@@ -787,15 +828,14 @@ void BRepMesh_Delaun::cleanupMesh()
 //=======================================================================
 void BRepMesh_Delaun::frontierAdjust()
 {
-  BRepMesh::HMapOfInteger        aFrontier = Frontier();
+  Handle(IMeshData::MapOfInteger)  aFrontier = Frontier();
 
   Handle(NCollection_IncAllocator) aAllocator =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
-  BRepMesh::VectorOfInteger      aFailedFrontiers(256, aAllocator);
-  BRepMesh::MapOfIntegerInteger  aLoopEdges(10, aAllocator);
-  BRepMesh::HMapOfInteger        aIntFrontierEdges = 
-    new BRepMesh::MapOfInteger(10, aAllocator);
+  IMeshData::VectorOfInteger      aFailedFrontiers(256, aAllocator);
+  IMeshData::MapOfIntegerInteger  aLoopEdges(10, aAllocator);
+  Handle(IMeshData::MapOfInteger) aIntFrontierEdges = new IMeshData::MapOfInteger;
 
   for ( Standard_Integer aPass = 1; aPass <= 2; ++aPass )
   {      
@@ -803,7 +843,7 @@ void BRepMesh_Delaun::frontierAdjust()
     // 2 pass): find external triangles on boundary edges appeared 
     //          during triangles replacement.
     
-    BRepMesh::MapOfInteger::Iterator aFrontierIt( *aFrontier );
+    IMeshData::IteratorOfMapOfInteger aFrontierIt( *aFrontier );
     for ( ; aFrontierIt.More(); aFrontierIt.Next() )
     {
       Standard_Integer aFrontierId = aFrontierIt.Key();
@@ -815,9 +855,9 @@ void BRepMesh_Delaun::frontierAdjust()
         if( aPriorElemId < 0 )
           continue;
             
-        Standard_Integer e[3];
-        Standard_Boolean o[3];
-        GetTriangle( aPriorElemId ).Edges( e, o );
+        const BRepMesh_Triangle& aElement = GetTriangle(aPriorElemId);
+        const Standard_Integer(&e)[3] = aElement.myEdges;
+        const Standard_Boolean(&o)[3] = aElement.myOrientations;
 
         Standard_Boolean isTriangleFound = Standard_False;
         for ( Standard_Integer n = 0; n < 3; ++n )
@@ -837,7 +877,7 @@ void BRepMesh_Delaun::frontierAdjust()
     }
 
     // destrucrion of remaining hanging edges :
-    BRepMesh::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
+    IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
     for ( ; aLoopEdgesIt.More(); aLoopEdgesIt.Next() )
     {
       Standard_Integer aLoopEdgeId = aLoopEdgesIt.Key();
@@ -868,7 +908,7 @@ void BRepMesh_Delaun::frontierAdjust()
   // situation when frontier edge has a triangle at a right side, but its free 
   // links cross another frontieres  and meshLeftPolygonOf itself can't collect 
   // a closed polygon.
-  BRepMesh::VectorOfInteger::Iterator aFailedFrontiersIt( aFailedFrontiers );
+  IMeshData::VectorOfInteger::Iterator aFailedFrontiersIt( aFailedFrontiers );
   for ( ; aFailedFrontiersIt.More(); aFailedFrontiersIt.Next() )
   {
     Standard_Integer aFrontierId = aFailedFrontiersIt.Value();
@@ -884,9 +924,9 @@ void BRepMesh_Delaun::frontierAdjust()
 //purpose  : Add boundig box for edge defined by start & end point to
 //           the given vector of bounding boxes for triangulation edges
 //=======================================================================
-void BRepMesh_Delaun::fillBndBox(BRepMesh::SequenceOfBndB2d& theBoxes,
-                                 const BRepMesh_Vertex&      theV1,
-                                 const BRepMesh_Vertex&      theV2)
+void BRepMesh_Delaun::fillBndBox(IMeshData::SequenceOfBndB2d& theBoxes,
+                                 const BRepMesh_Vertex&       theV1,
+                                 const BRepMesh_Vertex&       theV2)
 {
   Bnd_B2d aBox;
   UpdateBndBox(theV1.Coord(), theV2.Coord(), aBox);
@@ -898,16 +938,16 @@ void BRepMesh_Delaun::fillBndBox(BRepMesh::SequenceOfBndB2d& theBoxes,
 //purpose  : Collect the polygon at the left of the given edge (material side)
 //=======================================================================
 Standard_Boolean BRepMesh_Delaun::meshLeftPolygonOf( 
-  const Standard_Integer  theStartEdgeId,
-  const Standard_Boolean  isForward,
-  BRepMesh::HMapOfInteger theSkipped )
+  const Standard_Integer          theStartEdgeId,
+  const Standard_Boolean          isForward,
+  Handle(IMeshData::MapOfInteger) theSkipped)
 {
   if ( !theSkipped.IsNull() && theSkipped->Contains( theStartEdgeId ) )
     return Standard_True;
 
   const BRepMesh_Edge& aRefEdge = GetEdge( theStartEdgeId );
 
-  BRepMesh::SequenceOfInteger aPolygon;
+  IMeshData::SequenceOfInteger aPolygon;
   Standard_Integer aStartNode, aPivotNode;
   if ( isForward )
   {
@@ -935,14 +975,14 @@ Standard_Boolean BRepMesh_Delaun::meshLeftPolygonOf(
   // Auxilary structures.
   // Bounding boxes of polygon links to be used for preliminary
   // analysis of intersections
-  BRepMesh::SequenceOfBndB2d aBoxes;
+  IMeshData::SequenceOfBndB2d aBoxes;
   fillBndBox( aBoxes, aStartEdgeVertexS, aPivotVertex );
 
   // Hanging ends
-  BRepMesh::MapOfInteger aDeadLinks;
+  IMeshData::MapOfInteger aDeadLinks;
 
   // Links are temporarily excluded from consideration
-  BRepMesh::MapOfInteger aLeprousLinks;
+  IMeshData::MapOfInteger aLeprousLinks;
   aLeprousLinks.Add( theStartEdgeId );
 
   Standard_Boolean isSkipLeprous = Standard_True;
@@ -1027,26 +1067,26 @@ Standard_Boolean BRepMesh_Delaun::meshLeftPolygonOf(
 //           consideration next time until a hanging end is occured.
 //=======================================================================
 Standard_Integer BRepMesh_Delaun::findNextPolygonLink(
-  const Standard_Integer&            theFirstNode,
-  const Standard_Integer&            thePivotNode,
-  const BRepMesh_Vertex&             thePivotVertex,
-  const gp_Vec2d&                    theRefLinkDir,
-  const BRepMesh::SequenceOfBndB2d&  theBoxes,
-  const BRepMesh::SequenceOfInteger& thePolygon,
-  const BRepMesh::HMapOfInteger      theSkipped,
-  const Standard_Boolean&            isSkipLeprous,
-  BRepMesh::MapOfInteger&            theLeprousLinks,
-  BRepMesh::MapOfInteger&            theDeadLinks,
-  Standard_Integer&                  theNextPivotNode,
-  gp_Vec2d&                          theNextLinkDir,
-  Bnd_B2d&                           theNextLinkBndBox )
+  const Standard_Integer&               theFirstNode,
+  const Standard_Integer&               thePivotNode,
+  const BRepMesh_Vertex&                thePivotVertex,
+  const gp_Vec2d&                       theRefLinkDir,
+  const IMeshData::SequenceOfBndB2d&    theBoxes,
+  const IMeshData::SequenceOfInteger&   thePolygon,
+  const Handle(IMeshData::MapOfInteger) theSkipped,
+  const Standard_Boolean&               isSkipLeprous,
+  IMeshData::MapOfInteger&              theLeprousLinks,
+  IMeshData::MapOfInteger&              theDeadLinks,
+  Standard_Integer&                     theNextPivotNode,
+  gp_Vec2d&                             theNextLinkDir,
+  Bnd_B2d&                              theNextLinkBndBox )
 {
   // Find the next link having the greatest angle 
   // respect to a direction of a reference one
   Standard_Real aMaxAngle = RealFirst();
 
   Standard_Integer aNextLinkId = 0;
-  BRepMesh::ListOfInteger::Iterator aLinkIt( myMeshData->LinksConnectedTo( thePivotNode ) );
+  IMeshData::ListOfInteger::Iterator aLinkIt( myMeshData->LinksConnectedTo( thePivotNode ) );
   for ( ; aLinkIt.More(); aLinkIt.Next() )
   {
     const Standard_Integer& aNeighbourLinkInfo = aLinkIt.Value();
@@ -1136,13 +1176,13 @@ Standard_Integer BRepMesh_Delaun::findNextPolygonLink(
 //           <theLinkBndBox> parameter.
 //=======================================================================
 Standard_Boolean BRepMesh_Delaun::checkIntersection( 
-  const BRepMesh_Edge&               theLink,
-  const BRepMesh::SequenceOfInteger& thePolygon,
-  const BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-  const Standard_Boolean             isConsiderEndPointTouch,
-  const Standard_Boolean             isConsiderPointOnEdge,
-  const Standard_Boolean             isSkipLastEdge,
-  Bnd_B2d&                           theLinkBndBox ) const
+  const BRepMesh_Edge&                theLink,
+  const IMeshData::SequenceOfInteger& thePolygon,
+  const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+  const Standard_Boolean              isConsiderEndPointTouch,
+  const Standard_Boolean              isConsiderPointOnEdge,
+  const Standard_Boolean              isSkipLastEdge,
+  Bnd_B2d&                            theLinkBndBox ) const
 {
   UpdateBndBox(GetVertex(theLink.FirstNode()).Coord(),
     GetVertex(theLink.LastNode()).Coord(), theLinkBndBox);
@@ -1168,7 +1208,7 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection(
         continue;
 
       gp_Pnt2d anIntPnt;
-      BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( theLink, aPolyLink, 
+      BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( theLink, aPolyLink,
         isConsiderEndPointTouch, isConsiderPointOnEdge, anIntPnt );
 
       if ( aIntFlag != BRepMesh_GeomTool::NoIntersection )
@@ -1184,17 +1224,10 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection(
 //function : addTriangle
 //purpose  : Add a triangle based on the given oriented edges into mesh
 //=======================================================================
-void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
-                                   const Standard_Boolean (&theEdgesOri)[3],
-                                   const Standard_Integer (&theNodesId)[3])
+inline void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
+                                          const Standard_Boolean (&theEdgesOri)[3],
+                                          const Standard_Integer (&theNodesId)[3] )
 {
-  for (Standard_Integer i = 0; i < 3; ++i)
-  {
-    const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(theEdgesId[i]);
-    if (aPair.Extent() == 2)
-      // it is forbidden to have more than two triangles connected to the same link
-      return;
-  }
   Standard_Integer aNewTriangleId = 
     myMeshData->AddElement(BRepMesh_Triangle(theEdgesId, 
       theEdgesOri, BRepMesh_Free));
@@ -1213,20 +1246,20 @@ void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3],
 //function : cleanupPolygon
 //purpose  : Remove internal triangles from the given polygon
 //=======================================================================
-void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolygon,
-                                     const BRepMesh::SequenceOfBndB2d&  thePolyBoxes )
+void BRepMesh_Delaun::cleanupPolygon(const IMeshData::SequenceOfInteger& thePolygon,
+                                     const IMeshData::SequenceOfBndB2d&  thePolyBoxes )
 {
   Standard_Integer aPolyLen = thePolygon.Length();
   if ( aPolyLen < 3 )
     return;
 
   Handle(NCollection_IncAllocator) aAllocator =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
+    new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
-  BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
-  BRepMesh::MapOfInteger    anIgnoredEdges(10, aAllocator);
-  BRepMesh::MapOfInteger    aPolyVerticesFindMap(10, aAllocator);
-  BRepMesh::VectorOfInteger aPolyVertices(256, aAllocator);
+  IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
+  IMeshData::MapOfInteger    anIgnoredEdges;
+  IMeshData::MapOfInteger    aPolyVerticesFindMap;
+  IMeshData::VectorOfInteger aPolyVertices(256, aAllocator);
   // Collect boundary vertices of the polygon
   for ( Standard_Integer aPolyIt = 1; aPolyIt <= aPolyLen; ++aPolyIt )
   {
@@ -1245,9 +1278,9 @@ void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolyg
       if ( anElemId < 0 )
         continue;
 
-      Standard_Integer anEdges[3];
-      Standard_Boolean anEdgesOri[3];
-      GetTriangle( anElemId ).Edges(anEdges, anEdgesOri);
+      const BRepMesh_Triangle& aElement = GetTriangle(anElemId);
+      const Standard_Integer(&anEdges)[3] = aElement.myEdges;
+      const Standard_Boolean(&anEdgesOri)[3] = aElement.myOrientations;
 
       Standard_Integer isTriangleFound = Standard_False;
       for ( Standard_Integer anEdgeIt = 0; anEdgeIt < 3; ++anEdgeIt )
@@ -1292,7 +1325,7 @@ void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolyg
   if ( aPolyVertices.First() != aPolyVertices.Last() )
     aPolyVertices.Append( aPolyVertices.First() );
 
-  BRepMesh::MapOfInteger aSurvivedLinks( anIgnoredEdges );
+  IMeshData::MapOfInteger aSurvivedLinks( anIgnoredEdges );
 
   Standard_Integer aPolyVertIt          = 0;
   Standard_Integer anUniqueVerticesNum  = aPolyVertices.Length() - 1;
@@ -1303,7 +1336,7 @@ void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolyg
       thePolyBoxes, aSurvivedLinks, aLoopEdges );
   }
 
-  BRepMesh::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
+  IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
   for ( ; aLoopEdgesIt.More(); aLoopEdgesIt.Next() )
   {
     const Standard_Integer& aLoopEdgeId = aLoopEdgesIt.Key();
@@ -1321,19 +1354,19 @@ void BRepMesh_Delaun::cleanupPolygon(const BRepMesh::SequenceOfInteger& thePolyg
 //           inside the polygon or crossed it.
 //=======================================================================
 void BRepMesh_Delaun::killTrianglesAroundVertex( 
-  const Standard_Integer             theZombieNodeId,
-  const BRepMesh::VectorOfInteger&   thePolyVertices,
-  const BRepMesh::MapOfInteger&      thePolyVerticesFindMap,
-  const BRepMesh::SequenceOfInteger& thePolygon,
-  const BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-  BRepMesh::MapOfInteger&            theSurvivedLinks,
-  BRepMesh::MapOfIntegerInteger&     theLoopEdges )
+  const Standard_Integer              theZombieNodeId,
+  const IMeshData::VectorOfInteger&   thePolyVertices,
+  const IMeshData::MapOfInteger&      thePolyVerticesFindMap,
+  const IMeshData::SequenceOfInteger& thePolygon,
+  const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+  IMeshData::MapOfInteger&            theSurvivedLinks,
+  IMeshData::MapOfIntegerInteger&     theLoopEdges )
 {
-  BRepMesh::ListOfInteger::Iterator aNeighborsIt = 
+  IMeshData::ListOfInteger::Iterator aNeighborsIt = 
     myMeshData->LinksConnectedTo( theZombieNodeId );
 
   // Try to infect neighbor nodes
-  BRepMesh::VectorOfInteger aVictimNodes;
+  IMeshData::VectorOfInteger aVictimNodes;
   for ( ; aNeighborsIt.More(); aNeighborsIt.Next() )
   {
     const Standard_Integer& aNeighborLinkId = aNeighborsIt.Value();
@@ -1391,7 +1424,7 @@ void BRepMesh_Delaun::killTrianglesAroundVertex(
   }
 
   // Go and do your job!
-  BRepMesh::VectorOfInteger::Iterator aVictimIt( aVictimNodes );
+  IMeshData::VectorOfInteger::Iterator aVictimIt( aVictimNodes );
   for ( ; aVictimIt.More(); aVictimIt.Next() )
   {
     killTrianglesAroundVertex( aVictimIt.Value(), thePolyVertices,
@@ -1405,8 +1438,8 @@ void BRepMesh_Delaun::killTrianglesAroundVertex(
 //purpose  : Checks is the given vertex lies inside the polygon
 //=======================================================================
 Standard_Boolean BRepMesh_Delaun::isVertexInsidePolygon( 
-  const Standard_Integer&          theVertexId,
-  const BRepMesh::VectorOfInteger& thePolygonVertices ) const
+  const Standard_Integer&           theVertexId,
+  const IMeshData::VectorOfInteger& thePolygonVertices ) const
 {
   Standard_Integer aPolyLen = thePolygonVertices.Length();
   if ( aPolyLen < 3 )
@@ -1446,13 +1479,13 @@ Standard_Boolean BRepMesh_Delaun::isVertexInsidePolygon(
 //           boundary intersection. Does nothing elsewhere.
 //=======================================================================
 void BRepMesh_Delaun::killTrianglesOnIntersectingLinks( 
-  const Standard_Integer&            theLinkToCheckId, 
-  const BRepMesh_Edge&               theLinkToCheck,
-  const Standard_Integer&            theEndPoint,
-  const BRepMesh::SequenceOfInteger& thePolygon,
-  const BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-  BRepMesh::MapOfInteger&            theSurvivedLinks,
-  BRepMesh::MapOfIntegerInteger&     theLoopEdges )
+  const Standard_Integer&             theLinkToCheckId, 
+  const BRepMesh_Edge&                theLinkToCheck,
+  const Standard_Integer&             theEndPoint,
+  const IMeshData::SequenceOfInteger& thePolygon,
+  const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+  IMeshData::MapOfInteger&            theSurvivedLinks,
+  IMeshData::MapOfIntegerInteger&     theLoopEdges )
 {
   if ( theSurvivedLinks.Contains( theLinkToCheckId ) )
     return;
@@ -1470,7 +1503,7 @@ void BRepMesh_Delaun::killTrianglesOnIntersectingLinks(
 
   killLinkTriangles( theLinkToCheckId, theLoopEdges );
 
-  BRepMesh::ListOfInteger::Iterator aNeighborsIt(
+  IMeshData::ListOfInteger::Iterator aNeighborsIt(
     myMeshData->LinksConnectedTo(theEndPoint));
 
   for ( ; aNeighborsIt.More(); aNeighborsIt.Next() )
@@ -1492,8 +1525,8 @@ void BRepMesh_Delaun::killTrianglesOnIntersectingLinks(
 //purpose  : Kill triangles bound to the given link.
 //=======================================================================
 void BRepMesh_Delaun::killLinkTriangles( 
-  const Standard_Integer&        theLinkId, 
-  BRepMesh::MapOfIntegerInteger& theLoopEdges )
+  const Standard_Integer&         theLinkId, 
+  IMeshData::MapOfIntegerInteger& theLoopEdges )
 {
   const BRepMesh_PairOfIndex& aPair = 
     myMeshData->ElementsConnectedTo( theLinkId );
@@ -1535,17 +1568,17 @@ void BRepMesh_Delaun::getOrientedNodes(const BRepMesh_Edge&   theEdge,
 //purpose  : Processes loop within the given polygon formed by range of 
 //           its links specified by start and end link indices.
 //=======================================================================
-void BRepMesh_Delaun::processLoop(const Standard_Integer             theLinkFrom,
-                                  const Standard_Integer             theLinkTo,
-                                  const BRepMesh::SequenceOfInteger& thePolygon,
-                                  const BRepMesh::SequenceOfBndB2d&  thePolyBoxes)
+void BRepMesh_Delaun::processLoop(const Standard_Integer              theLinkFrom,
+                                  const Standard_Integer              theLinkTo,
+                                  const IMeshData::SequenceOfInteger& thePolygon,
+                                  const IMeshData::SequenceOfBndB2d&  thePolyBoxes)
 {
   Standard_Integer aNbOfLinksInLoop = theLinkTo - theLinkFrom - 1;
   if ( aNbOfLinksInLoop < 3 )
     return;
 
-  BRepMesh::SequenceOfInteger aPolygon;
-  BRepMesh::SequenceOfBndB2d  aPolyBoxes;
+  IMeshData::SequenceOfInteger aPolygon;
+  IMeshData::SequenceOfBndB2d  aPolyBoxes;
   for ( ; aNbOfLinksInLoop > 0; --aNbOfLinksInLoop )
   {
     Standard_Integer aLoopLinkIndex = theLinkFrom + aNbOfLinksInLoop;
@@ -1563,10 +1596,10 @@ void BRepMesh_Delaun::processLoop(const Standard_Integer             theLinkFrom
 Standard_Integer BRepMesh_Delaun::createAndReplacePolygonLink(
   const Standard_Integer       *theNodes,
   const gp_Pnt2d               *thePnts,
-  const Standard_Integer       theRootIndex,
-  const ReplaceFlag            theReplaceFlag,
-  BRepMesh::SequenceOfInteger& thePolygon,
-  BRepMesh::SequenceOfBndB2d&  thePolyBoxes )
+  const Standard_Integer        theRootIndex,
+  const ReplaceFlag             theReplaceFlag,
+  IMeshData::SequenceOfInteger& thePolygon,
+  IMeshData::SequenceOfBndB2d&  thePolyBoxes )
 {
   Standard_Integer aNewEdgeId = 
     myMeshData->AddLink( BRepMesh_Edge(
@@ -1600,9 +1633,9 @@ Standard_Integer BRepMesh_Delaun::createAndReplacePolygonLink(
 //function : meshPolygon
 //purpose  : 
 //=======================================================================
-void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
-                                  BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-                                  BRepMesh::HMapOfInteger      theSkipped )
+void BRepMesh_Delaun::meshPolygon(IMeshData::SequenceOfInteger&   thePolygon,
+                                  IMeshData::SequenceOfBndB2d&    thePolyBoxes,
+                                  Handle(IMeshData::MapOfInteger) theSkipped)
 {
   // Check is the source polygon elementary
   if ( meshElementaryPolygon( thePolygon ) )
@@ -1649,7 +1682,7 @@ void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
       };
 
       gp_Pnt2d anIntPnt;
-      BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( *aCurEdge, *aNextEdge, 
+      BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( *aCurEdge, *aNextEdge,
         Standard_False, Standard_True, anIntPnt );
 
       if ( aIntFlag == BRepMesh_GeomTool::NoIntersection )
@@ -1816,14 +1849,14 @@ void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
     }
   }
 
-  BRepMesh::SequenceOfInteger* aPolygon1   = &thePolygon;
-  BRepMesh::SequenceOfBndB2d*  aPolyBoxes1 = &thePolyBoxes;
+  IMeshData::SequenceOfInteger* aPolygon1   = &thePolygon;
+  IMeshData::SequenceOfBndB2d*  aPolyBoxes1 = &thePolyBoxes;
 
-  BRepMesh::HSequenceOfInteger aPolygon2   = new BRepMesh::SequenceOfInteger;
-  BRepMesh::HSequenceOfBndB2d  aPolyBoxes2 = new BRepMesh::SequenceOfBndB2d;
+  Handle(IMeshData::SequenceOfInteger) aPolygon2   = new IMeshData::SequenceOfInteger;
+  Handle(IMeshData::SequenceOfBndB2d)  aPolyBoxes2 = new IMeshData::SequenceOfBndB2d;
 
-  NCollection_Sequence<BRepMesh::HSequenceOfInteger> aPolyStack;
-  NCollection_Sequence<BRepMesh::HSequenceOfBndB2d>  aPolyBoxStack;
+  NCollection_Sequence<Handle(IMeshData::SequenceOfInteger)> aPolyStack;
+  NCollection_Sequence<Handle(IMeshData::SequenceOfBndB2d)>  aPolyBoxStack;
   for (;;)
   {
     decomposeSimplePolygon(*aPolygon1, *aPolyBoxes1, *aPolygon2, *aPolyBoxes2);
@@ -1832,8 +1865,8 @@ void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
       aPolyStack.Append(aPolygon2);
       aPolyBoxStack.Append(aPolyBoxes2);
       
-      aPolygon2   = new BRepMesh::SequenceOfInteger;
-      aPolyBoxes2 = new BRepMesh::SequenceOfBndB2d;
+      aPolygon2   = new IMeshData::SequenceOfInteger;
+      aPolyBoxes2 = new IMeshData::SequenceOfBndB2d;
     }
 
     if (aPolygon1->IsEmpty())
@@ -1858,7 +1891,7 @@ void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
 //purpose  : Triangulation of closed polygon containing only three edges.
 //=======================================================================
 inline Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon( 
-  const BRepMesh::SequenceOfInteger& thePolygon)
+  const IMeshData::SequenceOfInteger& thePolygon)
 {
   Standard_Integer aPolyLen = thePolygon.Length();
   if ( aPolyLen < 3 )
@@ -1898,10 +1931,10 @@ inline Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
 //purpose  : 
 //=======================================================================
 void BRepMesh_Delaun::decomposeSimplePolygon(
-  BRepMesh::SequenceOfInteger& thePolygon,
-  BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-  BRepMesh::SequenceOfInteger& thePolygonCut,
-  BRepMesh::SequenceOfBndB2d&  thePolyBoxesCut)
+  IMeshData::SequenceOfInteger& thePolygon,
+  IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+  IMeshData::SequenceOfInteger& thePolygonCut,
+  IMeshData::SequenceOfBndB2d&  thePolyBoxesCut)
 {
   // Check is the given polygon elementary
   if ( meshElementaryPolygon( thePolygon ) )
@@ -1993,7 +2026,7 @@ void BRepMesh_Delaun::decomposeSimplePolygon(
 
           // intersection is possible...                  
           gp_Pnt2d anIntPnt;
-          BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( aCheckLink, aPolyLink, 
+          BRepMesh_GeomTool::IntFlag aIntFlag = intSegSeg( aCheckLink, aPolyLink,
             Standard_False, Standard_False, anIntPnt );
 
           if( aIntFlag != BRepMesh_GeomTool::NoIntersection )
@@ -2085,17 +2118,17 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
   BRepMesh_SelectorOfDataStructureOfDelaun aSelector( myMeshData );
   aSelector.NeighboursOf( theVertex );
 
-  BRepMesh::MapOfIntegerInteger aLoopEdges;//( 10, myMeshData->Allocator() );
+  IMeshData::MapOfIntegerInteger aLoopEdges;//( 10, myMeshData->Allocator() );
 
   // Loop on triangles to be destroyed :
-  BRepMesh::MapOfInteger::Iterator aTriangleIt( aSelector.Elements() );
+  IMeshData::IteratorOfMapOfInteger aTriangleIt( aSelector.Elements() );
   for ( ; aTriangleIt.More(); aTriangleIt.Next() )
     deleteTriangle( aTriangleIt.Key(), aLoopEdges );
 
-  BRepMesh::SequenceOfBndB2d  aBoxes;
-  BRepMesh::SequenceOfInteger aPolygon;
+  IMeshData::SequenceOfBndB2d  aBoxes;
+  IMeshData::SequenceOfInteger aPolygon;
   Standard_Integer aLoopEdgesCount = aLoopEdges.Extent();
-  BRepMesh::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
+  IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
 
   if ( aLoopEdgesIt.More() )
   {
@@ -2105,7 +2138,7 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
     Standard_Integer aPivotNode = anEdge.LastNode();
     Standard_Integer anEdgeId   = aLoopEdgesIt.Key();
     
-    Standard_Boolean isPositive = (aLoopEdges (anEdgeId) != 0);
+    Standard_Boolean isPositive = aLoopEdges( anEdgeId ) != 0;
     if ( !isPositive )
     {
       Standard_Integer aTmp;
@@ -2125,7 +2158,7 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
     aLastNode = aFirstNode;
     while ( aPivotNode != aLastNode )
     {
-      BRepMesh::ListOfInteger::Iterator aLinkIt( myMeshData->LinksConnectedTo( aPivotNode ) );
+      IMeshData::ListOfInteger::Iterator aLinkIt( myMeshData->LinksConnectedTo( aPivotNode ) );
       for ( ; aLinkIt.More(); aLinkIt.Next() )
       {
         if ( aLinkIt.Value() != anEdgeId &&
@@ -2161,33 +2194,18 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
   }
 }
 
-//=======================================================================
-//function : AddVertices
-//purpose  : Adds some vertices in the triangulation.
-//=======================================================================
-void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices)
-{
-  AddVertices (theVertices, NULL);
-}
 
 //=======================================================================
 //function : AddVertices
 //purpose  : Adds some vertices in the triangulation.
 //=======================================================================
-void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices,
-                                  Message_ProgressSentry*           theProgressEntry)
+void BRepMesh_Delaun::AddVertices(IMeshData::VectorOfInteger& theVertices)
 {
-  std::make_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
-  std::sort_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
-
-  Standard_Integer aLower  = theVertices.Lower();
-  Standard_Integer anUpper = theVertices.Upper();
-    
-  BRepMesh::Array1OfInteger aVertexIndexes( aLower, anUpper );
-  for ( Standard_Integer i = aLower; i <= anUpper; ++i )     
-    aVertexIndexes(i) = myMeshData->AddNode( theVertices(i) );
+  ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
+  std::make_heap(theVertices.begin(), theVertices.end(), aCmp);
+  std::sort_heap(theVertices.begin(), theVertices.end(), aCmp);
 
-  createTrianglesOnNewVertices( aVertexIndexes, theProgressEntry );
+  createTrianglesOnNewVertices(theVertices);
 }
 
 //=======================================================================
@@ -2282,12 +2300,12 @@ Standard_Boolean BRepMesh_Delaun::UseEdge( const Standard_Integer /*theIndex*/ )
 //function : getEdgesByType
 //purpose  : Gives the list of edges with type defined by input parameter
 //=======================================================================
-BRepMesh::HMapOfInteger BRepMesh_Delaun::getEdgesByType(
+Handle(IMeshData::MapOfInteger) BRepMesh_Delaun::getEdgesByType(
   const BRepMesh_DegreeOfFreedom theEdgeType ) const
 {
   Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-  BRepMesh::HMapOfInteger aResult = new BRepMesh::MapOfInteger(1, anAlloc);
-  BRepMesh::MapOfInteger::Iterator anEdgeIt( myMeshData->LinksOfDomain() );
+  Handle(IMeshData::MapOfInteger) aResult = new IMeshData::MapOfInteger;
+  IMeshData::IteratorOfMapOfInteger anEdgeIt( myMeshData->LinksOfDomain() );
 
   for ( ; anEdgeIt.More(); anEdgeIt.Next() )
   {
@@ -2350,12 +2368,10 @@ Standard_Boolean BRepMesh_Delaun::Contains( const Standard_Integer theTriangleId
 {
   theEdgeOn = 0;
   
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
   Standard_Integer p[3];
 
   const BRepMesh_Triangle& aElement = GetTriangle( theTriangleId );
-  aElement.Edges(e, o);
+  const Standard_Integer(&e)[3] = aElement.myEdges;
 
   const BRepMesh_Edge* anEdges[3] = { &GetEdge( e[0] ),
                                       &GetEdge( e[1] ),
@@ -2405,7 +2421,7 @@ Standard_Boolean BRepMesh_Delaun::Contains( const Standard_Integer theTriangleId
 //function : intSegSeg
 //purpose  : Checks intersection between the two segments.
 //=============================================================================
-BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg( 
+BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
   const BRepMesh_Edge&   theEdg1,
   const BRepMesh_Edge&   theEdg2,
   const Standard_Boolean isConsiderEndPointTouch,
@@ -2427,9 +2443,9 @@ BRepMesh_GeomTool::IntFlag BRepMesh_Delaun::intSegSeg(
 //purpose  : Returns area of the loop of the given polygon defined by indices 
 //           of its start and end links.
 //=============================================================================
-Standard_Real BRepMesh_Delaun::polyArea(const BRepMesh::SequenceOfInteger& thePolygon,
-                                        const Standard_Integer             theStartIndex,
-                                        const Standard_Integer             theEndIndex) const
+Standard_Real BRepMesh_Delaun::polyArea(const IMeshData::SequenceOfInteger& thePolygon,
+                                        const Standard_Integer              theStartIndex,
+                                        const Standard_Integer              theEndIndex) const
 {
   Standard_Real aArea = 0.0;
   Standard_Integer aPolyLen = thePolygon.Length();
@@ -2482,9 +2498,9 @@ Standard_CString BRepMesh_DumpPoly(void*            thePolygon,
     return "Error: file name or polygon data is null";
   }
 
-  BRepMesh::SequenceOfInteger& aPolygon = *(BRepMesh::SequenceOfInteger*)thePolygon;
+  IMeshData::SequenceOfInteger& aPolygon = *(IMeshData::SequenceOfInteger*)thePolygon;
 
-  Handle(BRepMesh_DataStructureOfDelaun) aMeshData = 
+  Handle(BRepMesh_DataStructureOfDelaun) aMeshData =
     *(Handle(BRepMesh_DataStructureOfDelaun)*)theMeshHandlePtr;
 
   if (aMeshData.IsNull())
@@ -2498,7 +2514,7 @@ Standard_CString BRepMesh_DumpPoly(void*            thePolygon,
   {
     OCC_CATCH_SIGNALS
 
-    BRepMesh::SequenceOfInteger::Iterator aLinksIt(aPolygon);
+    IMeshData::SequenceOfInteger::Iterator aLinksIt(aPolygon);
     for (; aLinksIt.More(); aLinksIt.Next())
     {
       const BRepMesh_Edge& aLink = aMeshData->GetLink(Abs(aLinksIt.Value()));
index 18f1339c1112e756bc8ce1b2f39f9dadf60e6996..f03a333a1120121a43a2b3363bc67daf564dfbb3 100755 (executable)
@@ -23,7 +23,7 @@
 #include <BRepMesh_CircleTool.hxx>
 #include <BRepMesh_Triangle.hxx>
 #include <BRepMesh_Edge.hxx>
-#include <BRepMesh.hxx>
+#include <IMeshData_Types.hxx>
 #include <BRepMesh_DataStructureOfDelaun.hxx>
 #include <BRepMesh_GeomTool.hxx>
 #include <TColStd_Array1OfInteger.hxx>
@@ -33,7 +33,6 @@
 class Bnd_B2d;
 class Bnd_Box2d;
 class BRepMesh_Vertex;
-class Message_ProgressSentry;
 
 //! Compute the Delaunay's triangulation with the algorithm of Watson.
 class BRepMesh_Delaun
@@ -42,29 +41,41 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
+  //! Creates instance of triangulator, but do not run the algorithm automatically.
+  Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
+                                   const Standard_Integer                        theCellsCountU,
+                                   const Standard_Integer                        theCellsCountV,
+                                   const Standard_Boolean                        isFillCircles);
+
   //! Creates the triangulation with an empty Mesh data structure.
-  Standard_EXPORT BRepMesh_Delaun (BRepMesh::Array1OfVertexOfDelaun& theVertices);
+  Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
 
   //! Creates the triangulation with an existent Mesh data structure.
   Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
-                                   BRepMesh::Array1OfVertexOfDelaun&             theVertices);
+                                   IMeshData::Array1OfVertexOfDelaun&            theVertices);
 
   //! Creates the triangulation with an existant Mesh data structure.
   Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
-                                   BRepMesh::Array1OfInteger&                    theVertexIndices);
+                                   IMeshData::VectorOfInteger&                   theVertexIndices);
+
+  //! Creates the triangulation with an existant Mesh data structure.
+  Standard_EXPORT BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)& theOldMesh,
+                                   IMeshData::VectorOfInteger&                    theVertexIndices,
+                                   const Standard_Integer                         theCellsCountU,
+                                   const Standard_Integer                         theCellsCountV);
 
   //! Initializes the triangulation with an array of vertices.
-  Standard_EXPORT void Init (BRepMesh::Array1OfVertexOfDelaun& theVertices);
+  Standard_EXPORT void Init (IMeshData::Array1OfVertexOfDelaun& theVertices);
+
+  //! Forces initialization of circles cell filter using working structure.
+  Standard_EXPORT void InitCirclesTool (const Standard_Integer theCellsCountU,
+                                        const Standard_Integer theCellsCountV);
 
   //! Removes a vertex from the triangulation.
   Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
 
   //! Adds some vertices into the triangulation.
-  Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices);
-
-  //! Adds some vertices into the triangulation.
-  Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices,
-                                    Message_ProgressSentry*           theProgressEntry);
+  Standard_EXPORT void AddVertices (IMeshData::VectorOfInteger& theVerticesIndices);
 
   //! Modify mesh to use the edge.
   //! @return True if done
@@ -76,20 +87,29 @@ public:
     return myMeshData;
   }
 
+  //! Forces insertion of constraint edges into the base triangulation. 
+  inline void ProcessConstraints()
+  {
+    insertInternalEdges();
+
+    // Adjustment of meshes to boundary edges
+    frontierAdjust();
+  }
+
   //! Gives the list of frontier edges.
-  inline BRepMesh::HMapOfInteger Frontier() const
+  inline Handle(IMeshData::MapOfInteger) Frontier() const
   {
     return getEdgesByType (BRepMesh_Frontier);
   }
 
   //! Gives the list of internal edges.
-  inline BRepMesh::HMapOfInteger InternalEdges() const
+  inline Handle(IMeshData::MapOfInteger) InternalEdges() const
   {
     return getEdgesByType (BRepMesh_Fixed);
   }
 
   //! Gives the list of free edges used only one time
-  inline BRepMesh::HMapOfInteger FreeEdges() const
+  inline Handle(IMeshData::MapOfInteger) FreeEdges() const
   {
     return getEdgesByType (BRepMesh_Free);
   }
@@ -136,74 +156,80 @@ private:
     InsertBefore
   };
 
-  typedef NCollection_DataMap<Standard_Integer, BRepMesh::MapOfInteger> DataMapOfMap;
+  typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
+
+  //! Performs initialization of circles cell filter tool.
+  void initCirclesTool (const Bnd_Box2d&       theBox,
+                        const Standard_Integer theCellsCountU,
+                        const Standard_Integer theCellsCountV);
 
   //! Add boundig box for edge defined by start & end point to
   //! the given vector of bounding boxes for triangulation edges.
-  void fillBndBox (BRepMesh::SequenceOfBndB2d&   theBoxes,
+  void fillBndBox (IMeshData::SequenceOfBndB2d&  theBoxes,
                    const BRepMesh_Vertex&        theV1,
                    const BRepMesh_Vertex&        theV2);
 
   //! Gives the list of edges with type defined by the input parameter.
   //! If the given type is BRepMesh_Free returns list of edges
   //! that have number of connected elements less or equal 1.
-  BRepMesh::HMapOfInteger getEdgesByType (const BRepMesh_DegreeOfFreedom theEdgeType) const;
+  Handle(IMeshData::MapOfInteger) getEdgesByType (const BRepMesh_DegreeOfFreedom theEdgeType) const;
 
-  //! Create super mesh and run triangulation procedure.
-  void perform (Bnd_Box2d&                 theBndBox,
-                BRepMesh::Array1OfInteger& theVertexIndices);
+  //! Run triangulation procedure.
+  void perform (IMeshData::VectorOfInteger& theVertexIndices,
+                const Standard_Integer      theCellsCountU = -1,
+                const Standard_Integer      theCellsCountV = -1);
 
   //! Build the super mesh.
   void superMesh (const Bnd_Box2d& theBox);
 
   //! Computes the triangulation and adds the vertices,
   //! edges and triangles to the Mesh data structure.
-  void compute (BRepMesh::Array1OfInteger& theVertexIndices);
+  void compute (IMeshData::VectorOfInteger& theVertexIndices);
 
   //! Adjust the mesh on the frontier.
   void frontierAdjust();
 
   //! Find left polygon of the given edge and call meshPolygon.
   Standard_Boolean meshLeftPolygonOf(
-    const Standard_Integer  theEdgeIndex,
-    const Standard_Boolean  isForward,
-    BRepMesh::HMapOfInteger theSkipped = NULL);
+    const Standard_Integer          theEdgeIndex,
+    const Standard_Boolean          isForward,
+    Handle(IMeshData::MapOfInteger) theSkipped = NULL);
 
   //! Find next link starting from the given node and has maximum
   //! angle respect the given reference link.
   //! Each time the next link is found other neighbor links at the pivot
   //! node are marked as leprous and will be excluded from consideration
   //! next time until a hanging end is occured.
-  Standard_Integer findNextPolygonLink (const Standard_Integer&            theFirstNode,
-                                        const Standard_Integer&            thePivotNode,
-                                        const BRepMesh_Vertex&             thePivotVertex,
-                                        const gp_Vec2d&                    theRefLinkDir,
-                                        const BRepMesh::SequenceOfBndB2d&  theBoxes,
-                                        const BRepMesh::SequenceOfInteger& thePolygon,
-                                        const BRepMesh::HMapOfInteger      theSkipped,
-                                        const Standard_Boolean&            isSkipLeprous,
-                                        BRepMesh::MapOfInteger&            theLeprousLinks,
-                                        BRepMesh::MapOfInteger&            theDeadLinks,
-                                        Standard_Integer&                  theNextPivotNode,
-                                        gp_Vec2d&                          theNextLinkDir,
-                                        Bnd_B2d&                           theNextLinkBndBox);
+  Standard_Integer findNextPolygonLink (const Standard_Integer&               theFirstNode,
+                                        const Standard_Integer&               thePivotNode,
+                                        const BRepMesh_Vertex&                thePivotVertex,
+                                        const gp_Vec2d&                       theRefLinkDir,
+                                        const IMeshData::SequenceOfBndB2d&    theBoxes,
+                                        const IMeshData::SequenceOfInteger&   thePolygon,
+                                        const Handle(IMeshData::MapOfInteger) theSkipped,
+                                        const Standard_Boolean&               isSkipLeprous,
+                                        IMeshData::MapOfInteger&              theLeprousLinks,
+                                        IMeshData::MapOfInteger&              theDeadLinks,
+                                        Standard_Integer&                     theNextPivotNode,
+                                        gp_Vec2d&                             theNextLinkDir,
+                                        Bnd_B2d&                              theNextLinkBndBox);
 
   //! Check is the given link intersects the polygon boundaries.
   //! Returns bounding box for the given link trough the theLinkBndBox parameter.
-  Standard_Boolean checkIntersection (const BRepMesh_Edge&               theLink,
-                                      const BRepMesh::SequenceOfInteger& thePolygon,
-                                      const BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-                                      const Standard_Boolean             isConsiderEndPointTouch,
-                                      const Standard_Boolean             isConsiderPointOnEdge,
-                                      const Standard_Boolean             isSkipLastEdge,
-                                      Bnd_B2d&                           theLinkBndBox) const;
+  Standard_Boolean checkIntersection (const BRepMesh_Edge&                theLink,
+                                      const IMeshData::SequenceOfInteger& thePolygon,
+                                      const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+                                      const Standard_Boolean              isConsiderEndPointTouch,
+                                      const Standard_Boolean              isConsiderPointOnEdge,
+                                      const Standard_Boolean              isSkipLastEdge,
+                                      Bnd_B2d&                            theLinkBndBox) const;
 
   //! Triangulatiion of a closed polygon described by the list
   //! of indexes of its edges in the structure.
   //! (negative index means reversed edge)
-  void meshPolygon (BRepMesh::SequenceOfInteger& thePolygon,
-                    BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-                    BRepMesh::HMapOfInteger      theSkipped = NULL);
+  void meshPolygon (IMeshData::SequenceOfInteger&   thePolygon,
+                    IMeshData::SequenceOfBndB2d&    thePolyBoxes,
+                    Handle(IMeshData::MapOfInteger) theSkipped = NULL);
 
   //! Decomposes the given closed simple polygon (polygon without glued edges 
   //! and loops) on two simpler ones by adding new link at the most thin part 
@@ -215,31 +241,27 @@ private:
   //! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
   //! @param thePolyBoxesCut bounding boxes corresponded to resulting polygon's links.
   void decomposeSimplePolygon (
-    BRepMesh::SequenceOfInteger& thePolygon,
-    BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-    BRepMesh::SequenceOfInteger& thePolygonCut,
-    BRepMesh::SequenceOfBndB2d&  thePolyBoxesCut);
+    IMeshData::SequenceOfInteger& thePolygon,
+    IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+    IMeshData::SequenceOfInteger& thePolygonCut,
+    IMeshData::SequenceOfBndB2d&  thePolyBoxesCut);
 
   //! Triangulation of closed polygon containing only three edges.
-  inline Standard_Boolean meshElementaryPolygon (const BRepMesh::SequenceOfInteger& thePolygon);
+  inline Standard_Boolean meshElementaryPolygon (const IMeshData::SequenceOfInteger& thePolygon);
 
   //! Creates the triangles beetween the given node and the given polyline.
   void createTriangles (const Standard_Integer         theVertexIndex,
-                        BRepMesh::MapOfIntegerInteger& thePoly);
-
-  void createTriangles (const Standard_Integer         theVertexIndex,
-                        BRepMesh::MapOfIntegerInteger& thePoly,
-                        Message_ProgressSentry*        theProgressEntry);
+                        IMeshData::MapOfIntegerInteger& thePoly);
 
   //! Add a triangle based on the given oriented edges into mesh
-  void addTriangle (const Standard_Integer (&theEdgesId)[3],
-                    const Standard_Boolean (&theEdgesOri)[3],
-                    const Standard_Integer (&theNodesId)[3]);
+  inline void addTriangle (const Standard_Integer (&theEdgesId)[3],
+                           const Standard_Boolean (&theEdgesOri)[3],
+                           const Standard_Integer (&theNodesId)[3]);
 
   //! Deletes the 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.
   void deleteTriangle (const Standard_Integer         theIndex,
-                       BRepMesh::MapOfIntegerInteger& theLoopEdges);
+                       IMeshData::MapOfIntegerInteger& theLoopEdges);
 
   //! Returns start and end nodes of the given edge in respect to its orientation.
   void getOrientedNodes (const BRepMesh_Edge&   theEdge,
@@ -248,25 +270,21 @@ private:
 
   //! Processes loop within the given polygon formed by range of its
   //! links specified by start and end link indices.
-  void processLoop (const Standard_Integer             theLinkFrom,
-                    const Standard_Integer             theLinkTo,
-                    const BRepMesh::SequenceOfInteger& thePolygon,
-                    const BRepMesh::SequenceOfBndB2d&  thePolyBoxes);
+  void processLoop (const Standard_Integer              theLinkFrom,
+                    const Standard_Integer              theLinkTo,
+                    const IMeshData::SequenceOfInteger& thePolygon,
+                    const IMeshData::SequenceOfBndB2d&  thePolyBoxes);
 
   //! Creates new link based on the given nodes and updates the given polygon.
-  Standard_Integer createAndReplacePolygonLink (const Standard_Integer       theNodes[],
-                                                const gp_Pnt2d               thePnts [],
-                                                const Standard_Integer       theRootIndex,
-                                                const ReplaceFlag            theReplaceFlag,
-                                                BRepMesh::SequenceOfInteger& thePolygon,
-                                                BRepMesh::SequenceOfBndB2d&  thePolyBoxes);
+  Standard_Integer createAndReplacePolygonLink (const Standard_Integer        theNodes[],
+                                                const gp_Pnt2d                thePnts [],
+                                                const Standard_Integer        theRootIndex,
+                                                const ReplaceFlag             theReplaceFlag,
+                                                IMeshData::SequenceOfInteger& thePolygon,
+                                                IMeshData::SequenceOfBndB2d&  thePolyBoxes);
   
   //! Creates the triangles on new nodes.
-  void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices,
-                                     Message_ProgressSentry*    theProgressEntry);
-
-  //! Creates the triangles on new nodes.
-  void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices);
+  void createTrianglesOnNewVertices (IMeshData::VectorOfInteger& theVertexIndices);
 
   //! Cleanup mesh from the free triangles.
   void cleanupMesh();
@@ -282,35 +300,35 @@ private:
                                       const Standard_Integer thePrevElementId);
 
   //! Remove internal triangles from the given polygon.
-  void cleanupPolygon (const BRepMesh::SequenceOfInteger& thePolygon,
-                       const BRepMesh::SequenceOfBndB2d&  thePolyBoxes);
+  void cleanupPolygon (const IMeshData::SequenceOfInteger& thePolygon,
+                       const IMeshData::SequenceOfBndB2d&  thePolyBoxes);
 
   //! Checks is the given vertex lies inside the polygon.
-  Standard_Boolean isVertexInsidePolygon (const Standard_Integer&          theVertexId,
-                                          const BRepMesh::VectorOfInteger& thePolygonVertices) const;
+  Standard_Boolean isVertexInsidePolygon (const Standard_Integer&           theVertexId,
+                                          const IMeshData::VectorOfInteger& thePolygonVertices) const;
 
   //! Remove all triangles and edges that are placed inside the polygon or crossed it.
-  void killTrianglesAroundVertex (const Standard_Integer             theZombieNodeId,
-                                  const BRepMesh::VectorOfInteger&   thePolyVertices,
-                                  const BRepMesh::MapOfInteger&      thePolyVerticesFindMap,
-                                  const BRepMesh::SequenceOfInteger& thePolygon,
-                                  const BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
-                                  BRepMesh::MapOfInteger&            theSurvivedLinks,
-                                  BRepMesh::MapOfIntegerInteger&     theLoopEdges);
+  void killTrianglesAroundVertex (const Standard_Integer              theZombieNodeId,
+                                  const IMeshData::VectorOfInteger&   thePolyVertices,
+                                  const IMeshData::MapOfInteger&      thePolyVerticesFindMap,
+                                  const IMeshData::SequenceOfInteger& thePolygon,
+                                  const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
+                                  IMeshData::MapOfInteger&            theSurvivedLinks,
+                                  IMeshData::MapOfIntegerInteger&     theLoopEdges);
 
   //! Checks is the given link crosses the polygon boundary.
   //! If yes, kills its triangles and checks neighbor links on boundary intersection. Does nothing elsewhere.
-  void killTrianglesOnIntersectingLinks (const Standard_Integer&             theLinkToCheckId,
-                                         const BRepMesh_Edge&                theLinkToCheck,
-                                         const Standard_Integer&             theEndPoint,
-                                         const BRepMesh::SequenceOfInteger&  thePolygon,
-                                         const BRepMesh::SequenceOfBndB2d&   thePolyBoxes,
-                                         BRepMesh::MapOfInteger&             theSurvivedLinks,
-                                         BRepMesh::MapOfIntegerInteger&      theLoopEdges);
+  void killTrianglesOnIntersectingLinks (const Standard_Integer&              theLinkToCheckId,
+                                         const BRepMesh_Edge&                 theLinkToCheck,
+                                         const Standard_Integer&              theEndPoint,
+                                         const IMeshData::SequenceOfInteger&  thePolygon,
+                                         const IMeshData::SequenceOfBndB2d&   thePolyBoxes,
+                                         IMeshData::MapOfInteger&             theSurvivedLinks,
+                                         IMeshData::MapOfIntegerInteger&      theLoopEdges);
 
   //! Kill triangles bound to the given link.
-  void killLinkTriangles (const Standard_Integer&        theLinkId,
-                          BRepMesh::MapOfIntegerInteger& theLoopEdges);
+  void killLinkTriangles (const Standard_Integer&         theLinkId,
+                          IMeshData::MapOfIntegerInteger& theLoopEdges);
 
   //! Calculates distances between the given point and edges of triangle.
   Standard_Real calculateDist (const gp_XY            theVEdges[3],
@@ -329,16 +347,13 @@ private:
     gp_Pnt2d&              theIntPnt) const;
 
   //! Returns area of the loop of the given polygon defined by indices of its start and end links.
-  Standard_Real polyArea (const BRepMesh::SequenceOfInteger& thePolygon,
-                          const Standard_Integer             theStartIndex,
-                          const Standard_Integer             theEndIndex) const;
+  Standard_Real polyArea (const IMeshData::SequenceOfInteger& thePolygon,
+                          const Standard_Integer              theStartIndex,
+                          const Standard_Integer              theEndIndex) const;
 
   //! Performs insertion of internal edges into mesh.
   void insertInternalEdges();
 
-  //! Performs insertion of internal edges into mesh.
-  void insertInternalEdges (Message_ProgressSentry* theProgressEntry);
-
 private:
 
   Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
diff --git a/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx
new file mode 100644 (file)
index 0000000..1394bd7
--- /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.
+
+#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);
+  }
+
+  std::pair<Standard_Integer, Standard_Integer> aCellsCount = getCellsCount (aVerticesOrder.Size ());
+  BRepMesh_Delaun aMesher(aStructure, aVerticesOrder, aCellsCount.first, aCellsCount.second);
+  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..81bfdc7
--- /dev/null
@@ -0,0 +1,46 @@
+// 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_ConstrainedBaseMeshAlgo.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_ConstrainedBaseMeshAlgo
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT BRepMesh_DelaunayBaseMeshAlgo();
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
+
+protected:
+
+  //! Generates mesh for the contour stored in data structure.
+  Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
new file mode 100644 (file)
index 0000000..04f4708
--- /dev/null
@@ -0,0 +1,452 @@
+// 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>
+#include <GeomLib.hxx>
+
+//! Extends node insertion Delaunay meshing algo in order to control 
+//! deflection of generated trianges. Splits triangles failing the check.
+template<class RangeSplitter, class BaseAlgo>
+class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
+{
+private:
+  // Typedef for OCCT RTTI
+  typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> DelaunayInsertionBaseClass;
+
+public:
+
+  //! Constructor.
+  BRepMesh_DelaunayDeflectionControlMeshAlgo()
+    : myMaxSqDeflection(-1.),
+      myIsAllDegenerated(Standard_False)
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_DelaunayDeflectionControlMeshAlgo()
+  {
+  }
+
+protected:
+
+  //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+  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.
+  //! Inserts additional nodes in case of huge deviation.
+  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.;
+
+        if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point, 
+                                                 theNodesInfo[j].Point)))
+        {
+          if (!checkLinkEndsForAngularDeviation(theNodesInfo[i], 
+                                                theNodesInfo[j],
+                                                aMidPnt2d))
+          {
+            myControlNodes->Append(aMidPnt2d);
+          }
+        }
+      }
+    }
+  }
+
+  //! Checks the given point (located between the given nodes)
+  //! for specified angular deviation.
+  Standard_Boolean checkLinkEndsForAngularDeviation(const TriangleNodeInfo& theNodeInfo1,
+                                                    const TriangleNodeInfo& theNodeInfo2,
+                                                    const gp_XY& /*theMidPoint*/)
+  {
+    gp_Dir aNorm1, aNorm2;
+    const Handle(Geom_Surface)& aSurf = 
+      this->getDFace()->GetSurface()->ChangeSurface().Surface().Surface();
+    
+    if ((GeomLib::NormEstim(aSurf, theNodeInfo1.Point2d, Precision::Confusion(), aNorm1) == 0) &&
+        (GeomLib::NormEstim(aSurf, theNodeInfo2.Point2d, Precision::Confusion(), aNorm2) == 0))
+    {
+      Standard_Real anAngle = aNorm1.Angle(aNorm2);
+      if (anAngle > this->getParameters().AngleInterior)
+        return Standard_False;
+    }
+#if 0
+    else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0)
+    {
+      // It is better to consider the singular point as a node of triangulation.
+      // However, it leads to hangs up meshing some faces (including faces with
+      // degenerated edges). E.g. tests "mesh standard_incmesh Q6".
+      // So, this code fragment is better to implement in the future.
+      return Standard_False;
+    }
+#endif
+
+    return Standard_True;
+  }
+
+  //! 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 Standard_Boolean 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);
+      return Standard_True;
+    }
+
+    return Standard_False;
+  }
+
+  //! Checks the given point for specified linear 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;
+    }
+
+    return rejectByMinSize(thePnt2d, thePnt3d);
+  }
+
+  //! 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;
+
+    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..ccbe552
--- /dev/null
@@ -0,0 +1,159 @@
+// 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>
+#include <BRepMesh_GeomTool.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 BaseAlgo>
+class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
+{
+private:
+  // Typedef for OCCT RTTI
+  typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> InsertionBaseClass;
+
+public:
+
+  //! Constructor.
+  BRepMesh_DelaunayNodeInsertionMeshAlgo()
+    : myIsPreProcessSurfaceNodes (Standard_False)
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_DelaunayNodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Returns PreProcessSurfaceNodes flag. 
+  inline Standard_Boolean IsPreProcessSurfaceNodes () const
+  {
+    return myIsPreProcessSurfaceNodes;
+  }
+
+  //! Sets PreProcessSurfaceNodes flag.
+  //! If TRUE, registers surface nodes before generation of base mesh.
+  //! If FALSE, inserts surface nodes after generation of base mesh. 
+  inline void SetPreProcessSurfaceNodes (const Standard_Boolean isPreProcessSurfaceNodes)
+  {
+    myIsPreProcessSurfaceNodes = isPreProcessSurfaceNodes;
+  }
+
+protected:
+
+  //! Performs initialization of data structure using existing model data.
+  virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
+  {
+    if (!InsertionBaseClass::initDataStructure())
+    {
+      return Standard_False;
+    }
+
+    if (myIsPreProcessSurfaceNodes)
+    {
+      const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
+        this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
+
+      registerSurfaceNodes (aSurfaceNodes);
+    }
+
+    return Standard_True;
+  }
+
+  //! Returns size of cell to be used by acceleration circles grid structure.
+  virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
+  {
+    return BRepMesh_GeomTool::CellsCount (this->getDFace()->GetSurface(), theVerticesNb,
+                                          this->getDFace()->GetDeflection(),
+                                          &this->getRangeSplitter());
+  }
+
+  //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+  virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE
+  {
+    InsertionBaseClass::postProcessMesh(theMesher);
+
+    if (!myIsPreProcessSurfaceNodes)
+    {
+      const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
+        this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
+
+      insertNodes(aSurfaceNodes, theMesher);
+    }
+  }
+
+  //! Inserts nodes into mesh.
+  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();
+  }
+
+private:
+  
+  //! Registers surface nodes in data structure.
+  Standard_Boolean registerSurfaceNodes(
+    const Handle(IMeshData::ListOfPnt2d)& theNodes)
+  {
+    if (theNodes.IsNull() || theNodes->IsEmpty())
+    {
+      return Standard_False;
+    }
+
+    Standard_Boolean isAdded = Standard_False;
+    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)
+      {
+        isAdded = Standard_True;
+        this->registerNode(this->getRangeSplitter().Point(aPnt2d),
+                           aPnt2d, BRepMesh_Free, Standard_False);
+      }
+    }
+
+    return isAdded;
+  }
+
+private:
+
+  Standard_Boolean myIsPreProcessSurfaceNodes;
+};
+
+#endif
index dc47c791b2e89cea815b4d1f2dab8caf4f6d9341..a5f47d31112f9df783255d935c8bbf64ae5a033b 100644 (file)
@@ -47,7 +47,7 @@ public:
   //! Setup meshing algorithm by name. <br>
   //! Returns TRUE if requested tool is available. <br>
   //! On fail Factory will continue to use previous algo.
-  Standard_EXPORT Standard_Boolean SetDefaultName(const TCollection_AsciiString& theName)
+  Standard_Boolean SetDefaultName(const TCollection_AsciiString& theName)
   {
     return SetDefault(theName, myFunctionName);
   }
@@ -61,7 +61,7 @@ public:
   //! Advanced function. Changes function name to retrieve from plugin. <br>
   //! Returns TRUE if requested tool is available. <br>
   //! On fail Factory will continue to use previous algo.
-  Standard_EXPORT Standard_Boolean SetFunctionName(const TCollection_AsciiString& theFuncName)
+  Standard_Boolean SetFunctionName(const TCollection_AsciiString& theFuncName)
   {
     return SetDefault(myDefaultName, theFuncName);
   }
index f3834204dfa94f55c833c891218f879011dc29cd..361cf0e242a67eca37094bff830d28d89d47814d 100644 (file)
@@ -46,7 +46,7 @@ public:
   }
 
   //! Compute triangulation for set shape.
-  Standard_EXPORT virtual void Perform() = 0;
+  virtual void Perform() = 0;
 
 
   DEFINE_STANDARD_RTTIEXT(BRepMesh_DiscretRoot,Standard_Transient)
index 0eb80ddd421264c186659bd645b89e1cdd30dcf1..3ef815131180499b3be2312b04fd302dda4424a2 100644 (file)
@@ -76,7 +76,7 @@ public:
   }
 
   //! Alias for IsEqual.
-  Standard_Boolean operator ==(const BRepMesh_Edge& Other) const
+  inline Standard_Boolean operator ==(const BRepMesh_Edge& Other) const
   {
     return IsEqual(Other);
   }
@@ -86,10 +86,13 @@ private:
   BRepMesh_DegreeOfFreedom  myMovability;
 };
 
-inline Standard_Integer HashCode(const BRepMesh_Edge&   theEdge,
-                                 const Standard_Integer theUpper)
+//! Computes a hash code for the given edge, in the range [1, theUpperBound]
+//! @param theEdge the edge which hash code is to be computed
+//! @param theUpperBound the upper bound of the range a computing hash code must be within
+//! @return a computed hash code, in the range [1, theUpperBound]
+inline Standard_Integer HashCode (const BRepMesh_Edge& theEdge, const Standard_Integer theUpperBound)
 {
-  return theEdge.HashCode(theUpper);
+  return theEdge.HashCode (theUpperBound);
 }
 
 #endif
diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.cxx b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx
new file mode 100644 (file)
index 0000000..d9e575a
--- /dev/null
@@ -0,0 +1,333 @@
+// 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::performInternal (
+  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);
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    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();
+        aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
+      }
+      else
+      {
+        const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+        const IMeshData::IFaceHandle    aDFace  = aPCurve->GetFace();
+        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 ())
+      {
+        if (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);
+    }
+  }
+  catch (Standard_Failure const&)
+  {
+    aDEdge->SetStatus (IMeshData_Failure);
+  }
+}
+
+//=======================================================================
+// 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 ()->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(aFirstVertex.IsNull() || aLastVertex.IsNull())
+    return;
+
+  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);
+    const IMeshData::IFaceHandle    aDFace  = aPCurve->GetFace();
+    IMeshData::ICurveArrayAdaptorHandle aCurveArray(new IMeshData::ICurveArrayAdaptor(aCurve));
+    BRepMesh_EdgeParameterProvider<IMeshData::ICurveArrayAdaptorHandle> aProvider(
+      theDEdge, aPCurve->GetOrientation(), aDFace, 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..82ac8e4
--- /dev/null
@@ -0,0 +1,98 @@
+// 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);
+
+  //! 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)
+
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) Standard_OVERRIDE;
+
+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_EdgeParameterProvider.cxx b/src/BRepMesh/BRepMesh_EdgeParameterProvider.cxx
deleted file mode 100644 (file)
index c5ae9c1..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// Created on: 2014-08-13
-// 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.
-
-#include <BRepMesh_EdgeParameterProvider.hxx>
-#include <gp_Pnt.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <Precision.hxx>
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_EdgeParameterProvider::BRepMesh_EdgeParameterProvider(
-  const TopoDS_Edge&                   theEdge,
-  const TopoDS_Face&                   theFace,
-  const Handle(TColStd_HArray1OfReal)& theParameters)
-  : myParameters(theParameters),
-    myIsSameParam(BRep_Tool::SameParameter(theEdge)),
-    myScale(1.),
-    myCurveAdaptor(theEdge, theFace)
-{
-  if (myIsSameParam)
-    return;
-
-  // Extract actual parametric values
-  Standard_Real aLastParam;
-  BRep_Tool::Range(theEdge, theFace, myFirstParam, aLastParam);
-
-  myFoundParam = myCurParam = myFirstParam;
-
-  // Extract parameters stored in polygon
-  myOldFirstParam =
-    myParameters->Value(myParameters->Lower());
-
-  const Standard_Real aOldLastParam =
-    myParameters->Value(myParameters->Upper());
-
-  // Calculate scale factor between actual and stored parameters
-  if ((myOldFirstParam != myFirstParam || aOldLastParam != aLastParam) &&
-    myOldFirstParam != aOldLastParam)
-  {
-    myScale = (aLastParam - myFirstParam) /
-      (aOldLastParam - myOldFirstParam);
-  }
-
-  myProjector.Initialize(myCurveAdaptor, myCurveAdaptor.FirstParameter(),
-    myCurveAdaptor.LastParameter(), Precision::PConfusion());
-}
-
-//=======================================================================
-//function : Parameter
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_EdgeParameterProvider::Parameter(
-  const Standard_Integer theIndex,
-  const gp_Pnt&          thePoint3d)
-{
-  if (myIsSameParam)
-    return myParameters->Value(theIndex);
-
-  // Use scaled
-  Standard_Real aPrevParam = myCurParam;
-  myCurParam = myFirstParam + myScale * 
-    (myParameters->Value(theIndex) - myOldFirstParam);
-
-  myFoundParam += (myCurParam - aPrevParam);
-
-  myProjector.Perform(thePoint3d, myFoundParam);
-  if (myProjector.IsDone())
-    myFoundParam = myProjector.Point().Parameter();
-
-  return myFoundParam;
-}
index 7f735f7fce8c4b112f6efc7b39f030ce9506e762..64610fef1e497756bc038faa26682e423ce7d124 100644 (file)
 #ifndef _BRepMesh_EdgeParameterProvider_HeaderFile
 #define _BRepMesh_EdgeParameterProvider_HeaderFile
 
+#include <IMeshData_Types.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Face.hxx>
+#include <TopoDS.hxx>
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Extrema_LocateExtPC.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
 
 class gp_Pnt;
 class TopoDS_Edge;
 class TopoDS_Face;
-#include <TColStd_HArray1OfReal.hxx>
 
 //! Auxiliary class provides correct parameters 
 //! on curve regarding SameParameter flag.
-class BRepMesh_EdgeParameterProvider
+template<class ParametersCollection>
+class BRepMesh_EdgeParameterProvider : public Standard_Transient
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
+  //! Constructor. Initializes empty provider.
+  BRepMesh_EdgeParameterProvider()
+  {
+  }
+
   //! Constructor.
   //! @param theEdge edge which parameters should be processed.
   //! @param theFace face the parametric values are defined for.
   //! @param theParameters parameters corresponded to discretization points.
   BRepMesh_EdgeParameterProvider(
-    const TopoDS_Edge&                   theEdge,
-    const TopoDS_Face&                   theFace,
-    const Handle(TColStd_HArray1OfReal)& theParameters);
+    const IMeshData::IEdgeHandle& theEdge,
+    const TopAbs_Orientation      theOrientation,
+    const IMeshData::IFaceHandle& theFace,
+    const ParametersCollection&   theParameters)
+  {
+    Init(theEdge, theOrientation, theFace, theParameters);
+  }
+
+  //! Initialized provider by the given data.
+  void Init (
+    const IMeshData::IEdgeHandle& theEdge,
+    const TopAbs_Orientation      theOrientation,
+    const IMeshData::IFaceHandle& theFace,
+    const ParametersCollection&   theParameters)
+  {
+    myParameters  = theParameters;
+    myIsSameParam = theEdge->GetSameParam();
+    myScale = 1.;
+
+    // Extract actual parametric values
+    const TopoDS_Edge aEdge = TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation));
+
+    myCurveAdaptor.Initialize(aEdge, theFace->GetFace());
+    if (myIsSameParam)
+    {
+      return;
+    }
+
+    myFirstParam = myCurveAdaptor.FirstParameter();
+    const Standard_Real aLastParam = myCurveAdaptor.LastParameter();
+
+    myFoundParam = myCurParam = myFirstParam;
+
+    // Extract parameters stored in polygon
+    myOldFirstParam                   = myParameters->Value(myParameters->Lower());
+    const Standard_Real aOldLastParam = myParameters->Value(myParameters->Upper());
+
+    // Calculate scale factor between actual and stored parameters
+    if ((myOldFirstParam != myFirstParam || aOldLastParam != aLastParam) &&
+        myOldFirstParam != aOldLastParam)
+    {
+      myScale = (aLastParam - myFirstParam) / (aOldLastParam - myOldFirstParam);
+    }
+
+    myProjector.Initialize(myCurveAdaptor, myCurveAdaptor.FirstParameter(), 
+                           myCurveAdaptor.LastParameter(),Precision::PConfusion());
+  }
 
   //! Returns parameter according to SameParameter flag of the edge.
   //! If SameParameter is TRUE returns value from parameters w/o changes,
   //! elsewhere scales initial parameter and tries to determine resulting
   //! value using projection of the corresponded 3D point on PCurve.
   Standard_Real Parameter(const Standard_Integer theIndex,
-                          const gp_Pnt&          thePoint3d);
+                          const gp_Pnt&          thePoint3d) const
+  {
+    if (myIsSameParam)
+    {
+      return myParameters->Value(theIndex);
+    }
+
+    // Use scaled
+    const Standard_Real aParam = myParameters->Value(theIndex);
+
+    const Standard_Real aPrevParam = myCurParam;
+    myCurParam = myFirstParam + myScale * (aParam - myOldFirstParam);
+
+    const Standard_Real aPrevFoundParam = myFoundParam;
+    myFoundParam += (myCurParam - aPrevParam);
+
+    myProjector.Perform(thePoint3d, myFoundParam);
+    if (myProjector.IsDone())
+    {
+      const Standard_Real aFoundParam = myProjector.Point().Parameter();
+      if ((aPrevFoundParam < myFoundParam && aPrevFoundParam < aFoundParam) ||
+          (aPrevFoundParam > myFoundParam && aPrevFoundParam > aFoundParam))
+      {
+        // Rude protection against case when amplified parameter goes before 
+        // previous one due to period or other reason occurred in projector.
+        // Using parameter returned by projector as is can produce self-intersections.
+        myFoundParam = aFoundParam;
+      }
+    }
+
+    return myFoundParam;
+  }
+
+  //! Returns pcurve used to compute parameters.
+  const Handle(Adaptor2d_HCurve2d)& GetPCurve() const
+  {
+    return myCurveAdaptor.CurveOnSurface().GetCurve();
+  }
 
 private:
 
-  Handle(TColStd_HArray1OfReal) myParameters;
+  ParametersCollection          myParameters;
 
   Standard_Boolean              myIsSameParam;
   Standard_Real                 myFirstParam;
@@ -61,11 +155,12 @@ private:
   Standard_Real                 myOldFirstParam;
   Standard_Real                 myScale;
 
-  Standard_Real                 myCurParam;
-  Standard_Real                 myFoundParam;
+  mutable Standard_Real         myCurParam;
+  mutable Standard_Real         myFoundParam;
 
   BRepAdaptor_Curve             myCurveAdaptor;
-  Extrema_LocateExtPC           myProjector;
+
+  mutable Extrema_LocateExtPC   myProjector;
 };
 
 #endif
index 5fbb1bba33a83577436f94bb9aa0e47916411cdf..5e2748042d89d9f5559d35ae57b0aba5d7c536ed 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2014-08-13
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
 // Created by: Oleg AGASHIN
-// Copyright (c) 2011-2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // commercial license or contractual agreement.
 
 #include <BRepMesh_EdgeTessellationExtractor.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-#include <Poly_Triangulation.hxx>
 #include <BRepMesh_ShapeTool.hxx>
+#include <gp_Pnt.hxx>
+#include <BRep_Tool.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Edge.hxx>
 
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+BRepMesh_EdgeTessellationExtractor::BRepMesh_EdgeTessellationExtractor (
+  const IMeshData::IEdgeHandle& theEdge,
+  const IMeshData::IFaceHandle& theFace)
+{
+  Handle (Poly_Triangulation) aTriangulation =
+    BRep_Tool::Triangulation (theFace->GetFace(), myLoc);
+
+  Handle (Poly_PolygonOnTriangulation) aPolygon =
+    BRep_Tool::PolygonOnTriangulation (theEdge->GetEdge(), aTriangulation, myLoc);
 
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellationExtractor,BRepMesh_IEdgeTool)
+  myNodes   = &aTriangulation->Nodes ();
+  myIndices = &aPolygon->Nodes ();
+  myProvider.Init (theEdge, TopAbs_FORWARD, theFace, aPolygon->Parameters ());
+}
 
 //=======================================================================
 //function : Constructor
 //purpose  : 
 //=======================================================================
-BRepMesh_EdgeTessellationExtractor::BRepMesh_EdgeTessellationExtractor(
-  const TopoDS_Edge&                          theEdge,
-  const Handle(Geom2dAdaptor_HCurve)&         thePCurve,
-  const TopoDS_Face&                          theFace,
-  const Handle(Poly_Triangulation)&           theTriangulation,
-  const Handle(Poly_PolygonOnTriangulation)&  thePolygon,
-  const TopLoc_Location&                      theLocation)
-  : myProvider(theEdge, theFace, thePolygon->Parameters()),
-    myPCurve(thePCurve),
-    myNodes(theTriangulation->Nodes()),
-    myIndices(thePolygon->Nodes()),
-    myLoc(theLocation)
+BRepMesh_EdgeTessellationExtractor::~BRepMesh_EdgeTessellationExtractor ()
 {
 }
 
+//=======================================================================
+//function : NbPoints
+//purpose  : 
+//=======================================================================
+Standard_Integer BRepMesh_EdgeTessellationExtractor::PointsNb () const
+{
+  return myIndices->Size ();
+}
+
 //=======================================================================
 //function : Value
 //purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_EdgeTessellationExtractor::Value(
+Standard_Boolean BRepMesh_EdgeTessellationExtractor::Value (
   const Standard_Integer theIndex,
-  Standard_Real&         theParameter,
   gp_Pnt&                thePoint,
-  gp_Pnt2d&              theUV)
+  Standard_Real&         theParameter) const
 {
-  const gp_Pnt& theRefPnt = myNodes(myIndices(theIndex));
-  thePoint = BRepMesh_ShapeTool::UseLocation(theRefPnt, myLoc);
-
-  theParameter = myProvider.Parameter(theIndex, thePoint);
-  theUV        = myPCurve->Value(theParameter);
+  const gp_Pnt& theRefPnt = (*myNodes) ((*myIndices) (theIndex));
+  thePoint = BRepMesh_ShapeTool::UseLocation (theRefPnt, myLoc);
 
+  theParameter = myProvider.Parameter (theIndex, thePoint);
   return Standard_True;
 }
index d7f20a6146f2f7ef6cd4a2bce1e3997ec13d76af..8ce07f590f43cb50cc783427dad96fee578b553f 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2014-08-13
+// Created on: 2016-04-19
+// Copyright (c) 2016 OPEN CASCADE SAS
 // Created by: Oleg AGASHIN
-// Copyright (c) 2011-2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 #ifndef _BRepMesh_EdgeTessellationExtractor_HeaderFile
 #define _BRepMesh_EdgeTessellationExtractor_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <BRepMesh_IEdgeTool.hxx>
+#include <IMeshTools_CurveTessellator.hxx>
+#include <IMeshData_Types.hxx>
 #include <BRepMesh_EdgeParameterProvider.hxx>
-#include <TopLoc_Location.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <TColStd_Array1OfInteger.hxx>
-
-class Poly_Triangulation;
-class Poly_PolygonOnTriangulation;
-class TopoDS_Edge;
-class TopoDS_Face;
-class Geom2dAdaptor_HCurve;
+#include <TopLoc_Location.hxx>
 
 //! Auxiliary class implements functionality retrieving tessellated
 //! representation of an edge stored in polygon.
-class BRepMesh_EdgeTessellationExtractor : public BRepMesh_IEdgeTool
+class BRepMesh_EdgeTessellationExtractor : public IMeshTools_CurveTessellator
 {
 public:
 
   //! Constructor.
-  //! Initializes extractor.
-  BRepMesh_EdgeTessellationExtractor(
-    const TopoDS_Edge&                          theEdge,
-    const Handle(Geom2dAdaptor_HCurve)&         thePCurve,
-    const TopoDS_Face&                          theFace,
-    const Handle(Poly_Triangulation)&           theTriangulation,
-    const Handle(Poly_PolygonOnTriangulation)&  thePolygon,
-    const TopLoc_Location&                      theLocation);
+  Standard_EXPORT BRepMesh_EdgeTessellationExtractor (
+    const IMeshData::IEdgeHandle& theEdge,
+    const IMeshData::IFaceHandle& theFace);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~BRepMesh_EdgeTessellationExtractor ();
 
-  //! Returns number of dicretization points.
-  virtual Standard_Integer NbPoints() const Standard_OVERRIDE
-  {
-    return myIndices.Length();
-  }
+  //! 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.
-  //! @param theUV coordinates of tessellation point in parametric space of face.
   //! @return True in case of valid result, false elewhere.
-  virtual Standard_Boolean Value(
+  Standard_EXPORT virtual Standard_Boolean Value (
     const Standard_Integer theIndex,
-    Standard_Real&         theParameter,
     gp_Pnt&                thePoint,
-    gp_Pnt2d&              theUV) Standard_OVERRIDE;
+    Standard_Real&         theParameter) const Standard_OVERRIDE;
 
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_EdgeTessellationExtractor,BRepMesh_IEdgeTool)
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeTessellationExtractor, IMeshTools_CurveTessellator)
 
 private:
 
-  //! Assignment operator.
-  void operator =(const BRepMesh_EdgeTessellationExtractor& /*theOther*/)
-  {
-  }
-
-private:
-
-  BRepMesh_EdgeParameterProvider myProvider;
-  Handle(Geom2dAdaptor_HCurve)   myPCurve;
-  const TColgp_Array1OfPnt&      myNodes;
-  const TColStd_Array1OfInteger& myIndices;
-  const TopLoc_Location          myLoc;
+  BRepMesh_EdgeParameterProvider<Handle(TColStd_HArray1OfReal)>  myProvider;
+  const TColgp_Array1OfPnt*                                      myNodes;
+  const TColStd_Array1OfInteger*                                 myIndices;
+  TopLoc_Location                                                myLoc;
 };
 
-DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellationExtractor, BRepMesh_IEdgeTool)
-
-#endif
+#endif
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_EdgeTessellator.cxx b/src/BRepMesh/BRepMesh_EdgeTessellator.cxx
deleted file mode 100644 (file)
index 0daa350..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-// Created on: 2014-08-13
-// 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.
-
-#include <BRepMesh_EdgeTessellator.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopLoc_Location.hxx>
-#include <BRep_Tool.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TColStd_Array1OfReal.hxx>
-
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellator,BRepMesh_IEdgeTool)
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator(
-  const TopoDS_Edge&                               theEdge,
-  const Handle(BRepMesh_FaceAttribute)&            theFaceAttribute,
-  const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
-  const Standard_Real                              theLinDeflection,
-  const Standard_Real                              theAngDeflection,
-  const Standard_Real                              theMinSize)
-  : mySurface(theFaceAttribute->Surface())
-{
-  Standard_Real aPreciseAngDef = 0.5 * theAngDeflection;
-  Standard_Real aPreciseLinDef = 0.5 * theLinDeflection;
-  if (theEdge.Orientation() == TopAbs_INTERNAL)
-    aPreciseLinDef *= 0.5;
-
-  mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
-  mySquareMinSize = Max(mySquareEdgeDef, theMinSize * theMinSize);
-  myEdgeSqTol     = BRep_Tool::Tolerance (theEdge);
-  myEdgeSqTol    *= myEdgeSqTol;
-
-  Standard_Boolean isSameParam = BRep_Tool::SameParameter(theEdge);
-  if (isSameParam)
-    myCOnS.Initialize(theEdge);
-  else
-    myCOnS.Initialize(theEdge, theFaceAttribute->Face());
-
-  const GeomAbs_CurveType aCurveType = myCOnS.GetType();
-  Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287
-
-  // Get 2d curve and init geom tool
-  Standard_Real aFirstParam, aLastParam;
-  Handle(Geom2d_Curve) aCurve2d =
-    BRep_Tool::CurveOnSurface(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam);
-  myCurve2d.Load(aCurve2d, aFirstParam, aLastParam);
-  myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam, 
-    aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
-
-  if (aCurveType == GeomAbs_BSplineCurve)
-  {
-    // bug24220
-    const Standard_Integer aNbInt = myCOnS.NbIntervals(GeomAbs_C1);
-    if ( aNbInt > 1 )
-    {
-      TColStd_Array1OfReal anIntervals( 1, aNbInt + 1 );
-      myCOnS.Intervals(anIntervals, GeomAbs_C1);
-      for (Standard_Integer aIntIt = 1; aIntIt <= aNbInt; ++aIntIt)
-      {
-        const Standard_Real& aStartInt = anIntervals.Value( aIntIt );
-        const Standard_Real& anEndInt  = anIntervals.Value( aIntIt + 1 );
-
-        BRepMesh_GeomTool aDetalizator(myCOnS, aStartInt, anEndInt,
-          aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize);
-
-        Standard_Integer aNbAddNodes = aDetalizator.NbPoints();
-        for ( Standard_Integer aNodeIt = 1; aNodeIt <= aNbAddNodes; ++aNodeIt )
-        {
-          Standard_Real aParam;
-          gp_Pnt        aPoint3d;
-          gp_Pnt2d      aPoint2d;
-          aDetalizator.Value( aNodeIt, aParam, aPoint3d);
-          myCurve2d.D0(aParam, aPoint2d);
-
-          myTool->AddPoint( aPoint3d, aParam, Standard_False );
-        }
-      }
-    }
-  }
-
-  // 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(theEdge, TopAbs_VERTEX);
-  for (; aVertexIt.More(); aVertexIt.Next())
-  {
-    const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexIt.Current());
-    if (aVertex.Orientation() != TopAbs_INTERNAL)
-      continue;
-
-    myTool->AddPoint(BRep_Tool::Pnt(aVertex), 
-      BRep_Tool::Parameter(aVertex, theEdge), Standard_True);
-  }
-
-  Standard_Integer aNodesNb = myTool->NbPoints();
-  //Check deflection in 2d space for improvement of edge tesselation.
-  if( isSameParam && aNodesNb > 1)
-  {
-    const TopTools_ListOfShape& aSharedFaces = theMapOfSharedFaces.FindFromKey(theEdge);
-    TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces);
-    for (; aFaceIt.More(); aFaceIt.Next())
-    {
-      const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value());
-      BRepAdaptor_Surface aSurf(aFace, Standard_False);
-
-      if (aSurf.GetType() == GeomAbs_Plane)
-        continue;
-
-      Standard_Real aF, aL;
-      aCurve2d = BRep_Tool::CurveOnSurface(theEdge, aFace, aF, aL);
-      if ( Abs(aF - aFirstParam) > Precision::PConfusion() ||
-           Abs(aL - aLastParam ) > Precision::PConfusion() )
-      {
-        continue;
-      }
-      Geom2dAdaptor_Curve aGACurve(aCurve2d, aF, aL);
-
-      aNodesNb = myTool->NbPoints();
-      TColStd_Array1OfReal aParamArray(1, aNodesNb);
-      for (Standard_Integer i = 1; i <= aNodesNb; ++i)
-      {
-        gp_Pnt        aTmpPnt;
-        Standard_Real aParam;
-        myTool->Value(i, aParam, aTmpPnt);
-        aParamArray.SetValue(i, aParam);
-      }
-
-      for (Standard_Integer i = 1; i < aNodesNb; ++i)
-        splitSegment(aSurf, aGACurve, aParamArray(i), aParamArray(i + 1), 1);
-    }
-  }
-
-   const Standard_Real aTol = Precision::Confusion();
-   const Standard_Real aDu  = mySurface->UResolution (aTol);
-   const Standard_Real aDv  = mySurface->VResolution (aTol);
-
-   myFaceRangeU[0] = mySurface->FirstUParameter() - aDu;
-   myFaceRangeU[1] = mySurface->LastUParameter()  + aDu;
-
-   myFaceRangeV[0] = mySurface->FirstVParameter() - aDv;
-   myFaceRangeV[1] = mySurface->LastVParameter()  + aDv;
-}
-
-//=======================================================================
-//function : Value
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_EdgeTessellator::Value(
-  const Standard_Integer theIndex,
-  Standard_Real&         theParameter,
-  gp_Pnt&                thePoint,
-  gp_Pnt2d&              theUV)
-{
-  myTool->Value(theIndex, theParameter, thePoint);
-  myCurve2d.D0(theParameter, theUV);
-
-  // If point coordinates are out of surface range, 
-  // it is necessary to re-project point.
-  if (mySurface->GetType() != GeomAbs_BSplineSurface &&
-      mySurface->GetType() != GeomAbs_BezierSurface  &&
-      mySurface->GetType() != GeomAbs_OtherSurface)
-  {
-    return Standard_True;
-  }
-
-  // Let skip periodic case.
-  if (mySurface->IsUPeriodic() || mySurface->IsVPeriodic())
-    return Standard_True;
-
-  // Point lies within the surface range - nothing to do.
-  if (theUV.X() > myFaceRangeU[0] && theUV.X() < myFaceRangeU[1] &&
-      theUV.Y() > myFaceRangeV[0] && theUV.Y() < myFaceRangeV[1])
-  {
-    return Standard_True;
-  }
-
-  gp_Pnt aPntOnSurf;
-  mySurface->D0 (theUV.X (), theUV.Y (), aPntOnSurf);
-
-  return (thePoint.SquareDistance (aPntOnSurf) < myEdgeSqTol);
-}
-
-//=======================================================================
-//function : splitSegment
-//purpose  : 
-//=======================================================================
-void BRepMesh_EdgeTessellator::splitSegment(
-  const Adaptor3d_Surface&    theSurf,
-  const Geom2dAdaptor_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;
-  myCOnS.D0(midpar, midP3d);
-  myTool->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_EdgeTessellator.hxx b/src/BRepMesh/BRepMesh_EdgeTessellator.hxx
deleted file mode 100644 (file)
index 5af1a9e..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-// Created on: 2014-08-13
-// 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 _BRepMesh_EdgeTessellator_HeaderFile
-#define _BRepMesh_EdgeTessellator_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <BRepMesh.hxx>
-#include <BRepMesh_IEdgeTool.hxx>
-#include <BRepMesh_GeomTool.hxx>
-#include <BRepMesh_FaceAttribute.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-
-class Adaptor3d_Surface;
-class TopoDS_Edge;
-class BRepAdaptor_HSurface;
-
-//! Auxiliary class implements functionality producing tessellated
-//! representation of an edge based on edge geometry.
-class BRepMesh_EdgeTessellator : public BRepMesh_IEdgeTool
-{
-public:
-
-  //! Constructor.
-  //! Automatically performs tessellation of the edge according to the
-  //! given parameters.
-  BRepMesh_EdgeTessellator(
-    const TopoDS_Edge&                               theEdge,
-    const Handle(BRepMesh_FaceAttribute)&            theFaceAttribute,
-    const TopTools_IndexedDataMapOfShapeListOfShape& theMapOfSharedFaces,
-    const Standard_Real                              theLinDeflection,
-    const Standard_Real                              theAngDeflection,
-    const Standard_Real                              theMinSize);
-
-  //! Returns number of dicretization points.
-  virtual Standard_Integer NbPoints() const Standard_OVERRIDE
-  {
-    return myTool->NbPoints();
-  }
-
-  //! 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.
-  //! @param theUV coordinates of tessellation point in parametric space of face.
-  //! @return True in case of valid result, false elewhere.
-  virtual Standard_Boolean Value(
-    const Standard_Integer theIndex,
-    Standard_Real&         theParameter,
-    gp_Pnt&                thePoint,
-    gp_Pnt2d&              theUV) Standard_OVERRIDE;
-
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_EdgeTessellator,BRepMesh_IEdgeTool)
-
-private:
-
-  //! 
-  void splitSegment(const Adaptor3d_Surface&    theSurf,
-                    const Geom2dAdaptor_Curve&  theCurve2d,
-                    const Standard_Real         theFirst,
-                    const Standard_Real         theLast,
-                    const Standard_Integer      theNbIter);
-
-private:
-  NCollection_Handle<BRepMesh_GeomTool> myTool;
-  Handle(BRepAdaptor_HSurface)          mySurface;
-  BRepAdaptor_Curve                     myCOnS;
-  Geom2dAdaptor_Curve                   myCurve2d;
-  Standard_Real                         mySquareEdgeDef;
-  Standard_Real                         mySquareMinSize;
-  Standard_Real                         myEdgeSqTol;
-  Standard_Real                         myFaceRangeU[2];
-  Standard_Real                         myFaceRangeV[2];
-};
-
-DEFINE_STANDARD_HANDLE(BRepMesh_EdgeTessellator, BRepMesh_IEdgeTool)
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.cxx b/src/BRepMesh/BRepMesh_FaceAttribute.cxx
deleted file mode 100644 (file)
index 119a746..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-// Created by: Ekaterina SMIRNOVA
-// Copyright (c) 2008-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.
-
-#include <BRepMesh_FaceAttribute.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepMesh_ShapeTool.hxx>
-#include <BRepMesh_Classifier.hxx>
-#include <BRepTools.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopoDS_Wire.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <BRep_Tool.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_FaceAttribute::BRepMesh_FaceAttribute()
-  : myDefFace         (0.),
-    myUMin            (0.),
-    myUMax            (0.),
-    myVMin            (0.),
-    myVMax            (0.),
-    myDeltaX          (1.),
-    myDeltaY          (1.),
-    myMinStep         (-1.),
-    myStatus          (BRepMesh_NoError),
-    myAdaptiveMin     (Standard_False)
-{
-  init();
-}
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
-  const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
-  const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints)
-  : myDefFace         (0.),
-    myUMin            (0.),
-    myUMax            (0.),
-    myVMin            (0.),
-    myVMax            (0.),
-    myDeltaX          (1.),
-    myDeltaY          (1.),
-    myMinStep         (-1.),
-    myStatus          (BRepMesh_NoError),
-    myAdaptiveMin     (Standard_False),
-    myBoundaryVertices(theBoundaryVertices),
-    myBoundaryPoints  (theBoundaryPoints)
-{
-}
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
-  const TopoDS_Face&                    theFace,
-  const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
-  const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints,
-  const Standard_Boolean                theAdaptiveMin)
-  : myDefFace         (0.),
-    myUMin            (0.),
-    myUMax            (0.),
-    myVMin            (0.),
-    myVMax            (0.),
-    myDeltaX          (1.),
-    myDeltaY          (1.),
-    myMinStep         (-1.),
-    myStatus          (BRepMesh_NoError),
-    myAdaptiveMin     (theAdaptiveMin),
-    myBoundaryVertices(theBoundaryVertices),
-    myBoundaryPoints  (theBoundaryPoints),
-    myFace            (theFace)
-{
-  init();
-}
-
-//=======================================================================
-//function : Destructor
-//purpose  : 
-//=======================================================================
-BRepMesh_FaceAttribute::~BRepMesh_FaceAttribute()
-{
-}
-
-//=======================================================================
-//function : SetFace
-//purpose  : 
-//=======================================================================
-void BRepMesh_FaceAttribute::SetFace (
-  const TopoDS_Face&     theFace, 
-  const Standard_Boolean theAdaptiveMin)
-{
-  myFace        = theFace;
-  myAdaptiveMin = theAdaptiveMin;
-
-  init ();
-}
-
-//=======================================================================
-//function : init
-//purpose  : 
-//=======================================================================
-void BRepMesh_FaceAttribute::init()
-{
-  myVertexEdgeMap = new BRepMesh::IMapOfInteger;
-  myInternalEdges = new BRepMesh::DMapOfShapePairOfPolygon;
-  myLocation2D    = new BRepMesh::DMapOfIntegerListOfXY;
-  myClassifier    = new BRepMesh_Classifier;
-
-  if (myFace.IsNull())
-    return;
-
-  BRepTools::Update(myFace);
-  myFace.Orientation(TopAbs_FORWARD);
-  BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
-
-  if (myAdaptiveMin) 
-  {
-    // compute minimal UV distance
-    // between vertices
-
-    myMinStep = RealLast();
-    for (TopoDS_Iterator aFaceIt(myFace); aFaceIt.More(); aFaceIt.Next()) 
-    {
-      for (TopoDS_Iterator aWireIt(aFaceIt.Value()); aWireIt.More(); aWireIt.Next()) 
-      {
-        const TopoDS_Edge& anEdge = TopoDS::Edge(aWireIt.Value());
-        if (anEdge.IsNull() || BRep_Tool::IsClosed(anEdge))
-          continue;
-
-        // Get end points on 2d curve
-        gp_Pnt2d aFirst2d, aLast2d;
-        BRep_Tool::UVPoints(anEdge, myFace, aFirst2d, aLast2d);
-        Standard_Real aDist =aFirst2d.Distance(aLast2d);
-        if (aDist < myMinStep) 
-          myMinStep = aDist;
-      }
-    }
-  }
-  
-  BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False);
-  mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
-}
-
-//=======================================================================
-//function : Clear
-//purpose  : 
-//=======================================================================
-void BRepMesh_FaceAttribute::Clear()
-{
-  myStructure.Nullify();
-  myLocation2D->Clear();
-  myInternalEdges->Clear();
-  myVertexEdgeMap->Clear();
-}
-
-//=======================================================================
-//function : computeParametricTolerance
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_FaceAttribute::computeParametricTolerance(
-  const Standard_Real theFirstParam,
-  const Standard_Real theLastParam) const
-{
-  const Standard_Real aDeflectionUV = 1.e-05;
-  Standard_Real aPreci = (theLastParam - theFirstParam) * aDeflectionUV;
-  if(myAdaptiveMin && myMinStep < aPreci)
-    aPreci = myMinStep;
-
-  return Max(Precision::PConfusion(), aPreci);
-}
-
-//=======================================================================
-//function : getVertexIndex
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_FaceAttribute::getVertexIndex(
-  const TopoDS_Vertex& theVertex,
-  Standard_Integer&    theVertexIndex) const
-{
-  if (!myBoundaryVertices.IsNull() && myBoundaryVertices->IsBound(theVertex))
-    theVertexIndex = myBoundaryVertices->Find(theVertex);
-  else if (!mySurfaceVertices.IsNull() && mySurfaceVertices->IsBound(theVertex))
-    theVertexIndex = mySurfaceVertices->Find(theVertex);
-  else
-    return Standard_False;
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : AddNode
-//purpose  : 
-//=======================================================================
-void BRepMesh_FaceAttribute::AddNode(
-  const Standard_Integer         theIndex,
-  const gp_XY&                   theUV,
-  const BRepMesh_DegreeOfFreedom theMovability,
-  Standard_Integer&              theNodeIndex,
-  Standard_Integer&              theNodeOnEdgeIndex)
-{
-  BRepMesh_Vertex aNode(theUV, theIndex, theMovability);
-  theNodeIndex = myStructure->AddNode(aNode);
-  theNodeOnEdgeIndex = myVertexEdgeMap->FindIndex(theNodeIndex);
-  if (theNodeOnEdgeIndex == 0)
-    theNodeOnEdgeIndex = myVertexEdgeMap->Add(theNodeIndex);
-}
-
-//=======================================================================
-//function : Scale
-//purpose  : 
-//=======================================================================
-gp_XY BRepMesh_FaceAttribute::Scale(const gp_XY&           thePoint2d,
-                                    const Standard_Boolean isToFaceBasis)
-{
-  return isToFaceBasis ?
-    gp_XY((thePoint2d.X() - myUMin) / myDeltaX, (thePoint2d.Y() - myVMin) / myDeltaY) :
-    gp_XY(thePoint2d.X() * myDeltaX + myUMin, thePoint2d.Y() * myDeltaY + myVMin);
-}
-
-//=======================================================================
-//function : ToleranceU
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_FaceAttribute::ToleranceU() const
-{
-  return computeParametricTolerance(myUMin, myUMax);
-}
-
-//=======================================================================
-//function : ToleranceV
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_FaceAttribute::ToleranceV() const
-{
-  return computeParametricTolerance(myVMin, myVMax);
-}
diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.hxx b/src/BRepMesh/BRepMesh_FaceAttribute.hxx
deleted file mode 100644 (file)
index 0460d53..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright (c) 2013 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_FaceAttribute_HeaderFile
-#define _BRepMesh_FaceAttribute_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_Transient.hxx>
-#include <Standard_Type.hxx>
-
-#include <BRepMesh_Status.hxx>
-#include <BRepMesh.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-
-class BRepAdaptor_HSurface;
-
-//! Auxiliary class for FastDiscret and FastDiscretFace classes.
-class BRepMesh_FaceAttribute : public Standard_Transient
-{
-public:
-
-  //! Constructor. Initializes empty attribute.
-  //! @param theBoundaryVertices shared map of shape vertices.
-  //! @param theBoundaryPoints shared discretization points of shape boundaries.
-  Standard_EXPORT BRepMesh_FaceAttribute(
-    const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
-    const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints);
-
-  //! Constructor.
-  //! @param theFace face the attribute is created for. 
-  //! Used for default initialization. Attribute keeps reference 
-  //! to the source face with forward orientation.
-  //! @param theBoundaryVertices shared map of shape vertices.
-  //! @param theBoundaryPoints shared discretization points of shape boundaries.
-  //! @param theAdaptiveMin switches on adaptive computation of minimal parametric
-  //! tolerance (if true).
-  Standard_EXPORT BRepMesh_FaceAttribute(
-    const TopoDS_Face&                    theFace,
-    const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
-    const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints,
-    const Standard_Boolean                theAdaptiveMin);
-
-  //! Destructor.
-  Standard_EXPORT virtual ~BRepMesh_FaceAttribute();
-
-public: //! @name main geometrical properties.
-
-  //! Returns face's surface.
-  inline const Handle(BRepAdaptor_HSurface)& Surface() const
-  {
-    return mySurface;
-  }
-
-  //! Returns True in case if this attribute has already been intialized.
-  inline Standard_Boolean IsInitialized () const
-  {
-    return !myFace.IsNull ();
-  }
-
-  //! Initializes this attribute by the given face.
-  Standard_EXPORT void SetFace (
-    const TopoDS_Face&     theFace, 
-    const Standard_Boolean theAdaptiveMin);
-
-  //! Returns forward oriented face to be used for calculations.
-  inline const TopoDS_Face& Face() const
-  {
-    return myFace;
-  }
-
-  //! Sets boundary vertices map.
-  inline void SetBoundaryVertices(const BRepMesh::HDMapOfVertexInteger& theVertices)
-  {
-    myBoundaryVertices = theVertices;
-  }
-
-  //! Sets boundary points map.
-  inline void SetBoundaryPoints(const BRepMesh::HDMapOfIntegerPnt& theBoundaryPoints)
-  {
-    myBoundaryPoints = theBoundaryPoints;
-  }
-
-  //! Returns U tolerance of face calculated regarding its parameters.
-  Standard_EXPORT Standard_Real ToleranceU() const;
-  
-  //! Returns V tolerance of face calculated regarding its parameters.
-  Standard_EXPORT Standard_Real ToleranceV() const;
-  
-  //! Gives face deflection parameter.
-  inline Standard_Real GetDefFace() const
-  {
-    return myDefFace;
-  }
-
-  //! Sets face deflection.
-  inline void SetDefFace(const Standard_Real theDefFace)
-  {
-    myDefFace = theDefFace;
-  }
-
-  //! Gives minimal value in U domain.
-  inline Standard_Real GetUMin() const
-  {
-    return myUMin;
-  }
-
-  //! Sets minimal value in U domain.
-  inline void SetUMin(const Standard_Real theUMin)
-  {
-    myUMin = theUMin;
-  }
-
-  //! Gives minimal value in V domain.
-  inline Standard_Real GetVMin() const
-  {
-    return myVMin;
-  }
-
-  //! Sets minimal value in V domain.
-  inline void SetVMin(const Standard_Real theVMin)
-  {
-    myVMin = theVMin;
-  }
-
-  //! Gives maximal value in U domain.
-  inline Standard_Real GetUMax() const
-  {
-    return myUMax;
-  }
-
-  //! Sets maximal value in U domain.
-  inline void SetUMax(const Standard_Real theUMax)
-  {
-    myUMax = theUMax;
-  }
-
-  //! Gives maximal value in V domain.
-  inline Standard_Real GetVMax() const
-  {
-    return myVMax;
-  }
-
-  //! Sets maximal value in V domain.
-  inline void SetVMax(const Standard_Real theVMax)
-  {
-    myVMax = theVMax;
-  }
-
-  //! Gives value of step in U domain.
-  inline Standard_Real GetDeltaX() const
-  {
-    return myDeltaX;
-  }
-
-  //! Sets value of step in U domain.
-  inline void SetDeltaX(const Standard_Real theDeltaX)
-  {
-    myDeltaX = theDeltaX;
-  }
-
-  //! Gives value of step in V domain.
-  inline Standard_Real GetDeltaY() const
-  {
-    return myDeltaY;
-  }
-
-  //! Sets value of step in V domain.
-  inline void SetDeltaY(const Standard_Real theDeltaY)
-  {
-    myDeltaY = theDeltaY;
-  }
-
-  //! Sets set of status flags for this face.
-  inline Standard_Integer GetStatus() const
-  {
-    return myStatus;
-  }
-
-  //! Sets status flag for this face.
-  inline void SetStatus(const BRepMesh_Status theStatus)
-  {
-    myStatus |= theStatus;
-  }
-
-  //! Returns TRUE in case if computed data is valid.
-  inline Standard_Boolean IsValid() const
-  {
-    return (myStatus == BRepMesh_NoError || myStatus == BRepMesh_ReMesh);
-  }
-
-public: //! @name auxiliary structures
-
-  //! Clear face attribute.
-  Standard_EXPORT void Clear();
-
-  //! Gives reference to map of internal edges of face.
-  inline BRepMesh::HDMapOfShapePairOfPolygon& ChangeInternalEdges()
-  {
-    return myInternalEdges;
-  }
-
-  //! Gives reference to map of 2D points of discretization.
-  inline BRepMesh::HDMapOfIntegerListOfXY& ChangeLocation2D()
-  {
-    return myLocation2D;
-  }
-
-  //! Gives reference to map of 3D points of discretization.
-  inline BRepMesh::HDMapOfIntegerPnt& ChangeSurfacePoints()
-  {
-    return mySurfacePoints;
-  }
-
-  //! Gives reference to map of vertices of discretization.
-  inline BRepMesh::HDMapOfVertexInteger& ChangeSurfaceVertices()
-  {
-    return mySurfaceVertices;
-  }
-
-  //! Gives reference on map of (vertex, edge) pairs of face.
-  inline BRepMesh::HIMapOfInteger& ChangeVertexEdgeMap()
-  {
-    return myVertexEdgeMap;
-  }
-
-  //! Gives Delaunay data structure.
-  inline Handle(BRepMesh_DataStructureOfDelaun)& ChangeStructure()
-  {
-    return myStructure;
-  }
-
-  //! Returns classifier.
-  inline BRepMesh::HClassifier& ChangeClassifier()
-  {
-    return myClassifier;
-  }
-
-  //! Returns mesh nodes calculated for boundaries.
-  inline BRepMesh::HVectorOfVertex& ChangeMeshNodes()
-  {
-    return myMeshNodes;
-  }
-
-public: //! @name Point/Vertex/Node manipulators
-
-  //! Gives the number of different locations in 3D space.
-  inline Standard_Integer LastPointId() const
-  {
-    return (myBoundaryPoints.IsNull() ? 0 : myBoundaryPoints->Extent()) + 
-      (mySurfacePoints.IsNull() ? 0 : mySurfacePoints->Extent());
-  }
-
-  //! Gives the 3D location of the vertex.
-  inline const gp_Pnt& GetPoint(const BRepMesh_Vertex& theVertex) const
-  {
-    return GetPoint(theVertex.Location3d());
-  }
-
-  //! Gives the 3D location of the vertex.
-  inline const gp_Pnt& GetPoint(const Standard_Integer theIndex) const
-  {
-    if (!mySurfacePoints.IsNull() && theIndex > myBoundaryPoints->Extent())
-      return mySurfacePoints->Find(theIndex);
-
-    return myBoundaryPoints->Find(theIndex);
-  }
-
-  //! Returns index of the given vertex if it exists in cache, 
-  //! elsewhere adds it to cache and returns cached index.
-  //! @param theVertexExplorer template parameter intended to transfer
-  //! parameters of vertex to method. Explorer class can implement different
-  //! approaches of extraction of target parameters.
-  //! @param isFillEdgeVertices if TRUE adds vertex to shared map of 
-  //! edges vertices, elsewhere adds it map of face vertices.
-  template<class HVertexExplorer>
-    Standard_Integer GetVertexIndex(
-      const HVertexExplorer& theVertexExplorer,
-      const Standard_Boolean isFillEdgeVertices = Standard_False)
-  {
-    const TopoDS_Vertex& aVertex = theVertexExplorer->Vertex();
-    Standard_Integer aNewVertexIndex = 0;
-    if (getVertexIndex(aVertex, aNewVertexIndex))
-      return aNewVertexIndex;
-
-    if (!theVertexExplorer->IsSameUV() ||
-        !getVertexIndex(theVertexExplorer->SameVertex(), aNewVertexIndex))
-    {
-      aNewVertexIndex = LastPointId() + 1;
-
-      BRepMesh::DMapOfIntegerPnt& aPointsMap = isFillEdgeVertices ?
-        *myBoundaryPoints : *mySurfacePoints;
-
-      aPointsMap.Bind(aNewVertexIndex, theVertexExplorer->Point());
-    }
-
-    BRepMesh::DMapOfVertexInteger& aVertexMap = isFillEdgeVertices ?
-      *myBoundaryVertices : *mySurfaceVertices;
-
-    aVertexMap.Bind(aVertex, aNewVertexIndex);
-
-    return aNewVertexIndex;
-  }
-
-  //! Adds node with the given parameters to mesh.
-  //! @param theIndex index of 3D point corresponded to the node.
-  //! @param theUV node position.
-  //! @param theMovability movability of a node.
-  //! @param theNodeIndex index of vertex in mesh structure.
-  //! @param theNodeOnEdgeIndex ordered index of node on the boundary.
-  Standard_EXPORT void AddNode(const Standard_Integer         theIndex,
-                               const gp_XY&                   theUV,
-                               const BRepMesh_DegreeOfFreedom theMovability,
-                               Standard_Integer&              theNodeIndex,
-                               Standard_Integer&              theNodeOnEdgeIndex);
-
-public: //! @name Auxiliary methods
-  
-  //! Scales the given point from real parametric space 
-  //! to face basis and otherwise.
-  //! @param thePoint2d point to be scaled.
-  //! @param isToFaceBasis if TRUE converts point to face basis,
-  //! otherwise performs reverse conversion.
-  //! @return scaled point.
-  Standard_EXPORT gp_XY Scale(const gp_XY&           thePoint2d, 
-                              const Standard_Boolean isToFaceBasis);
-
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
-
-private:
-
-  //! Default constructor.
-  BRepMesh_FaceAttribute();
-
-  //! Assignment operator.
-  void operator =(const BRepMesh_FaceAttribute& /*theOther*/)
-  {
-  }
-
-  //! Initializes internal data structures.
-  void init();
-
-  //! Computes parametric tolerance of a face regarding the given limits.
-  Standard_Real computeParametricTolerance(
-    const Standard_Real theFirstParam,
-    const Standard_Real theLastParam) const;
-
-  //! Clears internal data structures local to face.
-  void clearLocal(
-    const Standard_Boolean isClearSurfaceDataOnly = Standard_False);
-
-  //! Returns index of the given vertex if it exists in cache.
-  //! @param theVertex vertex which index should be retrieved.
-  //! @param theVertexIndex index of the given vertex.
-  //! @return TRUE if cached value is found, FALSE elsewhere.
-  Standard_EXPORT Standard_Boolean getVertexIndex(
-    const TopoDS_Vertex& theVertex,
-    Standard_Integer&    theVertexIndex) const;
-
-private:
-
-  Standard_Real                           myDefFace;       //!< Restore face deflection
-  Standard_Real                           myUMin;          //!< Describes minimal value in U domain
-  Standard_Real                           myUMax;          //!< Describes maximal value in U domain
-  Standard_Real                           myVMin;          //!< Describes minimal value in V domain
-  Standard_Real                           myVMax;          //!< Describes maximal value in V domain
-  Standard_Real                           myDeltaX;
-  Standard_Real                           myDeltaY;
-  Standard_Real                           myMinStep;
-  Standard_Integer                        myStatus;
-  Standard_Boolean                        myAdaptiveMin;
-
-  BRepMesh::HDMapOfVertexInteger          myBoundaryVertices;
-  BRepMesh::HDMapOfIntegerPnt             myBoundaryPoints;
-
-  TopoDS_Face                             myFace;
-  Handle(BRepAdaptor_HSurface)            mySurface;
-  BRepMesh::HClassifier                   myClassifier;
-
-  BRepMesh::HDMapOfShapePairOfPolygon     myInternalEdges;
-
-  BRepMesh::HDMapOfIntegerListOfXY        myLocation2D;
-  BRepMesh::HIMapOfInteger                myVertexEdgeMap;
-
-  // This field is intended to keep calculated mesh nodes to prevent
-  // extremely high memory consumption in case if the whole structure is kept.
-  BRepMesh::HVectorOfVertex               myMeshNodes;
-
-  BRepMesh::HDMapOfVertexInteger          mySurfaceVertices;
-  BRepMesh::HDMapOfIntegerPnt             mySurfacePoints;
-  Handle(BRepMesh_DataStructureOfDelaun)  myStructure;
-};
-
-DEFINE_STANDARD_HANDLE(BRepMesh_FaceAttribute, Standard_Transient)
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_FaceChecker.cxx b/src/BRepMesh/BRepMesh_FaceChecker.cxx
new file mode 100644 (file)
index 0000000..cc2491d
--- /dev/null
@@ -0,0 +1,312 @@
+// 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>
+
+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 NCollection_IncAllocator();
+
+      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 NCollection_IncAllocator();
+      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->GetPCurve(myDFace.get(), 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.
+  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..ce6db21
--- /dev/null
@@ -0,0 +1,95 @@
+// 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::performInternal(
+  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;
+  }
+
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    Handle(IMeshTools_MeshAlgo) aMeshingAlgo = 
+      myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
+  
+    if (aMeshingAlgo.IsNull())
+    {
+      aDFace->SetStatus(IMeshData_Failure);
+      return;
+    }
+  
+    aMeshingAlgo->Perform(aDFace, myParameters);
+  }
+  catch (Standard_Failure const&)
+  {
+    aDFace->SetStatus (IMeshData_Failure);
+  }
+}
diff --git a/src/BRepMesh/BRepMesh_FaceDiscret.hxx b/src/BRepMesh/BRepMesh_FaceDiscret.hxx
new file mode 100644 (file)
index 0000000..9ca8680
--- /dev/null
@@ -0,0 +1,65 @@
+// 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 instance 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();
+
+  //! 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)
+
+protected:
+
+  //! Performs processing of faces of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+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_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx
deleted file mode 100644 (file)
index f64de14..0000000
+++ /dev/null
@@ -1,989 +0,0 @@
-// Created on: 1996-02-27
-// Created by: Ekaterina SMIRNOVA
-// Copyright (c) 1996-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <BRepMesh_FastDiscret.hxx>
-
-#include <BRepMesh_WireChecker.hxx>
-#include <BRepMesh_FastDiscretFace.hxx>
-#include <BRepMesh_FaceAttribute.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh_GeomTool.hxx>
-#include <BRepMesh_PairOfPolygon.hxx>
-#include <BRepMesh_Classifier.hxx>
-#include <BRepMesh_EdgeParameterProvider.hxx>
-#include <BRepMesh_IEdgeTool.hxx>
-#include <BRepMesh_EdgeTessellator.hxx>
-#include <BRepMesh_EdgeTessellationExtractor.hxx>
-
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-
-#include <Bnd_Box.hxx>
-#include <BRepTools.hxx>
-#include <BRepBndLib.hxx>
-#include <BndLib_Add3dCurve.hxx>
-#include <Poly_Triangulation.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-
-#include <Precision.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2dAdaptor_HCurve.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_Plane.hxx>
-#include <GeomAbs_SurfaceType.hxx>
-#include <Extrema_LocateExtPC.hxx>
-
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_Array1OfCharacter.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColGeom2d_SequenceOfCurve.hxx>
-
-#include <TopTools_SequenceOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-
-#include <OSD_Parallel.hxx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-#include <NCollection_IncAllocator.hxx>
-
-#include <Message_ProgressSentry.hxx>
-#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
-#include <BRep_PointRepresentation.hxx>
-
-#include <vector>
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
-
-#define UVDEFLECTION 1.e-05
-
-//=======================================================================
-//function : BRepMesh_FastDiscret
-//purpose  : 
-//=======================================================================
-BRepMesh_FastDiscret::BRepMesh_FastDiscret( const Bnd_Box&         theBox,
-                                            const BRepMesh_FastDiscret::Parameters& theParams)
-   :
-  myMapdefle(1000, new NCollection_IncAllocator()),
-  myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
-  myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
-  myParameters(theParams),
-  myDtotale(0.)
-{ 
-  if ( myParameters.Relative )
-    BRepMesh_ShapeTool::BoxMaxDimension(theBox, myDtotale);
-}
-
-//=======================================================================
-//function : InitSharedFaces
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::InitSharedFaces(const TopoDS_Shape& theShape)
-{
-  TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, mySharedFaces);
-}
-
-//=======================================================================
-//function : Perform(shape)
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
-{
-  InitSharedFaces(theShape);
-
-  std::vector<TopoDS_Face> aFaces;
-  TopExp_Explorer anExplorer(theShape, TopAbs_FACE);
-  for (; anExplorer.More(); anExplorer.Next())
-  {
-    const TopoDS_Face& aFace = TopoDS::Face(anExplorer.Current());
-    Add(aFace);
-    aFaces.push_back(aFace);
-  }
-
-  OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
-}
-
-//=======================================================================
-//function : Process
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
-{
-  Process (theFace, NULL);
-}
-
-//=======================================================================
-//function : Process
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::Process (const TopoDS_Face& theFace,
-                                    Message_ProgressSentry* theProgrEntry) const
-{
-  Handle(BRepMesh_FaceAttribute) anAttribute;
-  if (GetFaceAttribute(theFace, anAttribute)
-   && (theProgrEntry == NULL || theProgrEntry->More()))
-  {
-    try
-    {
-      OCC_CATCH_SIGNALS
-
-      BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize, 
-        myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
-      aTool.Perform (anAttribute, theProgrEntry);
-    }
-    catch (Standard_Failure)
-    {
-      anAttribute->SetStatus(BRepMesh_Failure);
-    }
-  }
-}
-
-//=======================================================================
-//function : resetDataStructure
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::resetDataStructure()
-{
-  Handle(NCollection_IncAllocator) aAllocator;
-  if (myAttribute->ChangeStructure().IsNull())
-    aAllocator = new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-  else
-    aAllocator = myAttribute->ChangeStructure()->Allocator();
-
-  myAttribute->Clear();
-  aAllocator->Reset(Standard_False);
-  Handle(BRepMesh_DataStructureOfDelaun) aStructure = 
-    new BRepMesh_DataStructureOfDelaun(aAllocator);
-
-  const Standard_Real aTolU = myAttribute->ToleranceU();
-  const Standard_Real aTolV = myAttribute->ToleranceV();
-  const Standard_Real uCellSize = 14.0 * aTolU;
-  const Standard_Real vCellSize = 14.0 * aTolV;
-
-  aStructure->Data()->SetCellSize ( uCellSize, vCellSize);
-  aStructure->Data()->SetTolerance( aTolU    , aTolV    );
-
-  myAttribute->ChangeStructure() = aStructure;
-}
-
-//=======================================================================
-//function : Add(face)
-//purpose  : 
-//=======================================================================
-Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
-{
-  myAttribute.Nullify();
-  GetFaceAttribute(theFace, myAttribute, Standard_True);
-
-  try
-  {
-    OCC_CATCH_SIGNALS
-
-    // Initialize face attributes
-    if (!myAttribute->IsInitialized ())
-      myAttribute->SetFace (theFace, myParameters.AdaptiveMin);
-    
-    BRepMesh::HIMapOfInteger&            aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
-    BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
-
-    resetDataStructure();
-
-    Standard_Real defedge = myParameters.Deflection;
-    Standard_Integer nbEdge = 0;
-    Standard_Real savangle = myParameters.Angle;
-    Standard_Real cdef;
-    Standard_Real maxdef = 2.* BRepMesh_ShapeTool::MaxFaceTolerance(theFace);
-
-    Standard_Real defface = 0.;
-    if (!myParameters.Relative)
-    {
-      defedge = Max(UVDEFLECTION, defedge);
-      defface = Max(myParameters.Deflection, maxdef);
-    }
-
-    const TopoDS_Face&                  aFace = myAttribute->Face();
-    for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
-    {
-      for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
-      {
-        const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value());
-        if (aEdge.IsNull())
-          continue;
-        if (myParameters.Relative)
-        {
-          if (!myMapdefle.IsBound(aEdge))
-          {
-            if (myEdges.IsBound(aEdge))
-            {
-              const BRepMesh_PairOfPolygon& aPair = myEdges.Find(aEdge);
-              const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
-              defedge = aPolygon->Deflection();
-            }
-            else
-            {
-              defedge = BRepMesh_ShapeTool::RelativeEdgeDeflection(
-                aEdge, myParameters.Deflection, myDtotale, cdef);
-
-              myParameters.Angle = savangle * cdef;
-            }
-          }
-          else
-          {
-            defedge = myMapdefle(aEdge);
-          }
-
-          defface += defedge;
-          defface = Max(maxdef, defface);
-
-          if (!myMapdefle.IsBound(aEdge))
-          {
-            defedge = Max(UVDEFLECTION, defedge);
-            myMapdefle.Bind(aEdge, defedge);
-          }
-        }
-        else
-        {
-          if (!myMapdefle.IsBound(aEdge))
-          {
-            myMapdefle.Bind(aEdge, defedge);
-          }
-        }
-
-        Standard_Real aFirstParam, aLastParam;
-        Handle(Geom2d_Curve) aCurve2d = 
-          BRep_Tool::CurveOnSurface(aEdge, aFace, aFirstParam, aLastParam);
-
-        if (aCurve2d.IsNull())
-          continue;
-        Handle(Geom2dAdaptor_HCurve) aPCurve =
-          new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
-
-        add(aEdge, aPCurve, defedge);
-        myParameters.Angle = savangle;
-      }
-    }
-
-    if ( nbEdge == 0 || aVertexEdgeMap->Extent() < 3 )
-    {
-      myAttribute->ChangeStructure().Nullify();
-      myAttribute->SetStatus(BRepMesh_Failure);
-      return myAttribute->GetStatus();
-    }
-
-    if ( myParameters.Relative )
-    {
-      defface = defface / nbEdge;
-    }
-    else
-    {
-      defface = myParameters.Deflection;
-    }
-
-    defface = Max(maxdef, defface);
-
-    TopLoc_Location aLoc;
-    Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
-    const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-
-    if ( aTriangulation.IsNull() )
-    {
-      Standard_Real xCur, yCur;
-      Standard_Real maxX, minX, maxY, minY;
-
-      minX = minY = 1.e100;
-      maxX = maxY =-1.e100;
-
-      Standard_Integer ipn = 0;
-      Standard_Integer i1 = 1;
-      for ( i1 = 1; i1 <= aVertexEdgeMap->Extent(); ++i1 )
-      {
-        const BRepMesh_Vertex& aVertex = 
-          myAttribute->ChangeStructure()->GetNode(aVertexEdgeMap->FindKey(i1));
-
-        ++ipn;
-
-        xCur = aVertex.Coord().X();
-        yCur = aVertex.Coord().Y();
-
-        minX = Min(xCur, minX);
-        maxX = Max(xCur, maxX);
-        minY = Min(yCur, minY);
-        maxY = Max(yCur, maxY);
-      }
-
-      Standard_Real myumin = minX;
-      Standard_Real myumax = maxX;
-      Standard_Real myvmin = minY;
-      Standard_Real myvmax = maxY;
-
-      const Standard_Real umin = gFace->FirstUParameter();
-      const Standard_Real umax = gFace->LastUParameter();
-      const Standard_Real vmin = gFace->FirstVParameter();
-      const Standard_Real vmax = gFace->LastVParameter();
-
-      if (myumin < umin || myumax > umax)
-      {
-        if (gFace->IsUPeriodic())
-        {
-          if ((myumax - myumin) > (umax - umin))
-            myumax = myumin + (umax - umin);
-        }
-        else
-        {
-          if (umin > myumin)
-            myumin = umin;
-
-          if (umax < myumax)
-            myumax = umax;
-        }
-      }
-
-      if (myvmin < vmin || myvmax > vmax)
-      {
-        if (gFace->IsVPeriodic())
-        {
-          if ((myvmax - myvmin) > (vmax - vmin))
-            myvmax = myvmin + (vmax - vmin);
-        }
-        else
-        {
-          if ( vmin > myvmin )
-            myvmin = vmin;
-
-          if (vmax < myvmax)
-            myvmax = vmax;
-        }
-      }
-
-      GeomAbs_SurfaceType aSurfType = gFace->GetType();
-      // Fast verification of the validity of calculated limits.
-      // If wrong, sure a problem of pcurve.
-      if (aSurfType == GeomAbs_BezierSurface &&
-         (myumin < -0.5 || myumax > 1.5 || myvmin < -0.5 || myvmax > 1.5) )
-      {
-        myAttribute->ChangeStructure().Nullify();
-        myAttribute->SetStatus(BRepMesh_Failure);
-        return myAttribute->GetStatus();
-      }
-
-      //define parameters for correct parametrics
-      Standard_Real deltaX = 1.0;
-      Standard_Real deltaY = 1.0;
-
-      {
-        Standard_Real aTolU, aTolV;
-        myAttribute->ChangeStructure()->Data()->GetTolerance(aTolU, aTolV);
-        const Standard_Real aTol = Sqrt(aTolU * aTolU + aTolV * aTolV);
-
-        BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
-        BRepMesh_WireChecker aDFaceChecker(aFace, aTol, aInternalEdges, 
-          aVertexEdgeMap, myAttribute->ChangeStructure(),
-          myumin, myumax, myvmin, myvmax, myParameters.InParallel );
-
-        aDFaceChecker.ReCompute(aClassifier);
-        BRepMesh_Status aCheckStatus = aDFaceChecker.Status();
-
-        if (aCheckStatus == BRepMesh_SelfIntersectingWire)
-        {
-          Standard_Integer nbmaill = 0;
-          Standard_Real eps = Precision::Confusion();
-          while (nbmaill < 5 && aCheckStatus != BRepMesh_ReMesh)
-          {
-            ++nbmaill;
-
-            resetDataStructure();
-
-            for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next())
-            {
-              for (TopoDS_Iterator aEdgeIt(aWireIt.Value()); aEdgeIt.More(); aEdgeIt.Next(), ++nbEdge)
-              {
-                const TopoDS_Edge& anEdge = TopoDS::Edge(aEdgeIt.Value());
-                if (anEdge.IsNull())
-                  continue;
-                if (myEdges.IsBound(anEdge))
-                  myEdges.UnBind(anEdge);
-
-                defedge = Max(myMapdefle(anEdge) / 3.0, eps);
-                myMapdefle.Bind(anEdge, defedge);
-
-                Standard_Real aFirstParam, aLastParam;
-                Handle(Geom2d_Curve) aCurve2d =
-                  BRep_Tool::CurveOnSurface(anEdge, aFace, aFirstParam, aLastParam);
-                if (aCurve2d.IsNull())
-                  continue;
-
-                Handle(Geom2dAdaptor_HCurve) aPCurve =
-                  new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam);
-                add(anEdge, aPCurve, defedge);
-              }
-            }
-
-            aDFaceChecker.ReCompute(aClassifier);
-            if (aDFaceChecker.Status() == BRepMesh_NoError)
-              aCheckStatus = BRepMesh_ReMesh;
-          }
-        }
-
-        myAttribute->SetStatus(aCheckStatus);
-        if (!myAttribute->IsValid())
-        {
-          myAttribute->ChangeStructure().Nullify();
-          return myAttribute->GetStatus();
-        }
-      }
-
-      // try to find the real length:
-      // akm (bug OCC16) : We must calculate these measures in non-singular
-      //     parts of face. Let's try to compute average value of three
-      //     (umin, (umin+umax)/2, umax), and respectively for v.
-      //                 vvvvv
-      Standard_Real longu = 0.0, longv = 0.0; //, last , first;
-      gp_Pnt P11, P12, P21, P22, P31, P32;
-
-      Standard_Real du = 0.05 * ( myumax - myumin );
-      Standard_Real dv = 0.05 * ( myvmax - myvmin );
-      Standard_Real dfuave = 0.5 * ( myumin + myumax );
-      Standard_Real dfvave = 0.5 * ( myvmin + myvmax );
-      Standard_Real dfucur, dfvcur;
-
-      // U loop
-      gFace->D0(myumin, myvmin, P11);
-      gFace->D0(myumin, dfvave, P21);
-      gFace->D0(myumin, myvmax, P31);
-      for (i1=1, dfucur=myumin+du; i1 <= 20; i1++, dfucur+=du)
-      {
-        gFace->D0(dfucur, myvmin, P12);
-        gFace->D0(dfucur, dfvave, P22);
-        gFace->D0(dfucur, myvmax, P32);
-        longu += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
-        P11 = P12;
-        P21 = P22;
-        P31 = P32;
-      }
-
-      // V loop
-      gFace->D0(myumin, myvmin, P11);
-      gFace->D0(dfuave, myvmin, P21);
-      gFace->D0(myumax, myvmin, P31);
-      for (i1=1, dfvcur=myvmin+dv; i1 <= 20; i1++, dfvcur+=dv)
-      {
-        gFace->D0(myumin, dfvcur, P12);
-        gFace->D0(dfuave, dfvcur, P22);
-        gFace->D0(myumax, dfvcur, P32);
-        longv += ( P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32) );
-        P11 = P12;
-        P21 = P22;
-        P31 = P32;
-      }
-
-      longu /= 3.;
-      longv /= 3.;
-      // akm (bug OCC16) ^^^^^
-
-      if (longu <= 1.e-16 || longv <= 1.e-16)
-      {
-        //yes, it is seen!!
-        myAttribute->ChangeStructure().Nullify();
-        myAttribute->SetStatus(BRepMesh_Failure);
-        return myAttribute->GetStatus();
-      }
-
-
-      if (aSurfType == GeomAbs_Torus)
-      {
-        gp_Torus Tor = gFace->Torus();
-        Standard_Real r = Tor.MinorRadius(), R = Tor.MajorRadius();
-        Standard_Real Du, Dv;//, pasu, pasv;
-
-        Dv = Max(1.0e0 - (defface/r),0.0e0) ;
-        Standard_Real oldDv = 2.0 * ACos (Dv);
-        oldDv = Min(oldDv, myParameters.Angle);
-        Dv  =  0.9*oldDv; //TWOTHIRD * oldDv;
-        Dv = oldDv;
-
-        Standard_Integer nbV = Max((Standard_Integer)((myvmax-myvmin)/Dv), 2);
-        Dv = (myvmax-myvmin)/(nbV+1);
-
-        Standard_Real ru = R + r;
-        if ( ru > 1.e-16 )
-        {
-          Du = Max(1.0e0 - (defface/ru),0.0e0);
-          Du  = (2.0 * ACos (Du));
-          Du = Min(Du, myParameters.Angle);
-          Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
-
-          if (aa < gp::Resolution())
-          {
-            myAttribute->ChangeStructure().Nullify();
-            return myAttribute->GetStatus();
-          }
-
-          Du = Du * Min(oldDv, Du) / aa;
-        }
-        else
-        {
-          Du = Dv;
-        }
-
-        Standard_Integer nbU = Max((Standard_Integer)((myumax-myumin)/Du), 2);
-        nbU = Max(nbU, (Standard_Integer)(nbV*(myumax-myumin)*R/((myvmax-myvmin)*r)/5.));
-      
-        Du = (myumax-myumin)/(nbU+1);
-        //-- DeltaX and DeltaY are chosen so that to avoid "jumping" 
-        //-- of points on the grid
-        deltaX = Du;
-        deltaY = Dv;
-      }
-      else if (aSurfType == GeomAbs_Cylinder)
-      {
-        gp_Cylinder Cyl = gFace->Cylinder();
-        Standard_Real R = Cyl.Radius();
-
-        // Calculate parameters for iteration in U direction
-        Standard_Real Du = 1.0 - (defface/R);
-        if (Du < 0.0)
-          Du = 0.0;
-
-        Du = 2.0 * ACos (Du);
-        if (Du > myParameters.Angle)
-          Du = myParameters.Angle;
-
-        deltaX = Du / longv;
-        deltaY = 1.;
-      }
-      else
-      {
-        deltaX = (myumax-myumin)/longu;
-        deltaY = (myvmax-myvmin)/longv;
-      }
-
-      // Restore face attribute
-      myAttribute->SetDefFace(defface);
-      myAttribute->SetUMax(myumax);
-      myAttribute->SetVMax(myvmax);
-      myAttribute->SetUMin(myumin);
-      myAttribute->SetVMin(myvmin);
-      myAttribute->SetDeltaX(deltaX);
-      myAttribute->SetDeltaY(deltaY);
-    }
-
-    myAttribute->ChangeMeshNodes() = 
-      myAttribute->ChangeStructure()->Data()->Vertices();
-  }
-  catch(Standard_Failure)
-  {
-    myAttribute->SetStatus(BRepMesh_Failure);
-  }
-
-  myAttribute->ChangeStructure().Nullify();
-  return myAttribute->GetStatus();
-}
-
-//=======================================================================
-//function : getEdgeAttributes
-//purpose  :
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes(
-  const TopoDS_Edge&                      theEdge,
-  const Handle(Geom2dAdaptor_HCurve)&     thePCurve,
-  const Standard_Real                     theDefEdge,
-  BRepMesh_FastDiscret::EdgeAttributes&   theAttributes) const
-{
-  EdgeAttributes& aEAttr = theAttributes;
-
-  // Get vertices
-  TopExp::Vertices(theEdge, aEAttr.FirstVertex, aEAttr.LastVertex);
-  if (aEAttr.FirstVertex.IsNull() || aEAttr.LastVertex.IsNull())
-    return Standard_False;
-
-  // Get range on 2d curve
-  const TopoDS_Face& aFace = myAttribute->Face();
-  BRep_Tool::Range(theEdge, aFace, aEAttr.FirstParam, aEAttr.LastParam);
-
-  // Get end points on 2d curve
-  BRep_Tool::UVPoints(theEdge, aFace, aEAttr.FirstUV, aEAttr.LastUV);
-
-  aEAttr.IsSameUV =
-    aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
-  if (aEAttr.IsSameUV)
-  {
-    // 1. is it really sameUV without being degenerated
-    gp_Pnt2d uvF, uvL;
-    thePCurve->D0(thePCurve->FirstParameter(), uvF);
-    thePCurve->D0(thePCurve->LastParameter(),  uvL);
-
-    if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion()))
-      aEAttr.FirstUV = uvF;
-
-    if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion()))
-      aEAttr.LastUV = uvL;
-
-    aEAttr.IsSameUV =
-      aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion());
-  }
-
-  //Control tolerance of vertices
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
-  gp_Pnt pLast  = gFace->Value(aEAttr.LastUV.X(),  aEAttr.LastUV.Y());
-
-  Standard_Real aSqDist = pFirst.SquareDistance(BRep_Tool::Pnt(aEAttr.FirstVertex));
-  aSqDist = Max(aSqDist, pLast.SquareDistance(BRep_Tool::Pnt(aEAttr.LastVertex)));
-
-  aEAttr.Deflection = Max(theDefEdge, BRep_Tool::Tolerance(theEdge));
-  aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : registerEdgeVertices
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::registerEdgeVertices(
-  BRepMesh_FastDiscret::EdgeAttributes& theAttributes,
-  Standard_Integer&                     ipf,
-  Standard_Integer&                     ivf,
-  Standard_Integer&                     isvf,
-  Standard_Integer&                     ipl,
-  Standard_Integer&                     ivl,
-  Standard_Integer&                     isvl)
-{
-  EdgeAttributes& aEAttr = theAttributes;
-  if (aEAttr.FirstVExtractor.IsNull())
-  {
-    // Use edge geometry to produce tesselation.
-    aEAttr.FirstVExtractor = 
-      new TopoDSVExplorer(aEAttr.FirstVertex, aEAttr.IsSameUV, aEAttr.LastVertex);
-  }
-
-  if (aEAttr.LastVExtractor.IsNull())
-  {
-    // Use edge geometry to produce tesselation.
-    aEAttr.LastVExtractor = 
-      new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex);
-  }
-
-  // Process first vertex
-  ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True);
-  Standard_Real aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.FirstVertex);
-  gp_XY aTmpUV1 = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aMinDist, myAttribute);
-
-  myAttribute->AddNode(ipf, aTmpUV1, BRepMesh_Frontier, ivf, isvf);
-
-  // Process last vertex
-  ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf :
-    myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True);
-  aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.LastVertex);
-  gp_XY aTmpUV2 = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aMinDist, myAttribute);
-
-  myAttribute->AddNode(ipl, aTmpUV2, BRepMesh_Frontier, ivl, isvl);
-
-  // Update edge deflection
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  gp_Pnt aPntE1 = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y());
-  gp_Pnt aPntFound1 = gFace->Value(aTmpUV1.X(), aTmpUV1.Y());
-  Standard_Real aSqDist = aPntE1.SquareDistance(aPntFound1);
-  gp_Pnt aPntE2 = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y());
-  gp_Pnt aPntFound2 = gFace->Value(aTmpUV2.X(), aTmpUV2.Y());
-  aSqDist = Max(aSqDist, aPntE2.SquareDistance(aPntFound2));
-  aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist));
-}
-
-//=======================================================================
-//function : add
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::add(
-  const TopoDS_Edge&                      theEdge,
-  const Handle(Geom2dAdaptor_HCurve)&     thePCurve,
-  const Standard_Real                     theDefEdge)
-{
-  const TopAbs_Orientation orEdge = theEdge.Orientation();
-  if (orEdge == TopAbs_EXTERNAL)
-    return;
-
-  EdgeAttributes aEAttr;
-  if (!getEdgeAttributes(theEdge, thePCurve, theDefEdge, aEAttr))
-    return;
-
-  if (!myEdges.IsBound(theEdge))
-  {
-    update(theEdge, thePCurve, theDefEdge, aEAttr);
-    return;
-  }
-
-  Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
-  registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
-
-  // If this Edge has been already checked and it is not degenerated, 
-  // the points of the polygon calculated at the first check are retrieved :
-
-  // retrieve the polygone:
-  const BRepMesh_PairOfPolygon&              aPair    = myEdges.Find(theEdge);
-  const Handle(Poly_PolygonOnTriangulation)& aPolygon = aPair.First();
-  const TColStd_Array1OfInteger&             aNodes   = aPolygon->Nodes();
-  Handle(TColStd_HArray1OfReal)              aParams  = aPolygon->Parameters();
-
-  // creation anew:
-  const Standard_Integer  aNodesNb = aNodes.Length();
-  TColStd_Array1OfInteger aNewNodes (1, aNodesNb);
-  TColStd_Array1OfReal    aNewParams(1, aNodesNb);
-
-  aNewNodes (1) = isvf;
-  aNewParams(1) = aEAttr.FirstParam;
-
-  aNewNodes (aNodesNb) = isvl;
-  aNewParams(aNodesNb) = aEAttr.LastParam;
-
-  const TopoDS_Face& aFace = myAttribute->Face();
-  if (!BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
-  {
-    BRepMesh_EdgeParameterProvider aProvider(theEdge, aFace, aParams);
-    for (Standard_Integer i = 2; i < aNodesNb; ++i)
-    {
-      const Standard_Integer aPointId = aNodes(i);
-      const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId);
-
-      const Standard_Real aParam = aProvider.Parameter(i, aPnt);
-      gp_Pnt2d aUV = thePCurve->Value(aParam);
-
-      Standard_Integer iv2, isv;
-      myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv);
-
-      aNewNodes (i) = isv;
-      aNewParams(i) = aParam;
-    }
-  }
-
-  Handle(Poly_PolygonOnTriangulation) P1 = 
-    new Poly_PolygonOnTriangulation(aNewNodes, aNewParams);
-
-  storePolygon(theEdge, P1, aEAttr.Deflection);
-}
-
-//=======================================================================
-//function : update(edge)
-//purpose  :
-//=======================================================================
-void BRepMesh_FastDiscret::update(
-  const TopoDS_Edge&                                theEdge,
-  const Handle(Geom2dAdaptor_HCurve)&               theC2d,
-  const Standard_Real                               theDefEdge,
-  BRepMesh_FastDiscret::EdgeAttributes&             theAttributes)
-{
-  EdgeAttributes& aEAttr = theAttributes;
-
-  const TopoDS_Face& aFace = myAttribute->Face();
-  Handle(BRepMesh_IEdgeTool) aEdgeTool;
-  // Try to find existing tessellation.
-  for (Standard_Integer i = 1; aEdgeTool.IsNull(); ++i)
-  {
-    TopLoc_Location aLoc;
-    Handle(Poly_Triangulation) aTriangulation;
-    Handle(Poly_PolygonOnTriangulation) aPolygon;
-    BRep_Tool::PolygonOnTriangulation(theEdge, aPolygon, aTriangulation, aLoc, i);
-
-    if (aPolygon.IsNull())
-      break;
-
-    if (aTriangulation.IsNull() || !aPolygon->HasParameters())
-      continue;
-
-    if (aPolygon->Deflection() > 1.1 * theDefEdge)
-      continue;
-
-    const TColgp_Array1OfPnt&      aNodes   = aTriangulation->Nodes();
-    const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
-    Handle(TColStd_HArray1OfReal)  aParams  = aPolygon->Parameters();
-
-    aEAttr.FirstVExtractor = new PolyVExplorer(aEAttr.FirstVertex, 
-      aEAttr.IsSameUV, aEAttr.LastVertex, aIndices(1), aNodes, aLoc);
-
-    aEAttr.LastVExtractor = new PolyVExplorer(aEAttr.LastVertex, 
-      aEAttr.IsSameUV, aEAttr.FirstVertex, aIndices(aIndices.Length()), aNodes, aLoc);
-
-    aEdgeTool = new BRepMesh_EdgeTessellationExtractor(theEdge, theC2d, 
-      aFace, aTriangulation, aPolygon, aLoc);
-  }
-
-  if (aEdgeTool.IsNull())
-  {
-    aEdgeTool = new BRepMesh_EdgeTessellator(theEdge, myAttribute, 
-      mySharedFaces, theDefEdge, myParameters.Angle, myParameters.MinSize);
-  }
-
-  Standard_Integer ipf, ivf, isvf, ipl, ivl, isvl;
-  registerEdgeVertices(aEAttr, ipf, ivf, isvf, ipl, ivl, isvl);
-
-  Handle(Poly_PolygonOnTriangulation) P1, P2;
-  if (BRepMesh_ShapeTool::IsDegenerated(theEdge, aFace))
-  {
-    // two nodes
-    Standard_Integer aNewNodesArr[] = {isvf, isvl};
-    Standard_Integer aNewNodInStructArr[] = {ipf, ipl};
-    Standard_Real aNewParamsArr[] = {aEAttr.FirstParam, aEAttr.LastParam};
-    TColStd_Array1OfInteger aNewNodes      (aNewNodesArr[0], 1, 2);
-    TColStd_Array1OfInteger aNewNodInStruct(aNewNodInStructArr[0], 1, 2);
-    TColStd_Array1OfReal    aNewParams     (aNewParamsArr[0], 1, 2);
-
-    P1 = new Poly_PolygonOnTriangulation(aNewNodes,       aNewParams);
-    P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
-  }
-  else
-  {
-    const Standard_Integer  aNodesNb = aEdgeTool->NbPoints();
-    // Allocate the memory for arrays aNewNodesVec, aNewNodesInStructVec, aNewParamsVec
-    // only once using the buffer aBuf.
-    TColStd_Array1OfCharacter aBuf(1, aNodesNb * (2*sizeof(Standard_Integer) + sizeof(Standard_Real)));
-    TColStd_Array1OfInteger aNewNodesVec(*reinterpret_cast<const Standard_Integer*>
-      (&aBuf(1)), 1, aNodesNb);
-    TColStd_Array1OfInteger aNewNodesInStructVec(*reinterpret_cast<const Standard_Integer*>
-      (&aBuf(1 + aNodesNb*sizeof(Standard_Integer))), 1, aNodesNb);
-    TColStd_Array1OfReal    aNewParamsVec(*reinterpret_cast<const Standard_Real*>
-      (&aBuf(1 + aNodesNb*2*sizeof(Standard_Integer))), 1, aNodesNb);
-
-    Standard_Integer aNodesCount = 1;
-    aNewNodesInStructVec(aNodesCount) = ipf;
-    aNewNodesVec        (aNodesCount) = isvf;
-    aNewParamsVec       (aNodesCount) = aEAttr.FirstParam;
-
-    ++aNodesCount;
-    Standard_Integer aPrevNodeId  = ivf;
-    Standard_Integer aLastPointId = myAttribute->LastPointId();
-    for (Standard_Integer i = 2; i < aNodesNb; ++i)
-    {
-      gp_Pnt        aPnt;
-      gp_Pnt2d      aUV;
-      Standard_Real aParam;
-      if (!aEdgeTool->Value(i, aParam, aPnt, aUV))
-        continue;
-
-      // Imitate index of 3d point in order to not to add points to map without necessity.
-      Standard_Integer iv2, isv;
-      myAttribute->AddNode(aLastPointId + 1, aUV.Coord(), BRepMesh_Frontier, iv2, isv);
-      if (aPrevNodeId == iv2)
-        continue;
-
-      // Ok, now we can add point to the map.
-      myBoundaryPoints->Bind (++aLastPointId, aPnt);
-
-      aNewNodesInStructVec(aNodesCount) = aLastPointId;
-      aNewNodesVec        (aNodesCount) = isv;
-      aNewParamsVec       (aNodesCount) = aParam;
-
-      ++aNodesCount;
-      aPrevNodeId = iv2;
-    }
-
-    aNewNodesInStructVec(aNodesCount) = ipl;
-    aNewNodesVec        (aNodesCount) = isvl;
-    aNewParamsVec       (aNodesCount) = aEAttr.LastParam;
-
-    TColStd_Array1OfInteger aNewNodes      (aNewNodesVec.First (),        1, aNodesCount);
-    TColStd_Array1OfInteger aNewNodInStruct(aNewNodesInStructVec.First(), 1, aNodesCount);
-    TColStd_Array1OfReal    aNewParams     (aNewParamsVec.First(),        1, aNodesCount);
-
-    P1 = new Poly_PolygonOnTriangulation(aNewNodes,       aNewParams);
-    P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams);
-  }
-
-  storePolygon(theEdge, P1, aEAttr.Deflection);
-  storePolygonSharedData(theEdge, P2, aEAttr.Deflection);
-}
-
-//=======================================================================
-//function : storeInternalPolygon
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::storePolygon(
-  const TopoDS_Edge&                         theEdge,
-  Handle(Poly_PolygonOnTriangulation)&       thePolygon,
-  const Standard_Real                        theDeflection)
-{
-  thePolygon->Deflection(theDeflection);
-  BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
-  if (aInternalEdges->IsBound(theEdge))
-  {
-    BRepMesh_PairOfPolygon& aPair = aInternalEdges->ChangeFind(theEdge);
-    if (theEdge.Orientation() == TopAbs_REVERSED)
-      aPair.Append(thePolygon);
-    else
-      aPair.Prepend(thePolygon);
-
-    return;
-  }
-
-  BRepMesh_PairOfPolygon aPair;
-  aPair.Append(thePolygon);
-  aInternalEdges->Bind(theEdge, aPair);
-}
-
-//=======================================================================
-//function : storePolygonSharedData
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::storePolygonSharedData(
-  const TopoDS_Edge&                         theEdge,
-  Handle(Poly_PolygonOnTriangulation)&       thePolygon,
-  const Standard_Real                        theDeflection)
-{
-  thePolygon->Deflection(theDeflection);
-  BRepMesh_PairOfPolygon aPair;
-  aPair.Append(thePolygon);
-  myEdges.Bind(theEdge, aPair);
-}
-
-//=======================================================================
-//function : GetFaceAttribute
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscret::GetFaceAttribute(
-  const TopoDS_Face&              theFace,
-  Handle(BRepMesh_FaceAttribute)& theAttribute,
-  const Standard_Boolean          isForceCreate) const
-{
-  if (myAttributes.IsBound(theFace))
-  {
-    theAttribute = myAttributes(theFace);
-    return Standard_True;
-  }
-  else if (isForceCreate)
-  {
-    theAttribute = new BRepMesh_FaceAttribute(myBoundaryVertices, myBoundaryPoints);
-    myAttributes.Bind(theFace, theAttribute);
-  }
-
-  return Standard_False;
-}
-
-//=======================================================================
-//function : RemoveFaceAttribute
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscret::RemoveFaceAttribute(const TopoDS_Face& theFace)
-{
-  if (myAttributes.IsBound(theFace))
-    myAttributes.UnBind(theFace);
-}
index 87cc55587d2f21a5c6ca0620f2445bfdf792def3..c21e20a753789891cf8a2eb876ee5999febf9597 100644 (file)
 #ifndef _BRepMesh_FastDiscret_HeaderFile
 #define _BRepMesh_FastDiscret_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-#include <BRepMesh_FastDiscret.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
-#include <BRepMesh_Status.hxx>
-#include <TopTools_DataMapOfShapeReal.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_MutexForShapeProvider.hxx>
-#include <Standard_Transient.hxx>
-#include <BRepMesh_Delaun.hxx>
-#include <TopAbs_ShapeEnum.hxx>
-#include <BRepMesh_Triangle.hxx>
-#include <BRepMesh_FaceAttribute.hxx>
-#include <BRepMesh.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepMesh_ShapeTool.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <IMeshTools_Parameters.hxx>
 
-class BRepMesh_DataStructureOfDelaun;
-class Bnd_Box;
-class TopoDS_Shape;
-class TopoDS_Face;
-class TopoDS_Edge;
-class Geom2dAdaptor_HCurve;
-class BRepAdaptor_HSurface;
-class BRepMesh_Edge;
-class BRepMesh_Vertex;
-class gp_Pnt;
-class BRepMesh_FaceAttribute;
-class Message_ProgressSentry;
-
-//! Algorithm to mesh a shape with respect of the <br>
-//! frontier the deflection and by option the shared <br>
-//! components. <br>
-class BRepMesh_FastDiscret : public Standard_Transient
+class Standard_DEPRECATED("The class BRepMesh_FastDiscret is deprecated. Please use IMeshTools package") BRepMesh_FastDiscret
 {
 public:
-
-
-  //! Structure storing meshing parameters
-  struct Parameters {
-
-    //! Default constructor
-    Parameters()
-      :
-     Angle(0.1),
-     Deflection(0.001),
-     MinSize(Precision::Confusion()),
-     InParallel(Standard_False),
-     Relative(Standard_False),
-     AdaptiveMin(Standard_False),
-     InternalVerticesMode(Standard_True),
-     ControlSurfaceDeflection(Standard_True)
-     {
-     }
-    
-    //! Angular deflection
-    Standard_Real                                    Angle;
-    
-    //! Deflection
-    Standard_Real                                    Deflection;  
-
-    //! Minimal allowed size of mesh element
-    Standard_Real                                    MinSize; 
-
-    //! Switches on/off multy thread computation
-    Standard_Boolean                                 InParallel; 
-
-    //! Switches on/off relative computation of edge tolerance<br>
-    //! If trur, 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;
-
-    //! Adaptive parametric tolerance flag. <br>
-    //! If this flag is set to true the minimal parametric tolerance
-    //! is computed taking minimal parametric distance between vertices
-    //! into account
-    Standard_Boolean                                 AdaptiveMin;
-
-    //! Mode to take or ont to take internal face vertices into account
-    //! in triangulation process
-    Standard_Boolean                                 InternalVerticesMode;
-
-    //! Prameter to check the deviation of triangulation and interior of
-    //! the face
-    Standard_Boolean                                 ControlSurfaceDeflection;
-  };
-
-public:
-  
-  
-  //! Constructor. 
-  //! Sets the meshing parameters and updates
-  //! relative defletion according to bounding box
-  //! @param B - bounding box encompasing shape
-  //! @param theParams - meshing algo parameters    
-  Standard_EXPORT BRepMesh_FastDiscret (const Bnd_Box& B,
-                                        const Parameters& theParams);
-
-  //! Build triangulation on the whole shape.
-  Standard_EXPORT void Perform(const TopoDS_Shape& shape);
-
-  //! Record a face for further processing.
-  //! @return status flags collected during discretization 
-  //! of boundaries of the given face.
-  Standard_EXPORT Standard_Integer Add(const TopoDS_Face& face);
-
-  //! Triangulate a face previously recorded for 
-  //! processing by call to Add(). Can be executed in 
-  //! parallel threads.
-  Standard_EXPORT void Process(const TopoDS_Face& face) const;
-
-  //! Triangulate a face previously recorded for
-  //! processing by call to Add(). Can be executed in
-  //! parallel threads.
-  Standard_EXPORT void Process (const TopoDS_Face& theFace,
-                                Message_ProgressSentry* theProgrEntry) const;
-
-  void operator () (const TopoDS_Face& face) const
-  {
-    Process(face);
-  }
-  
-  //! Returns parameters of meshing
-  inline const Parameters& MeshParameters() const
-  {
-    return myParameters;
-  }
-
-  //! Returns modificable mesh parameters
-  inline Parameters& ChangeMeshParameters()
-  {
-    return myParameters;
-  }
-    
-  
-  Standard_EXPORT void InitSharedFaces(const TopoDS_Shape& theShape);
-
-  inline const TopTools_IndexedDataMapOfShapeListOfShape& SharedFaces() const
-  {
-    return mySharedFaces;
-  }
-
-  //! Returns attribute descriptor for the given face.
-  //! @param theFace face the attribute should be returned for.
-  //! @param[out] theAttribute attribute found for the specified face.
-  //! @param isForceCreate if True creates new attribute in case if there 
-  //! is no data for the given face.
-  Standard_EXPORT Standard_Boolean GetFaceAttribute (
-    const TopoDS_Face&              theFace, 
-    Handle(BRepMesh_FaceAttribute)& theAttribute,
-    const Standard_Boolean          isForceCreate = Standard_False) const;
-
-  //! Remove face attribute as useless to free locate memory.
-  Standard_EXPORT void RemoveFaceAttribute( const TopoDS_Face& theFace );
-
-  //! Returns number of boundary 3d points.
-  inline Standard_Integer NbBoundaryPoints() const
-  {
-    return myBoundaryPoints->Extent();
-  }
-
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscret,Standard_Transient)
-
-private:
-
-  //! Auxiliary class used to extract geometrical parameters of TopoDS_Vertex.
-  class TopoDSVExplorer
-  {
-  public:
-    TopoDSVExplorer(
-      const TopoDS_Vertex&   theVertex,
-      const Standard_Boolean isSameUV,
-      const TopoDS_Vertex&   theSameVertex)
-      : myVertex(theVertex),
-        myIsSameUV(isSameUV),
-        mySameVertex(theSameVertex)
-    {
-    }
-    virtual ~TopoDSVExplorer() {
-    }
-    const TopoDS_Vertex& Vertex() const
-    {
-      return myVertex;
-    }
-
-    Standard_Boolean IsSameUV() const
-    {
-      return myIsSameUV;
-    }
-
-    const TopoDS_Vertex& SameVertex() const
-    {
-      return mySameVertex;
-    }
-
-    virtual gp_Pnt Point() const
-    {
-      return BRep_Tool::Pnt(myVertex);
-    }
-
-  private:
-
-    void operator =(const TopoDSVExplorer& /*theOther*/)
-    {
-    }
-
-  private:
-    const TopoDS_Vertex& myVertex;
-    Standard_Boolean     myIsSameUV;
-    const TopoDS_Vertex& mySameVertex;
-  };
-
-
-  //! Auxiliary class used to extract polygonal parameters of TopoDS_Vertex.
-  class PolyVExplorer : public TopoDSVExplorer
-  {
-  public:
-    PolyVExplorer(
-      const TopoDS_Vertex&      theVertex,
-      const Standard_Boolean    isSameUV,
-      const TopoDS_Vertex&      theSameVertex,
-      const Standard_Integer    theVertexIndex,
-      const TColgp_Array1OfPnt& thePolygon,
-      const TopLoc_Location&    theLoc)
-      : TopoDSVExplorer(theVertex, isSameUV, theSameVertex),
-        myVertexIndex(theVertexIndex),
-        myPolygon(thePolygon),
-        myLoc(theLoc)
-    {
-    }
-
-    virtual gp_Pnt Point() const
-    {
-      return BRepMesh_ShapeTool::UseLocation(myPolygon(myVertexIndex), myLoc);
-    }
-
-  private:
-
-    void operator =(const PolyVExplorer& /*theOther*/)
-    {
-    }
-
-  private:
-    Standard_Integer          myVertexIndex;
-    const TColgp_Array1OfPnt& myPolygon;
-    const TopLoc_Location     myLoc;
-  };
-
-  //! Structure keeps common parameters of edge
-  //! used for tessellation.
-  struct EdgeAttributes
-  {
-    TopoDS_Vertex                       FirstVertex;
-    TopoDS_Vertex                       LastVertex;
-
-    Standard_Real                       FirstParam;
-    Standard_Real                       LastParam;
-
-    gp_Pnt2d                            FirstUV;
-    gp_Pnt2d                            LastUV;
-
-    Standard_Real                       Deflection;
-    Standard_Boolean                    IsSameUV;
-
-    NCollection_Handle<TopoDSVExplorer> FirstVExtractor;
-    NCollection_Handle<TopoDSVExplorer> LastVExtractor;
-  };
-
-  //! Fills structure of by attributes of the given edge.
-  //! @return TRUE on success, FALSE elsewhere.
-  Standard_Boolean getEdgeAttributes(
-    const TopoDS_Edge&  theEdge,
-    const Handle(Geom2dAdaptor_HCurve)& thePCurve,
-    const Standard_Real theDefEdge,
-    EdgeAttributes&     theAttributes) const;
-
-  //! Registers end vertices of the edge in mesh data 
-  //! structure of currently processed face.
-  void registerEdgeVertices(
-    EdgeAttributes&   theAttributes,
-    Standard_Integer& ipf,
-    Standard_Integer& ivf, 
-    Standard_Integer& isvf,
-    Standard_Integer& ipl,
-    Standard_Integer& ivl,
-    Standard_Integer& isvl);
-
-  //! Adds tessellated representation of the given edge to
-  //! mesh data structure of currently processed face.
-  void add(const TopoDS_Edge&  theEdge,
-           const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
-           const Standard_Real theEdgeDeflection);
-
-  //! Updates tessellated representation of the given edge.
-  //! If edge already has a polygon which deflection satisfies
-  //! the given value, retrieves tessellation from polygon.
-  //! Computes tessellation using edge's geometry elsewhere.
-  void update(
-    const TopoDS_Edge&          theEdge,
-    const Handle(Geom2dAdaptor_HCurve)& theCurve2D,
-    const Standard_Real         theEdgeDeflection,
-    EdgeAttributes&             theAttributes);
-
-  //! Stores polygonal model of the given edge.
-  //! @param theEdge edge which polygonal model is stored.
-  //! @param thePolygon polygonal model of the edge.
-  //! @param theDeflection deflection with which polygonalization is performed.
-  //! This value is stored inside the polygon.
-  void storePolygon(
-    const TopoDS_Edge&                         theEdge,
-    Handle(Poly_PolygonOnTriangulation)&       thePolygon,
-    const Standard_Real                        theDeflection);
-
-  //! Caches polygonal model of the given edge to be used in further.
-  //! @param theEdge edge which polygonal data is stored.
-  //! @param thePolygon shared polygonal data of the edge.
-  //! @param theDeflection deflection with which polygonalization is performed.
-  //! This value is stored inside the polygon.
-  void storePolygonSharedData(
-    const TopoDS_Edge&                         theEdge,
-    Handle(Poly_PolygonOnTriangulation)&       thePolygon,
-    const Standard_Real                        theDeflection);
-
-  //! Resets temporary data structure used to collect unique nodes.
-  void resetDataStructure();
-
-private:
-
-  TopoDS_Face                                      myFace;
-
-  BRepMesh::DMapOfShapePairOfPolygon               myEdges;
-  mutable BRepMesh::DMapOfFaceAttribute            myAttributes;
-  TopTools_DataMapOfShapeReal                      myMapdefle;
-
-  // Data shared for whole shape
-  BRepMesh::HDMapOfVertexInteger                   myBoundaryVertices;
-  BRepMesh::HDMapOfIntegerPnt                      myBoundaryPoints;
-
-  // Fast access to attributes of current face
-  Handle(BRepMesh_FaceAttribute)                   myAttribute;
-  TopTools_IndexedDataMapOfShapeListOfShape        mySharedFaces;
-
-  Parameters                                       myParameters;
-
-  Standard_Real                                    myDtotale;
+  Standard_DEPRECATED("The class BRepMesh_FastDiscret is deprecated. Please use IMeshTools package")
+  typedef  IMeshTools_Parameters  Parameters;
 };
 
-DEFINE_STANDARD_HANDLE(BRepMesh_FastDiscret, Standard_Transient)
-
 #endif
diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx
deleted file mode 100644 (file)
index ed13287..0000000
+++ /dev/null
@@ -1,1585 +0,0 @@
-// Created by: Ekaterina SMIRNOVA
-// Copyright (c) 2008-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.
-
-#include <BRepMesh_FastDiscretFace.hxx>
-
-#include <BRepMesh_PairOfPolygon.hxx>
-#include <BRepMesh_ShapeTool.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-#include <Poly_Triangulation.hxx>
-
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <Adaptor3d_IsoCurve.hxx>
-
-#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
-#include <BRep_PointRepresentation.hxx>
-#include <BRep_TVertex.hxx>
-#include <BRep_Tool.hxx>
-
-#include <GeomLib.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_BSplineSurface.hxx>
-#include <Geom_BezierSurface.hxx>
-#include <GCPnts_TangentialDeflection.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_ListOfInteger.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TopTools_DataMapOfShapeReal.hxx>
-
-#include <TopExp_Explorer.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopExp.hxx>
-
-#include <Message_ProgressSentry.hxx>
-#include <NCollection_Map.hxx>
-#include <Bnd_Box2d.hxx>
-
-#include <algorithm>
-
-//#define DEBUG_MESH "mesh.tcl"
-#ifdef DEBUG_MESH
-#include <fstream>
-#endif
-
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
-
-static Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen)
-{
-  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.);
-}
-
-namespace
-{
-  Standard_Real deflectionOfSegment (
-    const gp_Pnt& theFirstPoint,
-    const gp_Pnt& theLastPoint,
-    const gp_Pnt& theMidPoint)
-  {
-    // 23.03.2010 skl for OCC21645 - change precision for comparison
-    if (theFirstPoint.SquareDistance (theLastPoint) > Precision::SquareConfusion ())
-    {
-      gp_Lin aLin (theFirstPoint, gp_Dir (gp_Vec (theFirstPoint, theLastPoint)));
-      return aLin.Distance (theMidPoint);
-    }
-
-    return theFirstPoint.Distance (theMidPoint);
-  }
-
-  Standard_Boolean IsCompexSurface (const GeomAbs_SurfaceType theType)
-  {
-    return (
-      theType != GeomAbs_Sphere   &&
-      theType != GeomAbs_Cylinder &&
-      theType != GeomAbs_Cone     &&
-      theType != GeomAbs_Torus);
-  }
-
-  //! Auxiliary class used to extract geometrical parameters of fixed TopoDS_Vertex.
-  class FixedVExplorer
-  {
-  public:
-
-    DEFINE_STANDARD_ALLOC
-
-    FixedVExplorer(const TopoDS_Vertex& theVertex)
-      : myVertex(theVertex)
-    {
-    }
-
-    const TopoDS_Vertex& Vertex() const
-    {
-      return myVertex;
-    }
-
-    Standard_Boolean IsSameUV() const
-    {
-      return Standard_False;
-    }
-
-    TopoDS_Vertex SameVertex() const
-    {
-      return TopoDS_Vertex();
-    }
-
-    gp_Pnt Point() const
-    {
-      return BRep_Tool::Pnt(myVertex);
-    }
-
-  private:
-
-    void operator =(const FixedVExplorer& /*theOther*/)
-    {
-    }
-
-  private:
-    const TopoDS_Vertex& myVertex;
-  };
-}
-
-
-//=======================================================================
-//function : BRepMesh_FastDiscretFace
-//purpose  :
-//=======================================================================
-BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace(
-  const Standard_Real    theAngle,
-  const Standard_Real    theMinSize,
-  const Standard_Boolean isInternalVerticesMode,
-  const Standard_Boolean isControlSurfaceDeflection)
-: myAngle(theAngle),
-  myInternalVerticesMode(isInternalVerticesMode),
-  myMinSize(theMinSize),
-  myIsControlSurfaceDeflection(isControlSurfaceDeflection)
-{
-}
-
-//=======================================================================
-//function : Perform
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute)
-{
-  Perform (theAttribute, NULL);
-}
-
-//=======================================================================
-//function : Perform
-//purpose  :
-//=======================================================================
-void BRepMesh_FastDiscretFace::Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
-                                        Message_ProgressSentry*               theProgressEntry)
-{
-  add(theAttribute, theProgressEntry);
-  if (theProgressEntry != NULL && !theProgressEntry->More())
-  {
-    return;
-  }
-  commitSurfaceTriangulation();
-}
-
-//=======================================================================
-//function : initDataStructure
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::initDataStructure()
-{
-  const Standard_Real aTolU = myAttribute->ToleranceU();
-  const Standard_Real aTolV = myAttribute->ToleranceV();
-  const Standard_Real uCellSize = 14.0 * aTolU;
-  const Standard_Real vCellSize = 14.0 * aTolV;
-
-  const Standard_Real deltaX = myAttribute->GetDeltaX();
-  const Standard_Real deltaY = myAttribute->GetDeltaY();
-
-  Handle(NCollection_IncAllocator) aAllocator = 
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-  myStructure = new BRepMesh_DataStructureOfDelaun(aAllocator);
-  myStructure->Data()->SetCellSize ( uCellSize / deltaX, vCellSize / deltaY);
-  myStructure->Data()->SetTolerance( aTolU     / deltaX, aTolV     / deltaY);
-
-  myAttribute->ChangeStructure() = myStructure;
-  myAttribute->ChangeSurfacePoints() = new BRepMesh::DMapOfIntegerPnt(1, aAllocator);
-  myAttribute->ChangeSurfaceVertices()= new BRepMesh::DMapOfVertexInteger(1, aAllocator);
-
-  // Check the necessity to fill the map of parameters
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  GeomAbs_SurfaceType thetype = gFace->GetType();
-  const Standard_Boolean isBSpline = (thetype == GeomAbs_BezierSurface ||
-                                      thetype == GeomAbs_BSplineSurface);
-  const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || IsCompexSurface (thetype));
-
-  Handle(NCollection_BaseAllocator) aBaseAlloc = aAllocator;
-  myUParam.Clear (aBaseAlloc);
-  myVParam.Clear (aBaseAlloc);
-
-  // essai de determination de la longueur vraie:
-  // akm (bug OCC16) : We must calculate these measures in non-singular
-  //     parts of face. Let`s try to compute average value of three
-  //     (umin, (umin+umax)/2, umax), and respectively for v.
-  //                 vvvvv
-  //Standard_Real longu = 0.0, longv = 0.0; //, last , first;
-  //gp_Pnt P11, P12, P21, P22, P31, P32;
-  BRepMesh::HVectorOfVertex& aBoundaryNodes = myAttribute->ChangeMeshNodes();
-  BRepMesh::VectorOfVertex::Iterator aNodesIt(*aBoundaryNodes);
-  for (; aNodesIt.More(); aNodesIt.Next())
-  {
-    BRepMesh_Vertex& aNode = aNodesIt.ChangeValue();
-    gp_XY aPnt2d = aNode.Coord();
-
-    if (useUVParam)
-    {
-      myUParam.Add(aPnt2d.X());
-      myVParam.Add(aPnt2d.Y());
-    }
-
-    aNode.ChangeCoord() = myAttribute->Scale(aPnt2d, Standard_True);
-    myStructure->AddNode(aNode, Standard_True);
-  }
-  aBoundaryNodes.Nullify();
-
-  if (isBSpline)
-  {
-    const Standard_Real aRange[2][2] = {
-      {myAttribute->GetUMin(), myAttribute->GetUMax()},
-      {myAttribute->GetVMin(), myAttribute->GetVMax()}
-    };
-
-    const GeomAbs_Shape aContinuity = GeomAbs_CN;
-    for (Standard_Integer i = 0; i < 2; ++i)
-    {
-      const Standard_Boolean isU = (i == 0);
-      const Standard_Integer aIntervalsNb = isU ?
-        gFace->NbUIntervals(aContinuity) :
-        gFace->NbVIntervals(aContinuity);
-
-      BRepMesh::IMapOfReal& aParams = isU ? myUParam : myVParam;
-      if (aIntervalsNb < aParams.Size())
-        continue;
-
-      TColStd_Array1OfReal aIntervals(1, aIntervalsNb + 1);
-      if (isU)
-        gFace->UIntervals(aIntervals, aContinuity);
-      else
-        gFace->VIntervals(aIntervals, aContinuity);
-
-      for (Standard_Integer j = 1; j <= aIntervals.Upper(); ++j)
-      {
-        const Standard_Real aParam = aIntervals(j);
-        if (aParam > aRange[i][0] && aParam < aRange[i][1])
-          aParams.Add(aParam);
-      }
-    }
-  }
-
-  //////////////////////////////////////////////////////////// 
-  //add internal vertices after self-intersection check
-  if ( myInternalVerticesMode )
-  {
-    TopExp_Explorer anExplorer(myAttribute->Face(), TopAbs_VERTEX, TopAbs_EDGE);
-    for ( ; anExplorer.More(); anExplorer.Next() )
-      add(TopoDS::Vertex(anExplorer.Current()));
-  }
-
-  const BRepMesh::HDMapOfShapePairOfPolygon& aEdges = myAttribute->ChangeInternalEdges();
-  TopExp_Explorer aWireIt(myAttribute->Face(), TopAbs_WIRE);
-  for (; aWireIt.More(); aWireIt.Next())
-  {
-    TopExp_Explorer aEdgeIt(aWireIt.Current(), TopAbs_EDGE);
-    for (; aEdgeIt.More(); aEdgeIt.Next())
-    {
-      const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-      BRepMesh_PairOfPolygon aPair;
-      if (!aEdges->Find(aEdge, aPair))
-        continue;
-
-      TopAbs_Orientation aOri = aEdge.Orientation();
-      const Handle(Poly_PolygonOnTriangulation)& aPolygon = 
-        aOri == TopAbs_REVERSED ? aPair.Last() : aPair.First();
-
-      const TColStd_Array1OfInteger& aIndices = aPolygon->Nodes();
-      const Standard_Integer aNodesNb = aPolygon->NbNodes();
-
-      Standard_Integer aPrevId = aIndices(1);
-      for (Standard_Integer i = 2; i <= aNodesNb; ++i)
-      {
-        const Standard_Integer aCurId = aIndices(i);
-        addLinkToMesh(aPrevId, aCurId, aOri);
-        aPrevId = aCurId;
-      }
-    }
-  }
-}
-
-//=======================================================================
-//function : addLinkToMesh
-//purpose  :
-//=======================================================================
-void BRepMesh_FastDiscretFace::addLinkToMesh(
-  const Standard_Integer   theFirstNodeId,
-  const Standard_Integer   theLastNodeId,
-  const TopAbs_Orientation theOrientation)
-{
-  if (theOrientation == TopAbs_FORWARD)
-    myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier));
-  else if (theOrientation == TopAbs_REVERSED)
-    myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier));
-  else if (theOrientation == TopAbs_INTERNAL)
-    myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed));
-}
-
-//=======================================================================
-//function : Add
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::add (const Handle(BRepMesh_FaceAttribute)& theAttribute,
-                                    Message_ProgressSentry* theProgressEntry)
-{
-  if (!theAttribute->IsValid() || theAttribute->ChangeMeshNodes()->IsEmpty())
-    return;
-
-  myAttribute = theAttribute;
-  initDataStructure();
-
-  BRepMesh::HIMapOfInteger& aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
-  Standard_Integer nbVertices = aVertexEdgeMap->Extent();
-  BRepMesh::Array1OfInteger tabvert_corr(1, nbVertices);
-  for ( Standard_Integer i = 1; i <= nbVertices; ++i )
-    tabvert_corr(i) = i;
-
-  BRepMesh_Delaun trigu(myStructure, tabvert_corr);
-
-  //removed all free edges from triangulation
-  const Standard_Integer nbLinks = myStructure->NbLinks();
-  for( Standard_Integer i = 1; i <= nbLinks; i++ ) 
-  {
-    if( myStructure->ElementsConnectedTo(i).Extent() < 1 )
-    {
-      BRepMesh_Edge& anEdge = (BRepMesh_Edge&)trigu.GetEdge(i);
-      if ( anEdge.Movability() == BRepMesh_Deleted )
-        continue;
-
-      anEdge.SetMovability(BRepMesh_Free);
-      myStructure->RemoveLink(i);
-    }
-  }
-
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  GeomAbs_SurfaceType thetype = gFace->GetType();
-
-  Standard_Boolean rajout = 
-    (thetype == GeomAbs_Sphere || thetype == GeomAbs_Torus);
-
-  // Check the necessity to fill the map of parameters
-  const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus         ||
-                                       thetype == GeomAbs_BezierSurface ||
-                                       thetype == GeomAbs_BSplineSurface);
-
-  const Standard_Real umax = myAttribute->GetUMax();
-  const Standard_Real umin = myAttribute->GetUMin();
-  const Standard_Real vmax = myAttribute->GetVMax();
-  const Standard_Real vmin = myAttribute->GetVMin();
-
-  Standard_Boolean isaline = 
-    ((umax - umin) < Precision::PConfusion() || 
-     (vmax - vmin) < Precision::PConfusion());
-
-  Standard_Real aDef = -1;
-  if (theProgressEntry != NULL && !theProgressEntry->More())
-  {
-    return;
-  }
-
-  if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
-  {
-    if (!rajout)
-    {
-      // compute maximal deflection
-      aDef = control(trigu, Standard_True, theProgressEntry);
-      if (theProgressEntry != NULL && !theProgressEntry->More())
-      {
-        return;
-      }
-
-      rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.);
-    }
-    if (thetype != GeomAbs_Plane)
-    {
-      if (!rajout && useUVParam)
-      {
-        rajout = (myVParam.Extent() > 2 &&
-          (gFace->IsUClosed() || gFace->IsVClosed()));
-      }
-
-      if (rajout)
-      {
-        insertInternalVertices(trigu, theProgressEntry);
-        if (theProgressEntry != NULL && !theProgressEntry->More())
-        {
-          return;
-        }
-
-        //control internal points
-        if (myIsControlSurfaceDeflection)
-        {
-          aDef = control(trigu, Standard_False, theProgressEntry);
-          if (theProgressEntry != NULL && !theProgressEntry->More())
-          {
-            return;
-          }
-        }
-      }
-    }
-  }
-
-  //modify myStructure back
-  BRepMesh::HVectorOfVertex& aMeshNodes = myStructure->Data()->ChangeVertices();
-  for ( Standard_Integer i = 1; i <= myStructure->NbNodes(); ++i )
-  {
-    BRepMesh_Vertex& aNode = aMeshNodes->ChangeValue(i - 1);
-    aNode.ChangeCoord() = myAttribute->Scale(aNode.Coord(), Standard_False);
-
-    const BRepMesh::ListOfInteger& alist = myStructure->LinksConnectedTo(i);
-    // Register internal nodes used in triangulation
-    if (!alist.IsEmpty() && aVertexEdgeMap->FindIndex(i) == 0)
-      aVertexEdgeMap->Add(i);
-  }
-
-  if (!(aDef < 0.))
-    myAttribute->SetDefFace(aDef);
-}
-
-//=======================================================================
-//function : addVerticesToMesh
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
-  const BRepMesh::ListOfVertex& theVertices,
-  BRepMesh_Delaun&              theMeshBuilder,
-  Message_ProgressSentry*       theProgressEntry)
-{
-  if (theVertices.IsEmpty())
-    return Standard_False;
-
-  BRepMesh::Array1OfVertexOfDelaun aArrayOfNewVertices(1, theVertices.Extent());
-  BRepMesh::ListOfVertex::Iterator aVertexIt(theVertices);
-  for (Standard_Integer aVertexId = 0; aVertexIt.More(); aVertexIt.Next())
-    aArrayOfNewVertices(++aVertexId) = aVertexIt.Value();
-
-  theMeshBuilder.AddVertices(aArrayOfNewVertices, theProgressEntry);
-  return theProgressEntry == NULL || theProgressEntry->More();
-}
-
-//=======================================================================
-//function : filterParameters
-//purpose  : 
-//=======================================================================
-static void filterParameters(const BRepMesh::IMapOfReal& theParams,
-                             const Standard_Real         theMinDist,
-                             const Standard_Real         theFilterDist,
-                             BRepMesh::SequenceOfReal&   theResult)
-{
-  // 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;
-  theResult.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;
-      }
-      theResult.Append(aLastAdded);
-      continue;
-    }
-    
-    aLastCandidate = aVal;
-    isCandidateDefined = Standard_True;
-  }
-  theResult.Append(aParamArray(aParamLength));
-}
-
-//=======================================================================
-//function : insertInternalVertices
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVertices (BRepMesh_Delaun& theMeshBuilder,
-                                                       Message_ProgressSentry* theProgressEntry)
-{
-  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-  BRepMesh::ListOfVertex aNewVertices(anAlloc);
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-  switch (gFace->GetType())
-  {
-  case GeomAbs_Sphere:
-    insertInternalVerticesSphere(aNewVertices);
-    break;
-
-  case GeomAbs_Cylinder:
-    insertInternalVerticesCylinder(aNewVertices);
-    break;
-
-  case GeomAbs_Cone:
-    insertInternalVerticesCone(aNewVertices);
-    break;
-
-  case GeomAbs_Torus:
-    insertInternalVerticesTorus(aNewVertices);
-    break;
-
-  default:
-    insertInternalVerticesOther(aNewVertices);
-    break;
-  }
-  
-  addVerticesToMesh(aNewVertices, theMeshBuilder, theProgressEntry);
-}
-
-//=======================================================================
-//function : insertInternalVerticesSphere
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVerticesSphere(
-  BRepMesh::ListOfVertex& theNewVertices)
-{
-  Standard_Real aRange[] = {
-    myAttribute->GetVMin(), myAttribute->GetVMax(),
-    myAttribute->GetUMin(), myAttribute->GetUMax()
-  };
-
-  gp_Sphere aSphere = myAttribute->Surface()->Sphere();
-
-  // Calculate parameters for iteration in V direction
-  Standard_Real aStep = 0.7 * GCPnts_TangentialDeflection::ArcAngularStep(
-    aSphere.Radius(), myAttribute->GetDefFace(), myAngle, myMinSize);
-
-  Standard_Real aDd[2] = {aStep, aStep};
-  Standard_Real aPasMax[2] = {0., 0.};
-  for (Standard_Integer i = 0; i < 2; ++i)
-  {
-    const Standard_Real aMax = aRange[2 * i + 1];
-    const Standard_Real aDiff = aMax - aRange[2 * i + 0];
-    aDd[i] = aDiff / ((Standard_Integer)(aDiff / aDd[i]) + 1);
-    aPasMax[i] = aMax - Precision::PConfusion();
-  }
-
-  const Standard_Real aHalfDu = aDd[1] * 0.5;
-  Standard_Boolean Shift = Standard_False;
-  Standard_Real aPasV = aRange[0] + aDd[0];
-  for (; aPasV < aPasMax[0]; aPasV += aDd[0])
-  {
-    Shift = !Shift;
-    const Standard_Real d = (Shift) ? aHalfDu : 0.;
-    Standard_Real aPasU = aRange[2] + d;
-    for (; aPasU < aPasMax[1]; aPasU += aDd[1])
-    {
-      tryToInsertAnalyticVertex(gp_Pnt2d(aPasU, aPasV), aSphere, theNewVertices);
-    }
-  }
-}
-
-//=======================================================================
-//function : insertInternalVerticesCylinder
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVerticesCylinder(
-  BRepMesh::ListOfVertex& theNewVertices)
-{
-  const Standard_Real umax = myAttribute->GetUMax();
-  const Standard_Real umin = myAttribute->GetUMin();
-  const Standard_Real vmax = myAttribute->GetVMax();
-  const Standard_Real vmin = myAttribute->GetVMin();
-
-  gp_Cylinder aCylinder = myAttribute->Surface()->Cylinder();
-  const Standard_Real aRadius = aCylinder.Radius();
-
-  Standard_Integer nbU = 0;
-  Standard_Integer nbV = 0;
-  const Standard_Real su = umax - umin;
-  const Standard_Real sv = vmax - vmin;
-  const Standard_Real aArcLen = su * aRadius;
-  if (aArcLen > myAttribute->GetDefFace ())
-  {
-    // Calculate parameters for iteration in U direction
-    const Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep (
-      aRadius, myAttribute->GetDefFace (), myAngle, myMinSize);
-    nbU = (Standard_Integer)(su / Du);
-
-    // 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);
-
-  Standard_Real pasu, pasv, pasvmax = vmax - Dv*0.5, pasumax = umax - Du*0.5;
-  for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
-  {
-    for (pasu = umin + Du; pasu < pasumax; pasu += Du)
-    {
-      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), aCylinder, theNewVertices);
-    }
-  }
-}
-
-//=======================================================================
-//function : insertInternalVerticesCone
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVerticesCone(
-  BRepMesh::ListOfVertex& theNewVertices)
-{
-  const Standard_Real umax = myAttribute->GetUMax();
-  const Standard_Real umin = myAttribute->GetUMin();
-  const Standard_Real vmax = myAttribute->GetVMax();
-  const Standard_Real vmin = myAttribute->GetVMin();
-
-  gp_Cone aCone = myAttribute->Surface()->Cone();
-  Standard_Real RefR = aCone.RefRadius();
-  Standard_Real SAng = aCone.SemiAngle();
-  Standard_Real aRadius = Max(Abs(RefR + vmin*Sin(SAng)), Abs(RefR + vmax*Sin(SAng)));
-
-  Standard_Real Du = GCPnts_TangentialDeflection::ArcAngularStep(
-    aRadius, myAttribute->GetDefFace(), myAngle, myMinSize);
-
-  Standard_Real Dv, pasu, pasv;
-  Standard_Integer nbU = (Standard_Integer)((umax - umin) / Du);
-  Standard_Integer nbV = (Standard_Integer)(nbU*(vmax - vmin) / ((umax - umin)*aRadius));
-  Du = (umax - umin) / (nbU + 1);
-  Dv = (vmax - vmin) / (nbV + 1);
-
-  Standard_Real pasvmax = vmax - Dv*0.5, pasumax = umax - Du*0.5;
-  for (pasv = vmin + Dv; pasv < pasvmax; pasv += Dv)
-  {
-    for (pasu = umin + Du; pasu < pasumax; pasu += Du)
-    {
-      tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), aCone, theNewVertices);
-    }
-  }
-}
-
-//=======================================================================
-//function : insertInternalVerticesTorus
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVerticesTorus(
-  BRepMesh::ListOfVertex& theNewVertices)
-{
-  const Standard_Real umax     = myAttribute->GetUMax();
-  const Standard_Real umin     = myAttribute->GetUMin();
-  const Standard_Real vmax     = myAttribute->GetVMax();
-  const Standard_Real vmin     = myAttribute->GetVMin();
-  const Standard_Real deltaX   = myAttribute->GetDeltaX();
-  const Standard_Real deltaY   = myAttribute->GetDeltaY();
-  const Standard_Real aDefFace = myAttribute->GetDefFace();
-
-  gp_Torus T = myAttribute->Surface()->Torus();
-
-  Standard_Boolean insert;
-  Standard_Integer i, j, ParamULength, ParamVLength;
-  Standard_Real pp, pasu, pasv;
-  Standard_Real r = T.MinorRadius(), R = T.MajorRadius();
-
-  BRepMesh::SequenceOfReal ParamU, ParamV;
-
-  Standard_Real oldDv = GCPnts_TangentialDeflection::ArcAngularStep(
-    r, aDefFace, myAngle, myMinSize);
-
-  Standard_Real Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
-  Dv = oldDv;
-
-  Standard_Real Du;
-  Standard_Integer nbV = Max((Standard_Integer)((vmax - vmin) / Dv), 2);
-  Dv = (vmax - vmin) / (nbV + 1);
-  Standard_Real ru = R + r;
-  if (ru > 1.e-16)
-  {
-    Du = GCPnts_TangentialDeflection::ArcAngularStep(
-      ru, aDefFace, myAngle, myMinSize);
-
-    Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
-    if (aa < gp::Resolution())
-      return;
-    Du *= Min(oldDv, Du) / aa;
-  }
-  else Du = Dv;
-
-  Standard_Integer nbU = Max((Standard_Integer)((umax - umin) / Du), 2);
-  nbU = Max(nbU, (int)(nbV*(umax - umin)*R / ((vmax - vmin)*r) / 5.));
-  Du = (umax - umin) / (nbU + 1);
-
-  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
-    for (i = 0; i <= nbU; i++) ParamU.Append(umin + i* Du);
-  }//R<r
-  else //U if R > r
-  {
-    //--ofv: U
-    // Number of mapped U parameters
-    const Standard_Integer LenU = myUParam.Extent();
-    // Fill array of U parameters
-    TColStd_Array1OfReal Up(1, LenU);
-    for (j = 1; j <= LenU; j++) Up(j) = myUParam(j);
-
-    // Calculate DU, leave array of parameters
-    Standard_Real aDU = FUN_CalcAverageDUV(Up, LenU);
-    aDU = Max(aDU, Abs(umax - umin) / (Standard_Real)nbU / 2.);
-    Standard_Real dUstd = Abs(umax - umin) / (Standard_Real)LenU;
-    if (aDU > dUstd) dUstd = aDU;
-    // Add U parameters
-    for (j = 1; j <= LenU; j++)
-    {
-      pp = Up(j);
-      insert = Standard_True;
-      ParamULength = ParamU.Length();
-      for (i = 1; i <= ParamULength && insert; i++)
-      {
-        insert = (Abs(ParamU.Value(i) - pp) > (0.5*dUstd));
-      }
-      if (insert) ParamU.Append(pp);
-    }
-  }
-
-  //--ofv: V
-  // Number of mapped V parameters
-  const Standard_Integer LenV = myVParam.Extent();
-  // Fill array of V parameters
-  TColStd_Array1OfReal Vp(1, LenV);
-  for (j = 1; j <= LenV; j++) Vp(j) = myVParam(j);
-  // Calculate DV, sort array of parameters
-  Standard_Real aDV = FUN_CalcAverageDUV(Vp, LenV);
-  aDV = Max(aDV, Abs(vmax - vmin) / (Standard_Real)nbV / 2.);
-
-  Standard_Real dVstd = Abs(vmax - vmin) / (Standard_Real)LenV;
-  if (aDV > dVstd) dVstd = aDV;
-  // Add V parameters
-  for (j = 1; j <= LenV; j++)
-  {
-    pp = Vp(j);
-
-    insert = Standard_True;
-    ParamVLength = ParamV.Length();
-    for (i = 1; i <= ParamVLength && insert; i++)
-    {
-      insert = (Abs(ParamV.Value(i) - pp) > (dVstd*2. / 3.));
-    }
-    if (insert) ParamV.Append(pp);
-  }
-
-  Standard_Integer Lu = ParamU.Length(), Lv = ParamV.Length();
-  Standard_Real uminnew = umin + deltaY*0.1;
-  Standard_Real vminnew = vmin + deltaX*0.1;
-  Standard_Real umaxnew = umax - deltaY*0.1;
-  Standard_Real vmaxnew = vmax - deltaX*0.1;
-
-  for (i = 1; i <= Lu; i++)
-  {
-    pasu = ParamU.Value(i);
-    if (pasu >= uminnew && pasu < umaxnew)
-    {
-      for (j = 1; j <= Lv; j++)
-      {
-        pasv = ParamV.Value(j);
-        if (pasv >= vminnew && pasv < vmaxnew)
-        {
-          tryToInsertAnalyticVertex(gp_Pnt2d(pasu, pasv), T, theNewVertices);
-        }
-      }
-    }
-  }
-}
-
-//=======================================================================
-//function : insertInternalVerticesOther
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertInternalVerticesOther(
-  BRepMesh::ListOfVertex& theNewVertices)
-{
-  const Standard_Real aRange[2][2] = {
-      { myAttribute->GetUMax(), myAttribute->GetUMin() },
-      { myAttribute->GetVMax(), myAttribute->GetVMin() }
-  };
-
-  const Standard_Real aDelta[2] = { 
-    myAttribute->GetDeltaX(),
-    myAttribute->GetDeltaY()
-  };
-
-  const Standard_Real                 aDefFace = myAttribute->GetDefFace();
-  const Handle(BRepAdaptor_HSurface)& gFace    = myAttribute->Surface();
-
-  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-  BRepMesh::SequenceOfReal aParams[2] = { BRepMesh::SequenceOfReal(anAlloc), 
-                                          BRepMesh::SequenceOfReal(anAlloc) };
-  for (Standard_Integer i = 0; i < 2; ++i)
-  {
-    Standard_Boolean isU = (i == 0);
-    Standard_Real aRes = isU ?
-      gFace->UResolution(aDefFace) :
-      gFace->VResolution(aDefFace);
-
-    // Sort and filter sequence of parameters
-    Standard_Real aMinDiff = Precision::PConfusion();
-    if (aDelta[i] < 1.)
-      aMinDiff /= aDelta[i];
-
-    aMinDiff = Max(myMinSize, aMinDiff);
-
-    Standard_Real aRangeDiff = aRange[i][0] - aRange[i][1];
-    Standard_Real aDiffMaxLim = 0.1 * aRangeDiff;
-    Standard_Real aDiffMinLim = Max(0.005 * aRangeDiff, 2. * aRes);
-    Standard_Real aDiff = Max(myMinSize, Min(aDiffMaxLim, aDiffMinLim));
-    filterParameters(isU ? myUParam : myVParam, aMinDiff, aDiff, aParams[i]);
-  }
-
-  // check intermediate isolines
-  Handle (Geom_Surface) aSurface = gFace->ChangeSurface ().Surface ().Surface ();
-
-  BRepMesh::MapOfReal aParamsToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc),
-                                             BRepMesh::MapOfReal(1, anAlloc) };
-  BRepMesh::MapOfReal aParamsForbiddenToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc),
-                                                      BRepMesh::MapOfReal(1, anAlloc) };
-
-  // insert additional points where it is needed to conform criteria.
-  // precision for normals calculation
-  const Standard_Real aNormPrec = Precision::Confusion();
-  for (Standard_Integer k = 0; k < 2; ++k)
-  {
-    const Standard_Integer aOtherIndex = (k + 1) % 2;
-    BRepMesh::SequenceOfReal& aParams1 = aParams[k];
-    BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex];
-    const Standard_Boolean isU = (k == 0);
-    for (Standard_Integer i = 2; i < aParams1.Length(); ++i)
-    {
-      const Standard_Real aParam1 = aParams1(i);
-      GeomAdaptor_Curve aIso(isU ?
-        aSurface->UIso(aParam1) : aSurface->VIso(aParam1));
-
-      Standard_Real aPrevParam2 = aParams2(1);
-      gp_Pnt aPrevPnt2;
-      gp_Vec aPrevVec2;
-      aIso.D1(aPrevParam2, aPrevPnt2, aPrevVec2);
-      for (Standard_Integer j = 2; j <= aParams2.Length();)
-      {
-        Standard_Real aParam2 = aParams2(j);
-        gp_Pnt aPnt2;
-        gp_Vec aVec2;
-        aIso.D1(aParam2, aPnt2, aVec2);
-
-        Standard_Real aMidParam = 0.5 * (aPrevParam2 + aParam2);
-        gp_Pnt aMidPnt = aIso.Value(aMidParam);
-
-        Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aPnt2, aMidPnt);
-        if (aDist > aDefFace && aDist > myMinSize)
-        {
-          // insertion 
-          aParams2.InsertBefore(j, aMidParam);
-          continue;
-        }
-        //put regular grig for normals
-        gp_Pnt2d aStPnt1, aStPnt2;
-        if (isU)
-        {
-          aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2);
-          aStPnt2 = gp_Pnt2d(aParam1, aMidParam);
-        }
-        else
-        {
-          aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1);
-          aStPnt2 = gp_Pnt2d(aMidParam, aParam1);
-        }
-
-        gp_Dir N1(0, 0, 1), N2(0, 0, 1);
-        Standard_Integer aSt1 = GeomLib::NormEstim(aSurface, aStPnt1, aNormPrec, N1);
-        Standard_Integer aSt2 = GeomLib::NormEstim(aSurface, aStPnt2, aNormPrec, N2);
-
-        const Standard_Real aAngle = N2.Angle(N1);
-        if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle)
-        {
-          const Standard_Real aLen = GCPnts_AbscissaPoint::Length(
-            aIso, aPrevParam2, aMidParam, aDefFace);
-
-          if (aLen > myMinSize)
-          {
-            // insertion 
-            aParams2.InsertBefore(j, aMidParam);
-            continue;
-          }
-        }
-        aPrevParam2 = aParam2;
-        aPrevPnt2 = aPnt2;
-        aPrevVec2 = aVec2;
-
-        ++j;
-      }
-    }
-  }
-#ifdef DEBUG_InsertInternal
-  // output numbers of parameters along U and V
-  cout << "aParams: " << aParams[0].Length() << " " << aParams[1].Length() << endl;
-#endif
-  // try to reduce number of points evaluating of isolines sampling
-  for (Standard_Integer k = 0; k < 2; ++k)
-  {
-    const Standard_Integer aOtherIndex = (k + 1) % 2;
-    BRepMesh::SequenceOfReal& aParams1 = aParams[k];
-    BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex];
-    const Standard_Boolean isU = (k == 0);
-    BRepMesh::MapOfReal& aToRemove2          = aParamsToRemove[aOtherIndex];
-    BRepMesh::MapOfReal& aForbiddenToRemove1 = aParamsForbiddenToRemove[k];
-    BRepMesh::MapOfReal& aForbiddenToRemove2 = aParamsForbiddenToRemove[aOtherIndex];
-    for (Standard_Integer i = 2; i < aParams1.Length(); ++i)
-    {
-      const Standard_Real aParam1 = aParams1(i);
-      GeomAdaptor_Curve aIso(isU ?
-        aSurface->UIso (aParam1) : aSurface->VIso (aParam1));
-#ifdef DEBUG_InsertInternal
-      // write polyline containing initial parameters to the file
-      {
-        ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
-        ff << "polyline " << (k == 0 ? "u" : "v") << i << " ";
-        for (Standard_Integer j = 1; j <= aParams2.Length(); j++)
-        {
-          gp_Pnt aP;
-          aIso.D0(aParams2(j), aP);
-          ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " ";
-        }
-        ff << endl;
-      }
-#endif
-
-      Standard_Real aPrevParam2 = aParams2(1);
-      gp_Pnt aPrevPnt2;
-      gp_Vec aPrevVec2;
-      aIso.D1 (aPrevParam2, aPrevPnt2, aPrevVec2);
-      for (Standard_Integer j = 2; j <= aParams2.Length();)
-      {
-        Standard_Real aParam2 = aParams2(j);
-        gp_Pnt aPnt2;
-        gp_Vec aVec2;
-        aIso.D1 (aParam2, aPnt2, aVec2);
-
-        // 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 (aParams2.Length() > 3 && j < aParams2.Length())
-        {
-          // Remove too dense points
-          const Standard_Real aNextParam = aParams2(j + 1);
-          gp_Pnt aNextPnt;
-          gp_Vec aNextVec;
-          aIso.D1(aNextParam, aNextPnt, aNextVec);
-
-          // Lets check current parameter.
-          // If it fits deflection, we can remove it.
-          Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aNextPnt, aPnt2);
-          if (aDist < aDefFace)
-          {
-            // Lets check parameters for angular deflection.
-            if (aPrevVec2.SquareMagnitude() > gp::Resolution() &&
-                aNextVec.SquareMagnitude() > gp::Resolution() &&
-                aPrevVec2.Angle(aNextVec) < myAngle)
-            {
-              // For current Iso line we can remove this parameter.
-#ifdef DEBUG_InsertInternal
-              // write point of removed parameter
-              {
-                ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
-                ff << "point " << (k == 0 ? "u" : "v") << i << "r_" << j << " "
-                  << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl;
-              }
-#endif
-              aToRemove2.Add(aParam2);
-              aPrevParam2 = aNextParam;
-              aPrevPnt2 = aNextPnt;
-              aPrevVec2 = aNextVec;
-              j += 2;
-              continue;
-            }
-            else {
-              // We have found a place on the surface refusing 
-              // removement of this parameter.
-#ifdef DEBUG_InsertInternal
-              // write point of forbidden to remove parameter
-              {
-                ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
-                ff << "vertex " << (k == 0 ? "u" : "v") << i << "f_" << j << " "
-                  << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl;
-              }
-#endif
-              aForbiddenToRemove1.Add(aParam1);
-              aForbiddenToRemove2.Add(aParam2);
-            }
-          }
-        }
-        aPrevParam2 = aParam2;
-        aPrevPnt2 = aPnt2;
-        aPrevVec2 = aVec2;
-        ++j;
-      }
-    }
-  }
-  // remove filtered out parameters
-  for (Standard_Integer k = 0; k < 2; ++k)
-  {
-    BRepMesh::SequenceOfReal& aParamsk = aParams[k];
-    for (Standard_Integer i = 1; i <= aParamsk.Length();)
-    {
-      const Standard_Real aParam = aParamsk.Value(i);
-      if (aParamsToRemove[k].Contains(aParam) &&
-        !aParamsForbiddenToRemove[k].Contains(aParam))
-      {
-        aParamsk.Remove(i);
-      }
-      else
-        i++;
-    }
-  }
-#ifdef DEBUG_InsertInternal
-  // write polylines containing remaining parameters
-  {
-    ofstream ff(DEBUG_InsertInternal, std::ios_base::app);
-    for (Standard_Integer k = 0; k < 2; ++k)
-    {
-      for (Standard_Integer i = 1; i <= aParams[k].Length(); i++)
-      {
-        ff << "polyline " << (k == 0 ? "uo" : "vo") << i << " ";
-        for (Standard_Integer j = 1; j <= aParams[1 - k].Length(); j++)
-        {
-          gp_Pnt aP;
-          if (k == 0)
-            gFace->D0(aParams[k](i), aParams[1 - k](j), aP);
-          else
-            gFace->D0(aParams[1 - k](j), aParams[k](i), aP);
-          ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " ";
-        }
-        ff << endl;
-      }
-    }
-  }
-#endif
-
-  // insert nodes of the regular grid
-  const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
-  for (Standard_Integer i = 1; i <= aParams[0].Length(); ++i)
-  {
-    const Standard_Real aParam1 = aParams[0].Value (i);
-    for (Standard_Integer j = 1; j <= aParams[1].Length(); ++j)
-    {
-      const Standard_Real aParam2 = aParams[1].Value (j);
-      gp_Pnt2d aPnt2d(aParam1, aParam2);
-
-      // Classify intersection point
-      if (aClassifier->Perform(aPnt2d) == TopAbs_IN)
-      {
-        gp_Pnt aPnt;
-        gFace->D0(aPnt2d.X(), aPnt2d.Y(), aPnt);
-        insertVertex(aPnt, aPnt2d.Coord(), theNewVertices);
-      }
-    }
-  }
-}
-
-//=======================================================================
-//function : checkDeflectionAndInsert
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
-  const gp_Pnt&              thePnt3d,
-  const gp_XY&               theUV,
-  const Standard_Boolean     isDeflectionCheckOnly,
-  const Standard_Real        theTriangleDeflection,
-  const Standard_Real        theFaceDeflection,
-  const BRepMesh_CircleTool& theCircleTool,
-  BRepMesh::ListOfVertex&    theVertices,
-  Standard_Real&             theMaxTriangleDeflection,
-  const Handle(NCollection_IncAllocator)& theTempAlloc)
-{
-  if (theTriangleDeflection > theMaxTriangleDeflection)
-    theMaxTriangleDeflection = theTriangleDeflection;
-
-  if (theTriangleDeflection < theFaceDeflection)
-    return Standard_True;
-
-  if (myMinSize > Precision::Confusion())
-  {
-    // Iterator in the list of indexes of circles containing the node
-    BRepMesh::ListOfInteger& aCirclesList = 
-      const_cast<BRepMesh_CircleTool&>(theCircleTool).Select(
-      myAttribute->Scale(theUV, Standard_True));
-    
-    BRepMesh::MapOfInteger aUsedNodes(10, theTempAlloc);
-    BRepMesh::ListOfInteger::Iterator aCircleIt(aCirclesList);
-    for (; aCircleIt.More(); aCircleIt.Next())
-    {
-      const BRepMesh_Triangle& aTriangle = 
-        myStructure->GetElement(aCircleIt.Value());
-
-      Standard_Integer aNodes[3];
-      myStructure->ElementNodes(aTriangle, aNodes);
-
-      for (Standard_Integer i = 0; i < 3; ++i)
-      {
-        const Standard_Integer aNodeId = aNodes[i];
-        if (aUsedNodes.Contains(aNodeId))
-          continue;
-
-        aUsedNodes.Add(aNodeId);
-        const BRepMesh_Vertex& aNode = myStructure->GetNode(aNodeId);
-        const gp_Pnt& aPoint = myAttribute->GetPoint(aNode);
-
-        if (thePnt3d.SquareDistance(aPoint) < myMinSize * myMinSize)
-          return Standard_True;
-      }
-    }
-  }
-
-  if (isDeflectionCheckOnly)
-    return Standard_False;
-
-  insertVertex(thePnt3d, theUV, theVertices);
-  return Standard_True;
-}
-
-//=======================================================================
-//function : control
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_FastDiscretFace::control(
-  BRepMesh_Delaun&         theTrigu,
-  const Standard_Boolean   theIsFirst,
-  Message_ProgressSentry*  theProgressEntry)
-{
-  Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent();
-  if (aTrianglesNb < 1)
-    return -1.0;
-
-  //IMPORTANT: Constants used in calculations
-  const Standard_Real MinimalArea2d     = 1.e-9;
-  const Standard_Real MinimalSqLength3d = 1.e-12;
-  const Standard_Real aSqDefFace = myAttribute->GetDefFace() * myAttribute->GetDefFace();
-
-  const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
-
-  Handle(Geom_Surface) aBSpline;
-  const GeomAbs_SurfaceType aSurfType = gFace->GetType ();
-  if (IsCompexSurface (aSurfType) && aSurfType != GeomAbs_SurfaceOfExtrusion)
-    aBSpline = gFace->ChangeSurface ().Surface().Surface();
-
-  Handle(NCollection_IncAllocator) anAlloc =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-  NCollection_DataMap<Standard_Integer, gp_Dir> aNorMap(1, anAlloc);
-  BRepMesh::MapOfIntegerInteger                 aStatMap(1, anAlloc);
-  NCollection_Map<BRepMesh_Edge>                aCouples(3 * aTrianglesNb, anAlloc);
-  const BRepMesh_CircleTool& aCircles = theTrigu.Circles();
-
-  // Perform refinement passes
-  // Define the number of iterations
-  Standard_Integer       aIterationsNb = 11;
-  const Standard_Integer aPassesNb = (theIsFirst ? 1 : aIterationsNb);
-  // Initialize stop condition
-  Standard_Real aMaxSqDef = -1.;
-  Standard_Integer aPass = 1, aInsertedNb = 1;
-  Standard_Boolean isAllDegenerated = Standard_False;
-  Handle(NCollection_IncAllocator) aTempAlloc =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-  for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
-  {
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return 0;
-    }
-
-    aTempAlloc->Reset(Standard_False);
-    BRepMesh::ListOfVertex aNewVertices(aTempAlloc);
-
-    // Reset stop condition
-    aInsertedNb      = 0;
-    aMaxSqDef        = -1.;
-    isAllDegenerated = Standard_True;
-
-    aTrianglesNb = myStructure->ElementsOfDomain().Extent();
-    if (aTrianglesNb < 1)
-      break;
-
-    // Iterate on current triangles
-    const BRepMesh::MapOfInteger& aTriangles = myStructure->ElementsOfDomain();
-    BRepMesh::MapOfInteger::Iterator aTriangleIt(aTriangles);
-    for (; aTriangleIt.More(); aTriangleIt.Next())
-    {
-      if (theProgressEntry != NULL && !theProgressEntry->More())
-      {
-        return 0;
-      }
-
-      const Standard_Integer aTriangleId = aTriangleIt.Key();
-      const BRepMesh_Triangle& aCurrentTriangle = myStructure->GetElement(aTriangleId);
-
-      if (aCurrentTriangle.Movability() == BRepMesh_Deleted)
-        continue;
-
-      Standard_Integer v[3];
-      myStructure->ElementNodes(aCurrentTriangle, v);
-
-      Standard_Integer e[3];
-      Standard_Boolean o[3];
-      aCurrentTriangle.Edges(e, o);
-
-      gp_XY xy[3];
-      gp_XYZ p[3];
-      Standard_Boolean m[3];
-      for (Standard_Integer i = 0; i < 3; ++i)
-      {
-        m[i] = (myStructure->GetLink(e[i]).Movability() == BRepMesh_Frontier);
-
-        const BRepMesh_Vertex& aVertex = myStructure->GetNode(v[i]);
-        xy[i] = myAttribute->Scale(aVertex.Coord(), Standard_False);
-        p [i] = myAttribute->GetPoint(aVertex).Coord();
-      }
-
-      gp_XYZ aLinkVec[3];
-      Standard_Boolean isDegeneratedTri = Standard_False;
-      for (Standard_Integer i = 0; i < 3 && !isDegeneratedTri; ++i)
-      {
-        aLinkVec[i] = p[(i + 1) % 3] - p[i];
-        isDegeneratedTri = (aLinkVec[i].SquareModulus() < MinimalSqLength3d);
-      }
-
-      if (isDegeneratedTri) 
-        continue;
-
-      isAllDegenerated = Standard_False;
-
-      // Check triangle area in 2d
-      if (Abs((xy[1]-xy[0])^(xy[2]-xy[1])) < MinimalArea2d)
-        continue;
-
-      // Check triangle normal
-      gp_Pnt pDef;
-      Standard_Real aSqDef = -1.;
-      Standard_Boolean isSkipped = Standard_False;
-      gp_XYZ normal(aLinkVec[0] ^ aLinkVec[1]);
-      if (normal.SquareModulus () < gp::Resolution())
-        continue;
-
-      normal.Normalize();
-
-      // Check deflection at triangle centroid
-      gp_XY aCenter2d = (xy[0] + xy[1] + xy[2]) / 3.0;
-      gFace->D0(aCenter2d.X(), aCenter2d.Y(), pDef);
-      aSqDef = Abs(normal * (pDef.XYZ() - p[0]));
-      aSqDef *= aSqDef;
-
-      isSkipped = !checkDeflectionAndInsert(pDef, aCenter2d, theIsFirst, 
-        aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc);
-
-      if (isSkipped)
-        break;
-
-      // Check deflection at triangle links
-      for (Standard_Integer i = 0; i < 3 && !isSkipped; ++i)
-      {
-        if (m[i]) // is a boundary
-          continue;
-
-        // Check if this link was already processed
-        if (aCouples.Add(myStructure->GetLink(e[i])))
-        {
-          // Check deflection on edge 1
-          Standard_Integer j = (i + 1) % 3;
-          gp_XY mi2d = (xy[i] + xy[j]) * 0.5;
-          gFace->D0(mi2d.X(), mi2d.Y(), pDef);
-          gp_Lin aLin(p[i], gp_Vec(p[i], p[j]));
-          aSqDef = aLin.SquareDistance(pDef);
-
-          isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, 
-            aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc);
-        }
-      }
-
-      if (isSkipped)
-        break;
-
-      //check normal on bsplines
-      if (theIsFirst && !aBSpline.IsNull())
-      {
-        gp_Dir N[3] = { gp::DZ(), gp::DZ(), gp::DZ() };
-        Standard_Integer aSt[3];
-
-        for (Standard_Integer i = 0; i < 3; ++i)
-        {
-          if (aNorMap.IsBound(v[i]))
-          {
-            aSt[i] = aStatMap.Find(v[i]);
-            N[i] = aNorMap.Find(v[i]);
-          }
-          else
-          {
-            aSt[i] = GeomLib::NormEstim(aBSpline, gp_Pnt2d(xy[i]), Precision::Confusion(), N[i]);
-            aStatMap.Bind(v[i], aSt[i]);
-            aNorMap.Bind(v[i], N[i]);
-          }
-        }
-
-        Standard_Real aAngle[3];
-        for (Standard_Integer i = 0; i < 3; ++i)
-          aAngle[i] = N[(i + 1) % 3].Angle(N[i]);
-
-        if (aSt[0] < 1 && aSt[1] < 1 && aSt[2] < 1)
-        {
-          if (aAngle[0] > myAngle || aAngle[1] > myAngle || aAngle[2] > myAngle)
-          {
-            aMaxSqDef = -1.;
-            break;
-          }
-        }
-      }
-    }
-
-    if (theIsFirst)
-      continue;
-
-#ifdef DEBUG_MESH
-    // append to the file triangles in the form of polyline commands;
-    // so the file can be sourced in draw to analyze triangles on each pass of the algorithm.
-    // write triangles
-    ofstream ftt(DEBUG_MESH, std::ios_base::app);
-    Standard_Integer nbElem = myStructure->NbElements();
-    for (Standard_Integer i = 1; i <= nbElem; i++)
-    {
-      const BRepMesh_Triangle& aTri = myStructure->GetElement(i);
-      if (aTri.Movability() == BRepMesh_Deleted)
-        continue;
-      Standard_Integer n[3];
-      myStructure->ElementNodes(aTri, n);
-      const BRepMesh_Vertex& aV1 = myStructure->GetNode(n[0]);
-      const BRepMesh_Vertex& aV2 = myStructure->GetNode(n[1]);
-      const BRepMesh_Vertex& aV3 = myStructure->GetNode(n[2]);
-      const gp_Pnt& aP1 = myAttribute->GetPoint(aV1);
-      const gp_Pnt& aP2 = myAttribute->GetPoint(aV2);
-      const gp_Pnt& aP3 = myAttribute->GetPoint(aV3);
-      ftt << "polyline t" << aPass << "_" << i << " "
-        << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << " "
-        << aP2.X() << " " << aP2.Y() << " " << aP2.Z() << " "
-        << aP3.X() << " " << aP3.Y() << " " << aP3.Z() << " "
-        << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << endl;
-    }
-    // write points to insert on the current pass
-    BRepMesh::ListOfVertex::Iterator it(aNewVertices);
-    for (Standard_Integer i=1; it.More(); it.Next(), i++)
-    {
-      const BRepMesh_Vertex& aVertex = it.Value();
-      const gp_Pnt& aP = myAttribute->GetPoint(aVertex);
-      ftt << "vertex vt" << aPass << "_" << i << " "
-        << aP.X() << " " << aP.Y() << " " << aP.Z() << endl;
-    }
-#endif
-    if (theProgressEntry != NULL && !theProgressEntry->More())
-    {
-      return 0;
-    }
-
-    if (addVerticesToMesh(aNewVertices, theTrigu, theProgressEntry))
-      ++aInsertedNb;
-  }
-
-  return (aMaxSqDef < 0) ? aMaxSqDef : Sqrt(aMaxSqDef);
-}
-
-//=======================================================================
-//function : add
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::add(const TopoDS_Vertex& theVertex)
-{
-  if (theVertex.Orientation() != TopAbs_INTERNAL)
-    return;
-
-  try
-  {
-    OCC_CATCH_SIGNALS
-
-    gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, myAttribute->Face());
-    // check UV values for internal vertices
-    if (myAttribute->ChangeClassifier()->Perform(aPnt2d) != TopAbs_IN)
-      return;
-
-    NCollection_Handle<FixedVExplorer> aFixedVExplorer = new FixedVExplorer(theVertex);
-    Standard_Integer aIndex = myAttribute->GetVertexIndex(aFixedVExplorer);
-    gp_XY anUV = BRepMesh_ShapeTool::FindUV(aIndex, aPnt2d,
-      BRep_Tool::Tolerance(theVertex), myAttribute);
-
-    Standard_Integer aTmpId1, aTmpId2;
-    anUV = myAttribute->Scale(anUV, Standard_True);
-    myAttribute->AddNode(aIndex, anUV, BRepMesh_Fixed, aTmpId1, aTmpId2);
-  }
-  catch (Standard_Failure)
-  {
-  }
-}
-
-//=======================================================================
-//function : insertVertex
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::insertVertex(
-  const gp_Pnt&           thePnt3d,
-  const gp_XY&            theUV,
-  BRepMesh::ListOfVertex& theVertices)
-{
-  Standard_Integer aNbLocat = myAttribute->LastPointId();
-  myAttribute->ChangeSurfacePoints()->Bind(++aNbLocat, thePnt3d);
-
-  gp_XY aPnt2d  = myAttribute->Scale(theUV, Standard_True);
-  BRepMesh_Vertex aVertex(aPnt2d, aNbLocat, BRepMesh_Free);
-  theVertices.Append(aVertex);
-}
-
-//=======================================================================
-//function : commitSurfaceTriangulation
-//purpose  : 
-//=======================================================================
-void BRepMesh_FastDiscretFace::commitSurfaceTriangulation()
-{
-  if (myAttribute.IsNull() || !myAttribute->IsValid())
-    return;
-
-  const TopoDS_Face& aFace = myAttribute->Face();
-  BRepMesh_ShapeTool::NullifyFace(aFace);
-
-  Handle(BRepMesh_DataStructureOfDelaun)& aStructure = myAttribute->ChangeStructure();
-  const BRepMesh::MapOfInteger&           aTriangles = aStructure->ElementsOfDomain();
-
-  if (aTriangles.IsEmpty())
-  {
-    myAttribute->SetStatus(BRepMesh_Failure);
-    return;
-  }
-
-  BRepMesh::HIMapOfInteger& aVetrexEdgeMap = myAttribute->ChangeVertexEdgeMap();
-
-  // Store triangles
-  Standard_Integer aVerticesNb  = aVetrexEdgeMap->Extent();
-  Standard_Integer aTrianglesNb = aTriangles.Extent();
-  Handle(Poly_Triangulation) aNewTriangulation =
-    new Poly_Triangulation(aVerticesNb, aTrianglesNb, Standard_True);
-
-  Poly_Array1OfTriangle& aPolyTrianges = aNewTriangulation->ChangeTriangles();
-
-  Standard_Integer aTriangeId = 1;
-  BRepMesh::MapOfInteger::Iterator aTriIt(aTriangles);
-  for (; aTriIt.More(); aTriIt.Next())
-  {
-    const BRepMesh_Triangle& aCurElem = aStructure->GetElement(aTriIt.Key());
-
-    Standard_Integer aNode[3];
-    aStructure->ElementNodes(aCurElem, aNode);
-
-    Standard_Integer aNodeId[3];
-    for (Standard_Integer i = 0; i < 3; ++i)
-      aNodeId[i] = aVetrexEdgeMap->FindIndex(aNode[i]);
-
-    aPolyTrianges(aTriangeId++).Set(aNodeId[0], aNodeId[1], aNodeId[2]);
-  }
-
-  // Store mesh nodes
-  TColgp_Array1OfPnt&   aNodes   = aNewTriangulation->ChangeNodes();
-  TColgp_Array1OfPnt2d& aNodes2d = aNewTriangulation->ChangeUVNodes();
-
-  for (Standard_Integer i = 1; i <= aVerticesNb; ++i)
-  {
-    Standard_Integer       aVertexId = aVetrexEdgeMap->FindKey(i);
-    const BRepMesh_Vertex& aVertex   = aStructure->GetNode(aVertexId);
-    const gp_Pnt&          aPoint    = myAttribute->GetPoint(aVertex);
-
-    aNodes(i)   = aPoint;
-    aNodes2d(i) = aVertex.Coord();
-  }
-
-  aNewTriangulation->Deflection(myAttribute->GetDefFace());
-  BRepMesh_ShapeTool::AddInFace(aFace, aNewTriangulation);
-
-  // Delete unused data
-  myUParam.Clear(0L);
-  myVParam.Clear(0L);
-  myAttribute->ChangeStructure().Nullify();
-  myAttribute->ChangeSurfacePoints().Nullify();
-  myAttribute->ChangeSurfaceVertices().Nullify();
-
-  myAttribute->ChangeClassifier().Nullify();
-  myAttribute->ChangeLocation2D().Nullify();
-  myAttribute->ChangeVertexEdgeMap().Nullify();
-}
diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx
deleted file mode 100644 (file)
index dbf3019..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2013 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_FastDiscretFace_HeaderFile
-#define _BRepMesh_FastDiscretFace_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-#include <BRepMesh_FastDiscretFace.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh.hxx>
-#include <BRepMesh_FaceAttribute.hxx>
-#include <Standard_Transient.hxx>
-#include <TopTools_MutexForShapeProvider.hxx>
-#include <TopTools_DataMapOfShapeReal.hxx>
-#include <BRepMesh_Delaun.hxx>
-#include <BRepMesh_Triangle.hxx>
-#include <BRepMesh_Classifier.hxx>
-#include <ElSLib.hxx>
-
-class BRepMesh_DataStructureOfDelaun;
-class BRepMesh_FaceAttribute;
-class TopoDS_Face;
-class TopoDS_Vertex;
-class BRepAdaptor_HSurface;
-class TopoDS_Edge;
-class Poly_Triangulation;
-class TopLoc_Location;
-class gp_XY;
-class gp_Pnt2d;
-class BRepMesh_Edge;
-class BRepMesh_Vertex;
-class gp_Pnt;
-class Message_ProgressSentry;
-
-//! Algorithm to mesh a face with respect of the frontier 
-//! the deflection and by option the shared components.
-class BRepMesh_FastDiscretFace : public Standard_Transient 
-{
-public:
-  
-  //! Constructor.
-  //! @param theAngle deviation angle to be used for surface tessellation.
-  //! @param isInternalVerticesMode flag enabling/disabling internal 
-  //! vertices mode.
-  //! @param isControlSurfaceDeflection enables/disables adaptive 
-  //! reconfiguration of mesh.
-  Standard_EXPORT BRepMesh_FastDiscretFace(
-    const Standard_Real    theAngle,
-    const Standard_Real    theMinSize,
-    const Standard_Boolean isInternalVerticesMode,
-    const Standard_Boolean isControlSurfaceDeflection);
-
-  Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
-
-  Standard_EXPORT void Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
-                                Message_ProgressSentry* theProgressEntry);
-
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
-
-private:
-
-  void add(const Handle(BRepMesh_FaceAttribute)& theAttribute, Message_ProgressSentry* theProgressEntry);
-  void add(const TopoDS_Vertex& theVertex);
-
-  Standard_Real control(BRepMesh_Delaun&         theMeshBuilder,
-                        const Standard_Boolean   theIsFirst,
-                        Message_ProgressSentry*  theProgressEntry);
-
-  //! Registers the given nodes in mesh data structure and
-  //! performs refinement of existing mesh.
-  //! @param theVertices nodes to be inserted.
-  //! @param theMeshBuilder initialized tool refining mesh 
-  //! in respect to inserting nodes.
-  //! @return TRUE if vertices were been inserted, FALSE elewhere.
-  Standard_Boolean addVerticesToMesh(
-    const BRepMesh::ListOfVertex& theVertices,
-    BRepMesh_Delaun&              theMeshBuilder,
-    Message_ProgressSentry*       theProgressEntry);
-
-  //! Calculates nodes lying on face's surface and inserts them to a mesh.
-  //! @param theMeshBuilder initialized tool refining mesh 
-  //! in respect to inserting nodes.
-  void insertInternalVertices(BRepMesh_Delaun&         theMeshBuilder,
-                              Message_ProgressSentry*  theProgressEntry);
-
-  //! Calculates nodes lying on spherical surface.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
-  void insertInternalVerticesSphere(BRepMesh::ListOfVertex& theNewVertices);
-
-  //! Calculates nodes lying on cylindrical surface.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
-  void insertInternalVerticesCylinder(BRepMesh::ListOfVertex& theNewVertices);
-
-  //! Calculates nodes lying on conical surface.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
-  void insertInternalVerticesCone(BRepMesh::ListOfVertex& theNewVertices);
-
-  //! Calculates nodes lying on toroidal surface.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
-  void insertInternalVerticesTorus(BRepMesh::ListOfVertex& theNewVertices);
-
-  //! Calculates nodes lying on custom-type surface.
-  //! @param theNewVertices list of vertices to be extended and added to mesh.
-  void insertInternalVerticesOther(BRepMesh::ListOfVertex& theNewVertices);
-  
-  //! Template method trying to insert new internal vertex corresponded to
-  //! the given 2d point. Calculates 3d position analytically using the given
-  //! surface.
-  //! @param thePnt2d 2d point to be inserted to the list.
-  //! @param theAnalyticSurface analytic surface to calculate 3d point.
-  //! @param[out] theVertices list of vertices to be updated.
-  template<class AnalyticSurface>
-  void tryToInsertAnalyticVertex(const gp_Pnt2d&         thePnt2d,
-                                 const AnalyticSurface&  theAnalyticSurface,
-                                 BRepMesh::ListOfVertex& theVertices)
-  {
-    const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
-    if (aClassifier->Perform(thePnt2d) != TopAbs_IN)
-      return;
-
-    gp_Pnt aPnt;
-    ElSLib::D0(thePnt2d.X(), thePnt2d.Y(), theAnalyticSurface, aPnt);
-    insertVertex(aPnt, thePnt2d.Coord(), theVertices);
-  }
-
-  //! Creates new vertex with the given parameters.
-  //! @param thePnt3d 3d point corresponded to the vertex.
-  //! @param theUV UV point corresponded to the vertex.
-  //! @param[out] theVertices list of vertices to be updated.
-  void insertVertex(const gp_Pnt&           thePnt3d,
-                    const gp_XY&            theUV,
-                    BRepMesh::ListOfVertex& theVertices);
-
-  //! Stores mesh into the face (without internal edges).
-  void commitSurfaceTriangulation();
-
-  //! Performs initialization of data structure using existing data.
-  void initDataStructure();
-
-  //! Adds new link to the mesh data structure.
-  //! Movability of the link and order of nodes depend on orientation parameter.
-  void addLinkToMesh(const Standard_Integer   theFirstNodeId,
-                     const Standard_Integer   theLastNodeId,
-                     const TopAbs_Orientation theOrientation);
-
-  //! Inserts new node into a mesh in case if smoothed region build 
-  //! using the given node has better deflection metrics than source state.
-  //! @param thePnt3d 3d point corresponded to the vertex.
-  //! @param theUV UV point corresponded to the vertex.
-  //! @param isDeflectionCheckOnly if TRUE new node will not be added to a mesh
-  //! even if deflection parameter is better.
-  //! @param theTriangleDeflection deflection of a triangle from real geometry.
-  //! @param theFaceDeflection deflection to be achieved.
-  //! @param theCircleTool tool used for fast extraction of triangles 
-  //! touched by the given point.
-  //! @param[out] theVertices list of vertices to be updated.
-  //! @param[in out] theMaxTriangleDeflection maximal deflection of a mesh.
-  //! @return TRUE in case if the given deflection of triangle is fine and
-  //! there is no necessity to insert new node or new node was being inserted
-  //! successfully, FALSE in case if new configuration is better but 
-  //! isDeflectionCheckOnly flag is set.
-  Standard_Boolean checkDeflectionAndInsert(
-    const gp_Pnt&              thePnt3d,
-    const gp_XY&               theUV,
-    const Standard_Boolean     isDeflectionCheckOnly,
-    const Standard_Real        theTriangleDeflection,
-    const Standard_Real        theFaceDeflection,
-    const BRepMesh_CircleTool& theCircleTool,
-    BRepMesh::ListOfVertex&    theVertices,
-    Standard_Real&             theMaxTriangleDeflection,
-    const Handle(NCollection_IncAllocator)& theTempAlloc);
-
-private:
-
-  Standard_Real                          myAngle;
-  Standard_Boolean                       myInternalVerticesMode;
-  BRepMesh::IMapOfReal                   myUParam;
-  BRepMesh::IMapOfReal                   myVParam;
-
-  // Fast access to attributes of current face
-  Handle(BRepMesh_FaceAttribute)         myAttribute;
-  Handle(BRepMesh_DataStructureOfDelaun) myStructure;
-
-  Standard_Real                          myMinSize;
-  Standard_Boolean                       myIsControlSurfaceDeflection;
-};
-
-DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
-
-#endif
index 16c34331b216d262d81e6836ccbe2b41150687eb..ae3126741c0a2635e4e709d99484493048bb34fc 100644 (file)
 
 #include <BRepMesh_GeomTool.hxx>
 
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+
 #include <TopAbs_Orientation.hxx>
 #include <CSLib.hxx>
 #include <Precision.hxx>
 #include <Adaptor3d_IsoCurve.hxx>
+#include <Adaptor3d_HCurve.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_HSurface.hxx>
 #include <Geom2d_Curve.hxx>
 #include <BRep_Tool.hxx>
 
+namespace
+{
+  void ComputeErrFactors (const Standard_Real               theDeflection,
+                          const Handle(Adaptor3d_HSurface)& theFace,
+                          Standard_Real&                    theErrFactorU,
+                          Standard_Real&                    theErrFactorV)
+  {
+    theErrFactorU = theDeflection * 10.;
+    theErrFactorV = theDeflection * 10.;
+
+    switch (theFace->GetType ())
+    {
+    case GeomAbs_Cylinder:
+    case GeomAbs_Cone:
+    case GeomAbs_Sphere:
+    case GeomAbs_Torus:
+      break;
+
+    case GeomAbs_SurfaceOfExtrusion:
+    case GeomAbs_SurfaceOfRevolution:
+      {
+        Handle(Adaptor3d_HCurve) aCurve = theFace->BasisCurve ();
+        if (aCurve->GetType () == GeomAbs_BSplineCurve && aCurve->Degree () > 2)
+        {
+          theErrFactorV /= (aCurve->Degree () * aCurve->NbKnots ());
+        }
+        break;
+      }
+    case GeomAbs_BezierSurface:
+      {
+        if (theFace->UDegree () > 2)
+        {
+          theErrFactorU /= (theFace->UDegree ());
+        }
+        if (theFace->VDegree () > 2)
+        {
+          theErrFactorV /= (theFace->VDegree ());
+        }
+        break;
+      }
+    case GeomAbs_BSplineSurface:
+      {
+        if (theFace->UDegree () > 2)
+        {
+          theErrFactorU /= (theFace->UDegree () * theFace->NbUKnots ());
+        }
+        if (theFace->VDegree () > 2)
+        {
+          theErrFactorV /= (theFace->VDegree () *  theFace->NbVKnots ());
+        }
+        break;
+      }
+
+    case GeomAbs_Plane:
+    default:
+      theErrFactorU = theErrFactorV = 1.;
+    }
+  }
+
+  void AdjustCellsCounts (const Handle(Adaptor3d_HSurface)& theFace,
+                          const Standard_Integer            theNbVertices,
+                          Standard_Integer&                 theCellsCountU,
+                          Standard_Integer&                 theCellsCountV)
+  {
+    const GeomAbs_SurfaceType aType = theFace->GetType ();
+    if (aType == GeomAbs_OtherSurface)
+    {
+      // fallback to the default behavior
+      theCellsCountU = theCellsCountV = -1;
+      return;
+    }
+
+    Standard_Real aSqNbVert = theNbVertices;
+    if (aType == GeomAbs_Plane)
+    {
+      theCellsCountU = theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+    }
+    else if (aType == GeomAbs_Cylinder || aType == GeomAbs_Cone)
+    {
+      theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+    }
+    else if (aType == GeomAbs_SurfaceOfExtrusion || aType == GeomAbs_SurfaceOfRevolution)
+    {
+      Handle (Adaptor3d_HCurve) aCurve = theFace->BasisCurve ();
+      if (aCurve->GetType () == GeomAbs_Line ||
+         (aCurve->GetType () == GeomAbs_BSplineCurve && aCurve->Degree () < 2))
+      {
+        // planar, cylindrical, conical cases
+        if (aType == GeomAbs_SurfaceOfExtrusion)
+          theCellsCountU = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+        else
+          theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+      }
+      if (aType == GeomAbs_SurfaceOfExtrusion)
+      {
+        // V is always a line
+        theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+      }
+    }
+    else if (aType == GeomAbs_BezierSurface || aType == GeomAbs_BSplineSurface)
+    {
+      if (theFace->UDegree () < 2)
+      {
+        theCellsCountU = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+      }
+      if (theFace->VDegree () < 2)
+      {
+        theCellsCountV = (Standard_Integer)Ceiling (Pow (2, Log10 (aSqNbVert)));
+      }
+    }
+
+    theCellsCountU = Max (theCellsCountU, 2);
+    theCellsCountV = Max (theCellsCountV, 2);
+  }
+}
+
 //=======================================================================
 //function : Constructor
 //purpose  :
@@ -76,8 +195,10 @@ BRepMesh_GeomTool::BRepMesh_GeomTool(
 //=======================================================================
 Standard_Boolean BRepMesh_GeomTool::Value(
   const Standard_Integer              theIndex,
+  const Handle(BRepAdaptor_HSurface)& theSurface,
   Standard_Real&                      theParam,
-  gp_Pnt&                             thePoint) const
+  gp_Pnt&                             thePoint,
+  gp_Pnt2d&                           theUV) const
 {
   if (theIndex < 1 || theIndex > NbPoints())
     return Standard_False;
@@ -88,6 +209,14 @@ Standard_Boolean BRepMesh_GeomTool::Value(
   thePoint = myDiscretTool.Value(theIndex);
   theParam = myDiscretTool.Parameter(theIndex);
 
+  const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face();
+
+  Standard_Real aFirst, aLast;
+  Handle(Geom2d_Curve) aCurve = 
+    BRep_Tool::CurveOnSurface(*myEdge, aFace, aFirst, aLast);
+
+  aCurve->D0(theParam, theUV);
+
   return Standard_True;
 }
 
@@ -95,11 +224,12 @@ Standard_Boolean BRepMesh_GeomTool::Value(
 //function : Value
 //purpose  :
 //=======================================================================
-Standard_Boolean BRepMesh_GeomTool::Value(const Standard_Integer theIndex,
-                                          const Standard_Real    theIsoParam,
-                                          Standard_Real&         theParam,
-                                          gp_Pnt&                thePoint,
-                                          gp_Pnt2d&              theUV) const
+Standard_Boolean BRepMesh_GeomTool::Value(
+  const Standard_Integer theIndex,
+  const Standard_Real    theIsoParam,
+  Standard_Real&         theParam,
+  gp_Pnt&                thePoint,
+  gp_Pnt2d&              theUV) const
 {
   if (theIndex < 1 || theIndex > NbPoints())
     return Standard_False;
@@ -286,13 +416,63 @@ BRepMesh_GeomTool::IntFlag BRepMesh_GeomTool::IntSegSeg(
   const Standard_Real aEndPrec = 1 - aPrec;
   for (Standard_Integer i = 0; i < 2; ++i)
   {
-    if( aParam[i] < aPrec || aParam[i] > aEndPrec )
+    if(aParam[i] < aPrec || aParam[i] > aEndPrec )
       return BRepMesh_GeomTool::NoIntersection;
   }
  
   return BRepMesh_GeomTool::Cross;
 }
 
+//=============================================================================
+//function : CellsCount
+//purpose  :
+//=============================================================================
+std::pair<Standard_Integer, Standard_Integer> BRepMesh_GeomTool::CellsCount (
+  const Handle (Adaptor3d_HSurface)&   theSurface,
+  const Standard_Integer               theVerticesNb,
+  const Standard_Real                  theDeflection,
+  const BRepMesh_DefaultRangeSplitter* theRangeSplitter)
+{
+  if (theRangeSplitter == NULL)
+    return std::pair<Standard_Integer, Standard_Integer>(-1, -1);
+
+  const GeomAbs_SurfaceType aType = theSurface->GetType ();
+
+  Standard_Real anErrFactorU, anErrFactorV;
+  ComputeErrFactors(theDeflection, theSurface, anErrFactorU, anErrFactorV);
+
+  const std::pair<Standard_Real, Standard_Real>& aRangeU = theRangeSplitter->GetRangeU();
+  const std::pair<Standard_Real, Standard_Real>& aRangeV = theRangeSplitter->GetRangeV();
+  const std::pair<Standard_Real, Standard_Real>& aDelta  = theRangeSplitter->GetDelta ();
+
+  Standard_Integer aCellsCountU, aCellsCountV;
+  if (aType == GeomAbs_Torus)
+  {
+    aCellsCountU = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeU.second - aRangeU.first) / aDelta.first)));
+    aCellsCountV = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeV.second - aRangeV.first) / aDelta.second)));
+  }
+  else if (aType == GeomAbs_Cylinder)
+  {
+    aCellsCountU = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeU.second - aRangeU.first) / aDelta.first /
+      (aRangeV.second - aRangeV.first))));
+    aCellsCountV = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeV.second - aRangeV.first) / anErrFactorV)));
+  }
+  else
+  {
+    aCellsCountU = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeU.second - aRangeU.first) / aDelta.first  / anErrFactorU)));
+    aCellsCountV = (Standard_Integer)Ceiling(Pow(2, Log10(
+      (aRangeV.second - aRangeV.first) / aDelta.second / anErrFactorV)));
+  }
+
+  AdjustCellsCounts(theSurface, theVerticesNb, aCellsCountU, aCellsCountV);
+  return std::pair<Standard_Integer, Standard_Integer>(aCellsCountU, aCellsCountV);
+}
+
 //=============================================================================
 //function : classifyPoint
 //purpose  : 
index 047cb188c0104bc74de52ad474184a79da76338d..6d69c4bd76b099fca66a980800d705c1e799bf87 100644 (file)
@@ -27,6 +27,8 @@ class BRepAdaptor_HSurface;
 class gp_Pnt;
 class gp_Pnt2d;
 class gp_Dir;
+class BRepMesh_DefaultRangeSplitter;
+class Adaptor3d_HSurface;
 
 //! Tool class accumulating common geometrical functions as well as 
 //! functionality using shape geometry to produce data necessary for 
@@ -60,13 +62,14 @@ public:
   //! @param theLinDeflection linear deflection.
   //! @param theAngDeflection angular deflection.
   //! @param theMinPointsNb minimum nuber of points to be produced.
-  Standard_EXPORT BRepMesh_GeomTool(const BRepAdaptor_Curve& theCurve,
-                                    const Standard_Real      theFirstParam,
-                                    const Standard_Real      theLastParam,
-                                    const Standard_Real      theLinDeflection,
-                                    const Standard_Real      theAngDeflection,
-                                    const Standard_Integer   theMinPointsNb = 2,
-                                    const Standard_Real      theMinSize = Precision::Confusion());
+  Standard_EXPORT BRepMesh_GeomTool(
+    const BRepAdaptor_Curve& theCurve,
+    const Standard_Real      theFirstParam,
+    const Standard_Real      theLastParam,
+    const Standard_Real      theLinDeflection,
+    const Standard_Real      theAngDeflection,
+    const Standard_Integer   theMinPointsNb = 2,
+    const Standard_Real      theMinSize = Precision::Confusion());
   
   //! Constructor.
   //! Initiates discretization of geometric curve corresponding 
@@ -79,15 +82,16 @@ public:
   //! @param theLinDeflection linear deflection.
   //! @param theAngDeflection angular deflection.
   //! @param theMinPointsNb minimum nuber of points to be produced.
-  Standard_EXPORT BRepMesh_GeomTool(const Handle(BRepAdaptor_HSurface)& theSurface,
-                                    const GeomAbs_IsoType               theIsoType,
-                                    const Standard_Real                 theParamIso,
-                                    const Standard_Real                 theFirstParam,
-                                    const Standard_Real                 theLastParam,
-                                    const Standard_Real                 theLinDeflection,
-                                    const Standard_Real                 theAngDeflection,
-                                    const Standard_Integer              theMinPointsNb = 2,
-                                    const Standard_Real                 theMinSize = Precision::Confusion());
+  Standard_EXPORT BRepMesh_GeomTool(
+    const Handle(BRepAdaptor_HSurface)& theSurface,
+    const GeomAbs_IsoType               theIsoType,
+    const Standard_Real                 theParamIso,
+    const Standard_Real                 theFirstParam,
+    const Standard_Real                 theLastParam,
+    const Standard_Real                 theLinDeflection,
+    const Standard_Real                 theAngDeflection,
+    const Standard_Integer              theMinPointsNb = 2,
+    const Standard_Real                 theMinSize = Precision::Confusion());
 
   //! Adds point to already calculated points (or replaces existing).
   //! @param thePoint point to be added.
@@ -124,12 +128,16 @@ public:
   
   //! Gets parameters of discretization point with the given index.
   //! @param theIndex index of discretization point.
+  //! @param theSurface surface the curve is lying onto.
   //! @param theParam[out] parameter of the point on the curve.
   //! @param thePoint[out] discretization point.
+  //! @param theUV[out] discretization point in parametric space of the surface.
   //! @return TRUE on success, FALSE elsewhere.
   Standard_EXPORT Standard_Boolean Value(const Standard_Integer              theIndex,
+                                         const Handle(BRepAdaptor_HSurface)& theSurface,
                                          Standard_Real&                      theParam,
-                                         gp_Pnt&                             thePoint) const;
+                                         gp_Pnt&                             thePoint,
+                                         gp_Pnt2d&                           theUV) const;
   
 public: //! @name static API
 
@@ -188,6 +196,38 @@ public: //! @name static API
     const Standard_Boolean isConsiderPointOnSegment,
     gp_Pnt2d&              theIntPnt);
 
+  //! Compute deflection of the given segment.
+  static Standard_Real SquareDeflectionOfSegment(
+    const gp_Pnt& theFirstPoint,
+    const gp_Pnt& theLastPoint,
+    const gp_Pnt& theMidPoint)
+  {
+    // 23.03.2010 skl for OCC21645 - change precision for comparison
+    if (theFirstPoint.SquareDistance(theLastPoint) > Precision::SquareConfusion())
+    {
+      gp_Lin aLin(theFirstPoint, gp_Dir(gp_Vec(theFirstPoint, theLastPoint)));
+      return aLin.SquareDistance(theMidPoint);
+    }
+
+    return theFirstPoint.SquareDistance(theMidPoint);
+  }
+
+  // For better meshing performance we try to estimate the acceleration circles grid structure sizes:
+  // For each parametric direction (U, V) we estimate firstly an approximate distance between the future points -
+  // this estimation takes into account the required face deflection and the complexity of the face.
+  // Particularly, the complexity of the faces based on BSpline curves and surfaces requires much more points.
+  // At the same time, for planar faces and linear parts of the arbitrary surfaces usually no intermediate points
+  // are necessary.
+  // The general idea for each parametric direction:
+  // cells_count = 2 ^ log10 ( estimated_points_count )
+  // For linear parametric direction we fall back to the initial vertex count:
+  // cells_count = 2 ^ log10 ( initial_vertex_count )
+  Standard_EXPORT static std::pair<Standard_Integer, Standard_Integer> CellsCount (
+    const Handle (Adaptor3d_HSurface)&   theSurface,
+    const Standard_Integer               theVerticesNb,
+    const Standard_Real                  theDeflection,
+    const BRepMesh_DefaultRangeSplitter* theRangeSplitter);
+
 private:
 
   //! Classifies the point in case of coincidence of two vectors.
diff --git a/src/BRepMesh/BRepMesh_IEdgeTool.cxx b/src/BRepMesh/BRepMesh_IEdgeTool.cxx
deleted file mode 100644 (file)
index f343c21..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Created on: 2014-08-13
-// 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.
-
-#include <BRepMesh_IEdgeTool.hxx>
-
-
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IEdgeTool,Standard_Transient)
\ No newline at end of file
diff --git a/src/BRepMesh/BRepMesh_IEdgeTool.hxx b/src/BRepMesh/BRepMesh_IEdgeTool.hxx
deleted file mode 100644 (file)
index 6bbd84a..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// Created on: 2014-08-13
-// 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 _BRepMesh_IEdgeTool_HeaderFile
-#define _BRepMesh_IEdgeTool_HeaderFile
-
-#include <Standard.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <Standard_Transient.hxx>
-
-//! Interface class providing API for edge tessellation tools.
-class BRepMesh_IEdgeTool : public Standard_Transient
-{
-public:
-  //! Returns number of tessellation points.
-  virtual Standard_Integer NbPoints() const = 0;
-
-  //! 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.
-  //! @param theUV coordinates of tessellation point in parametric space of face.
-  //! @return True in case of valid result, false elewhere.
-  virtual Standard_Boolean Value(
-    const Standard_Integer theIndex,
-    Standard_Real&         theParameter,
-    gp_Pnt&                thePoint,
-    gp_Pnt2d&              theUV) = 0;
-
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_IEdgeTool,Standard_Transient)
-};
-
-DEFINE_STANDARD_HANDLE(BRepMesh_IEdgeTool, Standard_Transient)
-
-#endif
index e44d979ffb056b3bae3fbc4f18cd306519fff28b..24d3fd3658a3ff5b536ad882989a3e7857a8e3cf 100644 (file)
 // commercial license or contractual agreement.
 
 #include <BRepMesh_IncrementalMesh.hxx>
-
-#include <OSD_Parallel.hxx>
-#include <Precision.hxx>
-#include <Standard_ErrorHandler.hxx>
-
-#include <BRepMesh_ShapeTool.hxx>
-#include <BRepMesh_Edge.hxx>
+#include <BRepMesh_Context.hxx>
 #include <BRepMesh_PluginMacro.hxx>
-
-#include <Bnd_Box.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepTools.hxx>
-#include <BRepLib.hxx>
-#include <BRepBndLib.hxx>
-#include <BRepAdaptor_Curve.hxx>
-
-#include <Poly_Triangulation.hxx>
-#include <Poly_Polygon3D.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopAbs.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_MapOfTransient.hxx>
-#include <TopTools_HArray1OfShape.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-
-#include <GCPnts_TangentialDeflection.hxx>
-
-#include <Message_ProgressSentry.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
+#include <IMeshData_Status.hxx>
+#include <IMeshData_Face.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshTools_MeshBuilder.hxx>
 
 namespace
 {
@@ -65,60 +29,13 @@ namespace
   static Standard_Boolean IS_IN_PARALLEL = Standard_False;
 }
 
-class BRepMesh_IncrementalMesh::FaceListFunctor
-{
-public:
-  FaceListFunctor (BRepMesh_IncrementalMesh* theAlgo,
-                   const Handle(Message_ProgressIndicator)& theProgress,
-                   Standard_Boolean theParallel)
-  : myAlgo (theAlgo),
-    mySentry (theProgress, "Mesh faces", 0, theAlgo->myFaces.Size(), 1),
-    myThreadId (OSD_Thread::Current()),
-    myIsParallel (theParallel),
-    myHasProgress (!theProgress.IsNull())
-  {
-  }
-
-  void operator() (const Standard_Integer theFaceIndex) const
-  {
-    if (!mySentry.More())
-    {
-      return;
-    }
-
-    TopoDS_Face& aFace = myAlgo->myFaces.ChangeValue (theFaceIndex);
-    myAlgo->myMesh->Process (aFace, &mySentry);
-
-    if (myIsParallel)
-    {
-      // use a trick to avoid mutex locks - increment the progress only within main thread
-      if (myHasProgress && myThreadId == OSD_Thread::Current())
-      {
-        mySentry.Next (OSD_Parallel::NbLogicalProcessors());
-      }
-    }
-    else
-    {
-      mySentry.Next();
-    }
-  }
-
-private:
-  mutable BRepMesh_IncrementalMesh* myAlgo;
-  mutable Message_ProgressSentry mySentry;
-  Standard_ThreadId myThreadId;
-  Standard_Boolean myIsParallel;
-  Standard_Boolean myHasProgress;
-};
-
 //=======================================================================
 //function : Default constructor
 //purpose  : 
 //=======================================================================
 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
-: myMaxShapeSize(0.),
-  myModified(Standard_False),
-  myStatus(0)
+: myModified(Standard_False),
+  myStatus(IMeshData_NoError)
 {
 }
 
@@ -130,17 +47,14 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape&    theSh
                                                     const Standard_Real    theLinDeflection,
                                                     const Standard_Boolean isRelative,
                                                     const Standard_Real    theAngDeflection,
-                                                    const Standard_Boolean isInParallel,
-                                                    const Standard_Boolean adaptiveMin)
-: myMaxShapeSize(0.),
-  myModified(Standard_False),
-  myStatus(0)
+                                                    const Standard_Boolean isInParallel)
+: myModified(Standard_False),
+  myStatus(IMeshData_NoError)
 {
   myParameters.Deflection = theLinDeflection;
-  myParameters.Relative = isRelative;
-  myParameters.Angle = theAngDeflection;
+  myParameters.Angle      = theAngDeflection;
+  myParameters.Relative   = isRelative;
   myParameters.InParallel = isInParallel;
-  myParameters.AdaptiveMin = adaptiveMin;
 
   myShape = theShape;
   Perform();
@@ -150,12 +64,12 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh( const TopoDS_Shape&    theSh
 //function : Constructor
 //purpose  : 
 //=======================================================================
-BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
-                                                   const BRepMesh_FastDiscret::Parameters& theParameters)
+BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(
+  const TopoDS_Shape&          theShape,
+  const IMeshTools_Parameters& theParameters)
   : myParameters(theParameters)
 {
-  myShape       = theShape;
-  
+  myShape = theShape;
   Perform();
 }
 
@@ -167,490 +81,46 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
 {
 }
 
-//=======================================================================
-//function : clear
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::clear()
-{
-  // the allocator will be alive while the structures are alive
-  Handle(NCollection_BaseAllocator) anAlloc =
-    new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
-  myEdges.Clear(anAlloc);
-  myEdgeDeflection.Clear(anAlloc);
-  myFaces.Clear();
-  myMesh.Nullify();
-}
-
-//=======================================================================
-//function : init
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::init() 
-{
-  myStatus   = 0;
-  myModified = Standard_False;
-
-  setDone();
-  clear();
-
-  collectFaces();
-
-  Bnd_Box aBox;
-  if ( myParameters.Relative ) 
-  {
-    BRepBndLib::Add(myShape, aBox, Standard_False);
-
-    if (aBox.IsVoid())
-    {
-      // Nothing to mesh.
-      return;
-    }
-
-    BRepMesh_ShapeTool::BoxMaxDimension(aBox, myMaxShapeSize);
-  }
-
-  myMesh = new BRepMesh_FastDiscret (aBox, myParameters);
-  
-  myMesh->InitSharedFaces(myShape);
-}
-
-//=======================================================================
-//function : collectFaces
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::collectFaces()
-{
-  Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
-  TopTools_ListOfShape aFaceList(anAlloc);
-  BRepLib::ReverseSortFaces(myShape, aFaceList);
-  TColStd_MapOfTransient aTFaceMap(1, anAlloc);
-
-  // make array of faces suitable for processing (excluding faces without surface)
-  TopLoc_Location aDummyLoc;
-  TopTools_ListIteratorOfListOfShape aFaceIter(aFaceList);
-  for (; aFaceIter.More(); aFaceIter.Next())
-  {
-    const TopoDS_Face& aFace = TopoDS::Face(aFaceIter.Value());
-    const Handle(TopoDS_TShape)& aTFace = aFace.TShape();
-    if (!aTFaceMap.Add (aTFace))
-      continue; // already processed
-
-    const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aDummyLoc);
-    if (aSurf.IsNull())
-      continue;
-
-    myFaces.Append(aFace);
-  }
-}
-
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
 void BRepMesh_IncrementalMesh::Perform()
 {
-  Perform (Handle(Message_ProgressIndicator)());
+  Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
+  Perform (aContext);
 }
 
 //=======================================================================
 //function : Perform
-//purpose  :
-//=======================================================================
-void BRepMesh_IncrementalMesh::Perform (const Handle(Message_ProgressIndicator)& theProgress)
-{
-  init();
-
-  if (myMesh.IsNull())
-    return;
-
-  update (theProgress);
-}
-
-//=======================================================================
-//function : update()
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::update (const Handle(Message_ProgressIndicator)& theProgress)
-{
-  Message_ProgressSentry anOuterSentry (theProgress, "Updating", 0, 100, 1);
-
-  // Update edges data
-  anOuterSentry.Next(9);
-  {
-    int aNbEdges = 0;
-    for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
-    {
-      ++aNbEdges;
-    }
-
-    Message_ProgressSentry anEdgeSentry (theProgress, "Update edges data", 0, aNbEdges, 1);
-    for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE);
-         aExplorer.More() && anEdgeSentry.More(); aExplorer.Next(), anEdgeSentry.Next())
-    {
-      const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
-      if(!BRep_Tool::IsGeometric(aEdge))
-        continue;
-
-      update(aEdge);
-    }
-  }
-
-  if (!anOuterSentry.More())
-  {
-    myStatus = BRepMesh_UserBreak;
-    return;
-  }
-  anOuterSentry.Next(5);
-
-  // Update faces data
-  NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
-  for (Message_ProgressSentry aFacesSentry (theProgress, "Update faces data", 0, myFaces.Size(), 1);
-       aFaceIt.More() && aFacesSentry.More(); aFaceIt.Next(), aFacesSentry.Next())
-  {
-    update(aFaceIt.Value());
-  }
-
-  if (!anOuterSentry.More())
-  {
-    myStatus = BRepMesh_UserBreak;
-    return;
-  }
-
-  anOuterSentry.Next(80);
-
-  {
-    // Mesh faces
-    FaceListFunctor aFacesFunctor (this, theProgress, myParameters.InParallel);
-    OSD_Parallel::For (0, myFaces.Size(), aFacesFunctor, !myParameters.InParallel);
-  }
-
-  if (!anOuterSentry.More())
-  {
-    myStatus = BRepMesh_UserBreak;
-    return;
-  }
-
-  anOuterSentry.Next(5);
-  {
-    Message_ProgressSentry aSentry (theProgress, "Commit", 0, myFaces.Size(), 1);
-    commit (aSentry);
-  }
-  anOuterSentry.Next();
-  clear();
-}
-
-//=======================================================================
-//function : discretizeFreeEdges
 //purpose  : 
 //=======================================================================
-void BRepMesh_IncrementalMesh::discretizeFreeEdges()
+void BRepMesh_IncrementalMesh::Perform(const Handle(IMeshTools_Context)& theContext)
 {
-  TopExp_Explorer aExplorer(myShape ,TopAbs_EDGE, TopAbs_FACE);
-  for (; aExplorer.More(); aExplorer.Next())
-  {
-    const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
-    if(!BRep_Tool::IsGeometric(aEdge))
-      continue;
-    
-    TopLoc_Location aLoc;
-    Standard_Real aEdgeDeflection  = edgeDeflection(aEdge);
-    Handle(Poly_Polygon3D) aPoly3D = BRep_Tool::Polygon3D(aEdge, aLoc);
-    if (!aPoly3D.IsNull() && aPoly3D->Deflection() < 1.1 * aEdgeDeflection)
-      continue;
-
-    BRepAdaptor_Curve aCurve(aEdge);
-    GCPnts_TangentialDeflection aDiscret(aCurve, aCurve.FirstParameter(),
-      aCurve.LastParameter(), myParameters.Angle, aEdgeDeflection, 2,
-      Precision::PConfusion(), myParameters.MinSize);
-
-    Standard_Integer aNodesNb = aDiscret.NbPoints();
-    TColgp_Array1OfPnt   aNodes  (1, aNodesNb);
-    TColStd_Array1OfReal aUVNodes(1, aNodesNb);
-    for (Standard_Integer i = 1; i <= aNodesNb; ++i)
-    {
-      aNodes  (i) = aDiscret.Value(i);
-      aUVNodes(i) = aDiscret.Parameter(i);
-    }
-    
-    aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes);
-    aPoly3D->Deflection(myParameters.Deflection);
-
-    BRep_Builder aBuilder;
-    aBuilder.UpdateEdge(aEdge, aPoly3D);
-  }
-}
-
-//=======================================================================
-//function : edgeDeflection
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_IncrementalMesh::edgeDeflection(
-  const TopoDS_Edge& theEdge)
-{
-  const Standard_Real* pDef = myEdgeDeflection.Seek(theEdge);
-  if (pDef)
-    return *pDef;
-
-  Standard_Real aEdgeDeflection;
-  if ( myParameters.Relative ) 
-  {
-    Standard_Real aScale;
-    aEdgeDeflection = BRepMesh_ShapeTool::RelativeEdgeDeflection(theEdge, 
-      myParameters.Deflection, myMaxShapeSize, aScale);
-  }
-  else
-    aEdgeDeflection = myParameters.Deflection;
-
-  myEdgeDeflection.Bind(theEdge, aEdgeDeflection);
-  return aEdgeDeflection;
-}
-
-//=======================================================================
-//function : faceDeflection
-//purpose  : 
-//=======================================================================
-Standard_Real BRepMesh_IncrementalMesh::faceDeflection(
-  const TopoDS_Face& theFace)
-{
-  if ( !myParameters.Relative )
-    return myParameters.Deflection;
-
-  Standard_Integer aEdgesNb        = 0;
-  Standard_Real    aFaceDeflection = 0.;
-
-  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
-  for (; aEdgeIt.More(); aEdgeIt.Next(), ++aEdgesNb)
-  {
-    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-    aFaceDeflection += edgeDeflection(aEdge);
-  }
-
-  return (aEdgesNb == 0) ? myParameters.Deflection : (aFaceDeflection / aEdgesNb);
-}
-
-//=======================================================================
-//function : update(edge)
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::update(const TopoDS_Edge& theEdge)
-{
-  if (!myEdges.IsBound(theEdge))
-    myEdges.Bind(theEdge, BRepMesh::DMapOfTriangulationBool(3, myEdges.Allocator()));
-
-  Standard_Real aEdgeDeflection = edgeDeflection(theEdge);
-  // Check that triangulation relies to face of the given shape.
-  const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
-    myMesh->SharedFaces();
-
-  const TopTools_ListOfShape& aSharedFaces = 
-    aMapOfSharedFaces.FindFromKey(theEdge);
-
-  TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
-  for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
-  {
-    TopLoc_Location aLoc;
-    const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
-    const Handle(Poly_Triangulation)& aFaceTriangulation = 
-      BRep_Tool::Triangulation(aFace, aLoc);
-
-    if (aFaceTriangulation.IsNull())
-      continue;
-
-    Standard_Boolean isConsistent = Standard_False;
-    const Handle(Poly_PolygonOnTriangulation)& aPolygon =
-      BRep_Tool::PolygonOnTriangulation(theEdge, aFaceTriangulation, aLoc);
-
-    if (!aPolygon.IsNull())
-    {
-      isConsistent = aPolygon->Deflection() < 1.1 * aEdgeDeflection &&
-        aPolygon->HasParameters();
-
-      if (!isConsistent)
-      {
-        myModified = Standard_True;
-        BRepMesh_ShapeTool::NullifyEdge(theEdge, aFaceTriangulation, aLoc);
-      }
-    }
-
-    myEdges(theEdge).Bind(aFaceTriangulation, isConsistent);
-  }
-}
-
-//=======================================================================
-//function : isToBeMeshed
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_IncrementalMesh::toBeMeshed(
-  const TopoDS_Face&     theFace,
-  const Standard_Boolean isWithCheck)
-{
-  TopLoc_Location aLoc;
-  const Handle(Poly_Triangulation)& aTriangulation = 
-    BRep_Tool::Triangulation(theFace, aLoc);
-
-  if (aTriangulation.IsNull())
-    return Standard_True;
+  initParameters();
 
-  if (isWithCheck)
-  {
-    Standard_Real aFaceDeflection = faceDeflection(theFace);
-    if (aTriangulation->Deflection() < 1.1 * aFaceDeflection)
-    {
-      Standard_Boolean isEdgesConsistent = Standard_True;
-      TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
-      for (; aEdgeIt.More() && isEdgesConsistent; aEdgeIt.Next())
-      {
-        const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-        if (!myEdges.IsBound(aEdge))
-          continue;
+  theContext->SetShape(Shape());
+  theContext->ChangeParameters()            = myParameters;
+  theContext->ChangeParameters().CleanModel = Standard_False;
 
-        BRepMesh::DMapOfTriangulationBool& aTriMap = myEdges(aEdge);
-        isEdgesConsistent &= aTriMap.IsBound(aTriangulation) &&
-          aTriMap(aTriangulation);
-      }
+  IMeshTools_MeshBuilder aIncMesh(theContext);
+  aIncMesh.Perform();
 
-      if (isEdgesConsistent)
-      {
-        // #25080: check that indices of links forming triangles are in range.
-        Standard_Boolean isTriangulationConsistent = Standard_True;
-        const Standard_Integer aNodesNb = aTriangulation->NbNodes();
-        const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
-        Standard_Integer i = aTriangles.Lower();
-        for (; i <= aTriangles.Upper() && isTriangulationConsistent; ++i)
-        {
-          const Poly_Triangle& aTriangle = aTriangles(i);
-          Standard_Integer n[3];
-          aTriangle.Get(n[0], n[1], n[2]);
-          for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
-            isTriangulationConsistent = (n[j] >= 1 && n[j] <= aNodesNb);
-        }
-
-        if (isTriangulationConsistent)
-          return Standard_False;
-      }
-    }
-  }
-
-  // Nullify edges
-  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
-  for (; aEdgeIt.More(); aEdgeIt.Next())
+  myStatus = IMeshData_NoError;
+  const Handle(IMeshData_Model)& aModel = theContext->GetModel();
+  for (Standard_Integer aFaceIt = 0; aFaceIt < aModel->FacesNb(); ++aFaceIt)
   {
-    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-    BRepMesh_ShapeTool::NullifyEdge(aEdge, aTriangulation, aLoc);
-  }
-
-  BRepMesh_ShapeTool::NullifyFace(theFace);
-  return Standard_True;
-}
-
-//=======================================================================
-//function : update(face)
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace)
-{
-  if (!toBeMeshed(theFace, Standard_True))
-    return;
-
-  myModified = Standard_True;
-  Standard_Integer aStatus = myMesh->Add(theFace);
-
-  myStatus |= aStatus;
-  if (aStatus != BRepMesh_ReMesh)
-    return;
-
-  BRepMesh::MapOfShape aUsedFaces;
-  aUsedFaces.Add(theFace);
-
-  const TopTools_IndexedDataMapOfShapeListOfShape& aMapOfSharedFaces = 
-    myMesh->SharedFaces();
+    const IMeshData::IFaceHandle& aDFace = aModel->GetFace(aFaceIt);
+    myStatus |= aDFace->GetStatusMask();
 
-  TopExp_Explorer aEdgeIt(theFace, TopAbs_EDGE);
-  for (; aEdgeIt.More(); aEdgeIt.Next())
-  {
-    const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Current());
-    if (aMapOfSharedFaces.FindIndex(aEdge) == 0)
-      continue;
-     
-    const TopTools_ListOfShape& aSharedFaces = aMapOfSharedFaces.FindFromKey(aEdge);
-    TopTools_ListIteratorOfListOfShape aSharedFaceIt(aSharedFaces);
-    for (; aSharedFaceIt.More(); aSharedFaceIt.Next())
+    for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
     {
-      const TopoDS_Face& aFace = TopoDS::Face(aSharedFaceIt.Value());
-      if (aUsedFaces.Contains(aFace))
-        continue;
-
-      aUsedFaces.Add(aFace);
-      toBeMeshed(aFace, Standard_False);
-
-      myStatus |= myMesh->Add(aFace);
+      const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
+      myStatus |= aDWire->GetStatusMask();
     }
   }
-}
 
-//=======================================================================
-//function : commit
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::commit (Message_ProgressSentry& theSentry)
-{
-  NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
-  for (; aFaceIt.More() && theSentry.More(); aFaceIt.Next(), theSentry.Next())
-    commitEdges(aFaceIt.Value());
-
-  discretizeFreeEdges();
-}
-
-//=======================================================================
-//function : commitEdges
-//purpose  : 
-//=======================================================================
-void BRepMesh_IncrementalMesh::commitEdges(const TopoDS_Face& theFace)
-{
-  TopoDS_Face aFace = theFace;
-  aFace.Orientation(TopAbs_FORWARD);
-
-  Handle(BRepMesh_FaceAttribute) aFaceAttribute;
-  if (!myMesh->GetFaceAttribute(aFace, aFaceAttribute))
-    return;
-
-  if (!aFaceAttribute->IsValid())
-  {
-    myStatus |= aFaceAttribute->GetStatus();
-    return;
-  }
-
-  TopLoc_Location aLoc;
-  Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, aLoc);
-
-  if (aTriangulation.IsNull())
-    return;
-
-  try
-  {
-    OCC_CATCH_SIGNALS
-
-    // Store discretization of edges
-    BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = aFaceAttribute->ChangeInternalEdges();
-    BRepMesh::DMapOfShapePairOfPolygon::Iterator aEdgeIt(*aInternalEdges);
-    for (; aEdgeIt.More(); aEdgeIt.Next())
-    {
-      const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Key());
-      const BRepMesh_PairOfPolygon& aPolyPair = aEdgeIt.Value();
-      const Handle(Poly_PolygonOnTriangulation)& aPolygon1 = aPolyPair.First();
-      const Handle(Poly_PolygonOnTriangulation)& aPolygon2 = aPolyPair.Last();
-
-      if (aPolygon1 == aPolygon2)
-        BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aTriangulation, aLoc);
-      else
-        BRepMesh_ShapeTool::UpdateEdge(aEdge, aPolygon1, aPolygon2, aTriangulation, aLoc);
-    }
-  }
-  catch (Standard_Failure)
-  {
-    myStatus |= BRepMesh_Failure;
-  }
+  setDone();
 }
 
 //=======================================================================
@@ -665,9 +135,9 @@ Standard_Integer BRepMesh_IncrementalMesh::Discret(
 {
   BRepMesh_IncrementalMesh* anAlgo = new BRepMesh_IncrementalMesh();
   anAlgo->ChangeParameters().Deflection = theDeflection;
-  anAlgo->ChangeParameters().Angle = theAngle;
+  anAlgo->ChangeParameters().Angle      = theAngle;
   anAlgo->ChangeParameters().InParallel = IS_IN_PARALLEL;
-  anAlgo->SetShape     (theShape);
+  anAlgo->SetShape (theShape);
   theAlgo = anAlgo;
   return 0; // no error
 }
index 84541536f982606f9f3f889ddd4216f6d40f28d7..4831ffa43463402f80673190b4807ed7f3311386 100644 (file)
 #ifndef _BRepMesh_IncrementalMesh_HeaderFile
 #define _BRepMesh_IncrementalMesh_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <BRepMesh_FastDiscret.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_DataMapOfShapeReal.hxx>
 #include <BRepMesh_DiscretRoot.hxx>
-#include <BRepMesh.hxx>
-
-#include <vector>
-
-class Message_ProgressIndicator;
-class Poly_Triangulation;
-class TopoDS_Shape;
-class TopoDS_Edge;
-class TopoDS_Face;
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshTools_Context.hxx>
 
 //! Builds the mesh of a shape with respect of their 
 //! correctly triangulated parts 
@@ -52,41 +39,39 @@ public: //! @name mesher API
   //! used for the faces will be the maximum deflection of their edges.
   //! @param theAngDeflection angular deflection.
   //! @param isInParallel if TRUE shape will be meshed in parallel.
-  Standard_EXPORT BRepMesh_IncrementalMesh(
-    const TopoDS_Shape&    theShape,
-    const Standard_Real    theLinDeflection,
-    const Standard_Boolean isRelative = Standard_False,
-    const Standard_Real    theAngDeflection = 0.5,
-    const Standard_Boolean isInParallel = Standard_False,
-    const Standard_Boolean adaptiveMin = Standard_False);  
+  Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape&    theShape,
+                                           const Standard_Real    theLinDeflection,
+                                           const Standard_Boolean isRelative = Standard_False,
+                                           const Standard_Real    theAngDeflection = 0.5,
+                                           const Standard_Boolean isInParallel = Standard_False);
 
   //! Constructor.
   //! Automatically calls method Perform.
   //! @param theShape shape to be meshed.
   //! @param theParameters - parameters of meshing
-  Standard_EXPORT BRepMesh_IncrementalMesh (const TopoDS_Shape& theShape,
-                                            const BRepMesh_FastDiscret::Parameters& theParameters);
+  Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape&          theShape,
+                                           const IMeshTools_Parameters& theParameters);
 
   //! Performs meshing ot the shape.
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
 
-  //! Performs meshing ot the shape.
-  Standard_EXPORT void Perform(const Handle(Message_ProgressIndicator)& theProgress);
-
+  //! Performs meshing using custom context;
+  Standard_EXPORT void Perform(const Handle(IMeshTools_Context)& theContext);
+  
 public: //! @name accessing to parameters.
 
   //! Returns meshing parameters
-  inline const BRepMesh_FastDiscret::Parameters& Parameters() const
+  inline const IMeshTools_Parameters& Parameters() const
   {
     return myParameters;
   }
 
   //! Returns modifiable meshing parameters
-  inline BRepMesh_FastDiscret::Parameters& ChangeParameters()
+  inline IMeshTools_Parameters& ChangeParameters()
   {
     return myParameters;
   }
-  
+
   //! Returns modified flag.
   inline Standard_Boolean IsModified() const
   {
@@ -99,6 +84,29 @@ public: //! @name accessing to parameters.
     return myStatus;
   }
   
+private:
+
+  //! Initializes specific parameters
+  inline void initParameters()
+  {
+    if (myParameters.DeflectionInterior < Precision::Confusion())
+    {
+      myParameters.DeflectionInterior = myParameters.Deflection;
+    }
+
+    if (myParameters.MinSize < Precision::Confusion())
+    {
+      myParameters.MinSize =
+        Max(IMeshTools_Parameters::RelMinSize() * Min(myParameters.Deflection,
+                                                      myParameters.DeflectionInterior),
+            Precision::Confusion());
+    }
+
+    if (myParameters.AngleInterior < Precision::Angular())
+    {
+      myParameters.AngleInterior = 2.0 * myParameters.Angle;
+    }
+  }
 
 public: //! @name plugin API
 
@@ -121,81 +129,13 @@ public: //! @name plugin API
   //! Discret() static method (thus applied only to Mesh Factories).
   Standard_EXPORT static void SetParallelDefault(const Standard_Boolean isInParallel);
 
-  DEFINE_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_IncrementalMesh, BRepMesh_DiscretRoot)
 
 protected:
 
-  Standard_EXPORT virtual void init() Standard_OVERRIDE;
-
-private:
-
-  //! Builds the incremental mesh for the shape.
-  void update(const Handle(Message_ProgressIndicator)& theProgress);
-
-  //! Checks triangulation of the given face for consistency 
-  //! with the chosen tolerance. If some edge of face has no
-  //! discrete representation triangulation will be calculated.
-  //! @param theFace face to be checked.
-  void update(const TopoDS_Face& theFace);
-
-  //! Checks discretization of the given edge for consistency 
-  //! with the chosen tolerance.
-  //! @param theEdge edge to be checked.
-  void update(const TopoDS_Edge& theEdge);
-
-  //! Collects faces suitable for meshing.
-  void collectFaces();
-
-  //! Discretizes edges that have no associations with faces.
-  void discretizeFreeEdges();
-
-  //! Returns deflection of the given edge.
-  //! @param theEdge edge which tolerance should be taken.
-  Standard_Real edgeDeflection(const TopoDS_Edge& theEdge);
-
-  //! Returns deflection of the given face.
-  //! If relative flag is set, calculates relative deflection of the face 
-  //! as an average value of relative deflection regarding face's edges.
-  //! Returns value of deflection set by user elsewhere.
-  Standard_Real faceDeflection(const TopoDS_Face& theFace);
-
-  //! Prepares the given face for meshing.
-  //! Nullifies triangulation of face and polygons of face's edges.
-  //! @param theFace face to be checked.
-  //! @param isWithCheck if TRUE, checks parameters of triangulation 
-  //! existing in face. If its deflection satisfies the given value and
-  //! each edge of face has polygon corresponded to this triangulation,
-  //! method return FALSE.
-  //! @return TRUE in case if the given face should be meshed.
-  Standard_Boolean toBeMeshed(const TopoDS_Face&     theFace,
-                              const Standard_Boolean isWithCheck);
-
-  //! Stores mesh to the shape.
-  void commit(Message_ProgressSentry& theSentry);
-
-  //! Stores mesh of internal edges to the face.
-  void commitEdges(const TopoDS_Face& theFace);
-  
-  //! Clears internal data structures.
-  void clear();
-
-private:
-  class FaceListFunctor;
-
-protected:
-
-  BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges;
-  Handle(BRepMesh_FastDiscret)                myMesh;
-  TopTools_DataMapOfShapeReal                 myEdgeDeflection;
-  NCollection_Vector<TopoDS_Face>             myFaces;
-
-  BRepMesh_FastDiscret::Parameters myParameters;
-
-  Standard_Real                               myMaxShapeSize;
-  Standard_Boolean                            myModified;
-  Standard_Integer                            myStatus;
+  IMeshTools_Parameters myParameters;
+  Standard_Boolean      myModified;
+  Standard_Integer      myStatus;
 };
 
-DEFINE_STANDARD_HANDLE(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
-
 #endif
diff --git a/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx b/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx
new file mode 100644 (file)
index 0000000..891448a
--- /dev/null
@@ -0,0 +1,105 @@
+// 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, BRepMesh_DelaunayBaseMeshAlgo> Type;
+  };
+
+  template<class RangeSplitter>
+  struct DeflectionControlMeshAlgo
+  {
+    typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> 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 theParameters.InternalVerticesMode ?
+      new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
+      new BaseMeshAlgo::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_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..1a15482
--- /dev/null
@@ -0,0 +1,84 @@
+// 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_ShapeTool.hxx>
+#include <IMeshTools_ShapeExplorer.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::performInternal (
+  const TopoDS_Shape&          theShape,
+  const IMeshTools_Parameters& theParameters)
+{
+  Handle (BRepMeshData_Model) aModel;
+
+  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(Max(theParameters.Deflection,
+                             theParameters.DeflectionInterior));
+    }
+
+    Handle (IMeshTools_ShapeVisitor) aVisitor =
+      new BRepMesh_ShapeVisitor (aModel);
+
+    IMeshTools_ShapeExplorer aExplorer (theShape);
+    aExplorer.Accept (aVisitor);
+    SetStatus (Message_Done1);
+  }
+  else
+  {
+    SetStatus (Message_Fail1);
+  }
+
+  return aModel;
+}
diff --git a/src/BRepMesh/BRepMesh_ModelBuilder.hxx b/src/BRepMesh/BRepMesh_ModelBuilder.hxx
new file mode 100644 (file)
index 0000000..56898a1
--- /dev/null
@@ -0,0 +1,50 @@
+// 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 ();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
+
+protected:
+
+  //! Creates discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+};
+
+#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..6ad9b83
--- /dev/null
@@ -0,0 +1,499 @@
+// 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;
+      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();
+      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::performInternal(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   theParameters)
+{
+  myModel      = theModel;
+  myParameters = theParameters;
+  if (myModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  // MinSize is made as a constant. It is connected with
+  // the fact that too rude discretisation can lead to 
+  // self-intersecting polygon, which cannot be fixed.
+  // As result the face will not be triangulated at all.
+  // E.g. see "Test mesh standard_mesh C7", the face #17.
+  myParameters.MinSize = Precision::Confusion();
+
+  myFaceIntersectingEdges = new IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs;
+  for (Standard_Integer aFaceIt = 0; aFaceIt < myModel->FacesNb(); ++aFaceIt)
+  {
+    myFaceIntersectingEdges->Bind(myModel->GetFace(aFaceIt).get(), 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();
+      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),
+                          aEdgesToUpdate.Size());
+
+    IMeshData::MapOfIFacePtr aFacesToCheck(1, aTmpAlloc);
+    IMeshData::MapOfIEdgePtr::Iterator aEdgeIt(aEdgesToUpdate);
+    for (; aEdgeIt.More(); aEdgeIt.Next())
+    {
+      const IMeshData::IEdgeHandle aDEdge = aEdgeIt.Value();
+      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),
+                          aFacesToCheck.Size());
+
+    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
+{
+  try
+  {
+    OCC_CATCH_SIGNALS
+
+    Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
+    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();
+      }
+      else
+      {
+        if (theDFace->WiresNb () == 1)
+        {
+          const IMeshData::IWireHandle& aDWire = theDFace->GetWire (0);
+
+          if (aDWire->EdgesNb () == 2)
+          {
+            const IMeshData::IEdgePtr& aDEdge0 = aDWire->GetEdge (0);
+            const IMeshData::IEdgePtr& aDEdge1 = aDWire->GetEdge (1);
+
+            const IMeshData::IPCurveHandle& aPCurve0 = aDEdge0->GetPCurve (theDFace.get (), aDWire->GetEdgeOrientation (0));
+            const IMeshData::IPCurveHandle& aPCurve1 = aDEdge1->GetPCurve (theDFace.get (), aDWire->GetEdgeOrientation (1));
+
+            if (aPCurve0->ParametersNb () == 2 && aPCurve1->ParametersNb () == 2)
+            {
+              aIntersections = new IMeshData::MapOfIEdgePtr;
+              // a kind of degenerated face - 1 wire, 2 edges and both edges are very small
+              aIntersections->Add (aDEdge0);
+              aIntersections->Add (aDEdge1);
+            }
+          }
+        }
+      }
+    }
+  }
+  catch (Standard_Failure const&)
+  {
+    theDFace->SetStatus (IMeshData_Failure);
+  }
+}
+
+//=======================================================================
+// 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);
+      const IMeshData::IEdgeHandle aCurrEdge = aDWire->GetEdge(aEdgeIt);
+      const IMeshData::IEdgeHandle aNextEdge = aDWire->GetEdge(aNextEdgeIt);
+
+      Standard_Boolean isConnected = !getCommonVertex(aCurrEdge, aNextEdge).IsNull() &&
+                                     !getCommonVertex(aPrevEdge, aCurrEdge).IsNull();
+
+      if (isConnected)
+      {
+        const IMeshData::IPCurveHandle& aPrevPCurve =
+          aPrevEdge->GetPCurve(theDFace.get(), aDWire->GetEdgeOrientation(aPrevEdgeIt));
+
+        const IMeshData::IPCurveHandle& aCurrPCurve =
+          aCurrEdge->GetPCurve(theDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
+
+        const IMeshData::IPCurveHandle& aNextPCurve =
+          aNextEdge->GetPCurve(theDFace.get(), 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);
+
+  //Test bugs moddata_2 bug428.
+  //  restore [locate_data_file OCC428.brep] rr
+  //  explode rr f
+  //  explode rr_91 w
+  //  explode rr_91_2 e
+  //  nbshapes rr_91_2_2
+  //  # 0 vertices; 1 edge
+
+  //This shape is invalid and can lead to exception in this code.
+
+  if (aVertex1_1.IsNull() || aVertex1_2.IsNull())
+    return TopoDS_Vertex();
+
+  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 (aVertex2_1.IsNull() || aVertex2_2.IsNull())
+    return TopoDS_Vertex();
+
+  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..2e95c02
--- /dev/null
@@ -0,0 +1,185 @@
+// 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's 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();
+
+  //! 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::IFaceHandle& theDFace) const {
+    process(theDFace);
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
+
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+
+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..2315051
--- /dev/null
@@ -0,0 +1,192 @@
+// 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->GetCurve()->ParametersNb() == 0)
+        return;
+
+      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;
+        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()->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::performInternal(
+  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..129ba74
--- /dev/null
@@ -0,0 +1,45 @@
+// 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();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
+
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx b/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx
new file mode 100644 (file)
index 0000000..c9d02d4
--- /dev/null
@@ -0,0 +1,307 @@
+// 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>
+#include <BRepMesh_ConeRangeSplitter.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 = 
+          aTriangulation->Deflection() < 1.1 * aDFace->GetDeflection();
+
+        if (isTriangulationConsistent)
+        {
+          // #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;
+  };
+
+  //! Adds additional points to seam edges on specific surfaces.
+  class SeamEdgeAmplifier
+  {
+  public:
+    //! Constructor
+    SeamEdgeAmplifier(const Handle(IMeshData_Model)& theModel,
+                      const IMeshTools_Parameters&   theParameters)
+      : myModel (theModel)
+      , myParameters (theParameters)
+    {
+    }
+
+    //! Main functor.
+    void operator()(const Standard_Integer theFaceIndex) const
+    {
+      const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+      if (aDFace->GetSurface()->GetType() != GeomAbs_Cone)
+      {
+        return;
+      }
+
+      const IMeshData::IWireHandle& aDWire = aDFace->GetWire (0);
+      for (Standard_Integer aEdgeIdx = 0; aEdgeIdx < aDWire->EdgesNb() - 1; ++aEdgeIdx)
+      {
+        const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge (aEdgeIdx);
+        
+        if (aDEdge->GetPCurve(aDFace.get(), TopAbs_FORWARD) != aDEdge->GetPCurve(aDFace.get(), TopAbs_REVERSED))
+        {
+          if (aDEdge->GetCurve()->ParametersNb() == 2)
+          {
+            if (splitEdge (aDEdge, Abs (getConeStep (aDFace))))
+            {
+              TopLoc_Location aLoc;
+              const Handle (Poly_Triangulation)& aTriangulation =
+                BRep_Tool::Triangulation (aDFace->GetFace (), aLoc);
+
+              if (!aTriangulation.IsNull ())
+              {
+                aDFace->SetStatus (IMeshData_Outdated);
+              }
+            }
+          }
+          return;
+        } 
+      }
+    }
+
+  private:
+
+    //! Returns step for splitting seam edge of a cone.
+    Standard_Real getConeStep(const IMeshData::IFaceHandle& theDFace) const
+    {
+      BRepMesh_ConeRangeSplitter aSplitter;
+      aSplitter.Reset (theDFace, myParameters);
+
+      const IMeshData::IWireHandle& aDWire = theDFace->GetWire (0);
+      for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+      {
+        const IMeshData::IEdgeHandle    aDEdge  = aDWire->GetEdge(aEdgeIt);
+        const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+          theDFace.get(), aDWire->GetEdgeOrientation(aEdgeIt));
+
+        for (Standard_Integer aPointIt = 0; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
+        {
+          const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
+          aSplitter.AddPoint(aPnt2d);
+        }
+      }
+
+      std::pair<Standard_Integer, Standard_Integer> aStepsNb;
+      std::pair<Standard_Real, Standard_Real> aSteps = aSplitter.GetSplitSteps (myParameters, aStepsNb);
+      return aSteps.second;
+    } 
+
+    //! Splits 3D and all pcurves accoring using the specified step.
+    Standard_Boolean splitEdge(const IMeshData::IEdgePtr& theDEdge,
+                               const Standard_Real        theDU) const
+    {
+      if (!splitCurve<gp_XYZ> (theDEdge->GetCurve (), theDU))
+      {
+        return Standard_False;
+      }
+
+      for (Standard_Integer aPCurveIdx = 0; aPCurveIdx < theDEdge->PCurvesNb(); ++aPCurveIdx)
+      {
+        splitCurve<gp_XY> (theDEdge->GetPCurve (aPCurveIdx), theDU);
+      }
+
+      return Standard_True;
+    }
+
+    //! Splits the given curve using the specified step.
+    template<class PointType, class Curve>
+    Standard_Boolean splitCurve(Curve& theCurve, const Standard_Real theDU) const
+    {
+      Standard_Boolean isUpdated = Standard_False;
+      PointType aDir = theCurve->GetPoint(theCurve->ParametersNb() - 1).Coord() - theCurve->GetPoint(0).Coord();
+      const Standard_Real aModulus = aDir.Modulus();
+      if (aModulus < gp::Resolution())
+      {
+        return isUpdated;
+      }
+      aDir /= aModulus;
+
+      const Standard_Real    aLastParam = theCurve->GetParameter(theCurve->ParametersNb() - 1);
+      const Standard_Boolean isReversed = theCurve->GetParameter(0) > aLastParam;  
+      for (Standard_Integer aPointIdx = 1; ; ++aPointIdx)
+      {
+        const Standard_Real aCurrParam = theCurve->GetParameter(0) + aPointIdx * theDU * (isReversed ? -1.0 : 1.0); 
+        if (( isReversed &&  (aCurrParam < aLastParam)) ||
+            (!isReversed && !(aCurrParam < aLastParam)))
+        {
+          break;
+        }
+
+        theCurve->InsertPoint(theCurve->ParametersNb() - 1,
+          theCurve->GetPoint(0).Translated (aDir * aPointIdx * theDU),
+          aCurrParam);
+
+        isUpdated = Standard_True;
+      }
+
+      return isUpdated;
+    }
+
+  private:
+
+    Handle(IMeshData_Model) myModel;
+    IMeshTools_Parameters   myParameters;
+  };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPreProcessor::BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_ModelPreProcessor::performInternal(
+  const Handle(IMeshData_Model)& theModel,
+  const IMeshTools_Parameters&   theParameters)
+{
+  if (theModel.IsNull())
+  {
+    return Standard_False;
+  }
+
+  OSD_Parallel::For(0, theModel->FacesNb(), SeamEdgeAmplifier(theModel, theParameters), !theParameters.InParallel);
+  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();
+      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);
+              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..031053a
--- /dev/null
@@ -0,0 +1,46 @@
+// 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();
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
+
+protected:
+
+  //! Performs processing of edges of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle(IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&   theParameters) Standard_OVERRIDE;
+};
+
+#endif
diff --git a/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..332be97
--- /dev/null
@@ -0,0 +1,583 @@
+// 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 <algorithm>
+#include <BRepMesh_GeomTool.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomLib.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <NCollection_Handle.hxx>
+
+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);
+
+      Standard_Real anAngle = 0.0;
+      
+      if ((myPrevControlVec.SquareMagnitude() > Precision::SquareConfusion()) &&
+          (myCurrControlVec.SquareMagnitude() > Precision::SquareConfusion()))
+      {
+        anAngle = myPrevControlVec.Angle(myCurrControlVec);
+      }
+
+      const Standard_Real aSqMaxDeflection = myDFace->GetDeflection() *
+        myDFace->GetDeflection();
+
+      if (((aSqDist > aSqMaxDeflection) || (anAngle > myParameters.AngleInterior)) &&
+          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) || (anAngle < myParameters.AngleInterior)) &&
+            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.AngleInterior)
+        {
+          // 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 Standard_Boolean addParam(
+    const Standard_Real&                           theParam,
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    IMeshData::IMapOfReal&                         theParams)
+  {
+    if (theParam < theRange.first ||
+        theParam > theRange.second)
+    {
+      return Standard_False;
+    }
+
+    theParams.Add(theParam);
+    return Standard_True;
+  }
+
+  //! Initializes parameters map using CN intervals.
+  inline Standard_Boolean initParamsFromIntervals(
+    const TColStd_Array1OfReal&                    theIntervals,
+    const std::pair<Standard_Real, Standard_Real>& theRange,
+    const Standard_Boolean                         isSplitIntervals,
+    IMeshData::IMapOfReal&                         theParams)
+  {
+    Standard_Boolean isAdded = Standard_False;
+
+    for (Standard_Integer i = theIntervals.Lower(); i <= theIntervals.Upper(); ++i)
+    {
+      const Standard_Real aStartParam = theIntervals.Value(i);
+      if (addParam(aStartParam, theRange, theParams))
+      {
+        isAdded = Standard_True;
+      }
+
+      if (isSplitIntervals && i < theIntervals.Upper())
+      {
+        const Standard_Real aMidParam = (aStartParam + theIntervals.Value(i + 1)) / 2.;
+        if (addParam(aMidParam, theRange, theParams))
+        {
+          isAdded = Standard_True;
+        }
+      }
+    }
+
+    return isAdded;
+  }
+
+  //! Checks whether intervals should be split.
+  //! Returns true in case if it is impossible to compute normal 
+  //! directly on intervals, false is returned elsewhere.
+  Standard_Boolean toSplitIntervals (const Handle (Geom_Surface)&  theSurf,
+                                     const TColStd_Array1OfReal  (&theIntervals)[2])
+  {
+    Standard_Integer aIntervalU = theIntervals[0].Lower ();
+    for (; aIntervalU <= theIntervals[0].Upper (); ++aIntervalU)
+    {
+      const Standard_Real aParamU = theIntervals[0].Value(aIntervalU);
+      Standard_Integer aIntervalV = theIntervals[1].Lower ();
+      for (; aIntervalV <= theIntervals[1].Upper (); ++aIntervalV)
+      {
+        gp_Dir aNorm;
+        const Standard_Real aParamV = theIntervals[1].Value(aIntervalV);
+        if (GeomLib::NormEstim (theSurf, gp_Pnt2d (aParamU, aParamV), Precision::Confusion (), aNorm) != 0)
+        {
+          return Standard_True;
+        }
+        // TODO: do not split intervals if there is no normal in the middle of interval.
+      }
+    }
+
+    return Standard_False;
+  }
+}
+
+//=======================================================================
+// Function: AdjustRange
+// Purpose : 
+//=======================================================================
+void BRepMesh_NURBSRangeSplitter::AdjustRange()
+{
+  BRepMesh_DefaultRangeSplitter::AdjustRange();
+  mySurfaceType = GetSurface()->GetType();
+
+  if (mySurfaceType == GeomAbs_BezierSurface)
+  {
+    const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+    const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+    myIsValid = !(aRangeU.first  < -0.5 ||
+                  aRangeU.second >  1.5 ||
+                  aRangeV.first  < -0.5 ||
+                  aRangeV.second >  1.5);
+  }
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_NURBSRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& theParameters) const
+{
+  if (!initParameters())
+  {
+    return Handle(IMeshData::ListOfPnt2d)();
+  }
+
+  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 : 
+//=======================================================================
+Standard_Boolean 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);
+
+  const Standard_Boolean isSplitIntervals = toSplitIntervals (
+    aSurface->ChangeSurface().Surface().Surface(), aIntervals);
+
+  if (!initParamsFromIntervals(aIntervals[0], GetRangeU(), isSplitIntervals,
+                               const_cast<IMeshData::IMapOfReal&>(GetParametersU())))
+  {
+    //if (!grabParamsOfEdges (Edge_Frontier, Param_U))
+    {
+      return Standard_False;
+    }
+  }
+
+  if (!initParamsFromIntervals(aIntervals[1], GetRangeV(), isSplitIntervals,
+                               const_cast<IMeshData::IMapOfReal&>(GetParametersV())))
+  {
+    //if (!grabParamsOfEdges (Edge_Frontier, Param_V))
+    {
+      return Standard_False;
+    }
+  }
+
+  return grabParamsOfEdges(Edge_Internal, Param_U | Param_V);
+}
+
+//=======================================================================
+//function : grabParamsOfInternalEdges
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepMesh_NURBSRangeSplitter::grabParamsOfEdges (
+  const EdgeType         theEdgeType,
+  const Standard_Integer theParamDimensionFlag) const
+{
+  if ((theParamDimensionFlag & (Param_U | Param_V)) == 0)
+  {
+    return Standard_False;
+  }
+
+  const IMeshData::IFaceHandle& aDFace = GetDFace ();
+  for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb (); ++aWireIt)
+  {
+    const IMeshData::IWireHandle& aDWire = aDFace->GetWire (aWireIt);
+    for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb (); ++aEdgeIt)
+    {
+      const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge (aEdgeIt);
+      for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
+      {
+        const IMeshData::IPCurveHandle& aDPCurve = aDEdge->GetPCurve (aPCurveIt);
+        if (aDPCurve->GetFace () == aDFace)
+        {
+          if (theEdgeType == Edge_Internal && !aDPCurve->IsInternal ())
+          {
+            continue;
+          }
+
+          for (Standard_Integer aPointIt = 0; aPointIt < aDPCurve->ParametersNb (); ++aPointIt)
+          {
+            const gp_Pnt2d& aPnt2d = aDPCurve->GetPoint (aPointIt);
+            if (theParamDimensionFlag & Param_U)
+            {
+              const_cast<IMeshData::IMapOfReal&>(GetParametersU ()).Add (aPnt2d.X ());
+            }
+
+            if (theParamDimensionFlag & Param_V)
+            {
+              const_cast<IMeshData::IMapOfReal&>(GetParametersV ()).Add (aPnt2d.Y ());
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//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();
+
+  if (anInitLen < 1)
+  {
+    return aResult;
+  }
+
+  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..a74f2d2
--- /dev/null
@@ -0,0 +1,91 @@
+// 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.
+  BRepMesh_NURBSRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  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 Standard_Boolean 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;
+
+  enum EdgeType
+  {
+    Edge_Internal,
+    Edge_Frontier
+  };
+
+  enum ParamDimension
+  {
+    Param_U = 0x1,
+    Param_V = 0x2
+  };
+
+  //! Finds edges of discrete face and uses its points 
+  //! as auxiliary control parameters for generation of nodes.
+  Standard_Boolean grabParamsOfEdges (const EdgeType         theEdgeType,
+                                      const Standard_Integer theParamDimensionFlag) 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..54f80fd
--- /dev/null
@@ -0,0 +1,237 @@
+// 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.
+  BRepMesh_NodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_NodeInsertionMeshAlgo()
+  {
+  }
+
+  //! Performs processing of the given face.
+  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.
+  virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
+  {
+    Handle(NCollection_IncAllocator) aTmpAlloc = new NCollection_IncAllocator;
+
+    const IMeshData::IFaceHandle& aDFace = this->getDFace();
+    NCollection_Array1<Handle(SequenceOfPnt2d)> aWires(0, aDFace->WiresNb() - 1);
+    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.
+  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.
+  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);
+      const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+        this->getDFace().get(), theDWire->GetEdgeOrientation(aEdgeIt));
+
+      Standard_Integer aPointIt, aEndIndex, aInc;
+      if (aPCurve->IsForward())
+      {
+        // For an infinite cylinder (for example)
+        // aPCurve->ParametersNb() == 0
+
+        aEndIndex = aPCurve->ParametersNb() - 1;
+        aPointIt = Min(0, aEndIndex);
+        aInc = 1;
+      }
+      else
+      {
+        // For an infinite cylinder (for example)
+        // aPCurve->ParametersNb() == 0
+
+        aPointIt = aPCurve->ParametersNb() - 1;
+        aEndIndex = Min(0, aPointIt);
+        aInc = -1;
+      }
+
+      // For an infinite cylinder (for example)
+      // this cycle will not be executed.
+      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 const&)
+    {
+    }
+  }
+
+private:
+
+  RangeSplitter               myRangeSplitter;
+  Handle(BRepMesh_Classifier) myClassifier;
+};
+
+#endif
index 6f9f154e0b1f2a90b29b1f8252720857ff27e9b3..976c1ba4a26bb7cf351334f8d4b11c40ce9e13a0 100644 (file)
@@ -35,8 +35,8 @@ public:
 
   //! Constructs a link between two vertices.
   BRepMesh_OrientedEdge(
-    const Standard_Integer         theFirstNode,
-    const Standard_Integer         theLastNode)
+    const Standard_Integer theFirstNode,
+    const Standard_Integer theLastNode)
     : myFirstNode(theFirstNode),
       myLastNode(theLastNode)
   {
@@ -54,12 +54,12 @@ public:
     return myLastNode;
   }
 
-  //! Returns hash code for this edge.
-  //! @param theUpper upper index in the container.
-  //! @return hash code.
-  Standard_Integer HashCode(const Standard_Integer theUpper) const
+  //! Computes a hash code for this oriented edge, in the range [1, theUpperBound]
+  //! @param theUpperBound the upper bound of the range a computing hash code must be within
+  //! @return a computed hash code, in the range [1, theUpperBound]
+  inline Standard_Integer HashCode (const Standard_Integer theUpperBound) const
   {
-    return ::HashCode(myFirstNode + myLastNode, theUpper);
+    return ::HashCode (myFirstNode + myLastNode, theUpperBound);
   }
 
   //! Checks this and other edge for equality.
@@ -71,7 +71,7 @@ public:
   }
 
   //! Alias for IsEqual.
-  Standard_Boolean operator ==(const BRepMesh_OrientedEdge& Other) const
+  inline Standard_Boolean operator ==(const BRepMesh_OrientedEdge& Other) const
   {
     return IsEqual(Other);
   }
@@ -82,10 +82,13 @@ private:
   Standard_Integer myLastNode;
 };
 
-inline Standard_Integer HashCode(const BRepMesh_OrientedEdge&   theEdge,
-                                 const Standard_Integer         theUpper)
+//! Computes a hash code for the given oriented edge, in the range [1, theUpperBound]
+//! @param theOrientedEdge the oriented edge which hash code is to be computed
+//! @param theUpperBound the upper bound of the range a computing hash code must be within
+//! @return a computed hash code, in the range [1, theUpperBound]
+inline Standard_Integer HashCode (const BRepMesh_OrientedEdge& theOrientedEdge, const Standard_Integer theUpperBound)
 {
-  return theEdge.HashCode(theUpper);
+  return theOrientedEdge.HashCode (theUpperBound);
 }
 
 #endif
diff --git a/src/BRepMesh/BRepMesh_PairOfPolygon.hxx b/src/BRepMesh/BRepMesh_PairOfPolygon.hxx
deleted file mode 100644 (file)
index e695179..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2013 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_PairOfPolygon_HeaderFile
-#define _BRepMesh_PairOfPolygon_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
-
-class Poly_PolygonOnTriangulation;
-
-class BRepMesh_PairOfPolygon
-{
-public:
-
-  DEFINE_STANDARD_ALLOC
-
-  //! Constructor. Creates empty pair with null fileds.
-  BRepMesh_PairOfPolygon()
-  {
-  }
-
-  //! Clears pair handles.
-  inline void Clear()
-  {
-    myFirst.Nullify();
-    myLast.Nullify();
-  }
-  
-  //! Sets the first element of the pair.
-  //! If last element is empty, also assignes the given polygon to it.
-  //! @param thePolygon plygon to be set.
-  inline void Prepend(const Handle(Poly_PolygonOnTriangulation)& thePolygon)
-  {
-    myFirst = thePolygon;
-
-    if (myLast.IsNull())
-      myLast = thePolygon;
-  }
-
-  //! Sets the last element of the pair.
-  //! If first element is empty, also assignes the given polygon to it.
-  //! @param thePolygon plygon to be set.
-  inline void Append(const Handle(Poly_PolygonOnTriangulation)& thePolygon)
-  {
-    if (myFirst.IsNull())
-      myFirst = thePolygon;
-
-    myLast = thePolygon;
-  }
-
-  //! Returns first polygon on triangulation.
-  inline const Handle(Poly_PolygonOnTriangulation)& First() const
-  {
-    return myFirst;
-  }
-
-  //! Returns last polygon on triangulation.
-  inline const Handle(Poly_PolygonOnTriangulation)& Last() const
-  {
-    return myLast;
-  }
-
-private:
-
-  Handle(Poly_PolygonOnTriangulation) myFirst;
-  Handle(Poly_PolygonOnTriangulation) myLast;
-};
-
-#endif
index 03217709ea05e8d4e15e05ade6521d12376f40a6..dd323f29eb0fce7af11a5a44ebb48adc7c3fd64a 100644 (file)
 
 #include <BRepMesh_SelectorOfDataStructureOfDelaun.hxx>
 #include <BRepMesh_PairOfIndex.hxx>
+#include <BRepMesh_Edge.hxx>
 
 //=======================================================================
 //function : Default constructor
 //purpose  : 
 //=======================================================================
 BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDelaun()
-: myAllocator(new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE)),
-  myNodes   (10, myAllocator),
-  myLinks   (10, myAllocator),
-  myElements(10, myAllocator),
-  myFrontier(10, myAllocator)
 {
 }
 
@@ -36,12 +32,7 @@ BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDela
 //=======================================================================
 BRepMesh_SelectorOfDataStructureOfDelaun::BRepMesh_SelectorOfDataStructureOfDelaun(
   const Handle(BRepMesh_DataStructureOfDelaun)& theMesh)
-: myAllocator(new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE)),
-  myMesh    (theMesh),
-  myNodes   (10, myAllocator),
-  myLinks   (10, myAllocator),
-  myElements(10, myAllocator),
-  myFrontier(10, myAllocator)
+  : myMesh(theMesh)
 {
 }
 
@@ -76,7 +67,7 @@ void BRepMesh_SelectorOfDataStructureOfDelaun::NeighboursOf(
 void BRepMesh_SelectorOfDataStructureOfDelaun::NeighboursOfNode(
   const Standard_Integer theNodeIndex)
 {
-  BRepMesh::ListOfInteger::Iterator aLinkIt(
+  IMeshData::ListOfInteger::Iterator aLinkIt(
     myMesh->LinksConnectedTo(theNodeIndex));
 
   for (; aLinkIt.More(); aLinkIt.Next())
@@ -135,10 +126,7 @@ void BRepMesh_SelectorOfDataStructureOfDelaun::NeighboursOfElement(
 void BRepMesh_SelectorOfDataStructureOfDelaun::NeighboursByEdgeOf(
   const BRepMesh_Triangle& theElement)
 {
-  Standard_Integer e[3];
-  Standard_Boolean o[3];
-  theElement.Edges(e, o);
-
+  const Standard_Integer(&e)[3] = theElement.myEdges;
   for (Standard_Integer i = 0; i < 3; ++i)
     elementsOfLink(e[i]);
 }
index 65847ad55718c66ef1ce38c1139cc794fbcd5d16..2d1cc4684cda54cc8ba0c82a9b776695956c3bf9 100644 (file)
 #ifndef _BRepMesh_SelectorOfDataStructureOfDelaun_HeaderFile
 #define _BRepMesh_SelectorOfDataStructureOfDelaun_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
+#include <Standard_Transient.hxx>
 #include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh.hxx>
-#include <Standard_Integer.hxx>
 #include <BRepMesh_Triangle.hxx>
+#include <IMeshData_Types.hxx>
 
 class BRepMesh_Vertex;
 class BRepMesh_Edge;
 
 //! Describes a selector and an iterator on a 
 //! selector of components of a mesh.
-class BRepMesh_SelectorOfDataStructureOfDelaun
+class BRepMesh_SelectorOfDataStructureOfDelaun : public Standard_Transient
 {
 public:
 
-  DEFINE_STANDARD_ALLOC
-
   //! Default constructor.
   Standard_EXPORT BRepMesh_SelectorOfDataStructureOfDelaun();
   
@@ -75,41 +70,42 @@ public:
   }
   
   //! Returns selected nodes.
-  inline const BRepMesh::MapOfInteger& Nodes() const
+  inline const IMeshData::MapOfInteger& Nodes() const
   {
     return myNodes;
   }
   
   //! Returns selected links.
-  inline const BRepMesh::MapOfInteger& Links() const
+  inline const IMeshData::MapOfInteger& Links() const
   {
     return myLinks;
   }
   
   //! Returns selected elements.
-  inline const BRepMesh::MapOfInteger& Elements() const
+  inline const IMeshData::MapOfInteger& Elements() const
   {
     return myElements;
   }
   
   //! Gives the list of incices of frontier links.
-  inline const BRepMesh::MapOfInteger& FrontierLinks() const
+  inline const IMeshData::MapOfInteger& FrontierLinks() const
   {
     return myFrontier;
   }
 
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_SelectorOfDataStructureOfDelaun, Standard_Transient)
+
 private:
 
   //! Collects elements connected to link with the given index.
   void elementsOfLink(const Standard_Integer theIndex);
 
 private:
-  Handle(NCollection_IncAllocator)       myAllocator;
   Handle(BRepMesh_DataStructureOfDelaun) myMesh;
-  BRepMesh::MapOfInteger                 myNodes;
-  BRepMesh::MapOfInteger                 myLinks;
-  BRepMesh::MapOfInteger                 myElements;
-  BRepMesh::MapOfInteger                 myFrontier;
+  IMeshData::MapOfInteger                myNodes;
+  IMeshData::MapOfInteger                myLinks;
+  IMeshData::MapOfInteger                myElements;
+  IMeshData::MapOfInteger                myFrontier;
 };
 
 #endif
index ebd837bd7aa6e8838f725aa28507747c67a37407..83af4d601594cd57149c94dda91b6138fb69e4ab 100644 (file)
@@ -1,5 +1,6 @@
-// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// 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.
 //
 // commercial license or contractual agreement.
 
 #include <BRepMesh_ShapeTool.hxx>
-
-#include <Bnd_Box.hxx>
-#include <TopoDS_Edge.hxx>
-#include <BRepBndLib.hxx>
-#include <TopoDS.hxx>
-#include <BRep_Tool.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_PCurve.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <Poly_Triangulation.hxx>
+#include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
-#include <TopExp.hxx>
+#include <ShapeAnalysis_Edge.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <Precision.hxx>
+#include <Bnd_Box.hxx>
 
-namespace {
+namespace
+{
   //! Auxilary struct to take a tolerance of edge.
   struct EdgeTolerance
   {
@@ -64,7 +64,7 @@ namespace {
 }
 
 //=======================================================================
-//function : BoxMaxDimension
+//function : MaxFaceTolerance
 //purpose  : 
 //=======================================================================
 Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
@@ -72,7 +72,7 @@ Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
   Standard_Real aMaxTolerance = BRep_Tool::Tolerance(theFace);
 
   Standard_Real aTolerance = Max(
-    MaxTolerance<TopAbs_EDGE,   EdgeTolerance  >(theFace),
+    MaxTolerance<TopAbs_EDGE, EdgeTolerance  >(theFace),
     MaxTolerance<TopAbs_VERTEX, VertexTolerance>(theFace));
 
   return Max(aMaxTolerance, aTolerance);
@@ -85,7 +85,7 @@ Standard_Real BRepMesh_ShapeTool::MaxFaceTolerance(const TopoDS_Face& theFace)
 void BRepMesh_ShapeTool::BoxMaxDimension(const Bnd_Box& theBox,
                                          Standard_Real& theMaxDimension)
 {
-  if(theBox.IsVoid())
+  if (theBox.IsVoid())
     return;
 
   Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
@@ -95,98 +95,102 @@ void BRepMesh_ShapeTool::BoxMaxDimension(const Bnd_Box& theBox,
 }
 
 //=======================================================================
-//function : RelativeEdgeDeflection
+//function : CheckAndUpdateFlags
 //purpose  : 
 //=======================================================================
-Standard_Real BRepMesh_ShapeTool::RelativeEdgeDeflection(
-  const TopoDS_Edge&  theEdge,
-  const Standard_Real theDeflection,
-  const Standard_Real theMaxShapeSize,
-  Standard_Real&      theAdjustmentCoefficient)
+void BRepMesh_ShapeTool::CheckAndUpdateFlags (
+  const IMeshData::IEdgeHandle&   theEdge,
+  const IMeshData::IPCurveHandle& thePCurve)
 {
-  theAdjustmentCoefficient = 1.;
-  Standard_Real aDefEdge = theDeflection;
-  if(theEdge.IsNull())
-    return aDefEdge;
-
-  Bnd_Box aBox;
-  BRepBndLib::Add(theEdge, aBox, Standard_False);
-  BoxMaxDimension(aBox, aDefEdge);
-            
-  // Adjust resulting value in relation to the total size
-  theAdjustmentCoefficient = theMaxShapeSize / (2 * aDefEdge);
-  if (theAdjustmentCoefficient < 0.5)
-    theAdjustmentCoefficient = 0.5;
-  else if (theAdjustmentCoefficient > 2.)
-    theAdjustmentCoefficient = 2.;
-
-  return (theAdjustmentCoefficient * aDefEdge * theDeflection);
-}
-
-//=======================================================================
-//function : FindUV
-//purpose  : 
-//=======================================================================
-gp_XY BRepMesh_ShapeTool::FindUV(
-  const Standard_Integer                theIndexOfPnt3d,
-  const gp_Pnt2d&                       thePnt2d,
-  const Standard_Real                   theMinDistance,
-  const Handle(BRepMesh_FaceAttribute)& theFaceAttribute)
-{
-  const gp_XY& aPnt2d = thePnt2d.Coord();
-  BRepMesh::HDMapOfIntegerListOfXY& aLocation2D =
-    theFaceAttribute->ChangeLocation2D();
-
-  if (!aLocation2D->IsBound(theIndexOfPnt3d))
+  if (!theEdge->GetSameParam () &&
+      !theEdge->GetSameRange () &&
+       theEdge->GetDegenerated ())
   {
-    BRepMesh::ListOfXY aPoints2d;
-    aPoints2d.Append(aPnt2d);
-    aLocation2D->Bind(theIndexOfPnt3d, aPoints2d);
-    return aPnt2d;
+    // Nothing to do worse.
+    return;
   }
 
-  BRepMesh::ListOfXY& aPoints2d = aLocation2D->ChangeFind(theIndexOfPnt3d);
+  const TopoDS_Edge& aEdge = theEdge->GetEdge ();
+  const TopoDS_Face& aFace = thePCurve->GetFace ()->GetFace ();
 
-  // Find the most closest 2d point to the given one.
-  gp_XY aUV;
-  Standard_Real aMinDist = RealLast();
-  BRepMesh::ListOfXY::Iterator aPoint2dIt(aPoints2d);
-  for (; aPoint2dIt.More(); aPoint2dIt.Next())
+  Handle (Geom_Curve) aCurve;
+  Standard_Real aFirstParam, aLastParam;
+  Range (aEdge, aCurve, aFirstParam, aLastParam);
+  if (aCurve.IsNull())
   {
-    const gp_XY& aCurPnt2d = aPoint2dIt.Value();
+    theEdge->SetDegenerated(Standard_True);
+    return;
+  }
 
-    Standard_Real aDist = (aPnt2d - aCurPnt2d).Modulus();
-    if (aDist < aMinDist)
+  BRepAdaptor_Curve aCurveOnSurf(aEdge, aFace);
+  if (theEdge->GetSameParam () || theEdge->GetSameRange ())
+  {
+    if (theEdge->GetSameRange ())
     {
-      aUV      = aCurPnt2d;
-      aMinDist = aDist;
+      const Standard_Real aDiffFirst = aCurveOnSurf.FirstParameter () - aFirstParam;
+      const Standard_Real aDiffLast  = aCurveOnSurf.LastParameter ()  - aLastParam;
+      theEdge->SetSameRange (
+        Abs (aDiffFirst) < Precision::PConfusion () &&
+        Abs (aDiffLast ) < Precision::PConfusion ());
+
+      if (!theEdge->GetSameRange())
+      {
+        theEdge->SetSameParam(Standard_False);
+      }
     }
   }
 
-  const Standard_Real aTolerance = theMinDistance;
-
-  // Get face limits
-  Standard_Real aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
-  Standard_Real aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
-
-  const Standard_Real Utol2d = .5 * aDiffU;
-  const Standard_Real Vtol2d = .5 * aDiffV;
-
-  const Handle(BRepAdaptor_HSurface)& aSurface = theFaceAttribute->Surface();
-  const gp_Pnt aPnt1 = aSurface->Value(aUV.X(), aUV.Y());
-  const gp_Pnt aPnt2 = aSurface->Value(aPnt2d.X(), aPnt2d.Y());
-
-  //! If selected point is too far from the given one in parametric space
-  //! or their positions in 3d are different, add the given point as unique.
-  if (Abs(aUV.X() - aPnt2d.X()) > Utol2d ||
-      Abs(aUV.Y() - aPnt2d.Y()) > Vtol2d ||
-      !aPnt1.IsEqual(aPnt2, aTolerance))
+  if (!theEdge->GetDegenerated ()/* || theEdge->GetSameParam ()*/)
   {
-    aUV = aPnt2d;
-    aPoints2d.Append(aUV);
-  }
+    TopoDS_Vertex aStartVertex, aEndVertex;
+    TopExp::Vertices (aEdge, aStartVertex, aEndVertex);
+    if (aStartVertex.IsNull() || aEndVertex.IsNull())
+    {
+      theEdge->SetDegenerated(Standard_True);
+      return;
+    }
 
-  return aUV;
+    if (aStartVertex.IsSame(aEndVertex))
+    {
+      const Standard_Integer aPointsNb          = 20;
+      const Standard_Real    aVertexTolerance   = BRep_Tool::Tolerance (aStartVertex);
+      const Standard_Real    aDu                = (aLastParam - aFirstParam) / aPointsNb;
+      //const Standard_Real    aEdgeTolerance     = BRep_Tool::Tolerance (aEdge);
+      //const Standard_Real    aSqEdgeTolerance   = aEdgeTolerance * aEdgeTolerance;
+
+      gp_Pnt aPrevPnt;
+      aCurve->D0 (aFirstParam, aPrevPnt);
+
+      Standard_Real aLength = 0.0;
+      for (Standard_Integer i = 1; i <= aPointsNb; ++i)
+      {
+        const Standard_Real aParameter = aFirstParam + i * aDu;
+        // Calculation of the length of the edge in 3D
+        // in order to check degenerativity
+        gp_Pnt aPnt;
+        aCurve->D0 (aParameter, aPnt);
+        aLength += aPrevPnt.Distance (aPnt);
+
+        //if (theEdge->GetSameParam ())
+        //{
+        //  // Check that points taken at the 3d and pcurve using 
+        //  // same parameter are within tolerance of an edge.
+        //  gp_Pnt aPntOnSurf;
+        //  aCurveOnSurf.D0 (aParameter, aPntOnSurf);
+        //  theEdge->SetSameParam (aPnt.SquareDistance (aPntOnSurf) < aSqEdgeTolerance);
+        //}
+
+        if (aLength > aVertexTolerance /*&& !theEdge->GetSameParam()*/)
+        {
+          break;
+        }
+
+        aPrevPnt = aPnt;
+      }
+
+      theEdge->SetDegenerated (aLength < aVertexTolerance);
+    }
+  }
 }
 
 //=======================================================================
@@ -204,7 +208,7 @@ void BRepMesh_ShapeTool::AddInFace(
     aTrsf.Invert();
 
     TColgp_Array1OfPnt& aNodes = theTriangulation->ChangeNodes();
-    for (Standard_Integer i = aNodes.Lower(); i <= aNodes.Upper(); ++i) 
+    for (Standard_Integer i = aNodes.Lower(); i <= aNodes.Upper(); ++i)
       aNodes(i).Transform(aTrsf);
   }
 
@@ -212,117 +216,157 @@ void BRepMesh_ShapeTool::AddInFace(
   aBuilder.UpdateFace(theFace, theTriangulation);
 }
 
+
 //=======================================================================
 //function : NullifyFace
 //purpose  : 
 //=======================================================================
-void BRepMesh_ShapeTool::NullifyFace(const TopoDS_Face& theFace)
+void BRepMesh_ShapeTool::NullifyFace (const TopoDS_Face& theFace)
 {
   BRep_Builder aBuilder;
-  aBuilder.UpdateFace(theFace, Handle(Poly_Triangulation)());
+  aBuilder.UpdateFace (theFace, Handle (Poly_Triangulation)());
 }
 
 //=======================================================================
 //function : NullifyEdge
 //purpose  : 
 //=======================================================================
-void BRepMesh_ShapeTool::NullifyEdge(
-  const TopoDS_Edge&                theEdge,
-  const Handle(Poly_Triangulation)& theTriangulation,
-  const TopLoc_Location&            theLocation)
+void BRepMesh_ShapeTool::NullifyEdge (
+  const TopoDS_Edge&                 theEdge,
+  const Handle (Poly_Triangulation)& theTriangulation,
+  const TopLoc_Location&             theLocation)
 {
-  UpdateEdge(theEdge, Handle(Poly_PolygonOnTriangulation)(),
+  UpdateEdge (theEdge, Handle (Poly_PolygonOnTriangulation)(),
     theTriangulation, theLocation);
 }
 
+//=======================================================================
+//function : NullifyEdge
+//purpose  : 
+//=======================================================================
+void BRepMesh_ShapeTool::NullifyEdge (
+  const TopoDS_Edge&     theEdge,
+  const TopLoc_Location& theLocation)
+{
+  BRep_Builder aBuilder;
+  aBuilder.UpdateEdge (theEdge, Handle (Poly_Polygon3D)(), theLocation);
+}
+
 //=======================================================================
 //function : UpdateEdge
 //purpose  : 
 //=======================================================================
-void BRepMesh_ShapeTool::UpdateEdge(
-  const TopoDS_Edge&                         theEdge,
-  const Handle(Poly_PolygonOnTriangulation)& thePolygon,
-  const Handle(Poly_Triangulation)&          theTriangulation,
-  const TopLoc_Location&                     theLocation)
+void BRepMesh_ShapeTool::UpdateEdge (
+  const TopoDS_Edge&                          theEdge,
+  const Handle (Poly_PolygonOnTriangulation)& thePolygon,
+  const Handle (Poly_Triangulation)&          theTriangulation,
+  const TopLoc_Location&                      theLocation)
 {
   BRep_Builder aBuilder;
-  aBuilder.UpdateEdge(theEdge, thePolygon, theTriangulation, theLocation);
+  aBuilder.UpdateEdge (theEdge, thePolygon, theTriangulation, theLocation);
 }
 
 //=======================================================================
 //function : UpdateEdge
 //purpose  : 
 //=======================================================================
-void BRepMesh_ShapeTool::UpdateEdge(
-  const TopoDS_Edge&                         theEdge,
-  const Handle(Poly_PolygonOnTriangulation)& thePolygon1,
-  const Handle(Poly_PolygonOnTriangulation)& thePolygon2,
-  const Handle(Poly_Triangulation)&          theTriangulation,
-  const TopLoc_Location&                     theLocation)
+void BRepMesh_ShapeTool::UpdateEdge (
+  const TopoDS_Edge&                          theEdge,
+  const Handle (Poly_PolygonOnTriangulation)& thePolygon1,
+  const Handle (Poly_PolygonOnTriangulation)& thePolygon2,
+  const Handle (Poly_Triangulation)&          theTriangulation,
+  const TopLoc_Location&                      theLocation)
 {
   BRep_Builder aBuilder;
-  aBuilder.UpdateEdge(theEdge, thePolygon1, thePolygon2, 
+  aBuilder.UpdateEdge (theEdge, thePolygon1, thePolygon2,
     theTriangulation, theLocation);
 }
 
+//=======================================================================
+//function : UpdateEdge
+//purpose  : 
+//=======================================================================
+void BRepMesh_ShapeTool::UpdateEdge(
+  const TopoDS_Edge&            theEdge,
+  const Handle(Poly_Polygon3D)& thePolygon)
+{
+  BRep_Builder aBuilder;
+  aBuilder.UpdateEdge(theEdge, thePolygon);
+}
+
 //=======================================================================
 //function : UseLocation
 //purpose  : 
 //=======================================================================
-gp_Pnt BRepMesh_ShapeTool::UseLocation(const gp_Pnt&          thePnt,
-                                       const TopLoc_Location& theLoc)
+gp_Pnt BRepMesh_ShapeTool::UseLocation (
+  const gp_Pnt&          thePnt,
+  const TopLoc_Location& theLoc)
 {
   if (theLoc.IsIdentity())
+  {
     return thePnt;
+  }
 
-  return thePnt.Transformed(theLoc.Transformation());
+  return thePnt.Transformed (theLoc.Transformation ());
 }
 
 //=======================================================================
-//function : IsDegenerated
+//function : UVPoints
 //purpose  : 
 //=======================================================================
-Standard_Boolean BRepMesh_ShapeTool::IsDegenerated(
-  const TopoDS_Edge& theEdge,
-  const TopoDS_Face& theFace)
+Standard_Boolean BRepMesh_ShapeTool::UVPoints (
+  const TopoDS_Edge&      theEdge,
+  const TopoDS_Face&      theFace,
+  gp_Pnt2d&               theFirstPoint2d,
+  gp_Pnt2d&               theLastPoint2d,
+  const Standard_Boolean  isConsiderOrientation)
 {
-  // Get vertices
-  TopoDS_Vertex pBegin, pEnd;
-  TopExp::Vertices(theEdge, pBegin, pEnd);
-  if (pBegin.IsNull() || pEnd.IsNull())
-    return Standard_True;
-
-  if (BRep_Tool::Degenerated(theEdge))
-    return Standard_True;
 
-  if (!pBegin.IsSame(pEnd))
+  Handle (Geom2d_Curve) aCurve2d;
+  Standard_Real aFirstParam, aLastParam;
+  if (!Range(theEdge, theFace, aCurve2d, aFirstParam, aLastParam, isConsiderOrientation))
+  {
     return Standard_False;
+  }
 
-  Standard_Real wFirst, wLast;
-  BRep_Tool::Range(theEdge, theFace, wFirst, wLast);
-
-  // calculation of the length of the edge in 3D
-  Standard_Real longueur = 0.0;
-  Standard_Real du = (wLast - wFirst) * 0.05;
-  gp_Pnt P1, P2;
-  BRepAdaptor_Curve BC(theEdge);
-  BC.D0(wFirst, P1);
-  Standard_Real tolV = BRep_Tool::Tolerance(pBegin);
-  Standard_Real tolV2 = 1.2 * tolV;
-
-  for (Standard_Integer l = 1; l <= 20; ++l)
-  {
-    BC.D0(wFirst + l * du, P2);
-    longueur += P1.Distance(P2);
+  aCurve2d->D0 (aFirstParam, theFirstPoint2d);
+  aCurve2d->D0 (aLastParam,  theLastPoint2d);
+  return Standard_True;
+}
 
-    if (longueur > tolV2)
-      break;
+//=======================================================================
+//function : Range
+//purpose  :
+//=======================================================================
+Standard_Boolean BRepMesh_ShapeTool::Range (
+  const TopoDS_Edge&      theEdge,
+  const TopoDS_Face&      theFace,
+  Handle (Geom2d_Curve)&  thePCurve,
+  Standard_Real&          theFirstParam,
+  Standard_Real&          theLastParam,
+  const Standard_Boolean  isConsiderOrientation)
+{
 
-    P1 = P2;
-  }
+  ShapeAnalysis_Edge aEdge;
+  return aEdge.PCurve (theEdge, theFace, thePCurve,
+    theFirstParam, theLastParam,
+    isConsiderOrientation);
+}
 
-  if (longueur < tolV2)
-    return Standard_True;
+//=======================================================================
+//function : Range
+//purpose  :
+//=======================================================================
+Standard_Boolean BRepMesh_ShapeTool::Range (
+  const TopoDS_Edge&      theEdge,
+  Handle (Geom_Curve)&    theCurve,
+  Standard_Real&          theFirstParam,
+  Standard_Real&          theLastParam,
+  const Standard_Boolean  isConsiderOrientation)
+{
 
-  return Standard_False;
+  ShapeAnalysis_Edge aEdge;
+  return aEdge.Curve3d (theEdge, theCurve,
+    theFirstParam, theLastParam,
+    isConsiderOrientation);
 }
index e1883d774691ba60e9d6b6cf271c9a646b637b42..d257d612d0aaa448609bd682eeb17e901e96790c 100644 (file)
@@ -1,4 +1,6 @@
-// Copyright (c) 2013 OPEN CASCADE SAS
+// 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.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #ifndef _BRepMesh_ShapeTool_HeaderFile
 #define _BRepMesh_ShapeTool_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
-#include <BRepAdaptor_HSurface.hxx>
-#include <BRepMesh_FaceAttribute.hxx>
-#include <BRepMesh.hxx>
+#include <Standard_Transient.hxx>
+#include <Standard_Handle.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshData_Types.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Poly_PolygonOnTriangulation.hxx>
 
-class Poly_Triangulation;
+class Geom_Curve;
+class Geom2d_Curve;
+class Poly_Polygon3D;
 class TopoDS_Face;
 class TopoDS_Edge;
 class Bnd_Box;
-class TopoDS_Vertex;
-class gp_XY;
-class gp_Pnt2d;
 
-class BRepMesh_ShapeTool
+//! Auxiliary class providing functionality to compute,
+//! retrieve and store data to TopoDS and model shape.
+class BRepMesh_ShapeTool : public Standard_Transient
 {
 public:
 
-  DEFINE_STANDARD_ALLOC
-  
   //! Returns maximum tolerance of the given face.
   //! Considers tolerances of edges and vertices contained in the given face.
   Standard_EXPORT static Standard_Real MaxFaceTolerance(
@@ -48,39 +48,15 @@ public:
   Standard_EXPORT static void BoxMaxDimension(const Bnd_Box& theBox,
                                               Standard_Real& theMaxDimension);
 
-  //! 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);
-
-  //! Checks 2d representations of 3d point with the 
-  //! given index for equality to avoid duplications.
-  //! @param theIndexOfPnt3d index of 3d point with which 2d 
-  //! representation should be associated.
-  //! @param thePnt2d 2d representation of the point with the 
-  //! given index.
-  //! @param theMinDistance minimum distance between vertices 
-  //! regarding which they could be treated as distinct ones.
-  //! @param theFaceAttribute attributes contining data calculated
-  //! according to face geomtry and define limits of face in parametric 
-  //! space. If defined, will be used instead of surface parameter.
-  //! @param theLocation2dMap map of 2d representations of 3d points.
-  //! @return given 2d point in case if 3d poind does not alredy have 
-  //! the similar representation, otherwice 2d point corresponding to 
-  //! existing representation will be returned.
-  Standard_EXPORT static gp_XY FindUV(
-    const Standard_Integer                theIndexOfPnt3d,
-    const gp_Pnt2d&                       thePnt2d,
-    const Standard_Real                   theMinDistance,
-    const Handle(BRepMesh_FaceAttribute)& theFaceAttribute);
+  //! Checks same parameter, same range and degenerativity attributes
+  //! using geometrical data of the given edge and updates edge model
+  //! by computed parameters in case of worst case - it can drop flags
+  //! same parameter and same range to False but never to True if it is 
+  //! already set to False. In contrary, it can also drop degenerated 
+  //! flag to True, but never to False if it is already set to True.
+  Standard_EXPORT static void CheckAndUpdateFlags (
+    const IMeshData::IEdgeHandle&   theEdge,
+    const IMeshData::IPCurveHandle& thePCurve);
 
   //! Stores the given triangulation into the given face.
   //! @param theFace face to be updated by triangulation.
@@ -91,27 +67,41 @@ public:
 
   //! Nullifies triangulation stored in the face.
   //! @param theFace face to be updated by null triangulation.
-  Standard_EXPORT static void NullifyFace(const TopoDS_Face& theFace);
+  Standard_EXPORT static void NullifyFace (const TopoDS_Face& theFace);
 
   //! Nullifies polygon on triangulation stored in the edge.
   //! @param theEdge edge to be updated by null polygon.
   //! @param theTriangulation triangulation the given edge is associated to.
   //! @param theLocation face location.
-  Standard_EXPORT static void NullifyEdge(
-    const TopoDS_Edge&                theEdge,
-    const Handle(Poly_Triangulation)& theTriangulation,
-    const TopLoc_Location&            theLocation);
+  Standard_EXPORT static void NullifyEdge (
+    const TopoDS_Edge&                 theEdge,
+    const Handle (Poly_Triangulation)& theTriangulation,
+    const TopLoc_Location&             theLocation);
+
+  //! Nullifies 3d polygon stored in the edge.
+  //! @param theEdge edge to be updated by null polygon.
+  //! @param theLocation face location.
+  Standard_EXPORT static void NullifyEdge (
+    const TopoDS_Edge&     theEdge,
+    const TopLoc_Location& theLocation);
 
   //! Updates the given edge by the given tessellated representation.
   //! @param theEdge edge to be updated.
   //! @param thePolygon tessellated representation of the edge to be stored.
   //! @param theTriangulation triangulation the given edge is associated to.
   //! @param theLocation face location.
+  Standard_EXPORT static void UpdateEdge (
+    const TopoDS_Edge&                          theEdge,
+    const Handle (Poly_PolygonOnTriangulation)& thePolygon,
+    const Handle (Poly_Triangulation)&          theTriangulation,
+    const TopLoc_Location&                      theLocation);
+
+  //! Updates the given edge by the given tessellated representation.
+  //! @param theEdge edge to be updated.
+  //! @param thePolygon tessellated representation of the edge to be stored.
   Standard_EXPORT static void UpdateEdge(
-    const TopoDS_Edge&                         theEdge,
-    const Handle(Poly_PolygonOnTriangulation)& thePolygon,
-    const Handle(Poly_Triangulation)&          theTriangulation,
-    const TopLoc_Location&                     theLocation);
+    const TopoDS_Edge&            theEdge,
+    const Handle(Poly_Polygon3D)& thePolygon);
 
   //! Updates the given seam edge by the given tessellated representations.
   //! @param theEdge edge to be updated.
@@ -121,27 +111,46 @@ public:
   //! reversed direction of the seam edge.
   //! @param theTriangulation triangulation the given edge is associated to.
   //! @param theLocation face location.
-  Standard_EXPORT static void UpdateEdge(
-    const TopoDS_Edge&                         theEdge,
-    const Handle(Poly_PolygonOnTriangulation)& thePolygon1,
-    const Handle(Poly_PolygonOnTriangulation)& thePolygon2,
-    const Handle(Poly_Triangulation)&          theTriangulation,
-    const TopLoc_Location&                     theLocation);
+  Standard_EXPORT static void UpdateEdge (
+    const TopoDS_Edge&                          theEdge,
+    const Handle (Poly_PolygonOnTriangulation)& thePolygon1,
+    const Handle (Poly_PolygonOnTriangulation)& thePolygon2,
+    const Handle (Poly_Triangulation)&          theTriangulation,
+    const TopLoc_Location&                      theLocation);
 
   //! Applies location to the given point and return result.
   //! @param thePnt point to be transformed.
   //! @param theLoc location to be applied.
-  Standard_EXPORT static gp_Pnt UseLocation(const gp_Pnt&          thePnt,
-                                            const TopLoc_Location& theLoc);
-
-  //! Checks is the given edge degenerated.
-  //! Checks geometrical parameters in case if IsDegenerated flag is not set.
-  //! @param theEdge edge to be checked.
-  //! @param theFace face within which parametric space edge will be checked
-  //! for geometrical degenerativity.
-  Standard_EXPORT static Standard_Boolean IsDegenerated(
-    const TopoDS_Edge& theEdge,
-    const TopoDS_Face& theFace);
+  Standard_EXPORT static gp_Pnt UseLocation (
+    const gp_Pnt&          thePnt,
+    const TopLoc_Location& theLoc);
+
+  //! Gets the strict UV locations of the extremities of the edge using pcurve.
+  Standard_EXPORT static Standard_Boolean UVPoints (
+    const TopoDS_Edge&      theEdge,
+    const TopoDS_Face&      theFace,
+    gp_Pnt2d&               theFirstPoint2d,
+    gp_Pnt2d&               theLastPoint2d,
+    const Standard_Boolean  isConsiderOrientation = Standard_False);
+
+  //! Gets the parametric range of the given edge on the given face.
+  Standard_EXPORT static Standard_Boolean Range (
+    const TopoDS_Edge&      theEdge,
+    const TopoDS_Face&      theFace,
+    Handle (Geom2d_Curve)&  thePCurve,
+    Standard_Real&          theFirstParam,
+    Standard_Real&          theLastParam,
+    const Standard_Boolean  isConsiderOrientation = Standard_False);
+
+  //! Gets the 3d range of the given edge.
+  Standard_EXPORT static Standard_Boolean Range (
+    const TopoDS_Edge&      theEdge,
+    Handle (Geom_Curve)&    theCurve,
+    Standard_Real&          theFirstParam,
+    Standard_Real&          theLastParam,
+    const Standard_Boolean  isConsiderOrientation = Standard_False);
+
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeTool, Standard_Transient)
 };
 
-#endif
+#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..0705c13
--- /dev/null
@@ -0,0 +1,151 @@
+// 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)
+{
+  if (!myDEdgeMap.IsBound (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.get(), aEdge.Orientation());
+      aDWire->AddEdge   (aDEdge.get(),   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.cxx b/src/BRepMesh/BRepMesh_SphereRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..4a3112e
--- /dev/null
@@ -0,0 +1,59 @@
+// 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.
+
+#include <BRepMesh_SphereRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_SphereRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& theParameters) const
+{
+  // 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;
+}
diff --git a/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx b/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..c237df2
--- /dev/null
@@ -0,0 +1,56 @@
+// 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 <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.
+  BRepMesh_SphereRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  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;
+
+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_Status.hxx b/src/BRepMesh/BRepMesh_Status.hxx
deleted file mode 100644 (file)
index 0c4ce44..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 _BRepMesh_Status_HeaderFile
-#define _BRepMesh_Status_HeaderFile
-
-//! Discribes the wires discretisation.
-enum BRepMesh_Status
-{
-  BRepMesh_NoError              = 0x0,
-  BRepMesh_OpenWire             = 0x1,
-  BRepMesh_SelfIntersectingWire = 0x2,
-  BRepMesh_Failure              = 0x4,
-  BRepMesh_ReMesh               = 0x8,
-  BRepMesh_UserBreak            = 0x16
-};
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_TorusRangeSplitter.cxx b/src/BRepMesh/BRepMesh_TorusRangeSplitter.cxx
new file mode 100644 (file)
index 0000000..455a473
--- /dev/null
@@ -0,0 +1,218 @@
+// 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.
+
+#include <BRepMesh_TorusRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_TorusRangeSplitter::GenerateSurfaceNodes(
+  const IMeshTools_Parameters& theParameters) const
+{
+  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 - Du * 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;
+}
+
+//=======================================================================
+// Function: AddPoint
+// Purpose : 
+//=======================================================================
+void BRepMesh_TorusRangeSplitter::AddPoint(const gp_Pnt2d& thePoint)
+{
+  BRepMesh_DefaultRangeSplitter::AddPoint(thePoint);
+  GetParametersU().Add(thePoint.X());
+  GetParametersV().Add(thePoint.Y());
+}
+
+//=======================================================================
+// Function: fillParams
+// Purpose : 
+//=======================================================================
+Handle(IMeshData::SequenceOfReal) BRepMesh_TorusRangeSplitter::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;
+}
+
+//=======================================================================
+// Function: FUN_CalcAverageDUV
+// Purpose : 
+//=======================================================================
+Standard_Real BRepMesh_TorusRangeSplitter::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.);
+}
diff --git a/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx b/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..1373e7d
--- /dev/null
@@ -0,0 +1,57 @@
+// 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 <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.
+  BRepMesh_TorusRangeSplitter()
+  {
+  }
+
+  //! Destructor.
+  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;
+
+  //! Registers border point.
+  Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint) Standard_OVERRIDE;
+
+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;
+
+  Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen) const;
+};
+
+#endif
index f6a5bac3999cf061382859f7fb45446eabcb813b..6cb531a56bd5355ded9554b6d9ab624355d8607c 100644 (file)
@@ -34,14 +34,14 @@ public:
 
   //! Default constructor.
   BRepMesh_Triangle()
-  : myEdge1(0),
-    myEdge2(0),
-    myEdge3(0),
-    myOrientation1(Standard_False),
-    myOrientation2(Standard_False),
-    myOrientation3(Standard_False),
-    myMovability  (BRepMesh_Free)
+    : myMovability  (BRepMesh_Free)
   {
+    myEdges[0] = 0;
+    myEdges[1] = 0;
+    myEdges[2] = 0;
+    myOrientations[0] = Standard_False;
+    myOrientations[1] = Standard_False;
+    myOrientations[2] = Standard_False;
   }
 
   //! Constructor.
@@ -65,12 +65,8 @@ public:
     const Standard_Boolean          (&theOrientations)[3],
     const BRepMesh_DegreeOfFreedom  theMovability)
   {
-    myEdge1        = theEdges[0];
-    myEdge2        = theEdges[1];
-    myEdge3        = theEdges[2];
-    myOrientation1 = theOrientations[0];
-    myOrientation2 = theOrientations[1];
-    myOrientation3 = theOrientations[2];
+    memcpy(myEdges, theEdges, sizeof(theEdges));
+    memcpy(myOrientations, theOrientations, sizeof(theOrientations));
     myMovability   = theMovability;
   }
   
@@ -80,12 +76,8 @@ public:
   inline void Edges(Standard_Integer (&theEdges)[3],
                     Standard_Boolean (&theOrientations)[3]) const
   {
-    theEdges[0]        = myEdge1;
-    theEdges[1]        = myEdge2;
-    theEdges[2]        = myEdge3;
-    theOrientations[0] = myOrientation1;
-    theOrientations[1] = myOrientation2;
-    theOrientations[2] = myOrientation3;
+    memcpy(theEdges, myEdges, sizeof(myEdges));
+    memcpy(theOrientations, myOrientations, sizeof(myOrientations));
   }
   
   //! Returns movability of the triangle.
@@ -99,40 +91,40 @@ public:
   {
     myMovability = theMovability;
   }
-  
-  //! Returns hash code for this triangle.
-  //! @param theUpper upper index in the container.
-  //! @return hash code.
-  Standard_Integer HashCode(const Standard_Integer theUpper) const
+
+  //! Computes a hash code for this triangle, in the range [1, theUpperBound]
+  //! @param theUpperBound the upper bound of the range a computing hash code must be within
+  //! @return a computed hash code, in the range [1, theUpperBound]
+  inline Standard_Integer HashCode (const Standard_Integer theUpperBound) const
   {
-    return ::HashCode(myEdge1 + myEdge2 + myEdge3, theUpper);
+    return ::HashCode (myEdges[0] + myEdges[1] + myEdges[2], theUpperBound);
   }
-  
+
   //! Checks for equality with another triangle.
   //! @param theOther triangle to be checked against this one.
   //! @return TRUE if equal, FALSE if not.
-  Standard_Boolean IsEqual(const BRepMesh_Triangle& theOther) const
+  inline Standard_Boolean IsEqual(const BRepMesh_Triangle& theOther) const
   {
     if (myMovability == BRepMesh_Deleted || theOther.myMovability == BRepMesh_Deleted)
       return Standard_False;
 
-    if (myEdge1 == theOther.myEdge1 && 
-        myEdge2 == theOther.myEdge2 && 
-        myEdge3 == theOther.myEdge3)
+    if (myEdges[0] == theOther.myEdges[0] &&
+        myEdges[1] == theOther.myEdges[1] &&
+        myEdges[2] == theOther.myEdges[2])
     {
       return Standard_True;
     }
 
-    if (myEdge1 == theOther.myEdge2 && 
-        myEdge2 == theOther.myEdge3 && 
-        myEdge3 == theOther.myEdge1)
+    if (myEdges[0] == theOther.myEdges[1] &&
+        myEdges[1] == theOther.myEdges[2] &&
+        myEdges[2] == theOther.myEdges[0])
     {
       return Standard_True;
     }
 
-    if (myEdge1 == theOther.myEdge3 && 
-        myEdge2 == theOther.myEdge1 && 
-        myEdge3 == theOther.myEdge2)
+    if (myEdges[0] == theOther.myEdges[2] &&
+        myEdges[1] == theOther.myEdges[0] &&
+        myEdges[2] == theOther.myEdges[1])
     {
       return Standard_True;
     }
@@ -141,26 +133,23 @@ public:
   }
   
   //! Alias for IsEqual.
-  Standard_Boolean operator ==(const BRepMesh_Triangle& theOther) const
+  inline Standard_Boolean operator ==(const BRepMesh_Triangle& theOther) const
   {
     return IsEqual(theOther);
   }
 
-private:
-
-  Standard_Integer          myEdge1;
-  Standard_Integer          myEdge2;
-  Standard_Integer          myEdge3;
-  Standard_Boolean          myOrientation1;
-  Standard_Boolean          myOrientation2;
-  Standard_Boolean          myOrientation3;
+  Standard_Integer          myEdges[3];
+  Standard_Boolean          myOrientations[3];
   BRepMesh_DegreeOfFreedom  myMovability;
 };
 
-inline Standard_Integer HashCode(const BRepMesh_Triangle& theTriangle,
-                                 const Standard_Integer   theUpper)
+//! Computes a hash code for the given triangle, in the range [1, theUpperBound]
+//! @param theTriangle the triangle which hash code is to be computed
+//! @param theUpperBound the upper bound of the range a computing hash code must be within
+//! @return a computed hash code, in the range [1, theUpperBound]
+inline Standard_Integer HashCode (const BRepMesh_Triangle& theTriangle, const Standard_Integer theUpperBound)
 {
return theTriangle.HashCode(theUpper);
 return theTriangle.HashCode (theUpperBound);
 }
 
 #endif
diff --git a/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx b/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx
new file mode 100644 (file)
index 0000000..f6d2b62
--- /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 boundary discrete points.
+class BRepMesh_UVParamRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+  //! Constructor.
+  BRepMesh_UVParamRangeSplitter()
+    : myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+      myUParams(1, myAllocator),
+      myVParams(1, myAllocator)
+  {
+  }
+
+  //! Destructor.
+  virtual ~BRepMesh_UVParamRangeSplitter()
+  {
+  }
+
+  //! Resets this splitter.
+  virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+                     const IMeshTools_Parameters&  theParameters) Standard_OVERRIDE
+  {
+    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
index 7cb7d72346a76fde0c0c7002144d5e0b61730444..73a31798ea1cbab104b6fea7d64a35fced18b16b 100644 (file)
@@ -20,6 +20,7 @@
 #include <Standard_Macro.hxx>
 #include <gp_XY.hxx>
 #include <BRepMesh_DegreeOfFreedom.hxx>
+#include <Precision.hxx>
 
 //! Light weighted structure representing vertex 
 //! of the mesh in parametric space. Vertex could be 
@@ -102,19 +103,19 @@ public:
   {
     myMovability = theMovability;
   }
-  
-  //! Returns hash code for this vertex.
-  //! @param theUpper upper index in the container.
-  //! @return hash code.
-  Standard_Integer HashCode(const Standard_Integer Upper) const
+
+  //! Computes a hash code for this vertex, in the range [1, theUpperBound]
+  //! @param theUpperBound the upper bound of the range a computing hash code must be within
+  //! @return a computed hash code, in the range [1, theUpperBound]
+  inline Standard_Integer HashCode(const Standard_Integer theUpperBound) const
   {
-    return ::HashCode(Floor(1e5 * myUV.X()) * Floor(1e5 * myUV.Y()), Upper);
+    return ::HashCode(Floor(1e5 * myUV.X()) * Floor(1e5 * myUV.Y()), theUpperBound);
   }
   
   //! Checks for equality with another vertex.
   //! @param theOther vertex to be checked against this one.
   //! @return TRUE if equal, FALSE if not.
-  Standard_Boolean IsEqual(const BRepMesh_Vertex& theOther) const
+  inline Standard_Boolean IsEqual(const BRepMesh_Vertex& theOther) const
   {
     if (myMovability          == BRepMesh_Deleted || 
         theOther.myMovability == BRepMesh_Deleted)
@@ -126,7 +127,7 @@ public:
   }
 
   //! Alias for IsEqual.
-  Standard_Boolean operator ==(const BRepMesh_Vertex& Other) const
+  inline Standard_Boolean operator ==(const BRepMesh_Vertex& Other) const
   {
     return IsEqual(Other);
   }
@@ -138,9 +139,13 @@ private:
   BRepMesh_DegreeOfFreedom  myMovability;
 };
 
-inline Standard_Integer HashCode(const BRepMesh_Vertex& me, const Standard_Integer Upper)
+//! Computes a hash code for the given vertex, in the range [1, theUpperBound]
+//! @param theVertex the vertex which hash code is to be computed
+//! @param theUpperBound the upper bound of the range a computing hash code must be within
+//! @return a computed hash code, in the range [1, theUpperBound]
+inline Standard_Integer HashCode (const BRepMesh_Vertex& theVertex, const Standard_Integer theUpperBound)
 {
return me.HashCode(Upper);
 return theVertex.HashCode (theUpperBound);
 }
 
 #endif
index 3b22160ec6e9615fe7a4073ab7da1f98feb3affc..dfd51ae926c0f6838a63fdd73ee5cfd9b209dc55 100644 (file)
@@ -19,7 +19,7 @@
 #include <Precision.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
-#include <BRepMesh.hxx>
+#include <IMeshData_Types.hxx>
 #include <NCollection_CellFilter.hxx>
 #include <BRepMesh_Vertex.hxx>
 
@@ -31,13 +31,14 @@ public:
 
   //! Constructor.
   //! @param theAllocator memory allocator to be used by internal collections.
-  BRepMesh_VertexInspector (
+  BRepMesh_VertexInspector(
     const Handle(NCollection_IncAllocator)& theAllocator)
-    : myResIndices(theAllocator),
-      myVertices  (new BRepMesh::VectorOfVertex),
-      myDelNodes  (theAllocator)
+    : myIndex(0),
+      myMinSqDist(RealLast()),
+      myVertices(new IMeshData::VectorOfVertex),
+      myDelNodes(theAllocator)
   {
-    SetTolerance( Precision::Confusion() );
+    SetTolerance(Precision::Confusion());
   }
 
   //! Registers the given vertex.
@@ -106,35 +107,32 @@ public:
   //! Set reference point to be checked.
   inline void SetPoint(const gp_XY& thePoint) 
   { 
-    myResIndices.Clear();
-    myPoint = thePoint;
+    myIndex     = 0;
+    myMinSqDist = RealLast();
+    myPoint     = thePoint;
   }
 
   //! Returns index of point coinciding with regerence one.
   inline Standard_Integer GetCoincidentPoint() const
   {
-    if ( myResIndices.Size() > 0 )
-    {
-      return myResIndices.First();
-    }
-    return 0;
+    return myIndex;
   }
   
   //! Returns list with indexes of vertices that have movability attribute 
   //! equal to BRepMesh_Deleted and can be replaced with another node.
-  inline const BRepMesh::ListOfInteger& GetListOfDelPoints() const
+  inline const IMeshData::ListOfInteger& GetListOfDelPoints() const
   {
     return myDelNodes;
   }
 
   //! Returns set of mesh vertices.
-  inline const BRepMesh::HVectorOfVertex& Vertices() const
+  inline const Handle(IMeshData::VectorOfVertex)& Vertices() const
   {
     return myVertices;
   }
 
   //! Returns set of mesh vertices for modification.
-  inline BRepMesh::HVectorOfVertex& ChangeVertices()
+  inline Handle(IMeshData::VectorOfVertex)& ChangeVertices()
   {
     return myVertices;
   }
@@ -153,11 +151,12 @@ public:
 
 private:
 
-  Standard_Real             myTolerance[2];
-  BRepMesh::ListOfInteger   myResIndices;
-  BRepMesh::HVectorOfVertex myVertices;
-  BRepMesh::ListOfInteger   myDelNodes;
-  gp_XY                     myPoint;
+  Standard_Integer                  myIndex;
+  Standard_Real                     myMinSqDist;
+  Standard_Real                     myTolerance[2];
+  Handle(IMeshData::VectorOfVertex) myVertices;
+  IMeshData::ListOfInteger          myDelNodes;
+  gp_XY                             myPoint;
 };
 
 #endif
index ecad73c435328a66fd0229e13bd835ba6c4da192..fffa7ac4da535fcc5d435f3fcffe1950f9d8c17b 100644 (file)
 // commercial license or contractual agreement.
 
 #include <BRepMesh_VertexTool.hxx>
-#include <gp_XY.hxx>
-#include <gp_XYZ.hxx>
 #include <Precision.hxx>
-#include <BRepMesh_Vertex.hxx>
-#include <BRepMesh_VertexInspector.hxx>
 
 //=======================================================================
 //function : Inspect
@@ -45,8 +41,16 @@ NCollection_CellFilter_Action BRepMesh_VertexInspector::Inspect(
     inTol = ((aVec.X() * aVec.X()) < myTolerance[0]) && 
             ((aVec.Y() * aVec.Y()) < myTolerance[1]);
   }
+
   if (inTol)
-    myResIndices.Append(theTarget);
+  {
+    const Standard_Real aSqDist = aVec.SquareModulus();
+    if (aSqDist < myMinSqDist)
+    {
+      myMinSqDist = aSqDist;
+      myIndex     = theTarget;
+    }
+  }
 
   return CellFilter_Keep;
 }
@@ -90,7 +94,7 @@ Standard_Integer BRepMesh_VertexTool::Add(
 //function : Delete
 //purpose  : 
 //=======================================================================
-void BRepMesh_VertexTool::Delete(const Standard_Integer theIndex)
+void BRepMesh_VertexTool::DeleteVertex(const Standard_Integer theIndex)
 {
   BRepMesh_Vertex& aV = mySelector.GetVertex(theIndex);
 
index b18b3e617926fdf51f73498c75328a4142fa54da..35aa778a8ac8b1554095ab464e308849ddcdcff4 100644 (file)
 #define _BRepMesh_VertexTool_HeaderFile
 
 #include <NCollection_Array1.hxx>
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Macro.hxx>
+#include <Standard_Transient.hxx>
 #include <BRepMesh_VertexInspector.hxx>
-#include <BRepMesh.hxx>
 #include <Standard_OStream.hxx>
-#include <gp_XYZ.hxx>
 #include <gp_XY.hxx>
+#include <IMeshData_Types.hxx>
 
 class BRepMesh_Vertex;
 
 //! Describes data structure intended to keep mesh nodes 
 //! defined in UV space and implements functionality 
-//! providing their uniqueness regarding thir position.
-class BRepMesh_VertexTool
+//! providing their uniqueness regarding their position.
+class BRepMesh_VertexTool : public Standard_Transient
 {
 public:
 
-  DEFINE_STANDARD_ALLOC
-  
   //! Constructor.
   //! @param theAllocator memory allocator to be used by internal collections.
   Standard_EXPORT BRepMesh_VertexTool(
@@ -101,16 +96,16 @@ public:
     const Standard_Boolean isForceAdd);
 
   //! Deletes vertex with the given index from the tool.
-  Standard_EXPORT void Delete(const Standard_Integer theIndex);
+  Standard_EXPORT void DeleteVertex(const Standard_Integer theIndex);
 
   //! Returns set of mesh vertices.
-  inline const BRepMesh::HVectorOfVertex& Vertices() const
+  inline const Handle(IMeshData::VectorOfVertex)& Vertices() const
   {
     return mySelector.Vertices();
   }
 
   //! Returns set of mesh vertices.
-  inline BRepMesh::HVectorOfVertex& ChangeVertices()
+  inline Handle(IMeshData::VectorOfVertex)& ChangeVertices()
   {
     return mySelector.ChangeVertices();
   }
@@ -150,12 +145,12 @@ public:
   //! Remove last node from the structure.
   inline void RemoveLast()
   {
-    Delete(Extent());
+    DeleteVertex(Extent());
   }
 
   //! Returns the list with indexes of vertices that have movability attribute
   //! equal to BRepMesh_Deleted and can be replaced with another node.
-  inline const BRepMesh::ListOfInteger& GetListOfDelNodes() const
+  inline const IMeshData::ListOfInteger& GetListOfDelNodes() const
   {
     return mySelector.GetListOfDelPoints();
   }
@@ -163,6 +158,8 @@ public:
   //! Prints statistics.
   Standard_EXPORT void Statistics(Standard_OStream& theStream) const;
 
+  DEFINE_STANDARD_RTTI_INLINE(BRepMesh_VertexTool, Standard_Transient)
+
 private:
   
   //! Expands the given point according to specified tolerance.
@@ -181,10 +178,10 @@ private:
 
 private:
 
-  Handle(NCollection_IncAllocator)      myAllocator;
-  BRepMesh::VertexCellFilter            myCellFilter;
-  BRepMesh_VertexInspector              mySelector;
-  Standard_Real                         myTolerance[2];
+  Handle(NCollection_IncAllocator) myAllocator;
+  IMeshData::VertexCellFilter      myCellFilter;
+  BRepMesh_VertexInspector         mySelector;
+  Standard_Real                    myTolerance[2];
 };
 
 #endif
diff --git a/src/BRepMesh/BRepMesh_WireChecker.cxx b/src/BRepMesh/BRepMesh_WireChecker.cxx
deleted file mode 100644 (file)
index 5def2f1..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-// Created on: 2014-06-03
-// Created by: Oleg AGASHIN
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-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.
-
-#include <BRepMesh_WireChecker.hxx>
-
-#include <Precision.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <gp_Pnt2d.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <TopAbs_Orientation.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Wire.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <Poly_PolygonOnTriangulation.hxx>
-#include <BRepMesh_PairOfPolygon.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh_Classifier.hxx>
-#include <BRepMesh_WireInterferenceChecker.hxx>
-#include <OSD_Parallel.hxx>
-
-
-//=======================================================================
-//function : Selector::Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_WireChecker::BndBox2dTreeSelector::BndBox2dTreeSelector(
-  const Standard_Integer theReservedSize)
-  : mySkippedIndex(-1),
-    myIndices(0, theReservedSize - 1),
-    myIndicesNb(0)
-{
-}
-
-//=======================================================================
-//function : Reject
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_WireChecker::BndBox2dTreeSelector::Reject(
-  const Bnd_Box2d& theBox2D) const
-{
-  return myBox2D.IsOut(theBox2D);
-}
-
-//=======================================================================
-//function : Accept
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_WireChecker::BndBox2dTreeSelector::Accept(
-  const Standard_Integer& theIndex)
-{
-  if (theIndex <= mySkippedIndex)
-    return Standard_False;
-
-  myIndices(myIndicesNb++) = theIndex;
-  return Standard_True;
-}
-
-//=======================================================================
-//function : Clear
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireChecker::BndBox2dTreeSelector::Clear()
-{
-  mySkippedIndex = -1;
-  myIndicesNb    = 0;
-}
-
-//=======================================================================
-//function : SetBox
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireChecker::BndBox2dTreeSelector::SetBox(
-  const Bnd_Box2d& theBox2D)
-{
-  myBox2D = theBox2D;
-}
-
-//=======================================================================
-//function : Clear
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireChecker::BndBox2dTreeSelector::SetSkippedIndex(
-  const Standard_Integer theIndex)
-{
-  mySkippedIndex = theIndex;
-}
-
-//=======================================================================
-//function : Indices
-//purpose  : 
-//=======================================================================
-const BRepMesh::Array1OfInteger& 
-  BRepMesh_WireChecker::BndBox2dTreeSelector::Indices() const
-{
-  return myIndices;
-}
-
-//=======================================================================
-//function : IndicesNb
-//purpose  : 
-//=======================================================================
-Standard_Integer BRepMesh_WireChecker::BndBox2dTreeSelector::IndicesNb() const
-{
-  return myIndicesNb;
-}
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-BRepMesh_WireChecker::BRepMesh_WireChecker(
-  const TopoDS_Face&                            theFace,
-  const Standard_Real                           theTolUV,
-  const BRepMesh::HDMapOfShapePairOfPolygon&    theEdges,
-  const BRepMesh::HIMapOfInteger&               theVertexMap,
-  const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
-  const Standard_Real                           theUmin,
-  const Standard_Real                           theUmax,
-  const Standard_Real                           theVmin,
-  const Standard_Real                           theVmax,
-  const Standard_Boolean                        isInParallel)
-  : myTolUV(theTolUV),
-    myEdges(theEdges),
-    myVertexMap(theVertexMap),
-    myStructure(theStructure),
-    myUmin(theUmin),
-    myUmax(theUmax),
-    myVmin(theVmin),
-    myVmax(theVmax),
-    myStatus(BRepMesh_NoError),
-    myIsInParallel(isInParallel)
-{
-  TopoDS_Face aFace = theFace;
-  aFace.Orientation(TopAbs_FORWARD);
-
-  for (TopoDS_Iterator aFaceIt(aFace); aFaceIt.More(); aFaceIt.Next())
-  {
-    if (aFaceIt.Value().IsNull() || aFaceIt.Value().ShapeType() != TopAbs_WIRE) // may be inner vertex
-      continue;
-    const TopoDS_Wire& aWire = TopoDS::Wire(aFaceIt.Value());
-
-    myWiresEdges.Append(ListOfEdges());
-    ListOfEdges& aEdges = myWiresEdges.ChangeLast();
-
-    // Start traversing the wires
-    BRepTools_WireExplorer aWireExplorer(aWire, aFace);
-    for (; aWireExplorer.More(); aWireExplorer.Next())
-    {
-      const TopoDS_Edge& aEdge   = aWireExplorer.Current();
-      TopAbs_Orientation aOrient = aEdge.Orientation();
-      if (aOrient != TopAbs_FORWARD && aOrient != TopAbs_REVERSED)
-        continue;
-
-      aEdges.Append(aEdge);
-    }
-
-    if (aEdges.IsEmpty())
-      myWiresEdges.Remove(myWiresEdges.Size());
-  }
-}
-
-//=======================================================================
-//function : ReCompute
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireChecker::ReCompute(BRepMesh::HClassifier& theClassifier)
-{
-  if (theClassifier.IsNull())
-    return;
-
-  theClassifier->Destroy();
-  myStatus = BRepMesh_NoError;
-  
-  SeqOfDWires aDWires;
-  if (!collectDiscretizedWires(aDWires))
-    return;
-
-  const Standard_Integer aNbWires = aDWires.Size();
-  BRepMesh::Array1OfSegmentsTree aWiresBiPoints(1, aNbWires);
-  fillSegmentsTree(aDWires, aWiresBiPoints);
-
-  if (myIsInParallel && aNbWires > 1)
-  {
-    // Check wires in parallel threads.
-    Standard_Mutex aWireMutex;
-    BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus, &aWireMutex);
-    OSD_Parallel::For(1, aNbWires + 1, aIntChecker);
-  }
-  else
-  {
-    BRepMesh_WireInterferenceChecker aIntChecker(aWiresBiPoints, &myStatus);
-    OSD_Parallel::For(1, aNbWires + 1, aIntChecker, Standard_True);
-  }
-
-  if (myStatus == BRepMesh_SelfIntersectingWire)
-    return;
-
-  // Find holes
-  SeqOfDWires::Iterator aDWiresIt(aDWires);
-  for (; aDWiresIt.More(); aDWiresIt.Next())
-  {
-    const SeqOfPnt2d& aDWire = aDWiresIt.Value();
-    theClassifier->RegisterWire(aDWire, myTolUV, myUmin, myUmax, myVmin, myVmax);
-  }
-}
-
-//=======================================================================
-//function : collectDiscretizedWires
-//purpose  : 
-//=======================================================================
-Standard_Boolean BRepMesh_WireChecker::collectDiscretizedWires(
-  SeqOfDWires& theDWires)
-{
-  SeqOfWireEdges::Iterator aWireIt(myWiresEdges);
-  for(; aWireIt.More(); aWireIt.Next())
-  {
-    const ListOfEdges& aEdges = aWireIt.Value();
-    // For each wire we create a data map, linking vertices (only
-    // the ends of edges) with their positions in the sequence of
-    // all 2d points from this wire.
-    // When we meet some vertex for the second time - the piece
-    // of sequence is treated for a HOLE and quits the sequence.
-    // Actually, we must unbind the vertices belonging to the
-    // loop from the map, but since they can't appear twice on the
-    // valid wire, leave them for a little speed up.
-
-    SeqOfPnt2d                    aSeqPnt2d;
-    BRepMesh::MapOfIntegerInteger aNodeInSeq;
-    Standard_Integer aFirstIndex = 0, aLastIndex = 0;
-
-    // Start traversing the wire
-    ListOfEdges::Iterator aEdgeIt(aEdges);
-    for (; aEdgeIt.More(); aEdgeIt.Next())
-    {
-      const TopoDS_Edge& aEdge   = aEdgeIt.Value();
-      TopAbs_Orientation aOrient = aEdge.Orientation();
-      if (!myEdges->IsBound(aEdge))
-        continue;
-
-      // Retrieve polygon
-      // Define the direction for adding points to aSeqPnt2d
-      Standard_Integer aStartId, aEndId, aIncrement;
-      const BRepMesh_PairOfPolygon& aPair = myEdges->Find(aEdge);
-      Handle(Poly_PolygonOnTriangulation) aNOD;
-      if (aOrient == TopAbs_FORWARD)
-      {
-        aNOD       = aPair.First();
-        aStartId   = 1;
-        aEndId     = aNOD->NbNodes();
-        aIncrement = 1;
-      }
-      else
-      {
-        aNOD       = aPair.Last();
-        aStartId   = aNOD->NbNodes();
-        aEndId     = 1;
-        aIncrement = -1;
-      }
-
-      const TColStd_Array1OfInteger& aIndices = aNOD->Nodes();
-      const Standard_Integer aFirstVertexId = myVertexMap->FindKey(aIndices(aStartId));
-      const Standard_Integer aLastVertexId  = myVertexMap->FindKey(aIndices(aEndId)  );
-
-      if (aFirstVertexId == aLastVertexId && (aEndId - aStartId) == aIncrement)
-      {
-        // case of continuous set of degenerated edges
-        aLastIndex = aLastVertexId;
-        continue;
-      }
-
-      if (aFirstIndex != 0)
-      {
-        if (aFirstVertexId != aLastIndex)
-        {
-          // there's a gap between edges
-          myStatus = BRepMesh_OpenWire;
-          return Standard_False;
-        }
-      }
-      else
-        aFirstIndex = aFirstVertexId;
-
-      aLastIndex = aLastVertexId;
-
-      // Record first vertex (to detect loops)
-      aNodeInSeq.Bind(aFirstVertexId, (aSeqPnt2d.Length() + 1));
-
-      // Add vertices in sequence
-      for (Standard_Integer i = aStartId; i != aEndId; i += aIncrement)
-      {
-        Standard_Integer aIndex = ((i == aStartId) ? 
-          aFirstVertexId : 
-          myVertexMap->FindKey(aIndices(i)));
-
-        aSeqPnt2d.Append(gp_Pnt2d(myStructure->GetNode(aIndex).Coord()));
-      }
-
-      // Now, is there a loop?
-      if (aNodeInSeq.IsBound(aLastVertexId))
-      {
-        // Yes, treat it separately as a hole
-        // Divide points into main wire and a loop
-        const Standard_Integer aIdxWireStart = aNodeInSeq(aLastVertexId);
-        if(aIdxWireStart < aSeqPnt2d.Length())
-        {
-          theDWires.Append(SeqOfPnt2d());
-          SeqOfPnt2d& aWire = theDWires.ChangeLast();
-          aSeqPnt2d.Split(aIdxWireStart, aWire);
-        }
-      }
-    }
-
-    if (aFirstIndex == 0)
-      continue;
-
-    // Isn't wire open?
-    if (aFirstIndex != aLastIndex || aSeqPnt2d.Length() > 1)
-    {
-      myStatus = BRepMesh_OpenWire;
-      return Standard_False;
-    }
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : fillSegmentsTree
-//purpose  :
-//=======================================================================
-void BRepMesh_WireChecker::fillSegmentsTree(
-  const SeqOfDWires&              theDWires,
-  BRepMesh::Array1OfSegmentsTree& theWiresSegmentsTree)
-{
-  const Standard_Integer aNbWires = theDWires.Size();
-  for (Standard_Integer aWireIt = 1; aWireIt <= aNbWires; ++aWireIt)
-  {
-    const SeqOfPnt2d&      aWire    = theDWires(aWireIt);
-    const Standard_Integer aWireLen = aWire.Size();
-
-    BRepMesh::HArray1OfSegments  aWireSegments = 
-      new BRepMesh::Array1OfSegments(1, aWireLen);
-
-    BRepMesh::HBndBox2dTree      aBndBoxTree   = 
-      new BRepMesh::BndBox2dTree;
-
-    BRepMesh::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree);
-
-    Standard_Real x1 = 0., y1 = 0., aXstart = 0., aYstart = 0.;
-    for (Standard_Integer aPntIt = 0; aPntIt <= aWireLen; ++aPntIt)
-    {
-      Standard_Real x2, y2;
-      // Obtain last point of the segment
-      if (aPntIt == aWireLen)
-      {
-        x2 = aXstart;
-        y2 = aYstart;
-      }
-      else
-      {
-        const gp_Pnt2d& aPnt = aWire(aPntIt + 1);
-        x2 = aPnt.X();
-        y2 = aPnt.Y();
-      }
-
-      // Build segment (bi-point)
-      if (aPntIt == 0)
-      {
-        aXstart = x2;
-        aYstart = y2;
-      }
-      else
-      {
-        gp_Pnt2d aStartPnt(x1, y1);
-        gp_Pnt2d   aEndPnt(x2, y2);
-       
-        BRepMesh::Segment& aSegment = aWireSegments->ChangeValue(aPntIt);
-        aSegment.StartPnt = aStartPnt.XY();
-        aSegment.EndPnt   = aEndPnt.XY();
-
-        Bnd_Box2d aBox;
-        aBox.Add(aStartPnt);
-        aBox.Add(  aEndPnt);
-        aBndBoxTreeFiller.Add(aPntIt, aBox);
-      }
-      x1 = x2;
-      y1 = y2;
-    }
-    aBndBoxTreeFiller.Fill();
-
-    BRepMesh::SegmentsTree& aSegmentsTree = theWiresSegmentsTree(aWireIt);
-    aSegmentsTree.first  = aWireSegments;
-    aSegmentsTree.second = aBndBoxTree;
-  }
-}
diff --git a/src/BRepMesh/BRepMesh_WireChecker.hxx b/src/BRepMesh/BRepMesh_WireChecker.hxx
deleted file mode 100644 (file)
index 9b12a85..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-// Created on: 2014-06-03
-// Created by: Oleg AGASHIN
-// Copyright (c) 1997-1999 Matra Datavision
-// Copyright (c) 1999-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 _BRepMesh_WireChecker_HeaderFile
-#define _BRepMesh_WireChecker_HeaderFile
-
-#include <Standard.hxx>
-#include <TopoDS_Face.hxx>
-#include <BRepMesh_Status.hxx>
-#include <BRepMesh_DataStructureOfDelaun.hxx>
-#include <BRepMesh.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
-#include <TopoDS_Edge.hxx>
-#include <Bnd_Box2d.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_XY.hxx>
-
-#include <vector>
-
-
-//! Auxilary class intended to check correctness of discretized face.
-//! In particular, checks boundaries of discretized face for self 
-//! intersections and gaps.
-class BRepMesh_WireChecker
-{
-public:
-
-  //! Selector.
-  //! Used to identify segments with overlapped bounding boxes.
-  //! Note that instance of selector can be used only once due to
-  //! unextentable array of indices.
-  class BndBox2dTreeSelector : public BRepMesh::BndBox2dTree::Selector
-  {
-    public:
-      Standard_EXPORT BndBox2dTreeSelector(const Standard_Integer theReservedSize);
-      Standard_EXPORT virtual Standard_Boolean Reject(const Bnd_Box2d& theBox2D) const;
-      Standard_EXPORT virtual Standard_Boolean Accept(const Standard_Integer& theIndex);
-      
-      Standard_EXPORT void Clear();
-      Standard_EXPORT void SetBox(const Bnd_Box2d& theBox2D);
-      Standard_EXPORT void SetSkippedIndex(const Standard_Integer theIndex);
-      Standard_EXPORT const BRepMesh::Array1OfInteger& Indices() const;
-      Standard_EXPORT Standard_Integer IndicesNb() const;
-
-    protected:
-      Bnd_Box2d                  myBox2D;
-      Standard_Integer           mySkippedIndex;
-      BRepMesh::Array1OfInteger  myIndices;
-      Standard_Integer           myIndicesNb;
-  };
-
-private:
-
-  typedef NCollection_List<TopoDS_Edge>      ListOfEdges;
-  typedef NCollection_Sequence<ListOfEdges>  SeqOfWireEdges;
-
-  typedef NCollection_Sequence<gp_Pnt2d>     SeqOfPnt2d;
-  typedef NCollection_Sequence<SeqOfPnt2d>   SeqOfDWires;
-
-public:
-
-  //! Constructor.
-  //! @param theFace Face to be checked.
-  //! @param theTolUV Tolerance to be used for calculations in parametric space.
-  //! @param theEdges Map of edges with associated polygon on triangulation.
-  //! @param theVertexMap Map of face vertices.
-  //! @param theStructure Discretized representation of face in parametric space.
-  //! @param theUmin Lower U boundary of the face in parametric space.
-  //! @param theUmax Upper U boundary of the face in parametric space.
-  //! @param theVmin Lower V boundary of the face in parametric space.
-  //! @param theVmax Upper V boundary of the face in parametric space.
-  Standard_EXPORT BRepMesh_WireChecker(
-    const TopoDS_Face&                            theFace,
-    const Standard_Real                           theTolUV,
-    const BRepMesh::HDMapOfShapePairOfPolygon&    theEdges,
-    const BRepMesh::HIMapOfInteger&               theVertexMap,
-    const Handle(BRepMesh_DataStructureOfDelaun)& theStructure,
-    const Standard_Real                           theUmin,
-    const Standard_Real                           theUmax,
-    const Standard_Real                           theVmin,
-    const Standard_Real                           theVmax,
-    const Standard_Boolean                        isInParallel);
-
-  //! Recompute data using parameters passed in constructor.
-  //! @param[out] theClassifier Classifier to be updated using calculated data.
-  Standard_EXPORT void ReCompute(BRepMesh::HClassifier& theClassifier);
-
-  //! Returns status of the check.
-  inline BRepMesh_Status Status() const
-  {
-    return myStatus;
-  }
-
-private:
-
-  //! Collects discrete wires.
-  //! @param[out] theDWires sequence of discretized wires to be filled.
-  //! @return TRUE on success, FALSE in case of open wire.
-  Standard_Boolean collectDiscretizedWires(SeqOfDWires& theDWires);
-
-  //! Fills array of BiPoints for corresponding wire.
-  //! @param theDWires Sequence of wires to be processed.
-  //! @param theWiresSegmentsTree Array of segments with corresponding 
-  //! bounding boxes trees to be filled.
-  void fillSegmentsTree(
-    const SeqOfDWires&              theDWires, 
-    BRepMesh::Array1OfSegmentsTree& theWiresSegmentsTree);
-
-  //! Assignment operator.
-  void operator =(BRepMesh_WireChecker& /*theOther*/)
-  {
-  }
-
-private:
-
-  const Standard_Real                           myTolUV;
-  const BRepMesh::HDMapOfShapePairOfPolygon&    myEdges;
-  const BRepMesh::HIMapOfInteger&               myVertexMap;
-  const Handle(BRepMesh_DataStructureOfDelaun)& myStructure;
-  const Standard_Real                           myUmin;
-  const Standard_Real                           myUmax;
-  const Standard_Real                           myVmin;
-  const Standard_Real                           myVmax;
-  BRepMesh_Status                               myStatus;
-  SeqOfWireEdges                                myWiresEdges;
-  Standard_Boolean                              myIsInParallel;
-};
-
-#endif
diff --git a/src/BRepMesh/BRepMesh_WireInterferenceChecker.cxx b/src/BRepMesh/BRepMesh_WireInterferenceChecker.cxx
deleted file mode 100644 (file)
index 326dc8c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-// Created on: 2014-06-18
-// 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.
-
-#include <BRepMesh_WireInterferenceChecker.hxx>
-#include <BRepMesh_GeomTool.hxx>
-#include <Precision.hxx>
-
-// TODO: remove this variable after implementation of LoopChecker2d.
-static const Standard_Real MIN_LOOP_S = 2 * M_PI * 2.E-5;
-
-//=======================================================================
-//function : Constructor
-//purpose  :
-//=======================================================================
-BRepMesh_WireInterferenceChecker::BRepMesh_WireInterferenceChecker(
-  const BRepMesh::Array1OfSegmentsTree& theWires,
-  BRepMesh_Status*                      theStatus,
-  Standard_Mutex*                       theMutex)
-: myWires (theWires),
-  myStatus(theStatus),
-  myMutex (theMutex)
-{
-}
-
-//=======================================================================
-//function : Checker's body
-//purpose  : 
-//=======================================================================
-void BRepMesh_WireInterferenceChecker::operator ()(
-  const Standard_Integer& theWireId) const
-{
-  if (*myStatus == BRepMesh_SelfIntersectingWire)
-    return;
-
-  const BRepMesh::SegmentsTree&      aWireSegTree1  = myWires(theWireId);
-  const BRepMesh::HArray1OfSegments& aWireSegments1 = aWireSegTree1.first;
-  const BRepMesh::HBndBox2dTree&     aWireBoxTree1  = aWireSegTree1.second;
-
-  for (Standard_Integer aWireIt = theWireId; aWireIt <= myWires.Upper(); ++aWireIt)
-  {
-    // Break execution in case if flag was raised by another thread.
-    if (*myStatus == BRepMesh_SelfIntersectingWire)
-      return;
-
-    const Standard_Boolean isSelfIntCheck = (aWireIt == theWireId);
-    const BRepMesh::SegmentsTree& aWireSegTree2 = 
-      isSelfIntCheck ? aWireSegTree1 : myWires(aWireIt);
-
-    const BRepMesh::HArray1OfSegments& aWireSegments2 = aWireSegTree2.first;
-    const BRepMesh::HBndBox2dTree&     aWireBoxTree2  = aWireSegTree2.second;
-
-    BRepMesh_WireChecker::BndBox2dTreeSelector aSelector (aWireSegments2->Size());
-
-    Standard_Integer aSegmentId1 = aWireSegments1->Lower();
-    for (; aSegmentId1 <= aWireSegments1->Upper(); ++aSegmentId1)
-    {
-      // Break execution in case if flag was raised by another thread
-      if (*myStatus == BRepMesh_SelfIntersectingWire)
-        return;
-
-      aSelector.Clear();
-      aSelector.SetBox(aWireBoxTree1->FindNode(aSegmentId1).Bnd());
-      if (isSelfIntCheck)
-        aSelector.SetSkippedIndex(aSegmentId1);
-
-      if (aWireBoxTree2->Select(aSelector) == 0)
-        continue;
-
-      const BRepMesh::Segment& aSegment1 = aWireSegments1->Value(aSegmentId1);
-      const BRepMesh::Array1OfInteger& aSelected = aSelector.Indices();
-      const Standard_Integer aSelectedNb = aSelector.IndicesNb();
-      for (Standard_Integer aBndIt = 0; aBndIt < aSelectedNb; ++aBndIt)
-      {
-        // Break execution in case if flag was raised by another thread
-        if (*myStatus == BRepMesh_SelfIntersectingWire)
-          return;
-
-        const Standard_Integer aSegmentId2 = aSelected(aBndIt);
-        const BRepMesh::Segment& aSegment2 = aWireSegments2->Value(aSegmentId2);
-
-        gp_Pnt2d aIntPnt;
-        BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
-          aSegment1.StartPnt, aSegment1.EndPnt, 
-          aSegment2.StartPnt, aSegment2.EndPnt,
-          Standard_False, Standard_False,
-          aIntPnt);
-
-        if (aIntStatus == BRepMesh_GeomTool::Cross)
-        {
-          // TODO: remove this block after implementation of LoopChecker2d.
-          if (isSelfIntCheck)
-          {
-            gp_XY aPrevVec;
-            Standard_Real aSumS = 0.;
-            const gp_XY& aRefPnt  = aIntPnt.Coord();
-            for (Standard_Integer i = aSegmentId1; i < aSegmentId2; ++i)
-            {
-              const BRepMesh::Segment& aSeg = aWireSegments1->Value(i);
-              gp_XY aCurVec = aSeg.EndPnt - aRefPnt;
-
-              if (aCurVec.SquareModulus() < gp::Resolution())
-                continue;
-
-              if (aPrevVec.SquareModulus() > gp::Resolution())
-                aSumS += aPrevVec ^ aCurVec;
-
-              aPrevVec = aCurVec;
-            }
-
-            if (Abs(aSumS / 2.) < MIN_LOOP_S)
-              continue;
-          }
-
-          Standard_Mutex::Sentry aSentry(myMutex);
-          *myStatus = BRepMesh_SelfIntersectingWire;
-
-          return;
-        }
-      }
-    }
-  }
-}
diff --git a/src/BRepMesh/BRepMesh_WireInterferenceChecker.hxx b/src/BRepMesh/BRepMesh_WireInterferenceChecker.hxx
deleted file mode 100644 (file)
index 03e7055..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Created on: 2014-06-18
-// 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 _BRepMesh_WireInterferenceChecker_HeaderFile
-#define _BRepMesh_WireInterferenceChecker_HeaderFile
-
-#include <Standard.hxx>
-#include <Standard_Mutex.hxx>
-#include <BRepMesh_WireChecker.hxx>
-#include <BRepMesh_Status.hxx>
-
-//! Auxilary class implementing functionality for 
-//! checking interference between two discretized wires.
-class BRepMesh_WireInterferenceChecker
-{
-public:
-
-  //! Enumerates states of segments intersection check.
-  enum IntFlag
-  {
-    NoIntersection,
-    Cross,
-    EndPointTouch,
-    PointOnSegment,
-    Glued,
-    Same
-  };
-
-  //! Constructor
-  //! @param theWires wires that should be checked.
-  //! @param theStatus shared flag to set status of the check.
-  //! @param theMutex shared mutex for parallel processing.
-  BRepMesh_WireInterferenceChecker(
-    const BRepMesh::Array1OfSegmentsTree& theWires,
-    BRepMesh_Status*                      theStatus,
-    Standard_Mutex*                       theMutex = NULL);
-
-  //! Checker's body.
-  //! @param theWireId Id of discretized wire to be checked.
-  void operator ()(const Standard_Integer& theWireId) const;
-
-private:
-
-  //! Assignment operator.
-  void operator =(const BRepMesh_WireInterferenceChecker& /*theOther*/)
-  {
-  }
-
-private:
-  const BRepMesh::Array1OfSegmentsTree& myWires;
-  BRepMesh_Status*                      myStatus;
-  Standard_Mutex*                       myMutex;
-};
-
-#endif
index ec3909484278e7b4aacbb7c346f77c1920ce6874..a37a4504e43404e644f1bca6f0935dbc2f5f8c42 100755 (executable)
@@ -1,55 +1,88 @@
-BRepMesh.hxx
+BRepMesh_BaseMeshAlgo.cxx
+BRepMesh_BaseMeshAlgo.hxx
+BRepMesh_ConstrainedBaseMeshAlgo.hxx
+BRepMesh_BoundaryParamsRangeSplitter.hxx
 BRepMesh_Circle.hxx
 BRepMesh_CircleInspector.hxx
 BRepMesh_CircleTool.cxx
 BRepMesh_CircleTool.hxx
 BRepMesh_Classifier.cxx
 BRepMesh_Classifier.hxx
+BRepMesh_ConeRangeSplitter.cxx
+BRepMesh_ConeRangeSplitter.hxx
+BRepMesh_Context.cxx
+BRepMesh_Context.hxx
+BRepMesh_CurveTessellator.cxx
+BRepMesh_CurveTessellator.hxx
+BRepMesh_CylinderRangeSplitter.cxx
+BRepMesh_CylinderRangeSplitter.hxx
 BRepMesh_DataStructureOfDelaun.cxx
 BRepMesh_DataStructureOfDelaun.hxx
+BRepMesh_DefaultRangeSplitter.cxx
+BRepMesh_DefaultRangeSplitter.hxx
+BRepMesh_Deflection.cxx
+BRepMesh_Deflection.hxx
 BRepMesh_DegreeOfFreedom.hxx
 BRepMesh_Delaun.cxx
 BRepMesh_Delaun.hxx
+BRepMesh_DelaunayBaseMeshAlgo.cxx
+BRepMesh_DelaunayBaseMeshAlgo.hxx
+BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
+BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx
 BRepMesh_DiscretFactory.cxx
 BRepMesh_DiscretFactory.hxx
 BRepMesh_DiscretRoot.cxx
 BRepMesh_DiscretRoot.hxx
 BRepMesh_Edge.hxx
-BRepMesh_EdgeParameterProvider.cxx
+BRepMesh_EdgeDiscret.cxx
+BRepMesh_EdgeDiscret.hxx
 BRepMesh_EdgeParameterProvider.hxx
 BRepMesh_EdgeTessellationExtractor.cxx
 BRepMesh_EdgeTessellationExtractor.hxx
-BRepMesh_EdgeTessellator.cxx
-BRepMesh_EdgeTessellator.hxx
-BRepMesh_FaceAttribute.cxx
-BRepMesh_FaceAttribute.hxx
+BRepMesh_FaceChecker.cxx
+BRepMesh_FaceChecker.hxx
+BRepMesh_FaceDiscret.cxx
+BRepMesh_FaceDiscret.hxx
 BRepMesh_FactoryError.hxx
-BRepMesh_FastDiscret.cxx
 BRepMesh_FastDiscret.hxx
-BRepMesh_FastDiscretFace.cxx
-BRepMesh_FastDiscretFace.hxx
 BRepMesh_GeomTool.cxx
 BRepMesh_GeomTool.hxx
-BRepMesh_IEdgeTool.cxx
-BRepMesh_IEdgeTool.hxx
 BRepMesh_IncrementalMesh.cxx
 BRepMesh_IncrementalMesh.hxx
+BRepMesh_MeshAlgoFactory.cxx
+BRepMesh_MeshAlgoFactory.hxx
+BRepMesh_MeshTool.cxx
+BRepMesh_MeshTool.hxx
+BRepMesh_ModelBuilder.cxx
+BRepMesh_ModelBuilder.hxx
+BRepMesh_ModelHealer.cxx
+BRepMesh_ModelHealer.hxx
+BRepMesh_ModelPostProcessor.cxx
+BRepMesh_ModelPostProcessor.hxx
+BRepMesh_ModelPreProcessor.cxx
+BRepMesh_ModelPreProcessor.hxx
+BRepMesh_NURBSRangeSplitter.cxx
+BRepMesh_NURBSRangeSplitter.hxx
+BRepMesh_NodeInsertionMeshAlgo.hxx
 BRepMesh_OrientedEdge.hxx
 BRepMesh_PairOfIndex.hxx
-BRepMesh_PairOfPolygon.hxx
 BRepMesh_PluginEntryType.hxx
 BRepMesh_PluginMacro.hxx
 BRepMesh_SelectorOfDataStructureOfDelaun.cxx
 BRepMesh_SelectorOfDataStructureOfDelaun.hxx
 BRepMesh_ShapeTool.cxx
 BRepMesh_ShapeTool.hxx
-BRepMesh_Status.hxx
+BRepMesh_ShapeVisitor.cxx
+BRepMesh_ShapeVisitor.hxx
+BRepMesh_SphereRangeSplitter.cxx
+BRepMesh_SphereRangeSplitter.hxx
+BRepMesh_TorusRangeSplitter.cxx
+BRepMesh_TorusRangeSplitter.hxx
 BRepMesh_Triangle.hxx
+BRepMesh_UVParamRangeSplitter.hxx
 BRepMesh_Vertex.hxx
 BRepMesh_VertexInspector.hxx
 BRepMesh_VertexTool.cxx
 BRepMesh_VertexTool.hxx
-BRepMesh_WireChecker.cxx
-BRepMesh_WireChecker.hxx
-BRepMesh_WireInterferenceChecker.cxx
-BRepMesh_WireInterferenceChecker.hxx
+BRepMesh_CustomBaseMeshAlgo.hxx
+BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
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..08c07f8
--- /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_Model.hxx>
+
+#include <BRepMeshData_Face.hxx>
+#include <BRepMeshData_Edge.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+#include <NCollection_IncAllocator.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+BRepMeshData_Model::BRepMeshData_Model (const TopoDS_Shape& theShape)
+  : IMeshData_Model (theShape),
+    myMaxSize (0.),
+    myAllocator (new NCollection_IncAllocator (IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+    myDFaces (256, myAllocator),
+    myDEdges (256, myAllocator)
+{
+  myAllocator->SetThreadSafe();
+}
+
+//=======================================================================
+// 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..4c03911
--- /dev/null
@@ -0,0 +1,155 @@
+// 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>
+#include <Standard_OutOfRange.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)
+{
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myPoints2d.size()),
+    "BRepMeshData_PCurve::GetPoint");
+  return myPoints2d[theIndex];
+}
+
+//=======================================================================
+// Function: GetIndex
+// Purpose : 
+//=======================================================================
+Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
+{
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myIndices.size()),
+    "BRepMeshData_PCurve::GetIndex");
+  return myIndices[theIndex];
+}
+
+//=======================================================================
+// Function: GetParameter
+// Purpose : 
+//=======================================================================
+Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
+{
+  Standard_OutOfRange_Raise_if (
+    theIndex < 0 || theIndex >= ParametersNb(),
+    "BRepMeshData_PCurve::GetParameter");
+  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
index 22df8ddb50ece50516817a619e384600f916fc62..f300abe29467ec91c3238015872f25e45ec3150e 100644 (file)
@@ -840,7 +840,7 @@ void DBRep_DrawableShape::DisplayHiddenLines(Draw_Display& dis)
   if (!strcmp(dout.GetType(id),"PERS")) focal = dout.Focal(id);
   Standard_Real Ang,Def;
   HLRBRep::PolyHLRAngleAndDeflection(myAng,Ang,Def);
-  BRepMesh_FastDiscret::Parameters aMeshParams;
+  IMeshTools_Parameters aMeshParams;
   aMeshParams.Relative = Standard_True;
   aMeshParams.Deflection = Def;
   aMeshParams.Angle = Ang;
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..4ba98d7
--- /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,  //!< Mesh generation is successful.
+  IMeshData_OpenWire              = 0x1,  //!< Notifies open wire problem, which can potentially lead to incorrect results.
+  IMeshData_SelfIntersectingWire  = 0x2,  //!< Notifies self-intersections on discretized wire, which can potentially lead to incorrect results.
+  IMeshData_Failure               = 0x4,  //!< Failed to generate mesh for some faces.
+  IMeshData_ReMesh                = 0x8,  //!< Deflection of some edges has been decreased due to interference of discrete model.
+  IMeshData_UnorientedWire        = 0x10, //!< Notifies bad orientation of a wire, which can potentially lead to incorrect results. 
+  IMeshData_TooFewPoints          = 0x20, //!< Discrete model contains too few boundary points to generate mesh.
+  IMeshData_Outdated              = 0x40, //!< Existing triangulation of some faces corresponds to greater deflection than specified by parameter.
+  IMeshData_Reused                = 0x80  //!< Existing triangulation of some faces is reused as far as it fits specified deflection.
+};
+
+#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..0b52eff
--- /dev/null
@@ -0,0 +1,170 @@
+// 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 <BRepMesh_Circle.hxx>
+#include <BRepMesh_Triangle.hxx>
+#include <BRepMesh_PairOfIndex.hxx>
+#include <BRepMesh_Edge.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_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 IMeshData_Edge* IEdgePtr;
+  typedef IMeshData_Face* IFacePtr;
+
+  typedef Handle(IMeshData_Edge)   IEdgeHandle;
+  typedef Handle(IMeshData_Wire)   IWireHandle;
+  typedef Handle(IMeshData_Face)   IFaceHandle;
+  typedef Handle(IMeshData_Curve)  ICurveHandle;
+  typedef Handle(IMeshData_PCurve) IPCurveHandle;
+
+  typedef IMeshData_ParametersListArrayAdaptor<ICurveHandle> ICurveArrayAdaptor;
+  typedef Handle(ICurveArrayAdaptor)   ICurveArrayAdaptorHandle;
+
+  typedef NCollection_Shared<NCollection_EBTree<Standard_Integer, Bnd_Box2d> > BndBox2dTree;
+  typedef NCollection_UBTreeFiller<Standard_Integer, Bnd_Box2d>                BndBox2dTreeFiller;
+
+  // Vectors
+  typedef NCollection_Shared<NCollection_Vector<IFaceHandle> >          VectorOfIFaceHandles;
+  typedef NCollection_Shared<NCollection_Vector<IWireHandle> >          VectorOfIWireHandles;
+  typedef NCollection_Shared<NCollection_Vector<IEdgeHandle> >          VectorOfIEdgeHandles;
+  typedef NCollection_Shared<NCollection_Vector<IPCurveHandle> >        VectorOfIPCurveHandles;
+  typedef NCollection_Shared<NCollection_Vector<IEdgePtr> >             VectorOfIEdgePtrs;
+  typedef NCollection_Shared<NCollection_Vector<Standard_Boolean> >     VectorOfBoolean;
+  typedef NCollection_Shared<NCollection_Vector<Standard_Integer> >     VectorOfInteger;
+  typedef NCollection_Shared<NCollection_Vector<TopAbs_Orientation> >   VectorOfOrientation;
+  typedef NCollection_Shared<NCollection_Vector<BRepMesh_Triangle> >    VectorOfElements;
+  typedef NCollection_Shared<NCollection_Vector<BRepMesh_Circle> >      VectorOfCircle;
+
+  typedef NCollection_Shared<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_Shared<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 Type* theFirst,
+                                    const Type* theSecond)
+    {
+      return (theFirst == theSecond);
+    }
+
+    //! Computes a hash code for the given pointer, in the range [1, theUpperBound]
+    //! @param thePointer the pointer which hash code is to be computed
+    //! @param theUpperBound the upper bound of the range a computing hash code must be within
+    //! @return a computed hash code, in the range [1, theUpperBound]
+    static Standard_Integer HashCode (const Type* const thePointer, Standard_Integer theUpperBound)
+    {
+      return ::HashCode (thePointer, theUpperBound);
+    }
+  };
+
+  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_Shared<NCollection_IndexedDataMap<BRepMesh_Edge, BRepMesh_PairOfIndex> >                  IDMapOfLink;
+  typedef NCollection_Shared<NCollection_DataMap<Standard_Integer, ListOfInteger> >                             DMapOfIntegerListOfInteger;
+  typedef NCollection_Shared<NCollection_DataMap<Standard_Integer, Standard_Integer> >                          MapOfIntegerInteger;
+  typedef NCollection_Shared<NCollection_IndexedMap<Standard_Real> >                                            IMapOfReal;
+
+  typedef NCollection_Shared<NCollection_Array1<Standard_Integer> >                                             Array1OfInteger;
+}
+
+#endif
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..e582bc1
--- /dev/null
@@ -0,0 +1,12 @@
+IMeshTools_Context.hxx
+IMeshTools_CurveTessellator.hxx
+IMeshTools_MeshAlgo.hxx
+IMeshTools_MeshAlgoFactory.hxx
+IMeshTools_MeshBuilder.hxx
+IMeshTools_MeshBuilder.cxx
+IMeshTools_ModelAlgo.hxx
+IMeshTools_ModelBuilder.hxx
+IMeshTools_Parameters.hxx
+IMeshTools_ShapeExplorer.hxx
+IMeshTools_ShapeExplorer.cxx
+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.cxx b/src/IMeshTools/IMeshTools_MeshBuilder.cxx
new file mode 100644 (file)
index 0000000..3b67a6c
--- /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 <IMeshTools_MeshBuilder.hxx>
+#include <IMeshData_Face.hxx>
+#include <OSD_Parallel.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+IMeshTools_MeshBuilder::IMeshTools_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+IMeshTools_MeshBuilder::IMeshTools_MeshBuilder (
+  const Handle (IMeshTools_Context)& theContext)
+  : myContext(theContext)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+IMeshTools_MeshBuilder::~IMeshTools_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose : 
+//=======================================================================
+void IMeshTools_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_Fail7);
+            }
+          }
+          else
+          {
+            SetStatus(Message_Fail6);
+          }
+        }
+        else
+        {
+          SetStatus(Message_Fail5);
+        }
+      }
+      else
+      {
+        SetStatus(Message_Fail4);
+      }
+    }
+    else
+    {
+      SetStatus (Message_Fail3);
+    }
+  }
+  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/IMeshTools/IMeshTools_MeshBuilder.hxx b/src/IMeshTools/IMeshTools_MeshBuilder.hxx
new file mode 100644 (file)
index 0000000..8c0d314
--- /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 _IMeshTools_MeshBuilder_HeaderFile
+#define _IMeshTools_MeshBuilder_HeaderFile
+
+#include <Message_Algorithm.hxx>
+#include <IMeshTools_Context.hxx>
+#include <Standard_Type.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 - fail to discretize edges.
+//! Message_Fail4 - can't heal discrete model.
+//! Message_Fail5 - fail to pre-process model.
+//! Message_Fail6 - fail to discretize faces.
+//! Message_Fail7 - fail to post-process model.
+//! Message_Warn1 - shape contains no objects to mesh.
+class IMeshTools_MeshBuilder : public Message_Algorithm
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshBuilder();
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_MeshBuilder (const Handle (IMeshTools_Context)& theContext);
+  
+  //! 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 ();
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshBuilder, Message_Algorithm)
+
+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..963c880
--- /dev/null
@@ -0,0 +1,69 @@
+// 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_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#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()
+  {
+  }
+
+  //! Exceptions protected processing of the given model.
+  Standard_Boolean Perform (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters)
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      return performInternal (theModel, theParameters);
+    }
+    catch (Standard_Failure const&)
+    {
+      return Standard_False;
+    }
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ModelAlgo()
+  {
+  }
+
+  //! Performs processing of the given model.
+  Standard_EXPORT virtual Standard_Boolean performInternal (
+    const Handle (IMeshData_Model)& theModel,
+    const IMeshTools_Parameters&    theParameters) = 0;
+};
+
+#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..5d6d416
--- /dev/null
@@ -0,0 +1,80 @@
+// 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_ErrorHandler.hxx>
+#include <Standard_Failure.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()
+  {
+  }
+
+  //! Exceptions protected method to create discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Handle (IMeshData_Model) Perform (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters)
+  {
+    ClearStatus ();
+
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      return performInternal (theShape, theParameters);
+    }
+    catch (Standard_Failure const&)
+    {
+      SetStatus (Message_Fail2);
+      return NULL;
+    }
+  }
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
+
+protected:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ModelBuilder()
+  {
+  }
+
+  //! Creates discrete model for the given shape.
+  //! Returns nullptr in case of failure.
+  Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
+    const TopoDS_Shape&          theShape,
+    const IMeshTools_Parameters& theParameters) = 0;
+};
+
+#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..6279708
--- /dev/null
@@ -0,0 +1,88 @@
+// 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),
+    AngleInterior(-1.0),
+    DeflectionInterior(-1.0),
+    MinSize (-1.0),
+    InParallel (Standard_False),
+    Relative (Standard_False),
+    InternalVerticesMode (Standard_True),
+    ControlSurfaceDeflection (Standard_True),
+    CleanModel (Standard_True),
+    AdjustMinSize (Standard_False)
+  {
+  }
+
+  //! Returns factor used to compute default value of MinSize 
+  //! (minimum mesh edge length) from deflection
+  static Standard_Real RelMinSize()
+  {
+    return 0.1;
+  }
+
+  //! Angular deflection used to tessellate the boundary edges
+  Standard_Real                                    Angle;
+
+  //!Linear deflection used to tessellate the boundary edges
+  Standard_Real                                    Deflection;
+  
+  //! Angular deflection used to tessellate the face interior
+  Standard_Real                                    AngleInterior;
+
+  //! Linear deflection used to tessellate the face interior
+  Standard_Real                                    DeflectionInterior;
+  
+  //! 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;
+
+  //! Enables/disables local adjustment of min size depending on edge size.
+  //! Disabled by default.
+  Standard_Boolean                                 AdjustMinSize;
+};
+
+#endif
diff --git a/src/IMeshTools/IMeshTools_ShapeExplorer.cxx b/src/IMeshTools/IMeshTools_ShapeExplorer.cxx
new file mode 100644 (file)
index 0000000..2dc244a
--- /dev/null
@@ -0,0 +1,113 @@
+// 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 <IMeshTools_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>
+
+namespace
+{
+  //=======================================================================
+  // Function: visitEdges
+  // Purpose : Explodes the given shape on edges according to the specified
+  //           criteria and visits each one in order to add it to data model.
+  //=======================================================================
+  void visitEdges (const Handle (IMeshTools_ShapeVisitor)& theVisitor,
+                   const TopoDS_Shape&                     theShape,
+                   const TopAbs_ShapeEnum                  theToFind,
+                   const TopAbs_ShapeEnum                  theToAvoid = TopAbs_SHAPE)
+  {
+    TopExp_Explorer aEdgesIt (theShape, theToFind, theToAvoid);
+    for (; aEdgesIt.More (); aEdgesIt.Next ())
+    {
+      const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgesIt.Current ());
+      if (!BRep_Tool::IsGeometric (aEdge))
+      {
+        continue;
+      }
+
+      theVisitor->Visit (aEdge);
+    }
+  }
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose : 
+//=======================================================================
+IMeshTools_ShapeExplorer::IMeshTools_ShapeExplorer (
+  const TopoDS_Shape& theShape)
+  : IMeshData_Shape (theShape)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose : 
+//=======================================================================
+IMeshTools_ShapeExplorer::~IMeshTools_ShapeExplorer ()
+{
+}
+
+//=======================================================================
+// Function: Accept
+// Purpose : 
+//=======================================================================
+void IMeshTools_ShapeExplorer::Accept (
+  const Handle (IMeshTools_ShapeVisitor)& theVisitor)
+{
+  // Explore all free edges in shape.
+  visitEdges (theVisitor, GetShape (), TopAbs_EDGE, TopAbs_FACE);
+
+  // Explore all related to some face edges in shape.
+  // make array of faces suitable for processing (excluding faces without surface)
+  TopTools_ListOfShape aFaceList;
+  BRepLib::ReverseSortFaces (GetShape (), aFaceList);
+  TopTools_MapOfShape aFaceMap;
+
+  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
+    }
+
+    const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value ());
+    const Handle (Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
+    if (aSurf.IsNull())
+    {
+      continue;
+    }
+
+    // Explore all edges in face.
+    visitEdges (theVisitor, aFace, TopAbs_EDGE);
+
+    // Store only forward faces in order to prevent inverse issue.
+    theVisitor->Visit (TopoDS::Face (aFace.Oriented (TopAbs_FORWARD)));
+  }
+}
diff --git a/src/IMeshTools/IMeshTools_ShapeExplorer.hxx b/src/IMeshTools/IMeshTools_ShapeExplorer.hxx
new file mode 100644 (file)
index 0000000..0e96ddc
--- /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 _IMeshTools_ShapeExplorer_HeaderFile
+#define _IMeshTools_ShapeExplorer_HeaderFile
+
+#include <IMeshData_Shape.hxx>
+#include <Standard_Type.hxx>
+#include <IMeshTools_ShapeVisitor.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Explores TopoDS_Shape for parts to be meshed - faces and free edges.
+class IMeshTools_ShapeExplorer : public IMeshData_Shape
+{
+public:
+
+  //! Constructor.
+  Standard_EXPORT IMeshTools_ShapeExplorer (const TopoDS_Shape& theShape);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~IMeshTools_ShapeExplorer();
+
+  //! Starts exploring of a shape.
+  Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor);
+
+  DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ShapeExplorer, IMeshData_Shape)
+};
+
+#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
index 7db1a42f02764c1d3cb7b41510c66f3cea8b24e0..c7ff84c7f236d5be0dbb96831cb2d6f1f35deff2 100644 (file)
@@ -130,7 +130,7 @@ options:\n\
         -surf_def_off   disables control of deflection of mesh from real\n\
                         surface (enabled by default)\n\
         -parallel       enables parallel execution (switched off by default)\n\
-        -adaptive       enables adaptive computation of minimal value in parametric space\n";
+        -adjust_min     enables local adjustment of min size depending on edge size\n";
     return 0;
   }
 
@@ -148,7 +148,7 @@ options:\n\
   Standard_Boolean isInParallel    = Standard_False;
   Standard_Boolean isIntVertices   = Standard_True;
   Standard_Boolean isControlSurDef = Standard_True;
-  Standard_Boolean isAdaptiveMin   = Standard_False;
+  Standard_Boolean isAdjustMinSize = Standard_False;
 
   if (nbarg > 3)
   {
@@ -168,8 +168,8 @@ options:\n\
         isIntVertices = Standard_False;
       else if (aOpt == "-surf_def_off")
         isControlSurDef = Standard_False;
-      else if (aOpt == "-adaptive")
-        isAdaptiveMin   = Standard_True;
+      else if (aOpt == "-adjust_min")
+        isAdjustMinSize = Standard_True;
       else if (i < nbarg)
       {
         Standard_Real aVal = Draw::Atof(argv[i++]);
@@ -186,7 +186,7 @@ options:\n\
   di << "Incremental Mesh, multi-threading "
      << (isInParallel ? "ON" : "OFF") << "\n";
 
-  BRepMesh_FastDiscret::Parameters aMeshParams;
+  IMeshTools_Parameters aMeshParams;
   aMeshParams.Deflection = aLinDeflection;
   aMeshParams.Angle = aAngDeflection;
   aMeshParams.Relative =  isRelative;
@@ -194,13 +194,10 @@ options:\n\
   aMeshParams.MinSize = aMinSize;
   aMeshParams.InternalVerticesMode = isIntVertices;
   aMeshParams.ControlSurfaceDeflection = isControlSurDef;
-  aMeshParams.AdaptiveMin = isAdaptiveMin;
+  aMeshParams.AdjustMinSize = isAdjustMinSize;
   
   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
-  BRepMesh_IncrementalMesh aMesher;
-  aMesher.SetShape (aShape);
-  aMesher.ChangeParameters() = aMeshParams;
-  aMesher.Perform (aProgress);
+  BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams);
 
   di << "Meshing statuses: ";
   Standard_Integer statusFlags = aMesher.GetStatusFlags();
@@ -409,114 +406,6 @@ static Standard_Integer MemLeakTest(Draw_Interpretor&, Standard_Integer /*nbarg*
   return 0;
 }
 
-//=======================================================================
-//function : fastdiscret
-//purpose  : 
-//=======================================================================
-
-static Standard_Integer fastdiscret(Draw_Interpretor& di, Standard_Integer nbarg, const char** argv)
-{
-  if (nbarg < 3) return 1;
-
-  TopoDS_Shape S = DBRep::Get(argv[1]);
-  if (S.IsNull()) return 1;
-
-  const Standard_Real d = Draw::Atof(argv[2]);
-
-  Bnd_Box B;
-  BRepBndLib::Add(S,B);
-  BRepMesh_FastDiscret::Parameters aParams;
-  aParams.Deflection = d;
-  aParams.Angle = 0.5;
-  BRepMesh_FastDiscret MESH(B,aParams);
-
-  //Standard_Integer NbIterations = MESH.NbIterations();
-  //if (nbarg > 4) NbIterations = Draw::Atoi(argv[4]);
-  //MESH.NbIterations() = NbIterations;
-
-  di<<"Starting FastDiscret with :\n";
-  di<<"  Deflection="<<d<<"\n";
-  di<<"  Angle="<<0.5<<"\n";
-
-  Handle(Poly_Triangulation) T;
-  BRep_Builder aBuilder;
-  TopExp_Explorer ex;
-
-  // Clear existing triangulations
-  for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next())
-    aBuilder.UpdateFace(TopoDS::Face(ex.Current()),T);
-
-  MESH.Perform(S);
-
-  TopoDS_Compound aCompGood, aCompFailed, aCompViolating;
-
-  TopLoc_Location L;
-  Standard_Integer nbtriangles = 0, nbnodes = 0, nbfailed = 0, nbviolating = 0;
-  Standard_Real maxdef = 0.0;
-  for (ex.Init(S, TopAbs_FACE); ex.More(); ex.Next())
-  {
-    T = BRep_Tool::Triangulation(TopoDS::Face(ex.Current()),L);
-    if (T.IsNull())
-    {
-      nbfailed++;
-      if (aCompFailed.IsNull())
-        aBuilder.MakeCompound(aCompFailed);
-      aBuilder.Add(aCompFailed,ex.Current());
-    }
-    else
-    {
-      nbtriangles += T->NbTriangles();
-      nbnodes += T->NbNodes();
-      if (T->Deflection() > maxdef) maxdef = T->Deflection();
-      if (T->Deflection() > d)
-      {
-        nbviolating++;
-        if (aCompViolating.IsNull())
-          aBuilder.MakeCompound(aCompViolating);
-        aBuilder.Add(aCompViolating,ex.Current());
-      }
-      else
-      {
-        if (aCompGood.IsNull())
-          aBuilder.MakeCompound(aCompGood);
-        aBuilder.Add(aCompGood,ex.Current());
-      }
-    }
-  }
-
-  if (!aCompGood.IsNull())
-  {
-    char name[256];
-    strcpy(name,argv[1]);
-    strcat(name,"_good");
-    DBRep::Set(name,aCompGood);
-  }
-  if (!aCompFailed.IsNull())
-  {
-    char name[256];
-    strcpy(name,argv[1]);
-    strcat(name,"_failed");
-    DBRep::Set(name,aCompFailed);
-  }
-  if (!aCompViolating.IsNull())
-  {
-    char name[256];
-    strcpy(name,argv[1]);
-    strcat(name,"_violating");
-    DBRep::Set(name,aCompViolating);
-  }
-
-  di<<"FastDiscret completed with :\n";
-  di<<"  MaxDeflection="<<maxdef<<"\n";
-  di<<"  NbNodes="<<nbnodes<<"\n";
-  di<<"  NbTriangles="<<nbtriangles<<"\n";
-  di<<"  NbFailed="<<nbfailed<<"\n";
-  di<<"  NbViolating="<<nbviolating<<"\n";
-
-  return 0;
-}
-
-
 //=======================================================================
 //function : triangule
 //purpose  : 
@@ -1779,7 +1668,6 @@ void  MeshTest::Commands(Draw_Interpretor& theCommands)
   theCommands.Add("incmesh","Builds triangular mesh for the shape, run w/o args for help",__FILE__, incrementalmesh, g);
   theCommands.Add("tessellate","Builds triangular mesh for the surface, run w/o args for help",__FILE__, tessellate, g);
   theCommands.Add("MemLeakTest","MemLeakTest",__FILE__, MemLeakTest, g);
-  theCommands.Add("fastdiscret","fastdiscret shape deflection",__FILE__, fastdiscret, g);
   theCommands.Add("mesh","mesh result Shape deflection",__FILE__, triangule, g);
   theCommands.Add("addshape","addshape meshname Shape [deflection]",__FILE__, addshape, g);
   //theCommands.Add("smooth","smooth meshname",__FILE__, smooth, g);
index 43a359485745e50c03b86639d45933d2ca67baf4..ee2b132be57bc7a64a71d8efc97d934e6cdb0ecc 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BRepMesh_FaceAttribute.hxx>
 #include <Draw_Segment3D.hxx>
 #include <DrawTrSurf_Polygon3D.hxx>
 #include <Draw.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TColgp_Array1OfPnt.hxx>
 #include <Poly_Polygon3D.hxx>
+#include <BRepMesh_DataStructureOfDelaun.hxx>
 
 // This file defines global functions not declared in any public header,
 // intended for use from debugger prompt (Command Window in Visual Studio)
 //function : MeshTest_DrawLinks
 //purpose  : Draw links from mesh data structure of type BRepMesh_FaceAttribute
 //=======================================================================
-Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr)
+Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* theDataStruct)
 {
-  if (theNameStr == 0 || theFaceAttr == 0)
+  if (theNameStr == 0 || theDataStruct == 0)
   {
     return "Error: name or face attribute is null";
   }
   try {
-    const Handle(BRepMesh_FaceAttribute)& aFaceAttr = *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr;
-    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure();
+    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = *(Handle(BRepMesh_DataStructureOfDelaun)*)theDataStruct;
     if (aMeshData.IsNull())
       return "Null mesh data structure";
     Standard_Integer nbLinks = aMeshData->NbLinks();
-    cout << "nblink=" << nbLinks << endl;
+    std::cout << "nblink=" << nbLinks << std::endl;
     TCollection_AsciiString aName(theNameStr);
     for (Standard_Integer i = 1; i <= nbLinks; i++)
     {
@@ -51,9 +50,9 @@ Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* the
       Standard_Integer n2 = aLink.LastNode();
       const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n1);
       const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n2);
-      const gp_Pnt& aP1 = aFaceAttr->GetPoint(aV1);
-      const gp_Pnt& aP2 = aFaceAttr->GetPoint(aV2);
-      Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aP1, aP2, Draw_bleu);
+      Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(gp_Pnt(aV1.Coord().X(), aV1.Coord().Y(), 0),
+        gp_Pnt(aV2.Coord().X(), aV2.Coord().Y(), 0),
+        Draw_bleu);
       Draw::Set((aName + "_" + i).ToCString(), aSeg);
     }
     return theNameStr;
@@ -68,20 +67,20 @@ Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* the
 //function : MeshTest_DrawTriangles
 //purpose  : Draw triangles from mesh data structure of type BRepMesh_FaceAttribute
 //=======================================================================
-Standard_EXPORT const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr)
+Standard_EXPORT const char* MeshTest_DrawTriangles(const char* theNameStr, void* theDataStruct)
 {
-  if (theNameStr == 0 || theFaceAttr == 0)
+  if (theNameStr == 0 || theDataStruct == 0)
   {
     return "Error: name or face attribute is null";
   }
   try {
-    const Handle(BRepMesh_FaceAttribute)& aFaceAttr =
-      *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr;
-    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure();
+    const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData =
+      *(Handle(BRepMesh_DataStructureOfDelaun)*)theDataStruct;
+
     if (aMeshData.IsNull())
       return "Null mesh data structure";
     Standard_Integer nbElem = aMeshData->NbElements();
-    cout << "nbelem=" << nbElem << endl;
+    std::cout << "nbelem=" << nbElem << std::endl;
     TCollection_AsciiString aName(theNameStr);
     for (Standard_Integer i = 1; i <= nbElem; i++)
     {
@@ -93,8 +92,10 @@ Standard_EXPORT const char* MeshTest_DrawTriangles(const char* theNameStr, void*
       const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n[0]);
       const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n[1]);
       const BRepMesh_Vertex& aV3 = aMeshData->GetNode(n[2]);
-      gp_Pnt aP[4] = { aFaceAttr->GetPoint(aV1), aFaceAttr->GetPoint(aV2), 
-                       aFaceAttr->GetPoint(aV3), aFaceAttr->GetPoint(aV1) };
+      gp_Pnt aP[4] = { gp_Pnt(aV1.Coord().X(), aV1.Coord().Y(), 0),
+                       gp_Pnt(aV2.Coord().X(), aV2.Coord().Y(), 0),
+                       gp_Pnt(aV3.Coord().X(), aV3.Coord().Y(), 0),
+                       gp_Pnt(aV1.Coord().X(), aV1.Coord().Y(), 0) };
       TColgp_Array1OfPnt aPnts(aP[0], 1, 4);
       Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D(aPnts);
       Handle(DrawTrSurf_Polygon3D) aDPoly = new DrawTrSurf_Polygon3D(aPoly);
index 5385c51e55016226e40b0565defecd1f5b1ce35a..7a1a57400a6728147c6dcd1d0babf925fb6558f6 100644 (file)
@@ -29,6 +29,7 @@
 #include <BRepMesh_Triangle.hxx>
 #include <BRepMesh_DataStructureOfDelaun.hxx>
 #include <TopExp_Explorer.hxx>
+#include <BRep_Tool.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(MeshTest_DrawableMesh,Draw_Drawable3D)
index f432ca06c00992765c780b7281ead02e02ac7bd5..5c7e7665586c0bda7ffaaeaacae9f0cd37130a1e 100644 (file)
@@ -1309,7 +1309,7 @@ static Standard_Integer OCC369(Draw_Interpretor& di, Standard_Integer argc, cons
     if(aShape.IsNull()) {di << "OCC369 FAULTY. Entry shape is NULL \n"; return 0;}
 
     // 3. Build mesh
-    BRepMesh_FastDiscret::Parameters aMeshParams;
+    IMeshTools_Parameters aMeshParams;
     aMeshParams.Relative = Standard_True;
     aMeshParams.Deflection = 0.2;
     aMeshParams.Angle = M_PI / 6;
index 87f7a473f01b7e7da7c1e62bebcd16c5d72e3be7..1a442d4fccd493ed767cc9be5861d2bf504d4118 100644 (file)
@@ -37,11 +37,11 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
   Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
   Standard_Integer aPtsLower = thePoints.Lower();
   Standard_Integer aPtsUpper = thePoints.Upper();
-  BRepMesh::Array1OfInteger anIndexes (0, thePoints.Length() - 1);
+  IMeshData::VectorOfInteger anIndexes (thePoints.Length());
   for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
   {
     BRepMesh_Vertex aVertex (thePoints.Value (aPtIdx).XY(), aPtIdx, BRepMesh_Frontier);
-    anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
+    anIndexes.Append (aMeshStructure->AddNode (aVertex));
   }
 
   Standard_Real aPtSum = 0;
@@ -64,11 +64,11 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
   }
 
   BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
-  const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
+  const IMeshData::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
   if (aTriangles.Extent() < 1)
     return;
 
-  BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
+  IMeshData::IteratorOfMapOfInteger aTriangleIt (aTriangles);
   for (; aTriangleIt.More(); aTriangleIt.Next())
   {
     const Standard_Integer aTriangleId = aTriangleIt.Key();
index 4ade3a16cf176c034853ca97a08540d66525329e..e3f6a5cd89d6a6b9547e8ed62861b972a9aa848a 100644 (file)
@@ -68,7 +68,7 @@ void StdPrs_HLRPolyShape::Add(const Handle (Prs3d_Presentation)& aPresentation,
   {
     const Standard_Boolean aRel = aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE;
     Standard_Real aDef = aRel ? aDrawer->HLRDeviationCoefficient() : aDrawer->MaximalChordialDeviation();
-    BRepMesh_FastDiscret::Parameters aMeshParams;
+    IMeshTools_Parameters aMeshParams;
     aMeshParams.Relative = aRel;
     aMeshParams.Angle = aDrawer->HLRAngle();
     aMeshParams.Deflection = aDef;
index 97605066fae7b2d54a5d92a47f9a80af47ce435d..c428c625506df2a46f05a72f3674b4e389ccc562 100755 (executable)
@@ -1,9 +1,8 @@
-TKBRep
-TKMath
 TKernel
-TKG2d
-TKG3d
-TKGeomBase
+TKMath
+TKBRep
 TKTopAlgo
-TKGeomAlgo
-CSF_TBB
+TKShHealing
+TKGeomBase
+TKG3d
+TKG2d
index 0ce38247e0eb696c61299822f5b8d6896fcecb89..d5379def2fbe0863c808e93d025ac7f6ca03b4c7 100755 (executable)
@@ -1 +1,4 @@
+IMeshData
+IMeshTools
+BRepMeshData
 BRepMesh
index 5d666dbcad950d271068c3daafbcb597db82486c..1dbf87494d5f8794ca108a39b59255a1271287fb 100755 (executable)
@@ -19,4 +19,4 @@
 019 heal
 020 stlvrml
 021 splitshape
-022 splitshape1
+022 splitshape_1
index cbd0c385f24468be128d797666f4797fd438ff57..ee6ff4d6c24604a76ebf6cbc000205158660f3d6 100644 (file)
@@ -1,3 +1,2 @@
-001 2dinter
-002 bnd
-003 extcc
+001 bnd
+002 extcc