--- /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& /*theExeption*/)
+ {
+ }
+
+ myDFace.reset(); // Do not hold link to face.
+ myStructure.Nullify();
+ myNodesMap.Nullify();
+ myUsedNodes.Nullify();
+}
+
+//=======================================================================
+//function : initDataStructure
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_BaseMeshAlgo::initDataStructure()
+{
+ for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
+ {
+ const IMeshData::IWireHandle& aDWire = myDFace->GetWire(aWireIt);
+ if (aDWire->IsSet(IMeshData_SelfIntersectingWire))
+ {
+ // TODO: here we can add points of self-intersecting wire as fixed points
+ // in order to keep consistency of nodes with adjacent faces.
+ continue;
+ }
+
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+ {
+ const IMeshData::IEdgeHandle& aDEdge = aDWire->GetEdge(aEdgeIt).lock();
+ const IMeshData::ICurveHandle& aCurve = aDEdge->GetCurve();
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+ myDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+ const TopAbs_Orientation aOri = fixSeamEdgeOrientation(aDEdge, aPCurve);
+
+ Standard_Integer aPrevNodeIndex = -1;
+ const Standard_Integer aLastPoint = aPCurve->ParametersNb() - 1;
+ for (Standard_Integer aPointIt = 0; aPointIt <= aLastPoint; ++aPointIt)
+ {
+ const Standard_Integer aNodeIndex = registerNode(
+ aCurve ->GetPoint(aPointIt),
+ aPCurve->GetPoint(aPointIt),
+ BRepMesh_Frontier, Standard_False/*aPointIt > 0 && aPointIt < aLastPoint*/);
+
+ aPCurve->GetIndex(aPointIt) = aNodeIndex;
+ myUsedNodes->Bind(aNodeIndex, aNodeIndex);
+
+ if (aPrevNodeIndex != -1 && aPrevNodeIndex != aNodeIndex)
+ {
+ const Standard_Integer aLinksNb = myStructure->NbLinks();
+ const Standard_Integer aLinkIndex = addLinkToMesh(aPrevNodeIndex, aNodeIndex, aOri);
+ if (aWireIt != 0 && aLinkIndex <= aLinksNb)
+ {
+ // Prevent holes around wire of zero area.
+ BRepMesh_Edge& aLink = const_cast<BRepMesh_Edge&>(myStructure->GetLink(aLinkIndex));
+ aLink.SetMovability(BRepMesh_Fixed);
+ }
+ }
+
+ aPrevNodeIndex = aNodeIndex;
+ }
+ }
+ }
+
+ return Standard_True;
+}
+
+//=======================================================================
+// Function: registerNode
+// Purpose :
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::registerNode(
+ const gp_Pnt& thePoint,
+ const gp_Pnt2d& thePoint2d,
+ const BRepMesh_DegreeOfFreedom theMovability,
+ const Standard_Boolean isForceAdd)
+{
+ const Standard_Integer aNodeIndex = addNodeToStructure(
+ thePoint2d, myNodesMap->Size(), theMovability, isForceAdd);
+
+ if (aNodeIndex > myNodesMap->Size())
+ {
+ myNodesMap->Append(thePoint);
+ }
+
+ return aNodeIndex;
+}
+
+//=======================================================================
+// Function: addNode
+// Purpose :
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::addNodeToStructure(
+ const gp_Pnt2d& thePoint,
+ const Standard_Integer theLocation3d,
+ const BRepMesh_DegreeOfFreedom theMovability,
+ const Standard_Boolean isForceAdd)
+{
+ BRepMesh_Vertex aNode(thePoint.XY(), theLocation3d, theMovability);
+ return myStructure->AddNode(aNode, isForceAdd);
+}
+
+//=======================================================================
+//function : addLinkToMesh
+//purpose :
+//=======================================================================
+Standard_Integer BRepMesh_BaseMeshAlgo::addLinkToMesh(
+ const Standard_Integer theFirstNodeId,
+ const Standard_Integer theLastNodeId,
+ const TopAbs_Orientation theOrientation)
+{
+ Standard_Integer aLinkIndex;
+ if (theOrientation == TopAbs_REVERSED)
+ aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier));
+ else if (theOrientation == TopAbs_INTERNAL)
+ aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed));
+ else
+ aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier));
+
+ return Abs(aLinkIndex);
+}
+
+//=======================================================================
+//function : fixSeamEdgeOrientation
+//purpose :
+//=======================================================================
+TopAbs_Orientation BRepMesh_BaseMeshAlgo::fixSeamEdgeOrientation(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const IMeshData::IPCurveHandle& thePCurve) const
+{
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+ {
+ const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
+ if (aPCurve->GetFace().lock() == myDFace && thePCurve != aPCurve)
+ {
+ // Simple check that another pcurve of seam edge does not coincide with reference one.
+ const gp_Pnt2d& aPnt1_1 = thePCurve->GetPoint(0);
+ const gp_Pnt2d& aPnt2_1 = thePCurve->GetPoint(thePCurve->ParametersNb() - 1);
+
+ const gp_Pnt2d& aPnt1_2 = aPCurve->GetPoint(0);
+ const gp_Pnt2d& aPnt2_2 = aPCurve->GetPoint(aPCurve->ParametersNb() - 1);
+
+ const Standard_Real aSqDist1 = Min(aPnt1_1.SquareDistance(aPnt1_2), aPnt1_1.SquareDistance(aPnt2_2));
+ const Standard_Real aSqDist2 = Min(aPnt2_1.SquareDistance(aPnt1_2), aPnt2_1.SquareDistance(aPnt2_2));
+ if (aSqDist1 < Precision::SquareConfusion() &&
+ aSqDist2 < Precision::SquareConfusion())
+ {
+ return TopAbs_INTERNAL;
+ }
+ }
+ }
+
+ return thePCurve->GetOrientation();
+}
+
+//=======================================================================
+//function : commitSurfaceTriangulation
+//purpose :
+//=======================================================================
+void BRepMesh_BaseMeshAlgo::commitSurfaceTriangulation()
+{
+ Handle(Poly_Triangulation) aTriangulation = collectTriangles();
+ if (aTriangulation.IsNull())
+ {
+ myDFace->SetStatus(IMeshData_Failure);
+ return;
+ }
+
+ collectNodes(aTriangulation);
+
+ aTriangulation->Deflection(myDFace->GetDeflection());
+ BRepMesh_ShapeTool::AddInFace(myDFace->GetFace(), aTriangulation);
+}
+
+//=======================================================================
+//function : collectTriangles
+//purpose :
+//=======================================================================
+Handle(Poly_Triangulation) BRepMesh_BaseMeshAlgo::collectTriangles()
+{
+ const IMeshData::MapOfInteger& aTriangles = myStructure->ElementsOfDomain();
+ if (aTriangles.IsEmpty())
+ {
+ return Handle(Poly_Triangulation)();
+ }
+
+ Poly_Array1OfTriangle aPolyTrianges(1, aTriangles.Extent());
+ IMeshData::IteratorOfMapOfInteger aTriIt(aTriangles);
+ for (Standard_Integer aTriangeId = 1; aTriIt.More(); aTriIt.Next(), ++aTriangeId)
+ {
+ const BRepMesh_Triangle& aCurElem = myStructure->GetElement(aTriIt.Key());
+
+ Standard_Integer aNode[3];
+ myStructure->ElementNodes(aCurElem, aNode);
+
+ for (Standard_Integer i = 0; i < 3; ++i)
+ {
+ if (!myUsedNodes->IsBound(aNode[i]))
+ {
+ myUsedNodes->Bind(aNode[i], myUsedNodes->Size() + 1);
+ }
+
+ aNode[i] = myUsedNodes->Find(aNode[i]);
+ }
+
+ aPolyTrianges(aTriangeId).Set(aNode[0], aNode[1], aNode[2]);
+ }
+
+ Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation(
+ myUsedNodes->Extent(), aTriangles.Extent(), Standard_True);
+
+ aTriangulation->ChangeTriangles() = aPolyTrianges;
+ return aTriangulation;
+}
+
+//=======================================================================
+//function : collectNodes
+//purpose :
+//=======================================================================
+void BRepMesh_BaseMeshAlgo::collectNodes(
+ const Handle(Poly_Triangulation)& theTriangulation)
+{
+ // Store mesh nodes
+ TColgp_Array1OfPnt& aNodes = theTriangulation->ChangeNodes();
+ TColgp_Array1OfPnt2d& aNodes2d = theTriangulation->ChangeUVNodes();
+
+ for (Standard_Integer i = 1; i <= myNodesMap->Size(); ++i)
+ {
+ if (myUsedNodes->IsBound(i))
+ {
+ const BRepMesh_Vertex& aVertex = myStructure->GetNode(i);
+
+ const Standard_Integer aNodeIndex = myUsedNodes->Find(i);
+ aNodes(aNodeIndex) = myNodesMap->Value(aVertex.Location3d());
+ aNodes2d(aNodeIndex) = getNodePoint2d(aVertex);
+ }
+ }
+}
+
+//=======================================================================
+// Function: getNodePoint2d
+// Purpose :
+//=======================================================================
+gp_Pnt2d BRepMesh_BaseMeshAlgo::getNodePoint2d(
+ const BRepMesh_Vertex& theVertex) const
+{
+ return theVertex.Coord();
+}
--- /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.
+ Standard_EXPORT BRepMesh_BoundaryParamsRangeSplitter()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_BoundaryParamsRangeSplitter()
+ {
+ }
+
+ //! Registers border point.
+ Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint)
+ {
+ BRepMesh_NURBSRangeSplitter::AddPoint(thePoint);
+ GetParametersU().Add(thePoint.X());
+ GetParametersV().Add(thePoint.Y());
+ }
+
+protected:
+
+ //! Initializes U and V parameters lists using CN continuity intervals.
+ Standard_EXPORT virtual void initParameters() const
+ {
+ }
+};
+
+#endif
--- /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 <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for conical surface.
+class BRepMesh_ConeRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_ConeRangeSplitter()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_ConeRangeSplitter()
+ {
+ }
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+ {
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+ gp_Cone aCone = GetDFace()->GetSurface()->Cone();
+ Standard_Real aRefR = aCone.RefRadius();
+ Standard_Real aSAng = aCone.SemiAngle();
+ Standard_Real aRadius = Max(Abs(aRefR + aRangeV.first * Sin(aSAng)),
+ Abs(aRefR + aRangeV.second * Sin(aSAng)));
+
+ Standard_Real Dv, Du = GCPnts_TangentialDeflection::ArcAngularStep(
+ aRadius, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+ const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
+ const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
+ Standard_Integer nbU = (Standard_Integer) (aDiffU / Du);
+ Standard_Integer nbV = (Standard_Integer) (nbU * (aDiffV) / (aDiffU * aRadius));
+ Du = aDiffU / (nbU + 1);
+ Dv = aDiffV / (nbV + 1);
+
+ const Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+ Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+ const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5;
+ const Standard_Real aPasMaxU = aRangeU.second - Du*0.5;
+ for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv)
+ {
+ for (Standard_Real aPasU = aRangeV.first + Du; aPasU < aPasMaxU; aPasU += Du)
+ {
+ aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+ }
+ }
+
+ return aNodes;
+ }
+};
+
+#endif
--- /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>
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_CurveTessellator::BRepMesh_CurveTessellator(
+ const IMeshData::IEdgeHandle& theEdge,
+ const IMeshTools_Parameters& theParameters)
+ : myDEdge(theEdge),
+ myParameters(theParameters),
+ myEdge(theEdge->GetEdge()),
+ myCurve(myEdge)
+{
+ init();
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_CurveTessellator::BRepMesh_CurveTessellator (
+ const IMeshData::IEdgeHandle& theEdge,
+ const TopAbs_Orientation theOrientation,
+ const IMeshData::IFaceHandle& theFace,
+ const IMeshTools_Parameters& theParameters)
+ : myDEdge(theEdge),
+ myParameters(theParameters),
+ myEdge(TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation))),
+ myCurve(myEdge, theFace->GetFace())
+{
+ init();
+}
+
+//=======================================================================
+//function : init
+//purpose :
+//=======================================================================
+void BRepMesh_CurveTessellator::init()
+{
+ TopExp::Vertices(myEdge, myFirstVertex, myLastVertex);
+
+ Standard_Real aPreciseAngDef = 0.5 * myDEdge->GetAngularDeflection();
+ Standard_Real aPreciseLinDef = 0.5 * myDEdge->GetDeflection();
+ if (myEdge.Orientation() == TopAbs_INTERNAL)
+ {
+ aPreciseLinDef *= 0.5;
+ }
+
+ mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
+ mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize);
+
+ myEdgeSqTol = BRep_Tool::Tolerance(myEdge);
+ myEdgeSqTol *= myEdgeSqTol;
+
+ const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
+
+ myDiscretTool.Initialize(myCurve,
+ myCurve.FirstParameter(), myCurve.LastParameter(),
+ aPreciseAngDef, aPreciseLinDef, aMinPntNb,
+ Precision::PConfusion(), myParameters.MinSize);
+
+ if (myCurve.IsCurveOnSurface())
+ {
+ const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface();
+ const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface();
+
+ const Standard_Real aTol = Precision::Confusion();
+ const Standard_Real aDu = aSurface->UResolution(aTol);
+ const Standard_Real aDv = aSurface->VResolution(aTol);
+
+ myFaceRangeU[0] = aSurface->FirstUParameter() - aDu;
+ myFaceRangeU[1] = aSurface->LastUParameter() + aDu;
+
+ myFaceRangeV[0] = aSurface->FirstVParameter() - aDv;
+ myFaceRangeV[1] = aSurface->LastVParameter() + aDv;
+ }
+
+ addInternalVertices();
+ splitByDeflection2d();
+}
+
+//=======================================================================
+//function : Destructor
+//purpose :
+//=======================================================================
+BRepMesh_CurveTessellator::~BRepMesh_CurveTessellator ()
+{
+}
+
+//=======================================================================
+//function : NbPoints
+//purpose :
+//=======================================================================
+Standard_Integer BRepMesh_CurveTessellator::PointsNb () const
+{
+ return myDiscretTool.NbPoints ();
+}
+
+//=======================================================================
+//function : splitByDeflection2d
+//purpose :
+//=======================================================================
+void BRepMesh_CurveTessellator::splitByDeflection2d ()
+{
+ const Standard_Integer aNodesNb = myDiscretTool.NbPoints ();
+ if (!myDEdge->IsFree () &&
+ myDEdge->GetSameParam () &&
+ myDEdge->GetSameRange () &&
+ aNodesNb > 1)
+ {
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < myDEdge->PCurvesNb (); ++aPCurveIt)
+ {
+ TopLoc_Location aLoc;
+ const IMeshData::IPCurveHandle& aPCurve = myDEdge->GetPCurve(aPCurveIt);
+ const TopoDS_Face& aFace = aPCurve->GetFace ().lock ()->GetFace ();
+ const Handle (Geom_Surface)& aSurface = BRep_Tool::Surface (aFace, aLoc);
+ if (aSurface->IsInstance(STANDARD_TYPE(Geom_Plane)))
+ {
+ continue;
+ }
+
+ const TopoDS_Edge aCurrEdge = TopoDS::Edge(myEdge.Oriented(aPCurve->GetOrientation()));
+
+ Standard_Real aF, aL;
+ Handle (Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface (aCurrEdge, aFace, aF, aL);
+ TColStd_Array1OfReal aParamArray (1, aNodesNb);
+ for (Standard_Integer i = 1; i <= aNodesNb; ++i)
+ aParamArray.SetValue (i, myDiscretTool.Parameter (i));
+
+ for (Standard_Integer i = 1; i < aNodesNb; ++i)
+ splitSegment (aSurface, aCurve2d, aParamArray (i), aParamArray (i + 1), 1);
+ }
+ }
+}
+
+//=======================================================================
+//function : addInternalVertices
+//purpose :
+//=======================================================================
+void BRepMesh_CurveTessellator::addInternalVertices ()
+{
+ // PTv, chl/922/G9, Take into account internal vertices
+ // it is necessary for internal edges, which do not split other edges, by their vertex
+ TopExp_Explorer aVertexIt (myEdge, TopAbs_VERTEX);
+ for (; aVertexIt.More (); aVertexIt.Next ())
+ {
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVertexIt.Current ());
+ if (aVertex.Orientation() != TopAbs_INTERNAL)
+ {
+ continue;
+ }
+
+ myDiscretTool.AddPoint (BRep_Tool::Pnt (aVertex),
+ BRep_Tool::Parameter (aVertex, myEdge), Standard_True);
+ }
+}
+
+//=======================================================================
+//function : isInToleranceOfVertex
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_CurveTessellator::isInToleranceOfVertex (
+ const gp_Pnt& thePoint,
+ const TopoDS_Vertex& theVertex) const
+{
+ const gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
+ const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex);
+
+ return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
+}
+
+//=======================================================================
+//function : Value
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_CurveTessellator::Value (
+ const Standard_Integer theIndex,
+ gp_Pnt& thePoint,
+ Standard_Real& theParameter) const
+{
+ thePoint = myDiscretTool.Value (theIndex);
+ theParameter = myDiscretTool.Parameter (theIndex);
+
+ /*if (!isInToleranceOfVertex(thePoint, myFirstVertex) &&
+ !isInToleranceOfVertex(thePoint, myLastVertex))
+ {*/
+ if (!myCurve.IsCurveOnSurface())
+ {
+ return Standard_True;
+ }
+
+ // If point coordinates are out of surface range,
+ // it is necessary to re-project point.
+ const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface();
+ const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface();
+ if (aSurface->GetType() != GeomAbs_BSplineSurface &&
+ aSurface->GetType() != GeomAbs_BezierSurface &&
+ aSurface->GetType() != GeomAbs_OtherSurface)
+ {
+ return Standard_True;
+ }
+
+ // Let skip periodic case.
+ if (aSurface->IsUPeriodic() || aSurface->IsVPeriodic())
+ {
+ return Standard_True;
+ }
+
+ gp_Pnt2d aUV;
+ aCurve.GetCurve()->D0(theParameter, aUV);
+ // Point lies within the surface range - nothing to do.
+ if (aUV.X() > myFaceRangeU[0] && aUV.X() < myFaceRangeU[1] &&
+ aUV.Y() > myFaceRangeV[0] && aUV.Y() < myFaceRangeV[1])
+ {
+ return Standard_True;
+ }
+
+ gp_Pnt aPntOnSurf;
+ aSurface->D0(aUV.X(), aUV.Y(), aPntOnSurf);
+
+ return (thePoint.SquareDistance(aPntOnSurf) < myEdgeSqTol);
+ /*}
+
+ return Standard_False;*/
+}
+
+//=======================================================================
+//function : splitSegment
+//purpose :
+//=======================================================================
+void BRepMesh_CurveTessellator::splitSegment (
+ const Handle (Geom_Surface)& theSurf,
+ const Handle (Geom2d_Curve)& theCurve2d,
+ const Standard_Real theFirst,
+ const Standard_Real theLast,
+ const Standard_Integer theNbIter)
+{
+ // limit iteration depth
+ if (theNbIter > 10)
+ {
+ return;
+ }
+
+ gp_Pnt2d uvf, uvl, uvm;
+ gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf;
+ Standard_Real midpar;
+
+ if (Abs(theLast - theFirst) < 2 * Precision::PConfusion())
+ {
+ return;
+ }
+
+ theCurve2d->D0 (theFirst, uvf);
+ theCurve2d->D0 (theLast, uvl);
+
+ P3dF = theSurf->Value (uvf.X (), uvf.Y ());
+ P3dL = theSurf->Value (uvl.X (), uvl.Y ());
+
+ if (P3dF.SquareDistance(P3dL) < mySquareMinSize)
+ {
+ return;
+ }
+
+ uvm = gp_Pnt2d ((uvf.XY () + uvl.XY ())*0.5);
+ midP3dFromSurf = theSurf->Value (uvm.X (), uvm.Y ());
+
+ gp_XYZ Vec1 = midP3dFromSurf.XYZ () - P3dF.XYZ ();
+ if (Vec1.SquareModulus() < mySquareMinSize)
+ {
+ return;
+ }
+
+ gp_XYZ aVec = P3dL.XYZ () - P3dF.XYZ ();
+ aVec.Normalize ();
+
+ Standard_Real aModulus = Vec1.Dot (aVec);
+ gp_XYZ aProj = aVec * aModulus;
+ gp_XYZ aDist = Vec1 - aProj;
+
+ if (aDist.SquareModulus() < mySquareEdgeDef)
+ {
+ return;
+ }
+
+ midpar = (theFirst + theLast) * 0.5;
+ myCurve.D0 (midpar, midP3d);
+ myDiscretTool.AddPoint (midP3d, midpar, Standard_False);
+
+ splitSegment (theSurf, theCurve2d, theFirst, midpar, theNbIter + 1);
+ splitSegment (theSurf, theCurve2d, midpar, theLast, theNbIter + 1);
+}
--- /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: 2016-07-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_CylinderRangeSplitter_HeaderFile
+#define _BRepMesh_CylinderRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for cylindrical surface.
+class BRepMesh_CylinderRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_CylinderRangeSplitter()
+ : myDu(1.)
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_CylinderRangeSplitter()
+ {
+ }
+
+ //! Resets this splitter. Must be called before first use.
+ Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE
+ {
+ BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters);
+
+ const Standard_Real aRadius = GetDFace()->GetSurface()->Cylinder().Radius();
+ myDu = GCPnts_TangentialDeflection::ArcAngularStep(
+ aRadius, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+ }
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& /*theParameters*/) const Standard_OVERRIDE
+ {
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+ const Standard_Real aRadius = GetDFace()->GetSurface()->Cylinder().Radius();
+
+ Standard_Integer nbU = 0;
+ Standard_Integer nbV = 0;
+ const Standard_Real su = aRangeU.second - aRangeU.first;
+ const Standard_Real sv = aRangeV.second - aRangeV.first;
+ const Standard_Real aArcLen = su * aRadius;
+ if (aArcLen > GetDFace()->GetDeflection())
+ {
+ // Calculate parameters for iteration in U direction
+ nbU = (Standard_Integer) (su / myDu);
+
+ /*
+ // Calculate parameters for iteration in V direction
+ const Standard_Real aDv = nbU*sv / aArcLen;
+ // Protection against overflow during casting to int in case
+ // of long cylinder with small radius.
+ nbV = aDv > static_cast<Standard_Real> (IntegerLast()) ?
+ 0 : (Standard_Integer) (aDv);
+ nbV = Min(nbV, 100 * nbU);
+ */
+ }
+
+ const Standard_Real Du = su / (nbU + 1);
+ const Standard_Real Dv = sv / (nbV + 1);
+
+ const Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+ Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+ const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5;
+ const Standard_Real aPasMaxU = aRangeU.second - Du*0.5;
+ for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv)
+ {
+ for (Standard_Real aPasU = aRangeU.first + Du; aPasU < aPasMaxU; aPasU += Du)
+ {
+ aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+ }
+ }
+
+ return aNodes;
+ }
+
+protected:
+
+ //! Computes parametric delta taking length along U and V into account.
+ virtual void computeDelta(
+ const Standard_Real /*theLengthU*/,
+ const Standard_Real theLengthV) Standard_OVERRIDE
+ {
+ const std::pair<double, double>& aRangeV = GetRangeV();
+ myDelta.first = myDu / Max(theLengthV, aRangeV.second - aRangeV.first);
+ myDelta.second = 1.;
+ }
+
+private:
+
+ Standard_Real myDu;
+};
+
+#endif
--- /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>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <GeomAbs_IsoType.hxx>
+
+struct IMeshTools_Parameters;
+
+//! Default tool to define range of discrete face model and
+//! obtain grid points disturbed within this range.
+class BRepMesh_DefaultRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_DefaultRangeSplitter()
+ : myIsValid (Standard_True)
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_DefaultRangeSplitter()
+ {
+ }
+
+ //! Resets this splitter. Must be called before first use.
+ Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& /*theParameters*/)
+ {
+ myDFace = theDFace;
+ myRangeU.first = myRangeV.first = 1.e100;
+ myRangeU.second = myRangeV.second = -1.e100;
+ myDelta.first = myDelta.second = 1.;
+ myTolerance.first = myTolerance.second = Precision::Confusion();
+ }
+
+ //! Registers border point.
+ Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint)
+ {
+ myRangeU.first = Min(thePoint.X(), myRangeU.first);
+ myRangeU.second = Max(thePoint.X(), myRangeU.second);
+ myRangeV.first = Min(thePoint.Y(), myRangeV.first);
+ myRangeV.second = Max(thePoint.Y(), myRangeV.second);
+ }
+
+ //! Updates discrete range of surface according to its geometric range.
+ Standard_EXPORT virtual void AdjustRange()
+ {
+ const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
+ updateRange(aSurface->FirstUParameter(), aSurface->LastUParameter(),
+ aSurface->IsUPeriodic(), myRangeU.first, myRangeU.second);
+
+ updateRange(aSurface->FirstVParameter(), aSurface->LastVParameter(),
+ aSurface->IsVPeriodic(), myRangeV.first, myRangeV.second);
+
+ const Standard_Real aLengthU = computeLengthU();
+ const Standard_Real aLengthV = computeLengthV();
+ myIsValid = aLengthU > Precision::PConfusion () && aLengthV > Precision::PConfusion ();
+
+ if (myIsValid)
+ {
+ computeTolerance(aLengthU, aLengthV);
+ computeDelta (aLengthU, aLengthV);
+ }
+ }
+
+ //! Returns True if computed range is valid.
+ Standard_EXPORT virtual Standard_Boolean IsValid()
+ {
+ return myIsValid;
+ }
+
+ //! Scales the given point from real parametric space
+ //! to face basis and otherwise.
+ //! @param thePoint point to be scaled.
+ //! @param isToFaceBasis if TRUE converts point to face basis,
+ //! otherwise performs reverse conversion.
+ //! @return scaled point.
+ Standard_EXPORT gp_Pnt2d Scale(const gp_Pnt2d& thePoint,
+ const Standard_Boolean isToFaceBasis) const
+ {
+ return isToFaceBasis ?
+ gp_Pnt2d ((thePoint.X () - myRangeU.first) / myDelta.first,
+ (thePoint.Y () - myRangeV.first) / myDelta.second) :
+ gp_Pnt2d (thePoint.X () * myDelta.first + myRangeU.first,
+ thePoint.Y () * myDelta.second + myRangeV.first);
+ }
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ //! By default returns null ptr.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& /*theParameters*/) const
+ {
+ return Handle(IMeshData::ListOfPnt2d)();
+ }
+
+ //! Returns point in 3d space corresponded to the given
+ //! point defined in parameteric space of surface.
+ inline gp_Pnt Point(const gp_Pnt2d& thePoint2d) const
+ {
+ return GetSurface()->Value(thePoint2d.X(), thePoint2d.Y());
+ }
+
+protected:
+
+ //! Computes parametric tolerance taking length along U and V into account.
+ virtual void computeTolerance(
+ const Standard_Real /*theLenU*/,
+ const Standard_Real /*theLenV*/)
+ {
+ const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
+ const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
+
+ const Standard_Real aDeflectionUV = 1.e-05;
+ myTolerance.first = Max(aDeflectionUV, Precision::Confusion() * aDiffU);
+ myTolerance.second = Max(aDeflectionUV, Precision::Confusion() * aDiffV);
+ }
+
+ //! Computes parametric delta taking length along U and V and value of tolerance into account.
+ virtual void computeDelta(
+ const Standard_Real theLengthU,
+ const Standard_Real theLengthV)
+ {
+ const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
+ const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
+
+ myDelta.first = aDiffU / (theLengthU < myTolerance.first ? 1. : theLengthU);
+ myDelta.second = aDiffV / (theLengthV < myTolerance.second ? 1. : theLengthV);
+ }
+
+public:
+ //! Returns face model.
+ inline const IMeshData::IFaceHandle& GetDFace() const
+ {
+ return myDFace;
+ }
+
+ //! Returns surface.
+ inline const Handle(BRepAdaptor_HSurface)& GetSurface() const
+ {
+ return myDFace->GetSurface();
+ }
+
+ //! Returns U range.
+ inline const std::pair<Standard_Real, Standard_Real>& GetRangeU() const
+ {
+ return myRangeU;
+ }
+
+ //! Returns V range.
+ inline const std::pair<Standard_Real, Standard_Real>& GetRangeV() const
+ {
+ return myRangeV;
+ }
+
+ //! Returns delta.
+ inline const std::pair<Standard_Real, Standard_Real>& GetDelta () const
+ {
+ return myDelta;
+ }
+
+ inline const std::pair<Standard_Real, Standard_Real>& GetToleranceUV() const
+ {
+ return myTolerance;
+ }
+
+private:
+
+ //! Computes length along U direction.
+ inline Standard_Real computeLengthU()
+ {
+ Standard_Real longu = 0.0;
+ gp_Pnt P11, P12, P21, P22, P31, P32;
+
+ Standard_Real du = 0.05 * (myRangeU.second - myRangeU.first);
+ Standard_Real dfvave = 0.5 * (myRangeV.second + myRangeV.first);
+ Standard_Real dfucur;
+ Standard_Integer i1;
+
+ const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
+ gFace->D0(myRangeU.first, myRangeV.first, P11);
+ gFace->D0(myRangeU.first, dfvave, P21);
+ gFace->D0(myRangeU.first, myRangeV.second, P31);
+ for (i1 = 1, dfucur = myRangeU.first + du; i1 <= 20; i1++, dfucur += du)
+ {
+ gFace->D0(dfucur, myRangeV.first, P12);
+ gFace->D0(dfucur, dfvave, P22);
+ gFace->D0(dfucur, myRangeV.second, P32);
+ longu += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
+ P11 = P12;
+ P21 = P22;
+ P31 = P32;
+ }
+
+ return longu / 3.;
+ }
+
+ //! Computes length along V direction.
+ inline Standard_Real computeLengthV()
+ {
+ Standard_Real longv = 0.0;
+ gp_Pnt P11, P12, P21, P22, P31, P32;
+
+ Standard_Real dv = 0.05 * (myRangeV.second - myRangeV.first);
+ Standard_Real dfuave = 0.5 * (myRangeU.second + myRangeU.first);
+ Standard_Real dfvcur;
+ Standard_Integer i1;
+
+ const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
+ gFace->D0(myRangeU.first, myRangeV.first, P11);
+ gFace->D0(dfuave, myRangeV.first, P21);
+ gFace->D0(myRangeU.second, myRangeV.first, P31);
+ for (i1 = 1, dfvcur = myRangeV.first + dv; i1 <= 20; i1++, dfvcur += dv)
+ {
+ gFace->D0(myRangeU.first, dfvcur, P12);
+ gFace->D0(dfuave, dfvcur, P22);
+ gFace->D0(myRangeU.second, dfvcur, P32);
+ longv += (P11.Distance(P12) + P21.Distance(P22) + P31.Distance(P32));
+ P11 = P12;
+ P21 = P22;
+ P31 = P32;
+ }
+
+ return longv / 3.;
+ }
+
+ //! Updates discrete range of surface according to its geometric range.
+ inline void updateRange(const Standard_Real theGeomFirst,
+ const Standard_Real theGeomLast,
+ const Standard_Boolean isPeriodic,
+ Standard_Real& theDiscreteFirst,
+ Standard_Real& theDiscreteLast)
+ {
+ if (theDiscreteFirst < theGeomFirst ||
+ theDiscreteLast > theGeomLast)
+ {
+ if (isPeriodic)
+ {
+ if ((theDiscreteLast - theDiscreteFirst) > (theGeomLast - theGeomFirst))
+ {
+ theDiscreteLast = theDiscreteFirst + (theGeomLast - theGeomFirst);
+ }
+ }
+ else
+ {
+ if (theGeomFirst > theDiscreteFirst)
+ {
+ theDiscreteFirst = theGeomFirst;
+ }
+
+ if (theGeomLast < theDiscreteLast)
+ {
+ theDiscreteLast = theGeomLast;
+ }
+ }
+ }
+ }
+
+protected:
+ IMeshData::IFaceHandle myDFace;
+ std::pair<Standard_Real, Standard_Real> myRangeU;
+ std::pair<Standard_Real, Standard_Real> myRangeV;
+ std::pair<Standard_Real, Standard_Real> myDelta;
+ std::pair<Standard_Real, Standard_Real> myTolerance;
+ Standard_Boolean myIsValid;
+};
+
+#endif
\ No newline at end of file
--- /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 <BRepMesh_ShapeTool.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <IMeshData_Edge.hxx>
+#include <IMeshData_Wire.hxx>
+#include <IMeshData_Face.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopExp.hxx>
+
+//=======================================================================
+//function : RelativeEdgeDeflection
+//purpose :
+//=======================================================================
+Standard_Real BRepMesh_Deflection::RelativeEdgeDeflection(
+ const TopoDS_Edge& theEdge,
+ const Standard_Real theDeflection,
+ const Standard_Real theMaxShapeSize,
+ Standard_Real& theAdjustmentCoefficient)
+{
+ theAdjustmentCoefficient = 1.;
+ Standard_Real aEdgeDeflection = theDeflection;
+ if (theEdge.IsNull())
+ {
+ return aEdgeDeflection;
+ }
+
+ Bnd_Box aBox;
+ BRepBndLib::Add (theEdge, aBox, Standard_False);
+ BRepMesh_ShapeTool::BoxMaxDimension (aBox, aEdgeDeflection);
+
+ // Adjust resulting value in relation to the total size
+ theAdjustmentCoefficient = theMaxShapeSize / (2 * aEdgeDeflection);
+ if (theAdjustmentCoefficient < 0.5)
+ {
+ theAdjustmentCoefficient = 0.5;
+ }
+ else if (theAdjustmentCoefficient > 2.)
+ {
+ theAdjustmentCoefficient = 2.;
+ }
+
+ return (theAdjustmentCoefficient * aEdgeDeflection * theDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (edge)
+// Purpose :
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Standard_Real theMaxShapeSize,
+ const IMeshTools_Parameters& theParameters)
+{
+ Standard_Real aLinDeflection;
+ Standard_Real aAngDeflection;
+ if (theParameters.Relative)
+ {
+ Standard_Real aScale;
+ aLinDeflection = RelativeEdgeDeflection (theDEdge->GetEdge (),
+ theParameters.Deflection, theMaxShapeSize, aScale);
+ aAngDeflection = theParameters.Angle * aScale;
+ }
+ else
+ {
+ aLinDeflection = theParameters.Deflection;
+ aAngDeflection = theParameters.Angle;
+ }
+
+ TopoDS_Vertex aFirstVertex, aLastVertex;
+ TopExp::Vertices(theDEdge->GetEdge(), aFirstVertex, aLastVertex);
+
+ Handle(Geom_Curve) aCurve;
+ Standard_Real aFirstParam, aLastParam;
+ if (BRepMesh_ShapeTool::Range(theDEdge->GetEdge(), aCurve, aFirstParam, aLastParam))
+ {
+ const Standard_Real aVertexAdjustDistance =
+ Max(BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam)),
+ BRep_Tool::Pnt(aLastVertex ).Distance(aCurve->Value(aLastParam)));
+
+ aLinDeflection = Max(aVertexAdjustDistance, aLinDeflection);
+ }
+
+ theDEdge->SetDeflection (aLinDeflection);
+ theDEdge->SetAngularDeflection (aAngDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (wire)
+// Purpose :
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+ const IMeshData::IWireHandle& theDWire,
+ const IMeshTools_Parameters& theParameters)
+{
+ Standard_Real aWireDeflection = 0.;
+ if (theDWire->EdgesNb () > 0)
+ {
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
+ {
+ aWireDeflection += theDWire->GetEdge(aEdgeIt).lock()->GetDeflection();
+ }
+
+ aWireDeflection /= theDWire->EdgesNb ();
+ }
+ else
+ {
+ aWireDeflection = theParameters.Deflection;
+ }
+
+ theDWire->SetDeflection (aWireDeflection);
+}
+
+//=======================================================================
+// Function: ComputeDeflection (face)
+// Purpose :
+//=======================================================================
+void BRepMesh_Deflection::ComputeDeflection (
+ const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& theParameters)
+{
+ Standard_Real aFaceDeflection = 0.;
+ if (theDFace->WiresNb () > 0)
+ {
+ for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
+ {
+ aFaceDeflection += theDFace->GetWire(aWireIt)->GetDeflection();
+ }
+
+ aFaceDeflection /= theDFace->WiresNb ();
+ }
+ else
+ {
+ aFaceDeflection = theParameters.Deflection;
+ }
+
+ theDFace->SetDeflection (Max(2.* BRepMesh_ShapeTool::MaxFaceTolerance(
+ theDFace->GetFace()), aFaceDeflection));
+}
--- /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 relative deflection for edge with respect to shape size.
+ //! @param theEdge edge for which relative deflection should be computed.
+ //! @param theDeflection absolute deflection.
+ //! @param theMaxShapeSize maximum size of a shape.
+ //! @param theAdjustmentCoefficient coefficient of adjustment between maximum
+ //! size of shape and calculated relative deflection.
+ //! @return relative deflection for the edge.
+ Standard_EXPORT static Standard_Real RelativeEdgeDeflection (
+ const TopoDS_Edge& theEdge,
+ const Standard_Real theDeflection,
+ const Standard_Real theMaxShapeSize,
+ Standard_Real& theAdjustmentCoefficient);
+
+ //! Computes and updates deflection of the given discrete edge.
+ Standard_EXPORT static void ComputeDeflection (
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Standard_Real theMaxShapeSize,
+ const IMeshTools_Parameters& theParameters);
+
+ //! Computes and updates deflection of the given discrete wire.
+ Standard_EXPORT static void ComputeDeflection (
+ const IMeshData::IWireHandle& theDWire,
+ const IMeshTools_Parameters& theParameters);
+
+ //! Computes and updates deflection of the given discrete face.
+ Standard_EXPORT static void ComputeDeflection (
+ const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& theParameters);
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Deflection, Standard_Transient)
+};
+
+#endif
\ No newline at end of file
--- /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);
+ }
+
+ BRepMesh_Delaun aMesher(aStructure, aVerticesOrder);
+ 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_BaseMeshAlgo.hxx>
+#include <NCollection_Shared.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+class BRepMesh_DataStructureOfDelaun;
+class BRepMesh_Delaun;
+
+//! Class provides base fuctionality to build face triangulation using Dealunay approach.
+//! Performs generation of mesh using raw data from model.
+class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_DelaunayBaseMeshAlgo();
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
+
+protected:
+
+ //! Generates mesh for the contour stored in data structure.
+ Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
+
+ //! Perfroms processing of generated mesh.
+ //! By default does nothing.
+ Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/)
+ {
+ }
+};
+
+#endif
\ No newline at end of file
--- /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>
+
+//! Extends node insertion Delaunay meshing algo in order to control
+//! deflection of generated trianges. Splits triangles failing the check.
+template<class RangeSplitter>
+class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter>
+{
+private:
+ // Typedef for OCCT RTTI
+ typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> DelaunayInsertionBaseClass;
+
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_DelaunayDeflectionControlMeshAlgo()
+ : myMaxSqDeflection(-1.),
+ myIsAllDegenerated(Standard_False)
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_DelaunayDeflectionControlMeshAlgo()
+ {
+ }
+
+protected:
+
+ //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+ Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE
+ {
+ // Insert surface nodes.
+ DelaunayInsertionBaseClass::postProcessMesh(theMesher);
+
+ if (this->getParameters().ControlSurfaceDeflection &&
+ this->getStructure()->ElementsOfDomain().Extent() > 0)
+ {
+ optimizeMesh(theMesher);
+ }
+ }
+
+ //! Checks deviation of a mesh from geometrical surface.
+ //! Inerts additional nodes in case of huge deviation.
+ Standard_EXPORT virtual void optimizeMesh(BRepMesh_Delaun& theMesher)
+ {
+ Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ myCouplesMap = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc);
+ myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+ myCircles = &theMesher.Circles();
+
+ const Standard_Integer aIterationsNb = 11;
+ Standard_Boolean isInserted = Standard_True;
+ for (Standard_Integer aPass = 1; aPass <= aIterationsNb && isInserted && !myIsAllDegenerated; ++aPass)
+ {
+ // Reset stop condition
+ myMaxSqDeflection = -1.;
+ myIsAllDegenerated = Standard_True;
+ myControlNodes->Clear();
+
+ if (this->getStructure()->ElementsOfDomain().Extent() < 1)
+ {
+ break;
+ }
+
+ // Iterate on current triangles
+ IMeshData::IteratorOfMapOfInteger aTriangleIt(this->getStructure()->ElementsOfDomain());
+ for (; aTriangleIt.More(); aTriangleIt.Next())
+ {
+ const BRepMesh_Triangle& aTriangle = this->getStructure()->GetElement(aTriangleIt.Key());
+ splitTriangleGeometry(aTriangle);
+ }
+
+ isInserted = this->insertNodes(myControlNodes, theMesher);
+ }
+
+ myCouplesMap.Nullify();
+ myControlNodes.Nullify();
+
+ if (!(myMaxSqDeflection < 0.))
+ {
+ this->getDFace()->SetDeflection(Sqrt(myMaxSqDeflection));
+ }
+ }
+
+private:
+ //! Contains geometrical data related to node of triangle.
+ struct TriangleNodeInfo
+ {
+ gp_XY Point2d;
+ gp_XYZ Point;
+ Standard_Boolean isFrontierLink;
+ };
+
+ //! Functor computing deflection of a point from surface.
+ class NormalDeviation
+ {
+ public:
+ NormalDeviation(
+ const gp_Pnt& theRefPnt,
+ const gp_Vec& theNormal)
+ : myRefPnt(theRefPnt),
+ myNormal(theNormal)
+ {
+ }
+
+ Standard_Real SquareDeviation(const gp_Pnt& thePoint) const
+ {
+ const Standard_Real aDeflection = Abs(myNormal.Dot(gp_Vec(myRefPnt, thePoint)));
+ return aDeflection * aDeflection;
+ }
+
+ private:
+
+ NormalDeviation (const NormalDeviation& theOther);
+
+ void operator= (const NormalDeviation& theOther);
+
+ private:
+
+ const gp_Pnt& myRefPnt;
+ const gp_Vec& myNormal;
+ };
+
+ //! Functor computing deflection of a point on triangle link from surface.
+ class LineDeviation
+ {
+ public:
+
+ LineDeviation(
+ const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2)
+ : myPnt1(thePnt1),
+ myPnt2(thePnt2)
+ {
+ }
+
+ Standard_Real SquareDeviation(const gp_Pnt& thePoint) const
+ {
+ return BRepMesh_GeomTool::SquareDeflectionOfSegment(myPnt1, myPnt2, thePoint);
+ }
+
+ private:
+
+ LineDeviation (const LineDeviation& theOther);
+
+ void operator= (const LineDeviation& theOther);
+
+ private:
+ const gp_Pnt& myPnt1;
+ const gp_Pnt& myPnt2;
+ };
+
+ //! Returns nodes info of the given triangle.
+ inline void getTriangleInfo(
+ const BRepMesh_Triangle& theTriangle,
+ const Standard_Integer (&theNodesIndices)[3],
+ TriangleNodeInfo (&theInfo)[3]) const
+ {
+ const Standard_Integer(&e)[3] = theTriangle.myEdges;
+ for (Standard_Integer i = 0; i < 3; ++i)
+ {
+ const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(theNodesIndices[i]);
+ theInfo[i].Point2d = this->getRangeSplitter().Scale(aVertex.Coord(), Standard_False).XY();
+ theInfo[i].Point = this->getNodesMap()->Value(aVertex.Location3d()).XYZ();
+ theInfo[i].isFrontierLink = (this->getStructure()->GetLink(e[i]).Movability() == BRepMesh_Frontier);
+ }
+ }
+
+ // Check geometry of the given triangle. If triangle does not suit specified deflection, inserts new point.
+ void splitTriangleGeometry(const BRepMesh_Triangle& theTriangle)
+ {
+ if (theTriangle.Movability() != BRepMesh_Deleted)
+ {
+ Standard_Integer aNodexIndices[3];
+ this->getStructure()->ElementNodes(theTriangle, aNodexIndices);
+
+ TriangleNodeInfo aNodesInfo[3];
+ getTriangleInfo(theTriangle, aNodexIndices, aNodesInfo);
+
+ gp_Vec aNormal;
+ gp_Vec aLinkVec[3];
+ if (computeTriangleGeometry(aNodesInfo, aLinkVec, aNormal))
+ {
+ myIsAllDegenerated = Standard_False;
+
+ const gp_XY aCenter2d = (aNodesInfo[0].Point2d +
+ aNodesInfo[1].Point2d +
+ aNodesInfo[2].Point2d) / 3.;
+
+ usePoint(aCenter2d, NormalDeviation(aNodesInfo[0].Point, aNormal));
+ splitLinks(aNodesInfo, aNodexIndices);
+ }
+ }
+ }
+
+ //! Updates array of links vectors.
+ //! @return False on degenerative triangle.
+ inline Standard_Boolean computeTriangleGeometry(
+ const TriangleNodeInfo(&theNodesInfo)[3],
+ gp_Vec (&theLinks)[3],
+ gp_Vec &theNormal)
+ {
+ if (checkTriangleForDegenerativityAndGetLinks(theNodesInfo, theLinks))
+ {
+ if (checkTriangleArea2d(theNodesInfo))
+ {
+ if (computeNormal(theLinks[0], theLinks[1], theNormal))
+ {
+ return Standard_True;
+ }
+ }
+ }
+
+ return Standard_False;
+ }
+
+ //! Updates array of links vectors.
+ //! @return False on degenerative triangle.
+ inline Standard_Boolean checkTriangleForDegenerativityAndGetLinks(
+ const TriangleNodeInfo (&theNodesInfo)[3],
+ gp_Vec (&theLinks)[3])
+ {
+ const Standard_Real MinimalSqLength3d = 1.e-12;
+ for (Standard_Integer i = 0; i < 3; ++i)
+ {
+ theLinks[i] = theNodesInfo[(i + 1) % 3].Point - theNodesInfo[i].Point;
+ if (theLinks[i].SquareMagnitude() < MinimalSqLength3d)
+ {
+ return Standard_False;
+ }
+ }
+
+ return Standard_True;
+ }
+
+ //! Checks area of triangle in parametric space for degenerativity.
+ //! @return False on degenerative triangle.
+ inline Standard_Boolean checkTriangleArea2d(
+ const TriangleNodeInfo (&theNodesInfo)[3])
+ {
+ const gp_Vec2d aLink2d1(theNodesInfo[0].Point2d, theNodesInfo[1].Point2d);
+ const gp_Vec2d aLink2d2(theNodesInfo[1].Point2d, theNodesInfo[2].Point2d);
+
+ const Standard_Real MinimalArea2d = 1.e-9;
+ return (Abs(aLink2d1 ^ aLink2d2) > MinimalArea2d);
+ }
+
+ //! Computes normal using two link vectors.
+ //! @return True on success, False in case of normal of null magnitude.
+ inline Standard_Boolean computeNormal(const gp_Vec& theLink1,
+ const gp_Vec& theLink2,
+ gp_Vec& theNormal)
+ {
+ const gp_Vec aNormal(theLink1 ^ theLink2);
+ if (aNormal.SquareMagnitude() > gp::Resolution())
+ {
+ theNormal = aNormal.Normalized();
+ return Standard_True;
+ }
+
+ return Standard_False;
+ }
+
+ //! Computes deflection of midpoints of triangles links.
+ //! @return True if point fits specified deflection.
+ inline void splitLinks(
+ const TriangleNodeInfo (&theNodesInfo)[3],
+ const Standard_Integer (&theNodesIndices)[3])
+ {
+ // Check deflection at triangle links
+ for (Standard_Integer i = 0; i < 3; ++i)
+ {
+ if (theNodesInfo[i].isFrontierLink)
+ {
+ continue;
+ }
+
+ const Standard_Integer j = (i + 1) % 3;
+ // Check if this link was already processed
+ Standard_Integer aFirstVertex, aLastVertex;
+ if (theNodesIndices[i] < theNodesIndices[j])
+ {
+ aFirstVertex = theNodesIndices[i];
+ aLastVertex = theNodesIndices[j];
+ }
+ else
+ {
+ aFirstVertex = theNodesIndices[j];
+ aLastVertex = theNodesIndices[i];
+ }
+
+ if (myCouplesMap->Add(BRepMesh_OrientedEdge(aFirstVertex, aLastVertex)))
+ {
+ const gp_XY aMidPnt2d = (theNodesInfo[i].Point2d +
+ theNodesInfo[j].Point2d) / 2.;
+
+ usePoint(aMidPnt2d, LineDeviation(theNodesInfo[i].Point, theNodesInfo[j].Point));
+ }
+ }
+ }
+
+ //! Computes deflection of the given point and caches it for
+ //! insertion in case if it overflows deflection.
+ //! @return True if point has been cached for insertion.
+ template<class DeflectionFunctor>
+ inline void usePoint(
+ const gp_XY& thePnt2d,
+ const DeflectionFunctor& theDeflectionFunctor)
+ {
+ gp_Pnt aPnt;
+ this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
+ if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
+ {
+ myControlNodes->Append(thePnt2d);
+ }
+ }
+
+ //! Checks the given point for specified deflection.
+ //! Updates value of total mesh defleciton.
+ Standard_Boolean checkDeflectionOfPointAndUpdateCache(
+ const gp_XY& thePnt2d,
+ const gp_Pnt& thePnt3d,
+ const Standard_Real theSqDeflection)
+ {
+ if (theSqDeflection > myMaxSqDeflection)
+ {
+ myMaxSqDeflection = theSqDeflection;
+ }
+
+ const Standard_Real aSqDeflection = this->getDFace()->GetDeflection() * this->getDFace()->GetDeflection();
+ if (theSqDeflection < aSqDeflection)
+ {
+ return Standard_True;
+ }
+
+ if (this->getParameters().MinSize > Precision::Confusion())
+ {
+ return rejectByMinSize(thePnt2d, thePnt3d);
+ }
+
+ return Standard_False;
+ }
+
+ //! Checks the given node for
+ Standard_Boolean rejectByMinSize(
+ const gp_XY& thePnt2d,
+ const gp_Pnt& thePnt3d)
+ {
+ const Standard_Real aSqMinSize = this->getParameters().MinSize * this->getParameters().MinSize;
+
+ Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ IMeshData::MapOfInteger aUsedNodes;
+ IMeshData::ListOfInteger& aCirclesList =
+ const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
+ this->getRangeSplitter().Scale(thePnt2d, Standard_True).XY());
+
+ IMeshData::ListOfInteger::Iterator aCircleIt(aCirclesList);
+ for (; aCircleIt.More(); aCircleIt.Next())
+ {
+ const BRepMesh_Triangle& aTriangle = this->getStructure()->GetElement(aCircleIt.Value());
+
+ Standard_Integer aNodes[3];
+ this->getStructure()->ElementNodes(aTriangle, aNodes);
+
+ for (Standard_Integer i = 0; i < 3; ++i)
+ {
+ if (!aUsedNodes.Contains(aNodes[i]))
+ {
+ aUsedNodes.Add(aNodes[i]);
+ const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
+ const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
+
+ if (thePnt3d.SquareDistance(aPoint) < aSqMinSize)
+ {
+ return Standard_True;
+ }
+ }
+ }
+ }
+
+ return Standard_False;
+ }
+
+private:
+ Standard_Real myMaxSqDeflection;
+ Standard_Boolean myIsAllDegenerated;
+ Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
+ Handle(IMeshData::ListOfPnt2d) myControlNodes;
+ const BRepMesh_CircleTool* myCircles;
+};
+
+#endif
--- /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>
+
+//! Extends base Delaunay meshing algo in order to enable possibility
+//! of addition of free vertices and internal nodes into the mesh.
+template<class RangeSplitter>
+class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo>
+{
+private:
+ // Typedef for OCCT RTTI
+ typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> InsertionBaseClass;
+
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_DelaunayNodeInsertionMeshAlgo()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_DelaunayNodeInsertionMeshAlgo()
+ {
+ }
+
+protected:
+
+ //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
+ Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE
+ {
+ InsertionBaseClass::postProcessMesh(theMesher);
+
+ const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
+ this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
+
+ insertNodes(aSurfaceNodes, theMesher);
+ }
+
+ //! Inserts nodes into mesh.
+ Standard_EXPORT Standard_Boolean insertNodes(
+ const Handle(IMeshData::ListOfPnt2d)& theNodes,
+ BRepMesh_Delaun& theMesher)
+ {
+ if (theNodes.IsNull() || theNodes->IsEmpty())
+ {
+ return Standard_False;
+ }
+
+ IMeshData::VectorOfInteger aVertexIndexes(theNodes->Size(), this->getAllocator());
+ IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
+ for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
+ {
+ const gp_Pnt2d& aPnt2d = aNodesIt.Value();
+ if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
+ {
+ aVertexIndexes.Append(this->registerNode(this->getRangeSplitter().Point(aPnt2d),
+ aPnt2d, BRepMesh_Free, Standard_False));
+ }
+ }
+
+ theMesher.AddVertices(aVertexIndexes);
+ return !aVertexIndexes.IsEmpty();
+ }
+};
+
+#endif
--- /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::Perform (
+ const Handle (IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters)
+{
+ myModel = theModel;
+ myParameters = theParameters;
+ if (myModel.IsNull())
+ {
+ return Standard_False;
+ }
+
+ OSD_Parallel::For (0, myModel->EdgesNb (), *this, !myParameters.InParallel);
+
+ myModel.Nullify(); // Do not hold link to model.
+ return Standard_True;
+}
+
+//=======================================================================
+// Function: process
+// Purpose :
+//=======================================================================
+void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
+{
+ const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
+ BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
+
+ Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
+ if (!aDEdge->IsFree ())
+ {
+ // Iterate over pcurves and check deflection on corresponding face.
+ Standard_Real aMinDeflection = RealLast ();
+ Standard_Integer aMinPCurveIndex = -1;
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
+ {
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
+ const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
+ if (aTmpDeflection < aMinDeflection)
+ {
+ // Identify pcurve with the smallest deflection in order to
+ // retrieve polygon that represents the most smooth discretization.
+ aMinDeflection = aTmpDeflection;
+ aMinPCurveIndex = aPCurveIt;
+ }
+
+ BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
+ }
+
+ if (aMinPCurveIndex != -1)
+ {
+ aDEdge->SetDeflection (aMinDeflection);
+ const IMeshData::IFaceHandle& aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace().lock();
+ aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
+ }
+ else
+ {
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+ const IMeshData::IFaceHandle& aDFace = aPCurve->GetFace().lock();
+ aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+ aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
+ }
+ }
+ else
+ {
+ TopLoc_Location aLoc;
+ const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
+ if (!aPoly3D.IsNull () &&
+ aPoly3D->HasParameters () &&
+ aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
+ {
+ // Edge already has suitable 3d polygon.
+ aDEdge->SetStatus(IMeshData_Reused);
+ return;
+ }
+ else
+ {
+ aDEdge->SetStatus(IMeshData_Outdated);
+ }
+
+ aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
+ }
+
+ Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
+ if (!aDEdge->IsFree())
+ {
+ Tessellate2d(aDEdge, Standard_True);
+ }
+}
+
+//=======================================================================
+// Function: checkExistingPolygonAndUpdateStatus
+// Purpose :
+//=======================================================================
+Standard_Real BRepMesh_EdgeDiscret::checkExistingPolygonAndUpdateStatus(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const IMeshData::IPCurveHandle& thePCurve) const
+{
+ const TopoDS_Edge& aEdge = theDEdge->GetEdge ();
+ const TopoDS_Face& aFace = thePCurve->GetFace ().lock ()->GetFace ();
+
+ TopLoc_Location aLoc;
+ const Handle (Poly_Triangulation)& aFaceTriangulation =
+ BRep_Tool::Triangulation (aFace, aLoc);
+
+ Standard_Real aDeflection = RealLast ();
+ if (aFaceTriangulation.IsNull())
+ {
+ return aDeflection;
+ }
+
+ const Handle (Poly_PolygonOnTriangulation)& aPolygon =
+ BRep_Tool::PolygonOnTriangulation (aEdge, aFaceTriangulation, aLoc);
+
+ if (!aPolygon.IsNull ())
+ {
+ Standard_Boolean isConsistent = aPolygon->HasParameters () &&
+ aPolygon->Deflection () < 1.1 * theDEdge->GetDeflection ();
+
+ if (!isConsistent)
+ {
+ // Nullify edge data and mark discrete pcurve to
+ // notify necessity to mesh the entire face.
+ theDEdge->SetStatus(IMeshData_Outdated);
+ }
+ else
+ {
+ aDeflection = aPolygon->Deflection();
+ }
+ }
+
+ return aDeflection;
+}
+
+//=======================================================================
+// Function: Tessellate3d
+// Purpose :
+//=======================================================================
+void BRepMesh_EdgeDiscret::Tessellate3d(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Handle (IMeshTools_CurveTessellator)& theTessellator,
+ const Standard_Boolean theUpdateEnds)
+{
+ // Create 3d polygon.
+ const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+
+ const TopoDS_Edge& aEdge = theDEdge->GetEdge();
+ TopoDS_Vertex aFirstVertex, aLastVertex;
+ TopExp::Vertices(aEdge, aFirstVertex, aLastVertex);
+
+ if (theUpdateEnds)
+ {
+ gp_Pnt aPoint;
+ Standard_Real aParam;
+ theTessellator->Value(1, aPoint, aParam);
+ aCurve->AddPoint(BRep_Tool::Pnt(aFirstVertex), aParam);
+ }
+
+ if (!theDEdge->GetDegenerated())
+ {
+ for (Standard_Integer i = 2; i < theTessellator->PointsNb(); ++i)
+ {
+ gp_Pnt aPoint;
+ Standard_Real aParam;
+ if (!theTessellator->Value(i, aPoint, aParam))
+ continue;
+
+ if (theUpdateEnds)
+ {
+ aCurve->AddPoint(aPoint, aParam);
+ }
+ else
+ {
+ aCurve->InsertPoint(aCurve->ParametersNb() - 1, aPoint, aParam);
+ }
+ }
+ }
+
+ if (theUpdateEnds)
+ {
+ gp_Pnt aPoint;
+ Standard_Real aParam;
+ theTessellator->Value(theTessellator->PointsNb(), aPoint, aParam);
+ aCurve->AddPoint(BRep_Tool::Pnt(aLastVertex), aParam);
+ }
+}
+
+//=======================================================================
+// Function: Tessellate2d
+// Purpose :
+//=======================================================================
+void BRepMesh_EdgeDiscret::Tessellate2d(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Standard_Boolean theUpdateEnds)
+{
+ const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+ {
+ const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
+ IMeshData::ICurveArrayAdaptorHandle aCurveArray(new IMeshData::ICurveArrayAdaptor(aCurve));
+ BRepMesh_EdgeParameterProvider<IMeshData::ICurveArrayAdaptorHandle> aProvider(
+ theDEdge, aPCurve->GetOrientation(), aPCurve->GetFace().lock(), aCurveArray);
+
+ const Handle(Adaptor2d_HCurve2d)& aGeomPCurve = aProvider.GetPCurve();
+
+ Standard_Integer aParamIdx, aParamNb;
+ if (theUpdateEnds)
+ {
+ aParamIdx = 0;
+ aParamNb = aCurve->ParametersNb();
+ }
+ else
+ {
+ aParamIdx = 1;
+ aParamNb = aCurve->ParametersNb() - 1;
+ }
+
+ for (; aParamIdx < aParamNb; ++aParamIdx)
+ {
+ const Standard_Real aParam = aProvider.Parameter(aParamIdx, aCurve->GetPoint(aParamIdx));
+
+ gp_Pnt2d aPoint2d;
+ aGeomPCurve->D0(aParam, aPoint2d);
+ if (theUpdateEnds)
+ {
+ aPCurve->AddPoint(aPoint2d, aParam);
+ }
+ else
+ {
+ aPCurve->InsertPoint(aPCurve->ParametersNb() - 1, aPoint2d, aParam);
+ }
+ }
+ }
+}
--- /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);
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform (
+ const Handle (IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ //! Functor API to discretize the given edge.
+ inline void operator() (const Standard_Integer theEdgeIndex) const {
+ process (theEdgeIndex);
+ }
+
+ //! Updates 3d discrete edge model using the given tessellation tool.
+ Standard_EXPORT static void Tessellate3d(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Handle(IMeshTools_CurveTessellator)& theTessellator,
+ const Standard_Boolean theUpdateEnds);
+
+ //! Updates 2d discrete edge model using tessellation of 3D curve.
+ Standard_EXPORT static void Tessellate2d(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const Standard_Boolean theUpdateEnds);
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
+
+private:
+
+ //! Checks existing discretization of the edge and updates data model.
+ void process (const Standard_Integer theEdgeIndex) const;
+
+ //! Checks existing polygon on triangulation does it fit edge deflection or not.
+ //! @return deflection of polygon or RealLast () in case if edge has no polygon
+ //! or it was dropped.
+ Standard_Real checkExistingPolygonAndUpdateStatus(
+ const IMeshData::IEdgeHandle& theDEdge,
+ const IMeshData::IPCurveHandle& thePCurve) const;
+
+private:
+
+ Handle (IMeshData_Model) myModel;
+ IMeshTools_Parameters myParameters;
+};
+
+#endif
\ No newline at end of file
--- /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>
+#include <BRepMesh_IncAllocator.hxx>
+
+namespace
+{
+ const Standard_Real MaxTangentAngle = 5. * M_PI / 180.;
+
+ //! Functor to be used to fill segments and bounding box tree in parallel.
+ class SegmentsFiller
+ {
+ public:
+ //! Constructor.
+ SegmentsFiller(const IMeshData::IFaceHandle& theDFace,
+ Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments,
+ Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree)
+ : myDFace(theDFace),
+ myWiresSegments(theWiresSegments),
+ myWiresBndBoxTree(theWiresBndBoxTree)
+ {
+ myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1);
+ myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1);
+ }
+
+ //! Performs initialization of wire with the given index.
+ void operator()(const Standard_Integer theWireIndex) const
+ {
+ const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex);
+
+ Handle(NCollection_IncAllocator) aTmpAlloc1 =
+ new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ Handle(BRepMesh_FaceChecker::Segments) aSegments =
+ new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1);
+ Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1);
+
+ myWiresSegments ->ChangeValue(theWireIndex) = aSegments;
+ myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree;
+
+ Handle(NCollection_IncAllocator) aTmpAlloc2 =
+ new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+ IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2);
+
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+ {
+ // TODO: check 2d wire for consistency.
+
+ const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt);
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge.lock()->GetPCurve(myDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+ for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt)
+ {
+ gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1);
+ gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt);
+
+ Bnd_Box2d aBox;
+ aBox.Add(aPnt1);
+ aBox.Add(aPnt2);
+ aBox.Enlarge(Precision::Confusion());
+
+ aBndBoxTreeFiller.Add(aSegments->Size(), aBox);
+ aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2));
+ }
+ }
+
+ aBndBoxTreeFiller.Fill();
+ }
+
+ private:
+
+ SegmentsFiller (const SegmentsFiller& theOther);
+
+ void operator=(const SegmentsFiller& theOther);
+
+ private:
+
+ const IMeshData::IFaceHandle& myDFace;
+ Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments;
+ Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
+ };
+
+ //! Selector.
+ //! Used to identify segments with overlapped bounding boxes.
+ //! Selector.
+ //! Used to identify segments with overlapped bounding boxes.
+ class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
+ {
+ public:
+ //! Constructor.
+ BndBox2dTreeSelector(const Standard_Real theTolerance)
+ : myMaxLoopSize(M_PI * theTolerance * theTolerance),
+ mySelfSegmentIndex(-1),
+ myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
+ {
+ }
+
+ //! Sets working set of segments.
+ void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments)
+ {
+ mySegments = theSegments;
+ }
+
+ //! Resets current selector.
+ void Reset(const BRepMesh_FaceChecker::Segment* theSegment,
+ const Standard_Integer theSelfSegmentIndex)
+ {
+ myIndices.Clear();
+
+ mySelfSegmentIndex = theSelfSegmentIndex;
+ mySegment = theSegment;
+
+ myBox.SetVoid();
+ myBox.Add(*mySegment->Point1);
+ myBox.Add(*mySegment->Point2);
+ myBox.Enlarge(Precision::Confusion());
+ }
+
+ //! Indicates should the given box be rejected or not.
+ virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const
+ {
+ return myBox.IsOut(theBox);
+ }
+
+ //! Accepts segment with the given index in case if it fits conditions.
+ virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex)
+ {
+ const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex);
+
+ gp_Pnt2d aIntPnt;
+ const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg(
+ mySegment->Point1->XY(), mySegment->Point2->XY(),
+ aSegment.Point1->XY(), aSegment.Point2->XY(),
+ Standard_False, Standard_False, aIntPnt);
+
+ if (aIntStatus == BRepMesh_GeomTool::Cross)
+ {
+ const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle(
+ gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY()));
+
+ if (Abs(aAngle) < MaxTangentAngle)
+ {
+ return Standard_False;
+ }
+
+ if (mySelfSegmentIndex != -1)
+ {
+ gp_XY aPrevVec;
+ Standard_Real aSumS = 0.;
+ const gp_XY& aRefPnt = aIntPnt.Coord();
+ for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i)
+ {
+ const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i);
+ gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt;
+
+ if (aCurVec.SquareModulus() < gp::Resolution())
+ continue;
+
+ if (aPrevVec.SquareModulus() > gp::Resolution())
+ aSumS += aPrevVec ^ aCurVec;
+
+ aPrevVec = aCurVec;
+ }
+
+ if (Abs(aSumS / 2.) < myMaxLoopSize)
+ {
+ return Standard_False;
+ }
+ }
+
+ myIndices.Append(theSegmentIndex);
+ return Standard_True;
+ }
+
+ return Standard_False;
+ }
+
+ //! Returns indices of intersecting segments.
+ const IMeshData::VectorOfInteger& Indices() const
+ {
+ return myIndices;
+ }
+
+ private:
+
+ Standard_Real myMaxLoopSize;
+ Standard_Integer mySelfSegmentIndex;
+ Handle(BRepMesh_FaceChecker::Segments) mySegments;
+ const BRepMesh_FaceChecker::Segment* mySegment;
+ Bnd_Box2d myBox;
+ IMeshData::VectorOfInteger myIndices;
+ };
+}
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+BRepMesh_FaceChecker::BRepMesh_FaceChecker(
+ const IMeshData::IFaceHandle& theFace,
+ const IMeshTools_Parameters& theParameters)
+ : myDFace(theFace),
+ myParameters(theParameters)
+{
+}
+
+//=======================================================================
+//function : Destructor
+//purpose :
+//=======================================================================
+BRepMesh_FaceChecker::~BRepMesh_FaceChecker()
+{
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_FaceChecker::Perform()
+{
+ myIntersectingEdges = new IMeshData::MapOfIEdgePtr;
+ collectSegments();
+
+ OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel());
+ collectResult();
+
+ myWiresBndBoxTree.Nullify();
+ myWiresSegments.Nullify();
+ myWiresIntersectingEdges.Nullify();
+ return myIntersectingEdges->IsEmpty();
+}
+
+//=======================================================================
+//function : collectSegments
+//purpose :
+//=======================================================================
+void BRepMesh_FaceChecker::collectSegments()
+{
+ SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree);
+ OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel());
+
+ myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1);
+}
+
+//=======================================================================
+//function : perform
+//purpose :
+//=======================================================================
+void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
+{
+ const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex);
+ Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
+
+ // TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
+ BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
+ for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
+ {
+ const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
+ const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt);
+
+ aSelector.SetSegments(aSegments2);
+ for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt)
+ {
+ const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt);
+ aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1);
+ if (aBndBoxTree2->Select(aSelector) != 0)
+ {
+ if (aIntersections.IsNull())
+ {
+ aIntersections = new IMeshData::MapOfIEdgePtr;
+ }
+
+ aIntersections->Add(aSegment1.EdgePtr);
+
+ const IMeshData::VectorOfInteger& aSegments = aSelector.Indices();
+ for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt)
+ {
+ const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt));
+ aIntersections->Add(aSegment2.EdgePtr);
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : collectResult
+//purpose :
+//=======================================================================
+void BRepMesh_FaceChecker::collectResult()
+{
+ for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt)
+ {
+ const Handle(IMeshData::MapOfIEdgePtr)& aEdges = myWiresIntersectingEdges->Value(aWireIt);
+ if (!aEdges.IsNull())
+ {
+ myIntersectingEdges->Unite(*aEdges);
+ }
+ }
+}
--- /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::Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters)
+{
+ myModel = theModel;
+ myParameters = theParameters;
+ if (myModel.IsNull())
+ {
+ return Standard_False;
+ }
+
+ OSD_Parallel::For(0, myModel->FacesNb(), *this, !(myParameters.InParallel && myModel->FacesNb() > 1));
+
+ myModel.Nullify(); // Do not hold link to model.
+ return Standard_True;
+}
+
+//=======================================================================
+// Function: process
+// Purpose :
+//=======================================================================
+void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
+{
+ const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+ if (aDFace->IsSet(IMeshData_Failure) ||
+ aDFace->IsSet(IMeshData_Reused))
+ {
+ return;
+ }
+
+ Handle(IMeshTools_MeshAlgo) aMeshingAlgo =
+ myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
+
+ if (aMeshingAlgo.IsNull())
+ {
+ aDFace->SetStatus(IMeshData_Failure);
+ return;
+ }
+
+ aMeshingAlgo->Perform(aDFace, myParameters);
+}
--- /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 instace of triangulation
+//! algorithm according to type of surface of target face.
+class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_FaceDiscret(
+ const Handle(IMeshTools_MeshAlgoFactory)& theAlgoFactory);
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_FaceDiscret();
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ //! Functor API to discretize the given edge.
+ inline void operator() (const Standard_Integer theFaceIndex) const {
+ process(theFaceIndex);
+ }
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo)
+
+private:
+
+ //! Checks existing discretization of the face and updates data model.
+ void process(const Standard_Integer theFaceIndex) const;
+
+private:
+
+ Handle(IMeshTools_MeshAlgoFactory) myAlgoFactory;
+ Handle(IMeshData_Model) myModel;
+ IMeshTools_Parameters myParameters;
+};
+
+#endif
--- /dev/null
+// Created on: 2016-06-20
+// Created by: Oleg AGASHIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepMesh_IncAllocator_HeaderFile
+#define _BRepMesh_IncAllocator_HeaderFile
+
+#include <NCollection_IncAllocator.hxx>
+#include <Standard_Mutex.hxx>
+
+//! Extension for NCollection_IncAllocator implementing simple thread safety
+//! by introduction of Mutex. Intended for use in couple with BRepMeshData
+//! entities in order to prevent data races while building data model in
+//! parallel mode. Note that this allocator is supposed for use by collections
+//! which allocate memory by huge blocks at arbitrary moment, thus it should
+//! not introduce significant performance slow down.
+class BRepMesh_IncAllocator : public NCollection_IncAllocator
+{
+public:
+ //! Constructor
+ Standard_EXPORT BRepMesh_IncAllocator(const size_t theBlockSize = DefaultBlockSize)
+ : NCollection_IncAllocator(theBlockSize)
+ {
+ }
+
+ //! Allocate memory with given size. Returns NULL on failure
+ Standard_EXPORT virtual void* Allocate(const size_t size) Standard_OVERRIDE
+ {
+ Standard_Mutex::Sentry aSentry(myMutex);
+ return NCollection_IncAllocator::Allocate(size);
+ }
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_IncAllocator, NCollection_IncAllocator)
+
+private:
+ Standard_Mutex myMutex;
+};
+
+#endif
--- /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> Type;
+ };
+
+ template<class RangeSplitter>
+ struct DeflectionControlMeshAlgo
+ {
+ typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter> Type;
+ };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_MeshAlgoFactory::BRepMesh_MeshAlgoFactory()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_MeshAlgoFactory::~BRepMesh_MeshAlgoFactory()
+{
+}
+
+//=======================================================================
+// Function: GetAlgo
+// Purpose :
+//=======================================================================
+Handle(IMeshTools_MeshAlgo) BRepMesh_MeshAlgoFactory::GetAlgo(
+ const GeomAbs_SurfaceType theSurfaceType,
+ const IMeshTools_Parameters& theParameters) const
+{
+ switch (theSurfaceType)
+ {
+ case GeomAbs_Plane:
+ return theParameters.InternalVerticesMode ?
+ new NodeInsertionMeshAlgo<BRepMesh_DefaultRangeSplitter>::Type :
+ new BaseMeshAlgo::Type;
+ break;
+
+ case GeomAbs_Sphere:
+ return new NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type;
+ break;
+
+ case GeomAbs_Cylinder:
+ return new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type;
+ break;
+
+ case GeomAbs_Cone:
+ return new NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type;
+ break;
+
+ case GeomAbs_Torus:
+ return new NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type;
+ break;
+
+ case GeomAbs_SurfaceOfRevolution:
+ return new DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type;
+ break;
+
+ default:
+ return new DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type;
+ }
+}
--- /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-04-07
+// Copyright (c) 2016 OPEN CASCADE SAS
+// Created by: Oleg AGASHIN
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BRepMesh_MeshBuilder.hxx>
+#include <IMeshData_Face.hxx>
+#include <OSD_Parallel.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_MeshBuilder::BRepMesh_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_MeshBuilder::BRepMesh_MeshBuilder (
+ const Handle (IMeshTools_Context)& theContext)
+ : IMeshTools_MeshBuilder (theContext)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_MeshBuilder::~BRepMesh_MeshBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose :
+//=======================================================================
+void BRepMesh_MeshBuilder::Perform ()
+{
+ ClearStatus ();
+
+ const Handle (IMeshTools_Context)& aContext = GetContext ();
+ if (aContext.IsNull ())
+ {
+ SetStatus (Message_Fail1);
+ return;
+ }
+
+ if (aContext->BuildModel ())
+ {
+ if (aContext->DiscretizeEdges ())
+ {
+ if (aContext->HealModel ())
+ {
+ if (aContext->PreProcessModel())
+ {
+ if (aContext->DiscretizeFaces())
+ {
+ if (aContext->PostProcessModel())
+ {
+ SetStatus(Message_Done1);
+ }
+ else
+ {
+ SetStatus(Message_Fail6);
+ }
+ }
+ else
+ {
+ SetStatus(Message_Fail5);
+ }
+ }
+ else
+ {
+ SetStatus(Message_Fail4);
+ }
+ }
+ else
+ {
+ SetStatus(Message_Fail3);
+ }
+ }
+ else
+ {
+ SetStatus (Message_Fail1);
+ }
+ }
+ else
+ {
+ const Handle (IMeshTools_ModelBuilder)& aModelBuilder =
+ aContext->GetModelBuilder ();
+
+ if (aModelBuilder.IsNull ())
+ {
+ SetStatus (Message_Fail1);
+ }
+ else
+ {
+ // Is null shape or another problem?
+ SetStatus (aModelBuilder->GetStatus ().IsSet (Message_Fail1) ?
+ Message_Warn1 : Message_Fail2);
+ }
+ }
+
+ aContext->Clean ();
+}
--- /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_MeshBuilder_HeaderFile
+#define _BRepMesh_MeshBuilder_HeaderFile
+
+#include <IMeshTools_MeshBuilder.hxx>
+
+//! Builds mesh for each face of shape without triangulation.
+//! In case if some faces of shape have already been triangulated
+//! checks deflection of existing polygonal model and re-uses it
+//! if deflection satisfies the specified parameter. Otherwise
+//! nullifies existing triangulation and build triangulation anew.
+//!
+//! The following statuses are used:
+//! Message_Done1 - algorithm has finished without errors.
+//! Message_Fail1 - invalid context.
+//! Message_Fail2 - algorithm has faced unexpected error.
+//! Message_Fail3 - can't heal discrete model.
+//! Message_Warn1 - shape contains no objects to mesh.
+class BRepMesh_MeshBuilder : public IMeshTools_MeshBuilder
+{
+public: //! @name mesher API
+
+ //! Default constructor
+ Standard_EXPORT BRepMesh_MeshBuilder ();
+
+ //! Default constructor
+ Standard_EXPORT BRepMesh_MeshBuilder (const Handle (IMeshTools_Context)& theContext);
+
+ //! Destructor
+ Standard_EXPORT virtual ~BRepMesh_MeshBuilder ();
+
+ //! Performs meshing ot the shape.
+ Standard_EXPORT virtual void Perform () Standard_OVERRIDE;
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshBuilder, IMeshTools_MeshBuilder)
+};
+
+#endif
--- /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_ShapeExplorer.hxx>
+#include <BRepMesh_ShapeTool.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelBuilder::BRepMesh_ModelBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder ()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose :
+//=======================================================================
+Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
+ const TopoDS_Shape& theShape,
+ const IMeshTools_Parameters& theParameters)
+{
+ ClearStatus ();
+
+ Handle (BRepMeshData_Model) aModel;
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ Bnd_Box aBox;
+ BRepBndLib::Add (theShape, aBox, Standard_False);
+
+ if (!aBox.IsVoid ())
+ {
+ // Build data model for further processing.
+ aModel = new BRepMeshData_Model (theShape);
+
+ if (theParameters.Relative)
+ {
+ Standard_Real aMaxSize;
+ BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
+ aModel->SetMaxSize(aMaxSize);
+ }
+ else
+ {
+ aModel->SetMaxSize(theParameters.Deflection);
+ }
+
+ Handle (IMeshTools_ShapeVisitor) aVisitor =
+ new BRepMesh_ShapeVisitor (aModel);
+
+ Handle (IMeshTools_ShapeExplorer) aExplorer =
+ new BRepMesh_ShapeExplorer (theShape);
+
+ aExplorer->Accept (aVisitor);
+ SetStatus (Message_Done1);
+ }
+ else
+ {
+ SetStatus(Message_Fail1);
+ }
+ }
+ catch (Standard_Failure&)
+ {
+ SetStatus (Message_Fail2);
+ }
+
+ return aModel;
+}
--- /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 ();
+
+ //! Creates discrete model for the given shape.
+ //! Returns nullptr in case of failure.
+ Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+ const TopoDS_Shape& theShape,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
+};
+
+#endif
\ No newline at end of file
--- /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.lock();
+ aDEdge->Clear(Standard_True);
+ aDEdge->SetDeflection(Max(aDEdge->GetDeflection() / 3., Precision::Confusion()));
+
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
+ const IMeshData::IFaceHandle& aDFace = aPCurve->GetFace().lock();
+ Handle(IMeshTools_CurveTessellator) aTessellator =
+ BRepMesh_EdgeDiscret::CreateEdgeTessellator(
+ aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
+
+ BRepMesh_EdgeDiscret::Tessellate3d(aDEdge, aTessellator, Standard_False);
+ BRepMesh_EdgeDiscret::Tessellate2d(aDEdge, Standard_False);
+ }
+
+ private:
+
+ EdgeAmplifier (const EdgeAmplifier& theOther);
+
+ void operator=(const EdgeAmplifier& theOther);
+
+ private:
+ const IMeshTools_Parameters& myParameters;
+ };
+
+ //! Returns True if some of two vertcies is same with reference one.
+ inline Standard_Boolean isSameWithSomeOf(
+ const TopoDS_Vertex& theRefVertex,
+ const TopoDS_Vertex& theVertex1,
+ const TopoDS_Vertex& theVertex2)
+ {
+ return (theRefVertex.IsSame(theVertex1) ||
+ theRefVertex.IsSame(theVertex2));
+ }
+
+ //! Returns True if some of two vertcies is within tolerance of reference one.
+ inline Standard_Boolean isInToleranceWithSomeOf(
+ const gp_Pnt& theRefPoint,
+ const gp_Pnt& thePoint1,
+ const gp_Pnt& thePoint2,
+ const Standard_Real theTol)
+ {
+ const Standard_Real aSqTol = theTol * theTol;
+ return (theRefPoint.SquareDistance(thePoint1) < aSqTol ||
+ theRefPoint.SquareDistance(thePoint2) < aSqTol);
+ }
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelHealer::BRepMesh_ModelHealer()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelHealer::~BRepMesh_ModelHealer()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters)
+{
+ myModel = theModel;
+ myParameters = theParameters;
+ if (myModel.IsNull())
+ {
+ return Standard_False;
+ }
+
+ myFaceIntersectingEdges = new IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs;
+ for (Standard_Integer aFaceIt = 0; aFaceIt < myModel->FacesNb(); ++aFaceIt)
+ {
+ myFaceIntersectingEdges->Bind(myModel->GetFace(aFaceIt), Handle(IMeshData::MapOfIEdgePtr)());
+ }
+
+ // TODO: Here we can process edges in order to remove close discrete points.
+ OSD_Parallel::For(0, myModel->FacesNb(), *this, !isParallel());
+ amplifyEdges();
+
+ IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ {
+ if (!aFaceIt.Value().IsNull())
+ {
+ const IMeshData::IFaceHandle& aDFace = aFaceIt.Key().lock();
+ aDFace->SetStatus(IMeshData_SelfIntersectingWire);
+ aDFace->SetStatus(IMeshData_Failure);
+ }
+ }
+
+ myFaceIntersectingEdges.Nullify();
+ myModel.Nullify(); // Do not hold link to model.
+ return Standard_True;
+}
+
+//=======================================================================
+// Function: amplifyEdges
+// Purpose :
+//=======================================================================
+void BRepMesh_ModelHealer::amplifyEdges()
+{
+ Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ Standard_Integer aAmpIt = 0;
+ const Standard_Real aIterNb = 5;
+ IMeshData::MapOfIEdgePtr aEdgesToUpdate(1, aTmpAlloc);
+ while (aAmpIt++ < aIterNb && popEdgesToUpdate(aEdgesToUpdate))
+ {
+ // Try to update discretization by decreasing deflection of problematic edges.
+ OSD_Parallel::ForEach(aEdgesToUpdate.cbegin(), aEdgesToUpdate.cend(),
+ EdgeAmplifier(myParameters),
+ !(myParameters.InParallel && aEdgesToUpdate.Size() > 1));
+
+ IMeshData::MapOfIFacePtr aFacesToCheck(1, aTmpAlloc);
+ IMeshData::MapOfIEdgePtr::Iterator aEdgeIt(aEdgesToUpdate);
+ for (; aEdgeIt.More(); aEdgeIt.Next())
+ {
+ const IMeshData::IEdgeHandle& aDEdge = aEdgeIt.Value().lock();
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt)
+ {
+ aFacesToCheck.Add(aDEdge->GetPCurve(aPCurveIt)->GetFace());
+ }
+ }
+
+ OSD_Parallel::ForEach(aFacesToCheck.cbegin(), aFacesToCheck.cend(),
+ *this, !(myParameters.InParallel && aFacesToCheck.Size() > 1));
+
+ aEdgesToUpdate.Clear();
+ aTmpAlloc->Reset(Standard_False);
+ }
+}
+
+//=======================================================================
+// Function: popEdgesToUpdate
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate(
+ IMeshData::MapOfIEdgePtr& theEdgesToUpdate)
+{
+ IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges);
+ for (; aFaceIt.More(); aFaceIt.Next())
+ {
+ Handle(IMeshData::MapOfIEdgePtr)& aIntersections = aFaceIt.ChangeValue();
+ if (!aIntersections.IsNull())
+ {
+ theEdgesToUpdate.Unite(*aIntersections);
+ aIntersections.Nullify();
+ }
+ }
+
+ return !theEdgesToUpdate.IsEmpty();
+}
+
+//=======================================================================
+// Function: process
+// Purpose :
+//=======================================================================
+void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
+{
+ Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace);
+ aIntersections.Nullify();
+
+ fixFaceBoundaries(theDFace);
+
+ if (!theDFace->IsSet(IMeshData_Failure))
+ {
+ BRepMesh_FaceChecker aChecker(theDFace, myParameters);
+ if (!aChecker.Perform())
+ {
+#ifdef DEBUG_HEALER
+ std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
+#endif
+ aIntersections = aChecker.GetIntersectingEdges();
+ }
+ }
+}
+
+//=======================================================================
+// Function: fixFaceBoundaries
+// Purpose :
+//=======================================================================
+void BRepMesh_ModelHealer::fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const
+{
+#ifdef DEBUG_HEALER
+ TopoDS_Compound aComp;
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound(aComp);
+#endif
+
+ for (int aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
+ {
+ const IMeshData::IWireHandle& aDWire = theDFace->GetWire(aWireIt);
+ BRepMesh_Deflection::ComputeDeflection(aDWire, myParameters);
+ for (int aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt)
+ {
+ const int aPrevEdgeIt = (aEdgeIt + aDWire->EdgesNb() - 1) % aDWire->EdgesNb();
+ const int aNextEdgeIt = (aEdgeIt + 1) % aDWire->EdgesNb();
+
+ const IMeshData::IEdgeHandle& aPrevEdge = aDWire->GetEdge(aPrevEdgeIt).lock();
+ const IMeshData::IEdgeHandle& aCurrEdge = aDWire->GetEdge(aEdgeIt).lock();
+ const IMeshData::IEdgeHandle& aNextEdge = aDWire->GetEdge(aNextEdgeIt).lock();
+
+ Standard_Boolean isConnected = !getCommonVertex(aCurrEdge, aNextEdge).IsNull() &&
+ !getCommonVertex(aPrevEdge, aCurrEdge).IsNull();
+
+ if (isConnected)
+ {
+ const IMeshData::IPCurveHandle& aPrevPCurve =
+ aPrevEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aPrevEdgeIt));
+
+ const IMeshData::IPCurveHandle& aCurrPCurve =
+ aCurrEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aEdgeIt));
+
+ const IMeshData::IPCurveHandle& aNextPCurve =
+ aNextEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aNextEdgeIt));
+
+ isConnected = connectClosestPoints(aPrevPCurve, aCurrPCurve, aNextPCurve);
+
+#ifdef DEBUG_HEALER
+ BRepBuilderAPI_MakePolygon aPoly;
+ for (int i = 0; i < aCurrPCurve->ParametersNb(); ++i)
+ {
+ const gp_Pnt2d& aPnt = aCurrPCurve->GetPoint(i);
+ aPoly.Add(gp_Pnt(aPnt.X(), aPnt.Y(), 0.));
+ }
+
+ if (aPoly.IsDone())
+ {
+ aBuilder.Add(aComp, aPoly.Shape());
+ }
+ TCollection_AsciiString aName("face_discr.brep");
+ BRepTools::Write(aComp, aName.ToCString());
+#endif
+ }
+
+ if (!isConnected || aCurrEdge->IsSet(IMeshData_Outdated))
+ {
+ // We have to clean face from triangulation.
+ theDFace->SetStatus(IMeshData_Outdated);
+
+ if (!isConnected)
+ {
+ // Just mark wire as open, but continue fixing other inconsistencies
+ // in hope that this data could be suitable to build mesh somehow.
+ aDWire->SetStatus(IMeshData_OpenWire);
+ }
+ }
+ }
+ }
+
+#ifdef DEBUG_HEALER
+ TCollection_AsciiString aName ("face_discr.brep");
+ TCollection_AsciiString aFaceName("face_geom.brep");
+ BRepTools::Write(aComp, aName.ToCString());
+ BRepTools::Write(theDFace->GetFace(), aFaceName.ToCString());
+#endif
+
+ BRepMesh_Deflection::ComputeDeflection(theDFace, myParameters);
+}
+
+//=======================================================================
+// Function: hasCommonVertex
+// Purpose :
+//=======================================================================
+TopoDS_Vertex BRepMesh_ModelHealer::getCommonVertex(
+ const IMeshData::IEdgeHandle& theEdge1,
+ const IMeshData::IEdgeHandle& theEdge2) const
+{
+ TopoDS_Vertex aVertex1_1, aVertex1_2;
+ TopExp::Vertices(theEdge1->GetEdge(), aVertex1_1, aVertex1_2);
+ if (theEdge1->GetEdge().IsSame(theEdge2->GetEdge()))
+ {
+ return aVertex1_1.IsSame(aVertex1_2) ? aVertex1_1 : TopoDS_Vertex();
+ }
+
+ TopoDS_Vertex aVertex2_1, aVertex2_2;
+ TopExp::Vertices(theEdge2->GetEdge(), aVertex2_1, aVertex2_2);
+
+ if (isSameWithSomeOf(aVertex1_1, aVertex2_1, aVertex2_2))
+ {
+ return aVertex1_1;
+ }
+ else if (isSameWithSomeOf(aVertex1_2, aVertex2_1, aVertex2_2))
+ {
+ return aVertex1_2;
+ }
+
+ const gp_Pnt aPnt1_1 = BRep_Tool::Pnt(aVertex1_1);
+ const gp_Pnt aPnt1_2 = BRep_Tool::Pnt(aVertex1_2);
+ const Standard_Real aTol1_1 = BRep_Tool::Tolerance(aVertex1_1);
+ const Standard_Real aTol1_2 = BRep_Tool::Tolerance(aVertex1_2);
+
+ const gp_Pnt aPnt2_1 = BRep_Tool::Pnt(aVertex2_1);
+ const gp_Pnt aPnt2_2 = BRep_Tool::Pnt(aVertex2_2);
+ const Standard_Real aTol2_1 = BRep_Tool::Tolerance(aVertex2_1);
+ const Standard_Real aTol2_2 = BRep_Tool::Tolerance(aVertex2_2);
+
+ if (isInToleranceWithSomeOf(aPnt1_1, aPnt2_1, aPnt2_2, aTol1_1 + Max(aTol2_1, aTol2_2)))
+ {
+ return aVertex1_1;
+ }
+ else if (isInToleranceWithSomeOf(aPnt1_2, aPnt2_1, aPnt2_2, aTol1_2 + Max(aTol2_1, aTol2_2)))
+ {
+ return aVertex1_2;
+ }
+
+ return TopoDS_Vertex();
+}
+
+//=======================================================================
+// Function: connectClosestPoints
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ModelHealer::connectClosestPoints(
+ const IMeshData::IPCurveHandle& thePrevDEdge,
+ const IMeshData::IPCurveHandle& theCurrDEdge,
+ const IMeshData::IPCurveHandle& theNextDEdge) const
+{
+ if (thePrevDEdge->IsInternal() ||
+ theCurrDEdge->IsInternal() ||
+ theNextDEdge->IsInternal())
+ {
+ return Standard_True;
+ }
+
+ gp_Pnt2d& aPrevFirstUV = thePrevDEdge->GetPoint(0);
+ gp_Pnt2d& aPrevLastUV = thePrevDEdge->GetPoint(thePrevDEdge->ParametersNb() - 1);
+
+ if (thePrevDEdge == theCurrDEdge)
+ {
+ // Wire consists of a single edge.
+ aPrevFirstUV = aPrevLastUV;
+ return Standard_True;
+ }
+
+ gp_Pnt2d& aCurrFirstUV = theCurrDEdge->GetPoint(0);
+ gp_Pnt2d& aCurrLastUV = theCurrDEdge->GetPoint(theCurrDEdge->ParametersNb() - 1);
+
+ gp_Pnt2d *aPrevUV = NULL, *aCurrPrevUV = NULL;
+ const Standard_Real aPrevSqDist = closestPoints(aPrevFirstUV, aPrevLastUV,
+ aCurrFirstUV, aCurrLastUV,
+ aPrevUV, aCurrPrevUV);
+
+ gp_Pnt2d *aNextUV = NULL, *aCurrNextUV = NULL;
+ if (thePrevDEdge == theNextDEdge)
+ {
+ // Wire consists of two edges. Connect both ends.
+ aNextUV = (aPrevUV == &aPrevFirstUV) ? &aPrevLastUV : &aPrevFirstUV;
+ aCurrNextUV = (aCurrPrevUV == &aCurrFirstUV) ? &aCurrLastUV : &aCurrFirstUV;
+
+ *aNextUV = *aCurrNextUV;
+ *aPrevUV = *aCurrPrevUV;
+ return Standard_True;
+ }
+
+ gp_Pnt2d& aNextFirstUV = theNextDEdge->GetPoint(0);
+ gp_Pnt2d& aNextLastUV = theNextDEdge->GetPoint(theNextDEdge->ParametersNb() - 1);
+
+ const Standard_Real aNextSqDist = closestPoints(aNextFirstUV, aNextLastUV,
+ aCurrFirstUV, aCurrLastUV,
+ aNextUV, aCurrNextUV);
+
+#ifdef DEBUG_HEALER
+ std::cout << "PrevSqDist = " << aPrevSqDist << std::endl;
+ std::cout << "NextSqDist = " << aNextSqDist << std::endl;
+#endif
+
+ // Connect closest points first. This can help to identify
+ // which ends should be connected in case of gap.
+ if (aPrevSqDist - aNextSqDist > gp::Resolution())
+ {
+ adjustSamePoints(aCurrNextUV, aNextUV, aCurrPrevUV, aPrevUV, aCurrFirstUV, aCurrLastUV, aPrevFirstUV, aPrevLastUV);
+ }
+ else
+ {
+ adjustSamePoints(aCurrPrevUV, aPrevUV, aCurrNextUV, aNextUV, aCurrFirstUV, aCurrLastUV, aNextFirstUV, aNextLastUV);
+ }
+
+ return Standard_True;
+}
--- /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\92s shape and tries to
+//! amplify discrete represenation by decreasing of deflection for the target edge.
+//! Checks can be performed in parallel mode.
+class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_ModelHealer();
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_ModelHealer();
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ //! Functor API to discretize the given edge.
+ inline void operator() (const Standard_Integer theEdgeIndex) const {
+ process(theEdgeIndex);
+ }
+
+ //! Functor API to discretize the given edge.
+ inline void operator() (const IMeshData::IFacePtr& theDFace) const {
+ process(theDFace.lock());
+ }
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
+
+private:
+
+ //! Checks existing discretization of the face and updates data model.
+ inline void process(const Standard_Integer theFaceIndex) const
+ {
+ const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+ process(aDFace);
+ }
+
+ //! Checks existing discretization of the face and updates data model.
+ void process(const IMeshData::IFaceHandle& theDFace) const;
+
+ //! Amplifies discretization of edges in case if self-intersection problem has been found.
+ void amplifyEdges();
+
+ //! Returns common vertex of two edges or null ptr in case if there is no such vertex.
+ TopoDS_Vertex getCommonVertex(
+ const IMeshData::IEdgeHandle& theEdge1,
+ const IMeshData::IEdgeHandle& theEdge2) const;
+
+ //! Connects pcurves of previous and current edge on the specified face
+ //! according to topological connectivity. Uses next edge in order to
+ //! identify closest point in case of signle vertex shared between both
+ //! ends of edge (degenerative edge)
+ Standard_Boolean connectClosestPoints(
+ const IMeshData::IPCurveHandle& thePrevDEdge,
+ const IMeshData::IPCurveHandle& theCurrDEdge,
+ const IMeshData::IPCurveHandle& theNextDEdge) const;
+
+ //! Chooses the most closest point to reference one from the given pair.
+ //! Returns square distance between reference point and closest one as
+ //! well as pointer to closest point.
+ inline Standard_Real closestPoint(
+ gp_Pnt2d& theRefPnt,
+ gp_Pnt2d& theFristPnt,
+ gp_Pnt2d& theSecondPnt,
+ gp_Pnt2d*& theClosestPnt) const
+ {
+ // Find the most closest end-points.
+ const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt);
+ const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt);
+ if (aSqDist1 < aSqDist2)
+ {
+ theClosestPnt = &theFristPnt;
+ return aSqDist1;
+ }
+
+ theClosestPnt = &theSecondPnt;
+ return aSqDist2;
+ }
+
+ //! Chooses the most closest points among the given to reference one from the given pair.
+ //! Returns square distance between reference point and closest one as
+ //! well as pointer to closest point.
+ inline Standard_Real closestPoints(
+ gp_Pnt2d& theFirstPnt1,
+ gp_Pnt2d& theSecondPnt1,
+ gp_Pnt2d& theFirstPnt2,
+ gp_Pnt2d& theSecondPnt2,
+ gp_Pnt2d*& theClosestPnt1,
+ gp_Pnt2d*& theClosestPnt2) const
+ {
+ gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL;
+ const Standard_Real aSqDist1 = closestPoint(theFirstPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV1);
+ const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2);
+ if (aSqDist1 - aSqDist2 < gp::Resolution())
+ {
+ theClosestPnt1 = &theFirstPnt1;
+ theClosestPnt2 = aCurrPrevUV1;
+ return aSqDist1;
+ }
+
+ theClosestPnt1 = &theSecondPnt1;
+ theClosestPnt2 = aCurrPrevUV2;
+ return aSqDist2;
+ }
+
+ //! Adjusts the given pair of points supposed to be the same.
+ //! In addition, adjusts another end-point of an edge in order
+ //! to perform correct matching in case of gap.
+ inline void adjustSamePoints(
+ gp_Pnt2d*& theMajorSamePnt1,
+ gp_Pnt2d*& theMinorSamePnt1,
+ gp_Pnt2d*& theMajorSamePnt2,
+ gp_Pnt2d*& theMinorSamePnt2,
+ gp_Pnt2d& theMajorFirstPnt,
+ gp_Pnt2d& theMajorLastPnt,
+ gp_Pnt2d& theMinorFirstPnt,
+ gp_Pnt2d& theMinorLastPnt) const
+ {
+ if (theMajorSamePnt2 == theMajorSamePnt1)
+ {
+ theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt;
+ closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2);
+ }
+
+ *theMajorSamePnt1 = *theMinorSamePnt1;
+ *theMajorSamePnt2 = *theMinorSamePnt2;
+ }
+
+ //! Connects ends of pcurves of face's wires according to topological coherency.
+ void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const;
+
+ //! Returns True if check can be done in parallel.
+ inline Standard_Boolean isParallel() const
+ {
+ return (myParameters.InParallel && myModel->FacesNb() > 1);
+ }
+
+ //! Collects unique edges to be updated from face map. Clears data stored in face map.
+ Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate);
+
+private:
+
+ Handle(IMeshData_Model) myModel;
+ IMeshTools_Parameters myParameters;
+ Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs) myFaceIntersectingEdges;
+};
+
+#endif
\ No newline at end of file
--- /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->IsFree())
+ {
+ if (!aDEdge->IsSet(IMeshData_Reused))
+ {
+ commitPolygon3D(aDEdge);
+ }
+ }
+ else
+ {
+ commitPolygons(aDEdge);
+ }
+ }
+
+ private:
+
+ //! Commits 3d polygon to topological edge
+ void commitPolygon3D(const IMeshData::IEdgeHandle& theDEdge) const
+ {
+ const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve();
+
+ TColgp_Array1OfPnt aNodes (1, aCurve->ParametersNb());
+ TColStd_Array1OfReal aUVNodes(1, aCurve->ParametersNb());
+ for (Standard_Integer i = 1; i <= aCurve->ParametersNb(); ++i)
+ {
+ aNodes (i) = aCurve->GetPoint (i - 1);
+ aUVNodes(i) = aCurve->GetParameter(i - 1);
+ }
+
+ Handle(Poly_Polygon3D) aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes);
+ aPoly3D->Deflection(theDEdge->GetDeflection());
+
+ BRepMesh_ShapeTool::UpdateEdge(theDEdge->GetEdge(), aPoly3D);
+ }
+
+ //! Commits all polygons on triangulations correspondent to the given edge.
+ void commitPolygons(const IMeshData::IEdgeHandle& theDEdge) const
+ {
+ // Collect pcurves associated with the given edge on the specific surface.
+ IMeshData::IDMapOfIFacePtrsListOfIPCurves aMapOfPCurves;
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt)
+ {
+ const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt);
+ const IMeshData::IFacePtr& aDFacePtr = aPCurve->GetFace();
+ const IMeshData::IFaceHandle& aDFace = aDFacePtr.lock();
+ if (aDFace->IsSet(IMeshData_Failure) ||
+ aDFace->IsSet(IMeshData_Reused))
+ {
+ continue;
+ }
+
+ if (!aMapOfPCurves.Contains(aDFacePtr))
+ {
+ aMapOfPCurves.Add(aDFacePtr, IMeshData::ListOfIPCurves());
+ }
+
+ IMeshData::ListOfIPCurves& aPCurves = aMapOfPCurves.ChangeFromKey(aDFacePtr);
+ aPCurves.Append(aPCurve);
+ }
+
+ // Commit polygons related to separate face.
+ const TopoDS_Edge& aEdge = theDEdge->GetEdge();
+ IMeshData::IDMapOfIFacePtrsListOfIPCurves::Iterator aPolygonIt(aMapOfPCurves);
+ for (; aPolygonIt.More(); aPolygonIt.Next())
+ {
+ const TopoDS_Face& aFace = aPolygonIt.Key().lock()->GetFace();
+
+ TopLoc_Location aLoc;
+ const Handle(Poly_Triangulation)& aTriangulation =
+ BRep_Tool::Triangulation(aFace, aLoc);
+
+ if (!aTriangulation.IsNull())
+ {
+ const IMeshData::ListOfIPCurves& aPCurves = aPolygonIt.Value();
+ if (aPCurves.Size() == 2)
+ {
+ BRepMesh_ShapeTool::UpdateEdge(
+ aEdge,
+ collectPolygon(aPCurves.First(), theDEdge->GetDeflection()),
+ collectPolygon(aPCurves.Last (), theDEdge->GetDeflection()),
+ aTriangulation, aLoc);
+ }
+ else
+ {
+ BRepMesh_ShapeTool::UpdateEdge(
+ aEdge,
+ collectPolygon(aPCurves.First(), theDEdge->GetDeflection()),
+ aTriangulation, aLoc);
+ }
+ }
+ }
+ }
+
+ //! Collects polygonal data for the given pcurve
+ Handle(Poly_PolygonOnTriangulation) collectPolygon(
+ const IMeshData::IPCurveHandle& thePCurve,
+ const Standard_Real theDeflection) const
+ {
+ TColStd_Array1OfInteger aNodes (1, thePCurve->ParametersNb());
+ TColStd_Array1OfReal aParams(1, thePCurve->ParametersNb());
+ for (Standard_Integer i = 1; i <= thePCurve->ParametersNb(); ++i)
+ {
+ aNodes (i) = thePCurve->GetIndex (i - 1);
+ aParams(i) = thePCurve->GetParameter(i - 1);
+ }
+
+ Handle(Poly_PolygonOnTriangulation) aPolygon =
+ new Poly_PolygonOnTriangulation(aNodes, aParams);
+
+ aPolygon->Deflection(theDeflection);
+ return aPolygon;
+ }
+
+ private:
+
+ Handle(IMeshData_Model) myModel;
+ };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelPostProcessor::BRepMesh_ModelPostProcessor()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ModelPostProcessor::Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& /*theParameters*/)
+{
+ if (theModel.IsNull())
+ {
+ return Standard_False;
+ }
+
+ // TODO: Force single threaded solution due to data races on edges sharing the same TShape
+ OSD_Parallel::For(0, theModel->EdgesNb(), PolygonCommitter(theModel), Standard_True/*!theParameters.InParallel*/);
+ return Standard_True;
+}
--- /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();
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
+};
+
+#endif
--- /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>
+
+namespace
+{
+ //! Checks consistency of triangulation stored in topological face.
+ class TriangulationConsistency
+ {
+ public:
+ //! Constructor
+ TriangulationConsistency(const Handle(IMeshData_Model)& theModel)
+ : myModel (theModel)
+ {
+ }
+
+ //! Main functor.
+ void operator()(const Standard_Integer theFaceIndex) const
+ {
+ const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex);
+ if (aDFace->IsSet(IMeshData_Outdated))
+ {
+ return;
+ }
+
+ TopLoc_Location aLoc;
+ const Handle(Poly_Triangulation)& aTriangulation =
+ BRep_Tool::Triangulation(aDFace->GetFace(), aLoc);
+
+ if (!aTriangulation.IsNull())
+ {
+ Standard_Boolean isTriangulationConsistent = Standard_False;
+ if (aTriangulation->Deflection() < 1.1 * aDFace->GetDeflection())
+ {
+ // #25080: check that indices of links forming triangles are in range.
+ const Standard_Integer aNodesNb = aTriangulation->NbNodes();
+ const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
+
+ Standard_Integer i = aTriangles.Lower();
+ for (; i <= aTriangles.Upper() && isTriangulationConsistent; ++i)
+ {
+ const Poly_Triangle& aTriangle = aTriangles(i);
+
+ Standard_Integer aNode[3];
+ aTriangle.Get(aNode[0], aNode[1], aNode[2]);
+ for (Standard_Integer j = 0; j < 3 && isTriangulationConsistent; ++j)
+ {
+ isTriangulationConsistent = (aNode[j] >= 1 && aNode[j] <= aNodesNb);
+ }
+ }
+ }
+
+ if (isTriangulationConsistent)
+ {
+ aDFace->SetStatus(IMeshData_Reused);
+ aDFace->SetDeflection(aTriangulation->Deflection());
+ }
+ else
+ {
+ aDFace->SetStatus(IMeshData_Outdated);
+ }
+ }
+ }
+
+ private:
+
+ Handle(IMeshData_Model) myModel;
+ };
+}
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelPreProcessor::BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
+{
+}
+
+//=======================================================================
+// Function: Perform
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ModelPreProcessor::Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters)
+{
+ if (theModel.IsNull())
+ {
+ return Standard_False;
+ }
+
+ OSD_Parallel::For(0, theModel->FacesNb(), TriangulationConsistency(theModel), !theParameters.InParallel);
+
+ // Clean edges and faces from outdated polygons.
+ Handle(NCollection_IncAllocator) aTmpAlloc(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));
+ NCollection_Map<IMeshData_Face*> aUsedFaces(1, aTmpAlloc);
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < theModel->EdgesNb(); ++aEdgeIt)
+ {
+ const IMeshData::IEdgeHandle& aDEdge = theModel->GetEdge(aEdgeIt);
+ if (aDEdge->IsFree())
+ {
+ if (aDEdge->IsSet(IMeshData_Outdated))
+ {
+ TopLoc_Location aLoc;
+ BRep_Tool::Polygon3D(aDEdge->GetEdge(), aLoc);
+ BRepMesh_ShapeTool::NullifyEdge(aDEdge->GetEdge(), aLoc);
+ }
+
+ continue;
+ }
+
+ for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt)
+ {
+ // Find adjacent outdated face.
+ const IMeshData::IFaceHandle& aDFace = aDEdge->GetPCurve(aPCurveIt)->GetFace().lock();
+ if (!aUsedFaces.Contains(aDFace.get()))
+ {
+ aUsedFaces.Add(aDFace.get());
+ if (aDFace->IsSet(IMeshData_Outdated))
+ {
+ TopLoc_Location aLoc;
+ const Handle(Poly_Triangulation)& aTriangulation =
+ BRep_Tool::Triangulation(aDFace->GetFace(), aLoc);
+
+ // Clean all edges of oudated face.
+ for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+ {
+ const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
+ for (Standard_Integer aWireEdgeIt = 0; aWireEdgeIt < aDWire->EdgesNb(); ++aWireEdgeIt)
+ {
+ const IMeshData::IEdgeHandle& aTmpDEdge = aDWire->GetEdge(aWireEdgeIt).lock();
+ BRepMesh_ShapeTool::NullifyEdge(aTmpDEdge->GetEdge(), aTriangulation, aLoc);
+ }
+ }
+
+ BRepMesh_ShapeTool::NullifyFace(aDFace->GetFace());
+ }
+ }
+ }
+ }
+
+ return Standard_True;
+}
+
--- /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();
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform(
+ const Handle(IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
+};
+
+#endif
--- /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 <GeomAdaptor_Curve.hxx>
+#include <IMeshTools_Parameters.hxx>
+#include <GeomAbs_IsoType.hxx>
+#include <BRepMesh_GeomTool.hxx>
+#include <NCollection_Handle.hxx>
+#include <algorithm>
+
+namespace
+{
+ class AnalyticalFilter
+ {
+ public:
+ //! Constructor.
+ AnalyticalFilter(
+ const IMeshData::IFaceHandle& theDFace,
+ const GeomAbs_IsoType theIsoType,
+ const Handle(IMeshData::SequenceOfReal)& theParams,
+ const Handle(IMeshData::SequenceOfReal)& theControlParams,
+ const Handle(IMeshData::MapOfReal)& theParamsForbiddenToRemove,
+ const Handle(IMeshData::MapOfReal)& theControlParamsForbiddenToRemove)
+ : myDFace(theDFace),
+ mySurface(myDFace->GetSurface()->ChangeSurface().Surface().Surface()),
+ myIsoU(theIsoType == GeomAbs_IsoU),
+ myParams(theParams),
+ myControlParams(theControlParams),
+ myParamsForbiddenToRemove(theParamsForbiddenToRemove),
+ myControlParamsForbiddenToRemove(theControlParamsForbiddenToRemove),
+ myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+ myControlParamsToRemove(new IMeshData::MapOfReal(1, myAllocator))
+ {
+ }
+
+ //! Returns map of parameters supposed to be removed.
+ const Handle(IMeshData::MapOfReal)& GetControlParametersToRemove(
+ const IMeshTools_Parameters& theParameters)
+ {
+ myParameters = theParameters;
+
+ Standard_Integer aStartIndex, aEndIndex;
+ if (myIsoU)
+ {
+ aStartIndex = 1;
+ aEndIndex = myParams->Length();
+ }
+ else
+ {
+ aStartIndex = 2;
+ aEndIndex = myParams->Length() - 1;
+ }
+
+ for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i)
+ {
+ myCurrParam = myParams->Value(i);
+ myIso = new GeomAdaptor_Curve(myIsoU ? mySurface->UIso(myCurrParam) : mySurface->VIso(myCurrParam));
+
+ myPrevControlParam = myControlParams->Value(1);
+ myIso->D1(myPrevControlParam, myPrevControlPnt, myPrevControlVec);
+ for (Standard_Integer j = 2; j <= myControlParams->Length();)
+ {
+ j += checkControlPointAndMoveOn(j);
+ }
+ }
+
+ return myControlParamsToRemove;
+ }
+
+ private:
+
+ //! Checks the given control point for deviation.
+ //! Returns number of steps to be used to move point iterator.
+ Standard_Integer checkControlPointAndMoveOn(const Standard_Integer theIndex)
+ {
+ Standard_Integer aMoveSteps = 0;
+ myCurrControlParam = myControlParams->Value(theIndex);
+ myIso->D1(myCurrControlParam, myCurrControlPnt, myCurrControlVec);
+
+ const Standard_Real aMidParam = 0.5 * (myPrevControlParam + myCurrControlParam);
+ const gp_Pnt aMidPnt = myIso->Value(aMidParam);
+
+ const Standard_Real aSqDist = BRepMesh_GeomTool::SquareDeflectionOfSegment(
+ myPrevControlPnt, myCurrControlPnt, aMidPnt);
+
+ const Standard_Real aSqMaxDeflection = myDFace->GetDeflection() * myDFace->GetDeflection();
+ if (aSqDist > aSqMaxDeflection &&
+ aSqDist > myParameters.MinSize * myParameters.MinSize)
+ {
+ // insertion
+ myControlParams->InsertBefore(theIndex, aMidParam);
+ }
+ else
+ {
+ // Here we should leave at least 3 parameters as far as
+ // we must have at least one parameter related to surface
+ // internals in order to prevent movement of triangle body
+ // outside the surface in case of highly curved ones, e.g.
+ // BSpline springs.
+ if (aSqDist < aSqMaxDeflection &&
+ myControlParams->Length() > 3 &&
+ theIndex < myControlParams->Length())
+ {
+ // Remove too dense points
+ const Standard_Real aTmpParam = myControlParams->Value(theIndex + 1);
+ if (checkParameterForDeflectionAndUpdateCache(aTmpParam))
+ {
+ ++aMoveSteps;
+ }
+ }
+
+ myPrevControlParam = myCurrControlParam;
+ myPrevControlPnt = myCurrControlPnt;
+ myPrevControlVec = myCurrControlVec;
+
+ ++aMoveSteps;
+ }
+
+ return aMoveSteps;
+ }
+
+ //! Checks whether the given param suits specified deflection. Updates cache.
+ Standard_Boolean checkParameterForDeflectionAndUpdateCache(const Standard_Real theParam)
+ {
+ gp_Pnt aTmpPnt;
+ gp_Vec aTmpVec;
+ myIso->D1(theParam, aTmpPnt, aTmpVec);
+
+ const Standard_Real aTmpMidParam = 0.5 * (myPrevControlParam + theParam);
+ const gp_Pnt aTmpMidPnt = myIso->Value(aTmpMidParam);
+
+ // Lets check next parameter.
+ // If it also fits deflection, we can remove previous parameter.
+ const Standard_Real aSqDist = BRepMesh_GeomTool::SquareDeflectionOfSegment(
+ myPrevControlPnt, aTmpPnt, aTmpMidPnt);
+
+ if (aSqDist < myDFace->GetDeflection() * myDFace->GetDeflection())
+ {
+ // Lets check parameters for angular deflection.
+ if (myPrevControlVec.SquareMagnitude() < gp::Resolution() ||
+ aTmpVec.SquareMagnitude() < gp::Resolution() ||
+ myPrevControlVec.Angle(aTmpVec) < myParameters.Angle)
+ {
+ // For current Iso line we can remove this parameter.
+ myControlParamsToRemove->Add(myCurrControlParam);
+ myCurrControlParam = theParam;
+ myCurrControlPnt = aTmpPnt;
+ myCurrControlVec = aTmpVec;
+ return Standard_True;
+ }
+ else
+ {
+ // We have found a place on the surface refusing
+ // removement of this parameter.
+ myParamsForbiddenToRemove ->Add(myCurrParam);
+ myControlParamsForbiddenToRemove->Add(myCurrControlParam);
+ }
+ }
+
+ return Standard_False;
+ }
+
+ private:
+
+ IMeshData::IFaceHandle myDFace;
+ Handle(Geom_Surface) mySurface;
+ Standard_Boolean myIsoU;
+ Handle(IMeshData::SequenceOfReal) myParams;
+ Handle(IMeshData::SequenceOfReal) myControlParams;
+
+ Handle(IMeshData::MapOfReal) myParamsForbiddenToRemove;
+ Handle(IMeshData::MapOfReal) myControlParamsForbiddenToRemove;
+
+ Handle(NCollection_IncAllocator) myAllocator;
+ Handle(IMeshData::MapOfReal) myControlParamsToRemove;
+
+
+ IMeshTools_Parameters myParameters;
+ NCollection_Handle<GeomAdaptor_Curve> myIso;
+
+ Standard_Real myCurrParam;
+
+ Standard_Real myCurrControlParam;
+ gp_Pnt myCurrControlPnt;
+ gp_Vec myCurrControlVec;
+
+ Standard_Real myPrevControlParam;
+ gp_Pnt myPrevControlPnt;
+ gp_Vec myPrevControlVec;
+ };
+
+ //! Adds param to map if it fits specified range.
+ inline void addParam(
+ const Standard_Real& theParam,
+ const std::pair<Standard_Real, Standard_Real>& theRange,
+ IMeshData::IMapOfReal& theParams)
+ {
+ if (theParam < theRange.first ||
+ theParam > theRange.second)
+ {
+ return;
+ }
+
+ theParams.Add(theParam);
+ }
+
+ //! Initializes parameters map using CN intervals.
+ inline void initParamsFromIntervals(
+ const TColStd_Array1OfReal& theIntervals,
+ const std::pair<Standard_Real, Standard_Real>& theRange,
+ const Standard_Boolean isSplitIntervals,
+ IMeshData::IMapOfReal& theParams)
+ {
+ for (Standard_Integer i = theIntervals.Lower(); i <= theIntervals.Upper(); ++i)
+ {
+ const Standard_Real& aStartParam = theIntervals.Value(i);
+ addParam(aStartParam, theRange, theParams);
+
+ if (isSplitIntervals && i < theIntervals.Upper())
+ {
+ const Standard_Real aMidParam = (aStartParam + theIntervals.Value(i + 1)) / 2.;
+ addParam(aMidParam, theRange, theParams);
+ }
+ }
+ }
+}
+
+//=======================================================================
+// Function: AdjustRange
+// Purpose :
+//=======================================================================
+void BRepMesh_NURBSRangeSplitter::AdjustRange()
+{
+ BRepMesh_DefaultRangeSplitter::AdjustRange();
+ mySurfaceType = GetSurface()->GetType();
+
+ if (mySurfaceType == GeomAbs_BezierSurface ||
+ mySurfaceType == GeomAbs_BSplineSurface)
+ {
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+ if (mySurfaceType == GeomAbs_BezierSurface)
+ {
+ myIsValid = !(aRangeU.first < -0.5 ||
+ aRangeU.second > 1.5 ||
+ aRangeV.first < -0.5 ||
+ aRangeV.second > 1.5);
+
+ if (!myIsValid)
+ {
+ return;
+ }
+ }
+ }
+}
+
+//=======================================================================
+// Function: GenerateSurfaceNodes
+// Purpose :
+//=======================================================================
+Handle(IMeshData::ListOfPnt2d) BRepMesh_NURBSRangeSplitter::GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const
+{
+ initParameters();
+
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+ const std::pair<Standard_Real, Standard_Real>& aDelta = GetDelta ();
+
+ const Standard_Real aDefFace = GetDFace()->GetDeflection();
+ const Handle(BRepAdaptor_HSurface)& gFace = GetSurface();
+ Handle(Geom_Surface) aSurface = gFace->ChangeSurface().Surface().Surface();
+
+ const Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ const Handle(IMeshData::SequenceOfReal) aParams[2] = {
+ computeGrainAndFilterParameters(GetParametersU(), gFace->UResolution(aDefFace),
+ (aRangeU.second - aRangeU.first), aDelta.first, theParameters, aTmpAlloc),
+
+ computeGrainAndFilterParameters(GetParametersV(), gFace->VResolution(aDefFace),
+ (aRangeV.second - aRangeV.first), aDelta.second, theParameters, aTmpAlloc)
+ };
+
+ // check intermediate isolines
+ Handle(IMeshData::MapOfReal) aFixedParams[2] = {
+ new IMeshData::MapOfReal(1, aTmpAlloc),
+ new IMeshData::MapOfReal(1, aTmpAlloc)
+ };
+
+ const Handle(IMeshData::MapOfReal) aParamsToRemove[2] = {
+ AnalyticalFilter(GetDFace(), GeomAbs_IsoV, aParams[1], aParams[0],
+ aFixedParams[1], aFixedParams[0]).GetControlParametersToRemove(theParameters),
+
+ AnalyticalFilter(GetDFace(), GeomAbs_IsoU, aParams[0], aParams[1],
+ aFixedParams[0], aFixedParams[1]).GetControlParametersToRemove(theParameters),
+ };
+
+ aParamsToRemove[0]->Subtract(*aFixedParams[0]);
+ aParamsToRemove[1]->Subtract(*aFixedParams[1]);
+
+ // insert nodes of the regular grid
+ Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));
+
+ // insert nodes of the regular grid
+ for (Standard_Integer i = 1; i <= aParams[0]->Length(); ++i)
+ {
+ const Standard_Real aParam1 = aParams[0]->Value(i);
+ if (aParamsToRemove[0]->Contains(aParam1))
+ {
+ continue;
+ }
+
+ for (Standard_Integer j = 1; j <= aParams[1]->Length(); ++j)
+ {
+ const Standard_Real aParam2 = aParams[1]->Value(j);
+ if (aParamsToRemove[1]->Contains(aParam2))
+ {
+ continue;
+ }
+
+ aNodes->Append(gp_Pnt2d(aParam1, aParam2));
+ }
+ }
+
+ return aNodes;
+}
+
+//=======================================================================
+// Function: initParameters
+// Purpose :
+//=======================================================================
+void BRepMesh_NURBSRangeSplitter::initParameters() const
+{
+ const Handle(BRepAdaptor_HSurface)& aSurface = GetSurface();
+
+ const GeomAbs_Shape aContinuity = GeomAbs_CN;
+ const std::pair<Standard_Integer, Standard_Integer> aIntervalsNb(
+ aSurface->NbUIntervals(aContinuity),
+ aSurface->NbVIntervals(aContinuity)
+ );
+
+ TColStd_Array1OfReal aIntervals[2] = {
+ TColStd_Array1OfReal(1, aIntervalsNb.first + 1),
+ TColStd_Array1OfReal(1, aIntervalsNb.second + 1)
+ };
+
+ aSurface->UIntervals(aIntervals[0], aContinuity);
+ aSurface->VIntervals(aIntervals[1], aContinuity);
+
+ Standard_Boolean isSplitIntervals =
+ (aIntervalsNb.first > 1 || aIntervalsNb.second > 1);
+
+ if (!isSplitIntervals &&
+ (aSurface->GetType() == GeomAbs_BezierSurface ||
+ aSurface->GetType() == GeomAbs_BSplineSurface))
+ {
+ isSplitIntervals = (aSurface->NbUPoles() > 2 && aSurface->NbVPoles() > 2);
+ }
+
+ initParamsFromIntervals(aIntervals[0], GetRangeU(), isSplitIntervals,
+ const_cast<IMeshData::IMapOfReal&>(GetParametersU()));
+
+ initParamsFromIntervals(aIntervals[1], GetRangeV(), isSplitIntervals,
+ const_cast<IMeshData::IMapOfReal&>(GetParametersV()));
+}
+
+//=======================================================================
+//function : computeGrainAndFilterParameters
+//purpose :
+//=======================================================================
+Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::computeGrainAndFilterParameters(
+ const IMeshData::IMapOfReal& theSourceParams,
+ const Standard_Real theTol2d,
+ const Standard_Real theRangeDiff,
+ const Standard_Real theDelta,
+ const IMeshTools_Parameters& theParameters,
+ const Handle(NCollection_IncAllocator)& theAllocator) const
+{
+ // Sort and filter sequence of parameters
+ Standard_Real aMinDiff = Precision::PConfusion();
+ if (theDelta < 1.)
+ {
+ aMinDiff /= theDelta;
+ }
+
+ aMinDiff = Max(theParameters.MinSize, aMinDiff);
+
+ const Standard_Real aDiffMaxLim = 0.1 * theRangeDiff;
+ const Standard_Real aDiffMinLim = Max(0.005 * theRangeDiff, 2. * theTol2d);
+ const Standard_Real aDiff = Max(theParameters.MinSize, Min(aDiffMaxLim, aDiffMinLim));
+ return filterParameters(theSourceParams, aMinDiff, aDiff, theAllocator);
+}
+
+//=======================================================================
+//function : filterParameters
+//purpose :
+//=======================================================================
+Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::filterParameters(
+ const IMeshData::IMapOfReal& theParams,
+ const Standard_Real theMinDist,
+ const Standard_Real theFilterDist,
+ const Handle(NCollection_IncAllocator)& theAllocator) const
+{
+ Handle(IMeshData::SequenceOfReal) aResult = new IMeshData::SequenceOfReal(theAllocator);
+
+ // Sort sequence of parameters
+ const Standard_Integer anInitLen = theParams.Extent();
+
+ TColStd_Array1OfReal aParamArray(1, anInitLen);
+ Standard_Integer j;
+ for (j = 1; j <= anInitLen; j++)
+ aParamArray(j) = theParams(j);
+
+ std::sort(aParamArray.begin(), aParamArray.end());
+
+ // mandatory pre-filtering using the first (minimal) filter value
+ Standard_Integer aParamLength = 1;
+ for (j = 2; j <= anInitLen; j++)
+ {
+ if ((aParamArray(j) - aParamArray(aParamLength)) > theMinDist)
+ {
+ if (++aParamLength < j)
+ aParamArray(aParamLength) = aParamArray(j);
+ }
+ }
+
+ //perform filtering on series
+ Standard_Real aLastAdded, aLastCandidate;
+ Standard_Boolean isCandidateDefined = Standard_False;
+ aLastAdded = aParamArray(1);
+ aLastCandidate = aLastAdded;
+ aResult->Append(aLastAdded);
+
+ for (j = 2; j < aParamLength; j++)
+ {
+ Standard_Real aVal = aParamArray(j);
+ if (aVal - aLastAdded > theFilterDist)
+ {
+ //adds the parameter
+ if (isCandidateDefined)
+ {
+ aLastAdded = aLastCandidate;
+ isCandidateDefined = Standard_False;
+ j--;
+ }
+ else
+ {
+ aLastAdded = aVal;
+ }
+ aResult->Append(aLastAdded);
+ continue;
+ }
+
+ aLastCandidate = aVal;
+ isCandidateDefined = Standard_True;
+ }
+ aResult->Append(aParamArray(aParamLength));
+
+ return aResult;
+}
--- /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.
+ Standard_EXPORT BRepMesh_NURBSRangeSplitter()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_NURBSRangeSplitter()
+ {
+ }
+
+ //! Updates discrete range of surface according to its geometric range.
+ Standard_EXPORT virtual void AdjustRange() Standard_OVERRIDE;
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
+
+protected:
+
+ //! Initializes U and V parameters lists using CN continuity intervals.
+ Standard_EXPORT virtual void initParameters() const;
+
+private:
+
+ //! Computes parameters of filter and applies it to the source parameters.
+ Handle(IMeshData::SequenceOfReal) computeGrainAndFilterParameters(
+ const IMeshData::IMapOfReal& theSourceParams,
+ const Standard_Real theTol2d,
+ const Standard_Real theRangeDiff,
+ const Standard_Real theDelta,
+ const IMeshTools_Parameters& theParameters,
+ const Handle(NCollection_IncAllocator)& theAllocator) const;
+
+ //! Filters parameters in order to avoid too dence distribution.
+ Handle(IMeshData::SequenceOfReal) filterParameters(
+ const IMeshData::IMapOfReal& theParams,
+ const Standard_Real theMinDist,
+ const Standard_Real theFilterDist,
+ const Handle(NCollection_IncAllocator)& theAllocator) const;
+
+private:
+
+ GeomAbs_SurfaceType mySurfaceType;
+};
+
+#endif
--- /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.
+ Standard_EXPORT BRepMesh_NodeInsertionMeshAlgo()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_NodeInsertionMeshAlgo()
+ {
+ }
+
+ //! Performs processing of the given face.
+ Standard_EXPORT virtual void Perform(
+ const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& theParameters) Standard_OVERRIDE
+ {
+ myRangeSplitter.Reset(theDFace, theParameters);
+ myClassifier = new BRepMesh_Classifier;
+ BaseAlgo::Perform(theDFace, theParameters);
+ myClassifier.Nullify();
+ }
+
+protected:
+
+ typedef NCollection_Shared<NCollection_Sequence<const gp_Pnt2d*> > SequenceOfPnt2d;
+
+ //! Performs initialization of data structure using existing model data.
+ Standard_EXPORT virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
+ {
+ Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ const IMeshData::IFaceHandle& aDFace = this->getDFace();
+ NCollection_Array1<Handle(SequenceOfPnt2d)> aWires(0, aDFace->WiresNb());
+ for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+ {
+ const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt);
+ if (aDWire->IsSet(IMeshData_SelfIntersectingWire) ||
+ (aDWire->IsSet(IMeshData_OpenWire) && aWireIt != 0))
+ {
+ continue;
+ }
+
+ aWires(aWireIt) = collectWirePoints(aDWire, aTmpAlloc);
+ }
+
+ myRangeSplitter.AdjustRange();
+ if (!myRangeSplitter.IsValid())
+ {
+ aDFace->SetStatus(IMeshData_Failure);
+ return Standard_False;
+ }
+
+ const std::pair<Standard_Real, Standard_Real>& aDelta = myRangeSplitter.GetDelta();
+ const std::pair<Standard_Real, Standard_Real>& aTolUV = myRangeSplitter.GetToleranceUV();
+ const Standard_Real uCellSize = 14.0 * aTolUV.first;
+ const Standard_Real vCellSize = 14.0 * aTolUV.second;
+
+ this->getStructure()->Data()->SetCellSize (uCellSize / aDelta.first, vCellSize / aDelta.second);
+ this->getStructure()->Data()->SetTolerance(aTolUV.first / aDelta.first, aTolUV.second / aDelta.second);
+
+ for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt)
+ {
+ const Handle(SequenceOfPnt2d)& aWire = aWires(aWireIt);
+ if (!aWire.IsNull() && !aWire->IsEmpty())
+ {
+ myClassifier->RegisterWire(*aWire, aTolUV,
+ myRangeSplitter.GetRangeU(),
+ myRangeSplitter.GetRangeV());
+ }
+ }
+
+ if (this->getParameters().InternalVerticesMode)
+ {
+ insertInternalVertices();
+ }
+
+ return BaseAlgo::initDataStructure();
+ }
+
+ //! Adds the given 2d point to mesh data structure.
+ //! Returns index of node in the structure.
+ Standard_EXPORT virtual Standard_Integer addNodeToStructure(
+ const gp_Pnt2d& thePoint,
+ const Standard_Integer theLocation3d,
+ const BRepMesh_DegreeOfFreedom theMovability,
+ const Standard_Boolean isForceAdd) Standard_OVERRIDE
+ {
+ return BaseAlgo::addNodeToStructure(
+ myRangeSplitter.Scale(thePoint, Standard_True),
+ theLocation3d, theMovability, isForceAdd);
+ }
+
+ //! Returns 2d point associated to the given vertex.
+ Standard_EXPORT virtual gp_Pnt2d getNodePoint2d(
+ const BRepMesh_Vertex& theVertex) const Standard_OVERRIDE
+ {
+ return myRangeSplitter.Scale(theVertex.Coord(), Standard_False);
+ }
+
+ //! Returns range splitter.
+ const RangeSplitter& getRangeSplitter() const
+ {
+ return myRangeSplitter;
+ }
+
+ //! Returns classifier.
+ const Handle(BRepMesh_Classifier)& getClassifier() const
+ {
+ return myClassifier;
+ }
+
+private:
+
+ //! Creates collection of points representing discrete wire.
+ Handle(SequenceOfPnt2d) collectWirePoints(
+ const IMeshData::IWireHandle& theDWire,
+ const Handle(NCollection_IncAllocator)& theAllocator)
+ {
+ Handle(SequenceOfPnt2d) aWirePoints = new SequenceOfPnt2d(theAllocator);
+ for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
+ {
+ const IMeshData::IEdgeHandle& aDEdge = theDWire->GetEdge(aEdgeIt).lock();
+ const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(
+ this->getDFace(), theDWire->GetEdgeOrientation(aEdgeIt));
+
+ Standard_Integer aPointIt, aEndIndex, aInc;
+ if (aPCurve->IsForward())
+ {
+ aPointIt = 0;
+ aEndIndex = aPCurve->ParametersNb() - 1;
+ aInc = 1;
+ }
+ else
+ {
+ aPointIt = aPCurve->ParametersNb() - 1;
+ aEndIndex = 0;
+ aInc = -1;
+ }
+
+ for (; aPointIt != aEndIndex; aPointIt += aInc)
+ {
+ const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt);
+ aWirePoints->Append(&aPnt2d);
+ myRangeSplitter.AddPoint(aPnt2d);
+ }
+ }
+
+ return aWirePoints;
+ }
+
+ //! Iterates over internal vertices of a face and
+ //! creates corresponding nodes in data structure.
+ void insertInternalVertices()
+ {
+ TopExp_Explorer aExplorer(this->getDFace()->GetFace(), TopAbs_VERTEX, TopAbs_EDGE);
+ for (; aExplorer.More(); aExplorer.Next())
+ {
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aExplorer.Current());
+ if (aVertex.Orientation() != TopAbs_INTERNAL)
+ {
+ continue;
+ }
+
+ insertInternalVertex(aVertex);
+ }
+ }
+
+ //! Inserts the given vertex into mesh.
+ void insertInternalVertex(const TopoDS_Vertex& theVertex)
+ {
+ try
+ {
+ OCC_CATCH_SIGNALS
+
+ gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, this->getDFace()->GetFace());
+ // check UV values for internal vertices
+ if (myClassifier->Perform(aPnt2d) != TopAbs_IN)
+ return;
+
+ this->registerNode(BRep_Tool::Pnt(theVertex), aPnt2d,
+ BRepMesh_Fixed, Standard_False);
+ }
+ catch (Standard_Failure)
+ {
+ }
+ }
+
+private:
+
+ RangeSplitter myRangeSplitter;
+ Handle(BRepMesh_Classifier) myClassifier;
+};
+
+#endif
--- /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_ShapeExplorer.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <BRepLib.hxx>
+#include <BRep_Tool.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <Geom_Surface.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMesh_ShapeExplorer::BRepMesh_ShapeExplorer (
+ const TopoDS_Shape& theShape)
+ : IMeshTools_ShapeExplorer (theShape)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMesh_ShapeExplorer::~BRepMesh_ShapeExplorer ()
+{
+}
+
+//=======================================================================
+// Function: Accept
+// Purpose :
+//=======================================================================
+void BRepMesh_ShapeExplorer::Accept (
+ const Handle (IMeshTools_ShapeVisitor)& theVisitor)
+{
+ // Explore all edges in shape - either free or related to some face.
+ TopTools_IndexedMapOfShape aEdges;
+ TopExp::MapShapes (GetShape (), TopAbs_EDGE, aEdges);
+
+ TopTools_IndexedMapOfShape::Iterator aEdgeIt (aEdges);
+ for (; aEdgeIt.More (); aEdgeIt.Next ())
+ {
+ const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Value ());
+ if (!BRep_Tool::IsGeometric(aEdge))
+ {
+ continue;
+ }
+
+ theVisitor->Visit (aEdge);
+ }
+
+ // Explore faces
+ TopTools_ListOfShape aFaceList;
+ BRepLib::ReverseSortFaces (GetShape (), aFaceList);
+ TopTools_MapOfShape aFaceMap;
+
+ // make array of faces suitable for processing (excluding faces without surface)
+ TopLoc_Location aDummyLoc;
+ const TopLoc_Location aEmptyLoc;
+ TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList);
+ for (; aFaceIter.More (); aFaceIter.Next ())
+ {
+ TopoDS_Shape aFaceNoLoc = aFaceIter.Value ();
+ aFaceNoLoc.Location (aEmptyLoc);
+ if (!aFaceMap.Add(aFaceNoLoc))
+ {
+ continue; // already processed
+ }
+
+ TopoDS_Face aFace = TopoDS::Face (aFaceIter.Value ());
+ const Handle (Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
+ if (aSurf.IsNull())
+ {
+ continue;
+ }
+
+ // Store only forward faces in order to prevent inverse issue.
+ theVisitor->Visit (TopoDS::Face (aFace.Oriented (TopAbs_FORWARD)));
+ }
+}
--- /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_ShapeExplorer_HeaderFile
+#define _BRepMesh_ShapeExplorer_HeaderFile
+
+#include <IMeshTools_ShapeExplorer.hxx>
+#include <IMeshTools_ShapeVisitor.hxx>
+#include <TopoDS_Shape.hxx>
+
+//! Explores TopoDS_Shape for parts to be meshed - faces and free edges.
+class BRepMesh_ShapeExplorer : public IMeshTools_ShapeExplorer
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_ShapeExplorer (const TopoDS_Shape& theShape);
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_ShapeExplorer ();
+
+ //! Explores shape for edges to be disretized and faces to be meshed (edges first).
+ //! All faces passed to visitor are forced to be forward.
+ Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) Standard_OVERRIDE;
+
+ DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeExplorer, IMeshTools_ShapeExplorer)
+};
+
+#endif
\ No newline at end of file
--- /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)
+{
+ myModel->AddEdge(theEdge);
+ myDEdgeMap.Bind(theEdge, myModel->EdgesNb() - 1);
+}
+
+//=======================================================================
+// Function: Visit (face)
+// Purpose :
+//=======================================================================
+void BRepMesh_ShapeVisitor::Visit (const TopoDS_Face& theFace)
+{
+ BRepTools::Update(theFace);
+ const IMeshData::IFaceHandle& aDFace = myModel->AddFace (theFace);
+
+ // Outer wire should always be the first in the model.
+ TopoDS_Wire aOuterWire = ShapeAnalysis::OuterWire (theFace);
+ if (!addWire (aOuterWire, aDFace))
+ {
+ aDFace->SetStatus (IMeshData_Failure);
+ return;
+ }
+
+ TopExp_Explorer aWireIt (theFace, TopAbs_WIRE);
+ for (; aWireIt.More (); aWireIt.Next ())
+ {
+ const TopoDS_Wire& aWire = TopoDS::Wire (aWireIt.Current ());
+ if (aWire.IsSame(aOuterWire))
+ {
+ continue;
+ }
+
+ if (!addWire (aWire, aDFace))
+ {
+ // If there is a failure on internal wire, just skip it.
+ // The most significant is an outer wire.
+ aDFace->SetStatus (IMeshData_UnorientedWire);
+ }
+ }
+}
+
+//=======================================================================
+// Function: addWire
+// Purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_ShapeVisitor::addWire (
+ const TopoDS_Wire& theWire,
+ const IMeshData::IFaceHandle& theDFace)
+{
+ if (theWire.IsNull())
+ {
+ return Standard_False;
+ }
+
+ Handle(ShapeExtend_WireData) aWireData = new ShapeExtend_WireData(theWire, Standard_True, Standard_False);
+ ShapeAnalysis_Wire aWireTool (aWireData, theDFace->GetFace (), Precision::Confusion ());
+
+ ShapeAnalysis_WireOrder aOrderTool;
+ aWireTool.CheckOrder (aOrderTool, Standard_True, Standard_False);
+ if (aWireTool.LastCheckStatus(ShapeExtend_FAIL))
+ {
+ return Standard_False;
+ }
+
+ if (aWireTool.LastCheckStatus(ShapeExtend_DONE3))
+ {
+ theDFace->SetStatus(IMeshData_UnorientedWire);
+ }
+
+ const Standard_Integer aEdgesNb = aOrderTool.NbEdges ();
+ if (aEdgesNb != aWireData->NbEdges())
+ {
+ return Standard_False;
+ }
+
+ const IMeshData::IWireHandle& aDWire = theDFace->AddWire (theWire, aEdgesNb);
+ for (Standard_Integer i = 1; i <= aEdgesNb; ++i)
+ {
+ const Standard_Integer aEdgeIndex = aOrderTool.Ordered (i);
+ const TopoDS_Edge& aEdge = aWireData->Edge (aEdgeIndex);
+ if (aEdge.Orientation() != TopAbs_EXTERNAL)
+ {
+ const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (myDEdgeMap.Find (aEdge));
+
+ aDEdge->AddPCurve (theDFace, aEdge.Orientation());
+ aDWire->AddEdge (aDEdge, aEdge.Orientation());
+ }
+ }
+
+ return Standard_True;
+}
--- /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.
+
+#ifndef _BRepMesh_SphereRangeSplitter_HeaderFile
+#define _BRepMesh_SphereRangeSplitter_HeaderFile
+
+#include <BRepMesh_DefaultRangeSplitter.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending default range splitter in
+//! order to generate internal nodes for spherical surface.
+class BRepMesh_SphereRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_SphereRangeSplitter()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_SphereRangeSplitter()
+ {
+ }
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+ {
+ // Calculate parameters for iteration in V direction
+ Standard_Real aStep = 0.7 * GCPnts_TangentialDeflection::ArcAngularStep(
+ GetDFace()->GetSurface()->Sphere().Radius(), GetDFace()->GetDeflection(),
+ theParameters.Angle, theParameters.MinSize);
+
+ const std::pair<Standard_Real, Standard_Real>* aRange[2] = {
+ &GetRangeV(),
+ &GetRangeU()
+ };
+
+ std::pair<Standard_Real, Standard_Real> aStepAndOffset[2];
+ computeStep(*aRange[0], aStep, aStepAndOffset[0]);
+ computeStep(*aRange[1], aStep, aStepAndOffset[1]);
+
+ const Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+ Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+
+ const Standard_Real aHalfDu = aStepAndOffset[1].first * 0.5;
+ Standard_Boolean Shift = Standard_False;
+ Standard_Real aPasV = aRange[0]->first + aStepAndOffset[0].first;
+ for (; aPasV < aStepAndOffset[0].second; aPasV += aStepAndOffset[0].first)
+ {
+ Shift = !Shift;
+ const Standard_Real d = (Shift) ? aHalfDu : 0.;
+ Standard_Real aPasU = aRange[1]->first + d;
+ for (; aPasU < aStepAndOffset[1].second; aPasU += aStepAndOffset[1].first)
+ {
+ aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+ }
+ }
+
+ return aNodes;
+ }
+
+private:
+
+ //! Computes step for the given range.
+ inline void computeStep(
+ const std::pair<Standard_Real, Standard_Real>& theRange,
+ const Standard_Real theDefaultStep,
+ std::pair<Standard_Real, Standard_Real>& theStepAndOffset) const
+ {
+ const Standard_Real aDiff = theRange.second - theRange.first;
+ theStepAndOffset.first = aDiff / ((Standard_Integer) (aDiff / theDefaultStep) + 1);
+ theStepAndOffset.second = theRange.second - Precision::PConfusion();
+ }
+};
+
+#endif
--- /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 <GCPnts_TangentialDeflection.hxx>
+#include <IMeshTools_Parameters.hxx>
+
+//! Auxiliary class extending UV range splitter in order to generate
+//! internal nodes for NURBS surface.
+class BRepMesh_TorusRangeSplitter : public BRepMesh_UVParamRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_TorusRangeSplitter()
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_TorusRangeSplitter()
+ {
+ }
+
+ //! Returns list of nodes generated using surface data and specified parameters.
+ Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes(
+ const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE
+ {
+ const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
+ const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
+
+ const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
+ const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
+
+ const gp_Torus aTorus = GetDFace()->GetSurface()->Torus();
+ const Standard_Real r = aTorus.MinorRadius();
+ const Standard_Real R = aTorus.MajorRadius();
+
+ const Standard_Real oldDv = GCPnts_TangentialDeflection::ArcAngularStep(
+ r, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+ Standard_Real Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
+ Dv = oldDv;
+
+ const Standard_Integer nbV = Max((Standard_Integer) (aDiffV / Dv), 2);
+ Dv = aDiffV / (nbV + 1);
+
+ Standard_Real Du;
+ const Standard_Real ru = R + r;
+ if (ru > 1.e-16)
+ {
+ Du = GCPnts_TangentialDeflection::ArcAngularStep(ru,
+ GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
+
+ const Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
+ if (aa < gp::Resolution())
+ {
+ return Handle(IMeshData::ListOfPnt2d)();
+ }
+
+ Du *= Min(oldDv, Du) / aa;
+ }
+ else
+ {
+ Du = Dv;
+ }
+
+ Standard_Integer nbU = Max((Standard_Integer) (aDiffU / Du), 2);
+ nbU = Max(nbU, (Standard_Integer) (nbV * aDiffU * R / (aDiffV * r) / 5.));
+ Du = aDiffU / (nbU + 1);
+
+ const Handle(NCollection_IncAllocator) aTmpAlloc =
+ new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
+
+ Handle(IMeshData::SequenceOfReal) aParamU, aParamV;
+ if (R < r)
+ {
+ // As the points of edges are returned.
+ // in this case, the points are not representative.
+
+ //-- Choose DeltaX and DeltaY so that to avoid skipping points on the grid
+ aParamU = new IMeshData::SequenceOfReal(aTmpAlloc);
+ for (Standard_Integer i = 0; i <= nbU; i++)
+ {
+ aParamU->Append(aRangeU.first + i * Du);
+ }
+ }//R<r
+ else //U if R > r
+ {
+ aParamU = fillParams(GetParametersU(), GetRangeU(), nbU, 0.5, aTmpAlloc);
+ }
+
+ aParamV = fillParams(GetParametersV(), GetRangeV(), nbV, 2. / 3., aTmpAlloc);
+
+ const std::pair<Standard_Real, Standard_Real> aNewRangeU(aRangeU.first + Du * 0.1,
+ aRangeU.second - Dv * 0.1);
+
+ const std::pair<Standard_Real, Standard_Real> aNewRangeV(aRangeV.first + Dv * 0.1,
+ aRangeV.second - Dv * 0.1);
+
+ Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
+ for (Standard_Integer i = 1; i <= aParamU->Length(); ++i)
+ {
+ const Standard_Real aPasU = aParamU->Value(i);
+ if (aPasU >= aNewRangeU.first && aPasU < aNewRangeU.second)
+ {
+ for (Standard_Integer j = 1; j <= aParamV->Length(); ++j)
+ {
+ const Standard_Real aPasV = aParamV->Value(j);
+ if (aPasV >= aNewRangeV.first && aPasV < aNewRangeV.second)
+ {
+ aNodes->Append(gp_Pnt2d(aPasU, aPasV));
+ }
+ }
+ }
+ }
+
+ return aNodes;
+ }
+
+ //! Registers border point.
+ Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint) Standard_OVERRIDE
+ {
+ BRepMesh_DefaultRangeSplitter::AddPoint(thePoint);
+ GetParametersU().Add(thePoint.X());
+ GetParametersV().Add(thePoint.Y());
+ }
+
+private:
+
+ Handle(IMeshData::SequenceOfReal) fillParams(
+ const IMeshData::IMapOfReal& theParams,
+ const std::pair<Standard_Real, Standard_Real>& theRange,
+ const Standard_Integer theStepsNb,
+ const Standard_Real theScale,
+ const Handle(NCollection_IncAllocator)& theAllocator) const
+ {
+ Handle(IMeshData::SequenceOfReal) aParams =
+ new IMeshData::SequenceOfReal(theAllocator);
+
+ const Standard_Integer aLength = theParams.Size();
+ TColStd_Array1OfReal aParamArray(1, aLength);
+
+ for (Standard_Integer j = 1; j <= aLength; ++j)
+ {
+ aParamArray(j) = theParams(j);
+ }
+
+ // Calculate DU, leave array of parameters
+ const Standard_Real aDiff = Abs(theRange.second - theRange.first);
+ Standard_Real aStep = FUN_CalcAverageDUV(aParamArray, aLength);
+ aStep = Max(aStep, aDiff / (Standard_Real) theStepsNb / 2.);
+
+ Standard_Real aStdStep = aDiff / (Standard_Real) aLength;
+ if (aStep > aStdStep)
+ {
+ aStdStep = aStep;
+ }
+ aStdStep *= theScale;
+
+ // Add parameters
+ for (Standard_Integer j = 1; j <= aLength; ++j)
+ {
+ const Standard_Real pp = aParamArray(j);
+
+ Standard_Boolean isToInsert = Standard_True;
+ const Standard_Integer aParamsLength = aParams->Length();
+ for (Standard_Integer i = 1; i <= aParamsLength && isToInsert; ++i)
+ {
+ isToInsert = (Abs(aParams->Value(i) - pp) > aStdStep);
+ }
+
+ if (isToInsert)
+ {
+ aParams->Append(pp);
+ }
+ }
+
+ return aParams;
+ }
+
+ inline Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen) const
+ {
+ Standard_Integer i, j, n = 0;
+ Standard_Real p, result = 0.;
+
+ for (i = 1; i <= PLen; i++)
+ {
+ // Sort
+ for (j = i + 1; j <= PLen; j++)
+ {
+ if (P(i) > P(j))
+ {
+ p = P(i);
+ P(i) = P(j);
+ P(j) = p;
+ }
+ }
+ // Accumulate
+ if (i != 1)
+ {
+ p = Abs(P(i) - P(i - 1));
+ if (p > 1.e-7)
+ {
+ result += p;
+ n++;
+ }
+ }
+ }
+ return (n ? (result / (Standard_Real) n) : -1.);
+ }
+};
+
+#endif
--- /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 bounday discrete points.
+class BRepMesh_UVParamRangeSplitter : public BRepMesh_DefaultRangeSplitter
+{
+public:
+
+ //! Constructor.
+ Standard_EXPORT BRepMesh_UVParamRangeSplitter()
+ : myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+ myUParams(1, myAllocator),
+ myVParams(1, myAllocator)
+ {
+ }
+
+ //! Destructor.
+ Standard_EXPORT virtual ~BRepMesh_UVParamRangeSplitter()
+ {
+ }
+
+ //! Resets this splitter.
+ Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace,
+ const IMeshTools_Parameters& theParameters)
+ {
+ BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters);
+ myUParams.Clear();
+ myVParams.Clear();
+ myAllocator->Reset(Standard_False);
+ }
+
+public:
+ //! Returns U parameters.
+ inline const IMeshData::IMapOfReal& GetParametersU() const
+ {
+ return myUParams;
+ }
+
+ //! Returns U parameters.
+ inline IMeshData::IMapOfReal& GetParametersU()
+ {
+ return myUParams;
+ }
+
+ //! Returns V parameters.
+ inline const IMeshData::IMapOfReal& GetParametersV() const
+ {
+ return myVParams;
+ }
+
+ //! Returns V parameters.
+ inline IMeshData::IMapOfReal& GetParametersV()
+ {
+ return myVParams;
+ }
+
+private:
+ Handle(NCollection_IncAllocator) myAllocator;
+ IMeshData::IMapOfReal myUParams;
+ IMeshData::IMapOfReal myVParams;
+};
+
+#endif
--- /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_IncAllocator.hxx>
+#include <BRepMesh_OrientedEdge.hxx>
+#include <BRepMesh_Vertex.hxx>
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMeshData_Model::BRepMeshData_Model (const TopoDS_Shape& theShape)
+ : IMeshData_Model (theShape),
+ myMaxSize (0.),
+ myAllocator (new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
+ myDFaces (256, myAllocator),
+ myDEdges (256, myAllocator)
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMeshData_Model::~BRepMeshData_Model ()
+{
+}
+
+//=======================================================================
+// Function: FacesNb
+// Purpose :
+//=======================================================================
+Standard_Integer BRepMeshData_Model::FacesNb () const
+{
+ return myDFaces.Size ();
+}
+
+//=======================================================================
+// Function: AddFace
+// Purpose :
+//=======================================================================
+const IMeshData::IFaceHandle& BRepMeshData_Model::AddFace (const TopoDS_Face& theFace)
+{
+ IMeshData::IFaceHandle aFace (new (myAllocator) BRepMeshData_Face (theFace, myAllocator));
+ myDFaces.Append (aFace);
+ return myDFaces (FacesNb () - 1);
+}
+
+//=======================================================================
+// Function: GetFace
+// Purpose :
+//=======================================================================
+const IMeshData::IFaceHandle& BRepMeshData_Model::GetFace (const Standard_Integer theIndex) const
+{
+ return myDFaces (theIndex);
+}
+
+//=======================================================================
+// Function: EdgesNb
+// Purpose :
+//=======================================================================
+Standard_Integer BRepMeshData_Model::EdgesNb () const
+{
+ return myDEdges.Size ();
+}
+
+//=======================================================================
+// Function: AddEdge
+// Purpose :
+//=======================================================================
+const IMeshData::IEdgeHandle& BRepMeshData_Model::AddEdge (const TopoDS_Edge& theEdge)
+{
+ IMeshData::IEdgeHandle aEdge (new (myAllocator) BRepMeshData_Edge (theEdge, myAllocator));
+ myDEdges.Append (aEdge);
+ return myDEdges (EdgesNb () - 1);
+}
+
+//=======================================================================
+// Function: GetEdge
+// Purpose :
+//=======================================================================
+const IMeshData::IEdgeHandle& BRepMeshData_Model::GetEdge (const Standard_Integer theIndex) const
+{
+ return myDEdges (theIndex);
+}
--- /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>
+
+//=======================================================================
+// Function: Constructor
+// Purpose :
+//=======================================================================
+BRepMeshData_PCurve::BRepMeshData_PCurve (
+ const IMeshData::IFacePtr& theDFace,
+ const TopAbs_Orientation theOrientation,
+ const Handle (NCollection_IncAllocator)& theAllocator)
+ : IMeshData_PCurve (theDFace, theOrientation),
+ myPoints2d (NCollection_StdAllocator<gp_Pnt2d>(theAllocator)),
+ myParameters (NCollection_StdAllocator<Standard_Real>(theAllocator)),
+ myIndices (NCollection_StdAllocator<Standard_Integer>(theAllocator))
+{
+}
+
+//=======================================================================
+// Function: Destructor
+// Purpose :
+//=======================================================================
+BRepMeshData_PCurve::~BRepMeshData_PCurve ()
+{
+}
+
+//=======================================================================
+// Function: InsertPoint
+// Purpose :
+//=======================================================================
+void BRepMeshData_PCurve::InsertPoint(
+ const Standard_Integer thePosition,
+ const gp_Pnt2d& thePoint,
+ const Standard_Real theParamOnPCurve)
+{
+ myPoints2d .insert(myPoints2d .begin() + thePosition, thePoint);
+ myParameters.insert(myParameters.begin() + thePosition, theParamOnPCurve);
+ myIndices .insert(myIndices .begin() + thePosition, 0);
+}
+
+//=======================================================================
+// Function: AddPoint
+// Purpose :
+//=======================================================================
+void BRepMeshData_PCurve::AddPoint (
+ const gp_Pnt2d& thePoint,
+ const Standard_Real theParamOnPCurve)
+{
+ myPoints2d .push_back(thePoint);
+ myParameters.push_back(theParamOnPCurve);
+ myIndices .push_back(0);
+}
+
+//=======================================================================
+// Function: GetPoint
+// Purpose :
+//=======================================================================
+gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
+{
+ return myPoints2d[theIndex];
+}
+
+//=======================================================================
+// Function: GetIndex
+// Purpose :
+//=======================================================================
+Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
+{
+ return myIndices[theIndex];
+}
+
+//=======================================================================
+// Function: GetParameter
+// Purpose :
+//=======================================================================
+Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
+{
+ return myParameters[theIndex];
+}
+
+//=======================================================================
+// Function: ParameterNb
+// Purpose :
+//=======================================================================
+Standard_Integer BRepMeshData_PCurve::ParametersNb() const
+{
+ return static_cast<Standard_Integer>(myParameters.size());
+}
+
+//=======================================================================
+// Function: RemovePoint
+// Purpose :
+//=======================================================================
+void BRepMeshData_PCurve::RemovePoint (const Standard_Integer theIndex)
+{
+ myPoints2d.erase(myPoints2d.begin() + theIndex);
+ myIndices .erase(myIndices .begin() + theIndex);
+ removeParameter (theIndex);
+}
+
+//=======================================================================
+// Function: removeParameter
+// Purpose :
+//=======================================================================
+void BRepMeshData_PCurve::removeParameter (const Standard_Integer theIndex)
+{
+ myParameters.erase(myParameters.begin() + theIndex);
+}
+
+//=======================================================================
+// Function: Clear
+// Purpose :
+//=======================================================================
+void BRepMeshData_PCurve::Clear(const Standard_Boolean isKeepEndPoints)
+{
+ if (!isKeepEndPoints)
+ {
+ myPoints2d .clear();
+ myParameters.clear();
+ myIndices .clear();
+ }
+ else if (ParametersNb() > 2)
+ {
+ myPoints2d .erase(myPoints2d .begin() + 1, myPoints2d .begin() + (myPoints2d .size() - 1));
+ myParameters.erase(myParameters.begin() + 1, myParameters.begin() + (myParameters.size() - 1));
+ myIndices .erase(myIndices .begin() + 1, myIndices .begin() + (myIndices .size() - 1));
+ }
+}
--- /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
--- /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,
+ IMeshData_OpenWire = 0x1,
+ IMeshData_SelfIntersectingWire = 0x2,
+ IMeshData_Failure = 0x4,
+ IMeshData_ReMesh = 0x8,
+ IMeshData_UnorientedWire = 0x10,
+ IMeshData_TooFewPoints = 0x20,
+ IMeshData_Outdated = 0x40,
+ IMeshData_Reused = 0x80
+};
+
+#endif
--- /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 <memory>
+#include <queue>
+#include <list>
+
+class IMeshData_Shape;
+class IMeshData_Face;
+class IMeshData_Wire;
+class IMeshData_Edge;
+class IMeshData_Curve;
+class IMeshData_PCurve;
+class IMeshData_Model;
+class BRepMesh_VertexInspector;
+class BRepMesh_Triangle;
+class BRepMesh_Edge;
+class BRepMesh_PairOfIndex;
+class BRepMesh_Circle;
+class BRepMesh_CircleInspector;
+
+#define DEFINE_INC_ALLOC \
+ DEFINE_NCOLLECTION_ALLOC \
+ void operator delete (void* /*theAddress*/) \
+ { \
+ /*it's inc allocator, nothing to do*/ \
+ }
+
+namespace IMeshData
+{
+ //! Default size for memory block allocated by IncAllocator.
+ /**
+ * The idea here is that blocks of the given size are returned to the system
+ * rather than retained in the malloc heap, at least on WIN32 and WIN64 platforms.
+ */
+#ifdef _WIN64
+ const size_t MEMORY_BLOCK_SIZE_HUGE = 1024 * 1024;
+#else
+ const size_t MEMORY_BLOCK_SIZE_HUGE = 512 * 1024;
+#endif
+
+ typedef std::weak_ptr<IMeshData_Shape> IShapePtr;
+ typedef std::weak_ptr<IMeshData_Edge> IEdgePtr;
+ typedef std::weak_ptr<IMeshData_Wire> IWirePtr;
+ typedef std::weak_ptr<IMeshData_Face> IFacePtr;
+ typedef std::weak_ptr<IMeshData_Curve> ICurvePtr;
+ typedef std::weak_ptr<IMeshData_PCurve> IPCurvePtr;
+ typedef std::weak_ptr<IMeshData_Model> IModelPtr;
+
+ typedef std::shared_ptr<IMeshData_Shape> IShapeHandle;
+ typedef std::shared_ptr<IMeshData_Edge> IEdgeHandle;
+ typedef std::shared_ptr<IMeshData_Wire> IWireHandle;
+ typedef std::shared_ptr<IMeshData_Face> IFaceHandle;
+ typedef std::shared_ptr<IMeshData_Curve> ICurveHandle;
+ typedef std::shared_ptr<IMeshData_PCurve> IPCurveHandle;
+ typedef std::shared_ptr<IMeshData_Model> IModelHandle;
+
+ typedef IMeshData_ParametersListArrayAdaptor<ICurveHandle> ICurveArrayAdaptor;
+ typedef std::shared_ptr<ICurveArrayAdaptor> ICurveArrayAdaptorHandle;
+
+ typedef NCollection_Shared<NCollection_EBTree<Standard_Integer, Bnd_Box2d> > BndBox2dTree;
+ typedef NCollection_UBTreeFiller<Standard_Integer, Bnd_Box2d> BndBox2dTreeFiller;
+
+ // Vectors
+ typedef NCollection_Vector<IFaceHandle> VectorOfIFaceHandles;
+ typedef NCollection_Vector<IWireHandle> VectorOfIWireHandles;
+ typedef NCollection_Vector<IEdgeHandle> VectorOfIEdgeHandles;
+ typedef NCollection_Vector<IPCurveHandle> VectorOfIPCurveHandles;
+ typedef NCollection_Vector<IEdgePtr> VectorOfIEdgePtrs;
+ typedef NCollection_Vector<IShapeHandle> VectorOfIShapesHandles;
+ typedef NCollection_Vector<Standard_Boolean> VectorOfBoolean;
+ typedef NCollection_Vector<Standard_Integer> VectorOfInteger;
+ typedef NCollection_Vector<TopAbs_Orientation> VectorOfOrientation;
+ typedef NCollection_Vector<Handle(BndBox2dTree)> VectorOfHBndBox2dTree;
+ typedef NCollection_Vector<BRepMesh_Triangle> VectorOfElements;
+ typedef NCollection_Vector<BRepMesh_Circle> VectorOfCircle;
+
+ typedef NCollection_Array1<BRepMesh_Vertex> Array1OfVertexOfDelaun;
+ typedef NCollection_Shared<NCollection_Vector<BRepMesh_Vertex> > VectorOfVertex;
+
+ // Sequences
+ typedef NCollection_Shared<NCollection_Sequence<Bnd_B2d> > SequenceOfBndB2d;
+ typedef NCollection_Shared<NCollection_Sequence<Standard_Integer> > SequenceOfInteger;
+ typedef NCollection_Shared<NCollection_Sequence<Standard_Real> > SequenceOfReal;
+
+ namespace Model
+ {
+ typedef std::deque<gp_Pnt, NCollection_StdAllocator<gp_Pnt> > SequenceOfPnt;
+ typedef std::deque<gp_Pnt2d, NCollection_StdAllocator<gp_Pnt2d> > SequenceOfPnt2d;
+ typedef std::deque<Standard_Real, NCollection_StdAllocator<Standard_Real> > SequenceOfReal;
+ typedef std::deque<Standard_Integer, NCollection_StdAllocator<Standard_Integer> > SequenceOfInteger;
+ }
+
+ // Lists
+ typedef NCollection_Shared<NCollection_List<Standard_Integer> > ListOfInteger;
+ typedef NCollection_Shared<NCollection_List<gp_Pnt2d> > ListOfPnt2d;
+ typedef NCollection_List<IPCurveHandle> ListOfIPCurves;
+
+ typedef NCollection_Shared<TColStd_PackedMapOfInteger> MapOfInteger;
+ typedef TColStd_MapIteratorOfPackedMapOfInteger IteratorOfMapOfInteger;
+
+ typedef NCollection_CellFilter<BRepMesh_CircleInspector> CircleCellFilter;
+ typedef NCollection_CellFilter<BRepMesh_VertexInspector> VertexCellFilter;
+
+ // Data Maps
+ template<typename Type>
+ struct WeakEqual
+ {
+ static Standard_Boolean IsEqual(const std::weak_ptr<Type>& theFirst,
+ const std::weak_ptr<Type>& theSecond)
+ {
+ return (theFirst.lock().get() == theSecond.lock().get());
+ }
+
+ static Standard_Integer HashCode(const std::weak_ptr<Type>& thePtr, Standard_Integer theUpper)
+ {
+ return ::HashCode(thePtr.lock().get(), theUpper);
+ }
+ };
+
+ typedef NCollection_Shared<NCollection_DataMap<TopoDS_Shape, Standard_Integer, TopTools_ShapeMapHasher> > DMapOfShapeInteger;
+ typedef NCollection_Shared<NCollection_DataMap<IFacePtr, ListOfInteger, WeakEqual<IMeshData_Face> > > DMapOfIFacePtrsListOfInteger;
+ typedef NCollection_Shared<NCollection_Map<IEdgePtr, WeakEqual<IMeshData_Edge> > > MapOfIEdgePtr;
+ typedef NCollection_Shared<NCollection_Map<IFacePtr, WeakEqual<IMeshData_Face> > > MapOfIFacePtr;
+ typedef NCollection_Shared<NCollection_Map<BRepMesh_OrientedEdge> > MapOfOrientedEdges;
+ typedef NCollection_Shared<NCollection_Map<Standard_Real> > MapOfReal;
+ typedef NCollection_Shared<NCollection_IndexedDataMap<IFacePtr, ListOfIPCurves, WeakEqual<IMeshData_Face> > > IDMapOfIFacePtrsListOfIPCurves;
+ typedef NCollection_Shared<NCollection_DataMap<IFacePtr, Handle(MapOfIEdgePtr), WeakEqual<IMeshData_Face> > > DMapOfIFacePtrsMapOfIEdgePtrs;
+ typedef NCollection_IndexedDataMap<BRepMesh_Edge, BRepMesh_PairOfIndex> IDMapOfLink;
+ typedef NCollection_DataMap<Standard_Integer, ListOfInteger> DMapOfIntegerListOfInteger;
+ typedef NCollection_DataMap<Standard_Integer, Standard_Integer> MapOfIntegerInteger;
+ typedef NCollection_IndexedMap<Standard_Real> IMapOfReal;
+
+ typedef NCollection_Array1<Standard_Integer> Array1OfInteger;
+}
+
+#endif
\ No newline at end of file
--- /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_ModelAlgo.hxx
+IMeshTools_ModelBuilder.hxx
+IMeshTools_Parameters.hxx
+IMeshTools_ShapeExplorer.hxx
+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.
+
+#ifndef _IMeshTools_MeshBuilder_HeaderFile
+#define _IMeshTools_MeshBuilder_HeaderFile
+
+#include <Message_Algorithm.hxx>
+#include <IMeshTools_Context.hxx>
+#include <Standard_Type.hxx>
+
+//! Interface class providing API for mesh builder tool.
+class IMeshTools_MeshBuilder : public Message_Algorithm
+{
+public:
+
+ //! Destructor.
+ Standard_EXPORT virtual ~IMeshTools_MeshBuilder()
+ {
+ }
+
+ //! Sets context for algorithm.
+ inline void SetContext (const Handle (IMeshTools_Context)& theContext)
+ {
+ myContext = theContext;
+ }
+
+ //! Gets context of algorithm.
+ inline const Handle (IMeshTools_Context)& GetContext () const
+ {
+ return myContext;
+ }
+
+ //! Performs meshing ot the shape using current context.
+ Standard_EXPORT virtual void Perform () = 0;
+
+ DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshBuilder, Message_Algorithm)
+
+protected:
+
+ //! Constructor.
+ Standard_EXPORT IMeshTools_MeshBuilder()
+ {
+ }
+
+ //! Constructor.
+ Standard_EXPORT IMeshTools_MeshBuilder (const Handle (IMeshTools_Context)& theContext)
+ : myContext(theContext)
+ {
+ }
+
+private:
+
+ Handle (IMeshTools_Context) myContext;
+};
+
+#endif
\ No newline at end of file
--- /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_Transient.hxx>
+#include <Standard_Type.hxx>
+
+class IMeshData_Model;
+struct IMeshTools_Parameters;
+
+//! Interface class providing API for algorithms intended to update or modify discrete model.
+class IMeshTools_ModelAlgo : public Standard_Transient
+{
+public:
+
+ //! Destructor.
+ Standard_EXPORT virtual ~IMeshTools_ModelAlgo()
+ {
+ }
+
+ //! Performs processing of edges of the given model.
+ Standard_EXPORT virtual Standard_Boolean Perform (
+ const Handle (IMeshData_Model)& theModel,
+ const IMeshTools_Parameters& theParameters) = 0;
+
+ DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
+
+protected:
+
+ //! Constructor.
+ Standard_EXPORT IMeshTools_ModelAlgo()
+ {
+ }
+};
+
+#endif
\ No newline at end of file
--- /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_Type.hxx>
+#include <TopoDS_Shape.hxx>
+
+class IMeshData_Model;
+struct IMeshTools_Parameters;
+
+//! Interface class represents API for tool building discrete model.
+//!
+//! The following statuses should be used by default:
+//! Message_Done1 - model has been sucessfully built.
+//! Message_Fail1 - empty shape.
+//! Message_Fail2 - model has not been build due to unexpected reason.
+class IMeshTools_ModelBuilder : public Message_Algorithm
+{
+public:
+
+ //! Destructor.
+ Standard_EXPORT virtual ~IMeshTools_ModelBuilder()
+ {
+ }
+
+ //! Creates discrete model for the given shape.
+ //! Returns nullptr in case of failure.
+ Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
+ const TopoDS_Shape& theShape,
+ const IMeshTools_Parameters& theParameters) = 0;
+
+ DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
+
+protected:
+
+ //! Constructor.
+ Standard_EXPORT IMeshTools_ModelBuilder()
+ {
+ }
+};
+
+#endif
\ No newline at end of file
--- /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),
+ MinSize (Precision::Confusion ()),
+ InParallel (Standard_False),
+ Relative (Standard_False),
+ InternalVerticesMode (Standard_True),
+ ControlSurfaceDeflection (Standard_True),
+ CleanModel(Standard_True)
+ {
+ }
+
+ //! Angular deflection
+ Standard_Real Angle;
+
+ //! Deflection
+ Standard_Real Deflection;
+
+ //! Minimal allowed size of mesh element
+ Standard_Real MinSize;
+
+ //! Switches on/off multi-thread computation
+ Standard_Boolean InParallel;
+
+ //! Switches on/off relative computation of edge tolerance<br>
+ //! If true, deflection used for the polygonalisation of each edge will be
+ //! <defle> * Size of Edge. The deflection used for the faces will be the
+ //! maximum deflection of their edges.
+ Standard_Boolean Relative;
+
+ //! Mode to take or not to take internal face vertices into account
+ //! in triangulation process
+ Standard_Boolean InternalVerticesMode;
+
+ //! Parameter to check the deviation of triangulation and interior of
+ //! the face
+ Standard_Boolean ControlSurfaceDeflection;
+
+ //! Cleans temporary data model when algorithm is finished.
+ Standard_Boolean CleanModel;
+};
+
+#endif
--- /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>
+
+//! Interface class for tools exploring TopoDS_Shape.
+class IMeshTools_ShapeExplorer : public IMeshData_Shape
+{
+public:
+
+ //! Destructor.
+ Standard_EXPORT virtual ~IMeshTools_ShapeExplorer()
+ {
+ }
+
+ //! Starts exploring of a shape.
+ Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) = 0;
+
+ DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ShapeExplorer, IMeshData_Shape)
+
+protected:
+
+ //! Constructor.
+ Standard_EXPORT IMeshTools_ShapeExplorer (const TopoDS_Shape& theShape)
+ : IMeshData_Shape(theShape)
+ {
+ }
+};
+
+#endif
\ No newline at end of file
--- /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