n BRepLib
n BRepMAT2d
n BRepMesh
+n BRepMeshData
n BRepOffset
n BRepOffsetAPI
n BRepPrim
n HLRAppli
n Hatch
n HatchGen
+n IMeshData
+n IMeshTools
n IntCurve
n IntCurveSurface
n IntCurvesFace
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;
}
BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
- const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
+ const IMeshData::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
if (aTriangles.Extent() < 1)
return Standard_False;
}
Standard_Integer aVertexIndex = 1;
- BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
+ IMeshData::IteratorOfMapOfInteger aTriangleIt (aTriangles);
for (; aTriangleIt.More(); aTriangleIt.Next())
{
const Standard_Integer aTriangleId = aTriangleIt.Key();
+++ /dev/null
-// 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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
#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>
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)
{
}
}
//! Resutns vector of registered circles.
- inline const BRepMesh::VectorOfCircle& Circles() const
+ inline const IMeshData::VectorOfCircle& Circles() const
{
return myCircles;
}
}
//! Returns list of circles shot by the reference point.
- inline BRepMesh::ListOfInteger& GetShotCircles()
+ inline IMeshData::ListOfInteger& GetShotCircles()
{
return myResIndices;
}
//! 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(
}
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
#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)
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)
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;
}
//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);
#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;
//! @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.
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.
//! 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:
Standard_Real myTolerance;
Handle(NCollection_IncAllocator) myAllocator;
- BRepMesh::CircleCellFilter myCellFilter;
+ IMeshData::CircleCellFilter myCellFilter;
BRepMesh_CircleInspector mySelector;
gp_XY myFaceMax;
gp_XY myFaceMin;
-// 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.
//
{
}
+//=======================================================================
+//function : Destructor
+//purpose :
+//=======================================================================
+BRepMesh_Classifier::~BRepMesh_Classifier()
+{
+}
+
//=======================================================================
//function : Perform
//purpose :
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;
//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 =
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)
{
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) );
}
-// 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
//! @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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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 ()
+{
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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.;
+}
--- /dev/null
+// 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
// 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 :
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)
{
}
{
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;
}
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)
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);
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]));
}
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);
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])
//=======================================================================
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]);
}
myElementsOfDomain.Clear();
- BRepMesh::MapOfInteger::Iterator aEdgeIt(aFreeEdges);
+ IMeshData::IteratorOfMapOfInteger aEdgeIt(aFreeEdges);
for (; aEdgeIt.More(); aEdgeIt.Next())
RemoveLink(aEdgeIt.Key());
}
--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)
{
// 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)
{
}
}
- myElements.Substitute(aLinkIt.Value(),
- BRepMesh_Triangle(e, o, aElement.Movability()));
+ myElements(aLinkIt.Value()) = BRepMesh_Triangle(e, o, aElement.Movability());
}
}
}
//=======================================================================
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())
continue;
BRepMesh_Vertex aNode = GetNode(aLastLiveItem);
- BRepMesh::ListOfInteger& aLinkList = linksConnectedTo(aLastLiveItem);
+ IMeshData::ListOfInteger& aLinkList = linksConnectedTo(aLastLiveItem);
myNodes->RemoveLast();
--aLastLiveItem;
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();
{
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;
}
//=======================================================================
return "Error: file name or mesh data is null";
}
- Handle(BRepMesh_DataStructureOfDelaun) aMeshData =
+ Handle(BRepMesh_DataStructureOfDelaun) aMeshData =
*(Handle(BRepMesh_DataStructureOfDelaun)*)theMeshHandlePtr;
if (aMeshData.IsNull())
}
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)
{
return theFileNameStr;
}
+
+void BRepMesh_DataStructureOfDelaun::Dump(Standard_CString theFileNameStr)
+{
+ Handle(BRepMesh_DataStructureOfDelaun) aMeshData (this);
+ BRepMesh_Dump((void*)&aMeshData, theFileNameStr);
+}
#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
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);
}
//! Returns map of indices of links registered in mesh.
- inline const BRepMesh::MapOfInteger& LinksOfDomain() const
+ inline const IMeshData::MapOfInteger& LinksOfDomain() const
{
return myLinksOfDomain;
}
//! 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.
//! @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;
}
const BRepMesh_Triangle& theElement,
Standard_Integer (&theNodes)[3]);
+ Standard_EXPORT void Dump(Standard_CString theFileNameStr);
+
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;
}
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
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
--- /dev/null
+// 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;
+ }
+ }
+ }
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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));
+}
--- /dev/null
+// 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
#include <BRepMesh_Vertex.hxx>
#include <BRepMesh_Triangle.hxx>
-#include <Message_ProgressSentry.hxx>
#include <NCollection_Vector.hxx>
#include <algorithm>
}
} // 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 );
}
//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 );
+ }
}
//=======================================================================
//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 ) );
{
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);
}
// 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 )
//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 );
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() )
//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 )
while ( !aLoopEdges.IsEmpty() )
{
- if (theProgressEntry != NULL && !theProgressEntry->More())
- {
- return;
- }
const BRepMesh_Edge& anEdge = GetEdge( Abs( aLoopEdges.First() ) );
if ( anEdge.Movability() != BRepMesh_Deleted )
{
//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);
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:
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] ) ||
}
}
- 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();
}
//=======================================================================
//=======================================================================
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);
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)
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 )
{
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();
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 )
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 =
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;
+ }
+ }
+ }
}
}
// 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 );
}
// 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() )
//=======================================================================
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 )
{
// 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();
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 )
}
// 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();
// 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();
//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);
//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 )
{
// 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;
// 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();
// <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);
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 )
//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));
//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 )
{
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 )
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;
thePolyBoxes, aSurvivedLinks, aLoopEdges );
}
- BRepMesh::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
+ IMeshData::MapOfIntegerInteger::Iterator aLoopEdgesIt( aLoopEdges );
for ( ; aLoopEdgesIt.More(); aLoopEdgesIt.Next() )
{
const Standard_Integer& aLoopEdgeId = aLoopEdgesIt.Key();
// 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();
}
// Go and do your job!
- BRepMesh::VectorOfInteger::Iterator aVictimIt( aVictimNodes );
+ IMeshData::VectorOfInteger::Iterator aVictimIt( aVictimNodes );
for ( ; aVictimIt.More(); aVictimIt.Next() )
{
killTrianglesAroundVertex( aVictimIt.Value(), thePolyVertices,
//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 )
// 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;
killLinkTriangles( theLinkToCheckId, theLoopEdges );
- BRepMesh::ListOfInteger::Iterator aNeighborsIt(
+ IMeshData::ListOfInteger::Iterator aNeighborsIt(
myMeshData->LinksConnectedTo(theEndPoint));
for ( ; aNeighborsIt.More(); aNeighborsIt.Next() )
//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 );
//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;
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(
//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 ) )
};
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 )
}
}
- 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);
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())
//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 )
//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 ) )
// 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 )
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() )
{
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;
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 &&
}
}
-//=======================================================================
-//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);
}
//=======================================================================
//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() )
{
{
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] ),
//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,
//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();
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())
{
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()));
#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>
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
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
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);
}
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
//! @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,
//! 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();
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],
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;
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
//! 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);
}
//! 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);
}
}
//! Compute triangulation for set shape.
- Standard_EXPORT virtual void Perform() = 0;
+ virtual void Perform() = 0;
DEFINE_STANDARD_RTTIEXT(BRepMesh_DiscretRoot,Standard_Transient)
}
//! Alias for IsEqual.
- Standard_Boolean operator ==(const BRepMesh_Edge& Other) const
+ inline Standard_Boolean operator ==(const BRepMesh_Edge& Other) const
{
return IsEqual(Other);
}
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
--- /dev/null
+// 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);
+ }
+ }
+ }
+}
--- /dev/null
+// 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
+++ /dev/null
-// 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;
-}
#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;
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
-// 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;
}
-// 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
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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);
-}
+++ /dev/null
-// 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
--- /dev/null
+// 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);
+ }
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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
+++ /dev/null
-// 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);
-}
#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
+++ /dev/null
-// 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();
-}
+++ /dev/null
-// 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
#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 :
//=======================================================================
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;
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;
}
//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;
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 :
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
//! @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
//! @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.
//! 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
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.
+++ /dev/null
-// 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
+++ /dev/null
-// 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
// 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
{
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)
{
}
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();
//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();
}
{
}
-//=======================================================================
-//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();
}
//=======================================================================
{
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
}
#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
//! 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
{
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
//! 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
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
+
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
//! 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)
{
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.
}
//! Alias for IsEqual.
- Standard_Boolean operator ==(const BRepMesh_OrientedEdge& Other) const
+ inline Standard_Boolean operator ==(const BRepMesh_OrientedEdge& Other) const
{
return IsEqual(Other);
}
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
+++ /dev/null
-// 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
#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)
{
}
//=======================================================================
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)
{
}
void BRepMesh_SelectorOfDataStructureOfDelaun::NeighboursOfNode(
const Standard_Integer theNodeIndex)
{
- BRepMesh::ListOfInteger::Iterator aLinkIt(
+ IMeshData::ListOfInteger::Iterator aLinkIt(
myMesh->LinksConnectedTo(theNodeIndex));
for (; aLinkIt.More(); aLinkIt.Next())
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]);
}
#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();
}
//! 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
-// 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
{
}
//=======================================================================
-//function : BoxMaxDimension
+//function : MaxFaceTolerance
//purpose :
//=======================================================================
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);
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;
}
//=======================================================================
-//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);
+ }
+ }
}
//=======================================================================
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);
}
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);
}
-// 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(
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.
//! 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.
//! 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
+++ /dev/null
-// 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
--- /dev/null
+// 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.);
+}
--- /dev/null
+// 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
//! 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.
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;
}
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.
{
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;
}
}
//! 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
--- /dev/null
+// 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
#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
{
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)
}
//! Alias for IsEqual.
- Standard_Boolean operator ==(const BRepMesh_Vertex& Other) const
+ inline Standard_Boolean operator ==(const BRepMesh_Vertex& Other) const
{
return IsEqual(Other);
}
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
#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>
//! 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.
//! 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;
}
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
// 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
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;
}
//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);
#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(
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();
}
//! 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();
}
//! 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.
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
+++ /dev/null
-// 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;
- }
-}
+++ /dev/null
-// 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
+++ /dev/null
-// 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;
- }
- }
- }
- }
-}
+++ /dev/null
-// 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
-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
--- /dev/null
+// 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));
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+// 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));
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
--- /dev/null
+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
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;
--- /dev/null
+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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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 ();
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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)));
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
-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;
}
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)
{
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++]);
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;
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();
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 :
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);
// 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++)
{
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;
//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++)
{
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);
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <TopExp_Explorer.hxx>
+#include <BRep_Tool.hxx>
IMPLEMENT_STANDARD_RTTIEXT(MeshTest_DrawableMesh,Draw_Drawable3D)
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;
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;
}
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();
{
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;
-TKBRep
-TKMath
TKernel
-TKG2d
-TKG3d
-TKGeomBase
+TKMath
+TKBRep
TKTopAlgo
-TKGeomAlgo
-CSF_TBB
+TKShHealing
+TKGeomBase
+TKG3d
+TKG2d
+IMeshData
+IMeshTools
+BRepMeshData
BRepMesh
019 heal
020 stlvrml
021 splitshape
-022 splitshape1
+022 splitshape_1
-001 2dinter
-002 bnd
-003 extcc
+001 bnd
+002 extcc