From 813ba252677c7c8e4b205d9f93f5e2a17575d387 Mon Sep 17 00:00:00 2001 From: bugmaster Date: Fri, 13 Jul 2018 13:02:15 +0300 Subject: [PATCH] Adding new files --- src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx | 315 ++++++++++++ src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx | 143 ++++++ .../BRepMesh_BoundaryParamsRangeSplitter.hxx | 53 ++ src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx | 80 +++ src/BRepMesh/BRepMesh_Context.cxx | 45 ++ src/BRepMesh/BRepMesh_Context.hxx | 36 ++ src/BRepMesh/BRepMesh_CurveTessellator.cxx | 318 ++++++++++++ src/BRepMesh/BRepMesh_CurveTessellator.hxx | 110 ++++ .../BRepMesh_CylinderRangeSplitter.hxx | 118 +++++ .../BRepMesh_DefaultRangeSplitter.hxx | 289 +++++++++++ src/BRepMesh/BRepMesh_Deflection.cxx | 157 ++++++ src/BRepMesh/BRepMesh_Deflection.hxx | 66 +++ .../BRepMesh_DelaunayBaseMeshAlgo.cxx | 56 +++ .../BRepMesh_DelaunayBaseMeshAlgo.hxx | 52 ++ ...Mesh_DelaunayDeflectionControlMeshAlgo.hxx | 414 +++++++++++++++ ...BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx | 82 +++ src/BRepMesh/BRepMesh_EdgeDiscret.cxx | 317 ++++++++++++ src/BRepMesh/BRepMesh_EdgeDiscret.hxx | 96 ++++ src/BRepMesh/BRepMesh_FaceChecker.cxx | 317 ++++++++++++ src/BRepMesh/BRepMesh_FaceChecker.hxx | 122 +++++ src/BRepMesh/BRepMesh_FaceDiscret.cxx | 86 ++++ src/BRepMesh/BRepMesh_FaceDiscret.hxx | 63 +++ src/BRepMesh/BRepMesh_IncAllocator.hxx | 50 ++ src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx | 103 ++++ src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx | 44 ++ src/BRepMesh/BRepMesh_MeshBuilder.cxx | 118 +++++ src/BRepMesh/BRepMesh_MeshBuilder.hxx | 52 ++ src/BRepMesh/BRepMesh_MeshTool.cxx | 368 ++++++++++++++ src/BRepMesh/BRepMesh_MeshTool.hxx | 235 +++++++++ src/BRepMesh/BRepMesh_ModelBuilder.cxx | 96 ++++ src/BRepMesh/BRepMesh_ModelBuilder.hxx | 48 ++ src/BRepMesh/BRepMesh_ModelHealer.cxx | 440 ++++++++++++++++ src/BRepMesh/BRepMesh_ModelHealer.hxx | 183 +++++++ src/BRepMesh/BRepMesh_ModelPostProcessor.cxx | 189 +++++++ src/BRepMesh/BRepMesh_ModelPostProcessor.hxx | 43 ++ src/BRepMesh/BRepMesh_ModelPreProcessor.cxx | 172 +++++++ src/BRepMesh/BRepMesh_ModelPreProcessor.hxx | 44 ++ src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx | 476 ++++++++++++++++++ src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx | 74 +++ .../BRepMesh_NodeInsertionMeshAlgo.hxx | 230 +++++++++ src/BRepMesh/BRepMesh_ShapeExplorer.cxx | 97 ++++ src/BRepMesh/BRepMesh_ShapeExplorer.hxx | 41 ++ src/BRepMesh/BRepMesh_ShapeVisitor.cxx | 148 ++++++ src/BRepMesh/BRepMesh_ShapeVisitor.hxx | 67 +++ src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx | 92 ++++ src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx | 228 +++++++++ .../BRepMesh_UVParamRangeSplitter.hxx | 81 +++ src/BRepMeshData/BRepMeshData_Curve.cxx | 126 +++++ src/BRepMeshData/BRepMeshData_Curve.hxx | 76 +++ src/BRepMeshData/BRepMeshData_Edge.cxx | 102 ++++ src/BRepMeshData/BRepMeshData_Edge.hxx | 65 +++ src/BRepMeshData/BRepMeshData_Face.cxx | 72 +++ src/BRepMeshData/BRepMeshData_Face.hxx | 58 +++ src/BRepMeshData/BRepMeshData_Model.cxx | 100 ++++ src/BRepMeshData/BRepMeshData_Model.hxx | 81 +++ src/BRepMeshData/BRepMeshData_PCurve.cxx | 145 ++++++ src/BRepMeshData/BRepMeshData_PCurve.hxx | 82 +++ src/BRepMeshData/BRepMeshData_Wire.cxx | 86 ++++ src/BRepMeshData/BRepMeshData_Wire.hxx | 63 +++ src/BRepMeshData/FILES | 12 + src/IMeshData/FILES | 13 + src/IMeshData/IMeshData_Curve.hxx | 62 +++ src/IMeshData/IMeshData_Edge.hxx | 167 ++++++ src/IMeshData/IMeshData_Face.hxx | 93 ++++ src/IMeshData/IMeshData_Model.hxx | 76 +++ src/IMeshData/IMeshData_PCurve.hxx | 99 ++++ src/IMeshData/IMeshData_ParametersList.hxx | 54 ++ .../IMeshData_ParametersListArrayAdaptor.hxx | 70 +++ src/IMeshData/IMeshData_Shape.hxx | 66 +++ src/IMeshData/IMeshData_Status.hxx | 33 ++ src/IMeshData/IMeshData_StatusOwner.hxx | 76 +++ src/IMeshData/IMeshData_TessellatedShape.hxx | 67 +++ src/IMeshData/IMeshData_Types.hxx | 175 +++++++ src/IMeshData/IMeshData_Wire.hxx | 74 +++ src/IMeshTools/FILES | 10 + src/IMeshTools/IMeshTools_Context.hxx | 240 +++++++++ .../IMeshTools_CurveTessellator.hxx | 57 +++ src/IMeshTools/IMeshTools_MeshAlgo.hxx | 50 ++ src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx | 52 ++ src/IMeshTools/IMeshTools_MeshBuilder.hxx | 68 +++ src/IMeshTools/IMeshTools_ModelAlgo.hxx | 50 ++ src/IMeshTools/IMeshTools_ModelBuilder.hxx | 57 +++ src/IMeshTools/IMeshTools_Parameters.hxx | 68 +++ src/IMeshTools/IMeshTools_ShapeExplorer.hxx | 48 ++ src/IMeshTools/IMeshTools_ShapeVisitor.hxx | 51 ++ 85 files changed, 9998 insertions(+) create mode 100644 src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx create mode 100644 src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx create mode 100644 src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_Context.cxx create mode 100644 src/BRepMesh/BRepMesh_Context.hxx create mode 100644 src/BRepMesh/BRepMesh_CurveTessellator.cxx create mode 100644 src/BRepMesh/BRepMesh_CurveTessellator.hxx create mode 100644 src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_Deflection.cxx create mode 100644 src/BRepMesh/BRepMesh_Deflection.hxx create mode 100644 src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx create mode 100644 src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx create mode 100644 src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx create mode 100644 src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx create mode 100644 src/BRepMesh/BRepMesh_EdgeDiscret.cxx create mode 100644 src/BRepMesh/BRepMesh_EdgeDiscret.hxx create mode 100644 src/BRepMesh/BRepMesh_FaceChecker.cxx create mode 100644 src/BRepMesh/BRepMesh_FaceChecker.hxx create mode 100644 src/BRepMesh/BRepMesh_FaceDiscret.cxx create mode 100644 src/BRepMesh/BRepMesh_FaceDiscret.hxx create mode 100644 src/BRepMesh/BRepMesh_IncAllocator.hxx create mode 100644 src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx create mode 100644 src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx create mode 100644 src/BRepMesh/BRepMesh_MeshBuilder.cxx create mode 100644 src/BRepMesh/BRepMesh_MeshBuilder.hxx create mode 100644 src/BRepMesh/BRepMesh_MeshTool.cxx create mode 100644 src/BRepMesh/BRepMesh_MeshTool.hxx create mode 100644 src/BRepMesh/BRepMesh_ModelBuilder.cxx create mode 100644 src/BRepMesh/BRepMesh_ModelBuilder.hxx create mode 100644 src/BRepMesh/BRepMesh_ModelHealer.cxx create mode 100644 src/BRepMesh/BRepMesh_ModelHealer.hxx create mode 100644 src/BRepMesh/BRepMesh_ModelPostProcessor.cxx create mode 100644 src/BRepMesh/BRepMesh_ModelPostProcessor.hxx create mode 100644 src/BRepMesh/BRepMesh_ModelPreProcessor.cxx create mode 100644 src/BRepMesh/BRepMesh_ModelPreProcessor.hxx create mode 100644 src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx create mode 100644 src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx create mode 100644 src/BRepMesh/BRepMesh_ShapeExplorer.cxx create mode 100644 src/BRepMesh/BRepMesh_ShapeExplorer.hxx create mode 100644 src/BRepMesh/BRepMesh_ShapeVisitor.cxx create mode 100644 src/BRepMesh/BRepMesh_ShapeVisitor.hxx create mode 100644 src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx create mode 100644 src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx create mode 100644 src/BRepMeshData/BRepMeshData_Curve.cxx create mode 100644 src/BRepMeshData/BRepMeshData_Curve.hxx create mode 100644 src/BRepMeshData/BRepMeshData_Edge.cxx create mode 100644 src/BRepMeshData/BRepMeshData_Edge.hxx create mode 100644 src/BRepMeshData/BRepMeshData_Face.cxx create mode 100644 src/BRepMeshData/BRepMeshData_Face.hxx create mode 100644 src/BRepMeshData/BRepMeshData_Model.cxx create mode 100644 src/BRepMeshData/BRepMeshData_Model.hxx create mode 100644 src/BRepMeshData/BRepMeshData_PCurve.cxx create mode 100644 src/BRepMeshData/BRepMeshData_PCurve.hxx create mode 100644 src/BRepMeshData/BRepMeshData_Wire.cxx create mode 100644 src/BRepMeshData/BRepMeshData_Wire.hxx create mode 100644 src/BRepMeshData/FILES create mode 100644 src/IMeshData/FILES create mode 100644 src/IMeshData/IMeshData_Curve.hxx create mode 100644 src/IMeshData/IMeshData_Edge.hxx create mode 100644 src/IMeshData/IMeshData_Face.hxx create mode 100644 src/IMeshData/IMeshData_Model.hxx create mode 100644 src/IMeshData/IMeshData_PCurve.hxx create mode 100644 src/IMeshData/IMeshData_ParametersList.hxx create mode 100644 src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx create mode 100644 src/IMeshData/IMeshData_Shape.hxx create mode 100644 src/IMeshData/IMeshData_Status.hxx create mode 100644 src/IMeshData/IMeshData_StatusOwner.hxx create mode 100644 src/IMeshData/IMeshData_TessellatedShape.hxx create mode 100644 src/IMeshData/IMeshData_Types.hxx create mode 100644 src/IMeshData/IMeshData_Wire.hxx create mode 100644 src/IMeshTools/FILES create mode 100644 src/IMeshTools/IMeshTools_Context.hxx create mode 100644 src/IMeshTools/IMeshTools_CurveTessellator.hxx create mode 100644 src/IMeshTools/IMeshTools_MeshAlgo.hxx create mode 100644 src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx create mode 100644 src/IMeshTools/IMeshTools_MeshBuilder.hxx create mode 100644 src/IMeshTools/IMeshTools_ModelAlgo.hxx create mode 100644 src/IMeshTools/IMeshTools_ModelBuilder.hxx create mode 100644 src/IMeshTools/IMeshTools_Parameters.hxx create mode 100644 src/IMeshTools/IMeshTools_ShapeExplorer.hxx create mode 100644 src/IMeshTools/IMeshTools_ShapeVisitor.hxx diff --git a/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx new file mode 100644 index 0000000000..af1c8e75b4 --- /dev/null +++ b/src/BRepMesh/BRepMesh_BaseMeshAlgo.cxx @@ -0,0 +1,315 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// 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(myStructure->GetLink(aLinkIndex)); + aLink.SetMovability(BRepMesh_Fixed); + } + } + + aPrevNodeIndex = aNodeIndex; + } + } + } + + return Standard_True; +} + +//======================================================================= +// Function: registerNode +// Purpose : +//======================================================================= +Standard_Integer BRepMesh_BaseMeshAlgo::registerNode( + const gp_Pnt& thePoint, + const gp_Pnt2d& thePoint2d, + const BRepMesh_DegreeOfFreedom theMovability, + const Standard_Boolean isForceAdd) +{ + const Standard_Integer aNodeIndex = addNodeToStructure( + thePoint2d, myNodesMap->Size(), theMovability, isForceAdd); + + if (aNodeIndex > myNodesMap->Size()) + { + myNodesMap->Append(thePoint); + } + + return aNodeIndex; +} + +//======================================================================= +// Function: addNode +// Purpose : +//======================================================================= +Standard_Integer BRepMesh_BaseMeshAlgo::addNodeToStructure( + const gp_Pnt2d& thePoint, + const Standard_Integer theLocation3d, + const BRepMesh_DegreeOfFreedom theMovability, + const Standard_Boolean isForceAdd) +{ + BRepMesh_Vertex aNode(thePoint.XY(), theLocation3d, theMovability); + return myStructure->AddNode(aNode, isForceAdd); +} + +//======================================================================= +//function : addLinkToMesh +//purpose : +//======================================================================= +Standard_Integer BRepMesh_BaseMeshAlgo::addLinkToMesh( + const Standard_Integer theFirstNodeId, + const Standard_Integer theLastNodeId, + const TopAbs_Orientation theOrientation) +{ + Standard_Integer aLinkIndex; + if (theOrientation == TopAbs_REVERSED) + aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theLastNodeId, theFirstNodeId, BRepMesh_Frontier)); + else if (theOrientation == TopAbs_INTERNAL) + aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Fixed)); + else + aLinkIndex = myStructure->AddLink(BRepMesh_Edge(theFirstNodeId, theLastNodeId, BRepMesh_Frontier)); + + return Abs(aLinkIndex); +} + +//======================================================================= +//function : fixSeamEdgeOrientation +//purpose : +//======================================================================= +TopAbs_Orientation BRepMesh_BaseMeshAlgo::fixSeamEdgeOrientation( + const IMeshData::IEdgeHandle& theDEdge, + const IMeshData::IPCurveHandle& thePCurve) const +{ + for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt) + { + const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt); + if (aPCurve->GetFace().lock() == myDFace && thePCurve != aPCurve) + { + // Simple check that another pcurve of seam edge does not coincide with reference one. + const gp_Pnt2d& aPnt1_1 = thePCurve->GetPoint(0); + const gp_Pnt2d& aPnt2_1 = thePCurve->GetPoint(thePCurve->ParametersNb() - 1); + + const gp_Pnt2d& aPnt1_2 = aPCurve->GetPoint(0); + const gp_Pnt2d& aPnt2_2 = aPCurve->GetPoint(aPCurve->ParametersNb() - 1); + + const Standard_Real aSqDist1 = Min(aPnt1_1.SquareDistance(aPnt1_2), aPnt1_1.SquareDistance(aPnt2_2)); + const Standard_Real aSqDist2 = Min(aPnt2_1.SquareDistance(aPnt1_2), aPnt2_1.SquareDistance(aPnt2_2)); + if (aSqDist1 < Precision::SquareConfusion() && + aSqDist2 < Precision::SquareConfusion()) + { + return TopAbs_INTERNAL; + } + } + } + + return thePCurve->GetOrientation(); +} + +//======================================================================= +//function : commitSurfaceTriangulation +//purpose : +//======================================================================= +void BRepMesh_BaseMeshAlgo::commitSurfaceTriangulation() +{ + Handle(Poly_Triangulation) aTriangulation = collectTriangles(); + if (aTriangulation.IsNull()) + { + myDFace->SetStatus(IMeshData_Failure); + return; + } + + collectNodes(aTriangulation); + + aTriangulation->Deflection(myDFace->GetDeflection()); + BRepMesh_ShapeTool::AddInFace(myDFace->GetFace(), aTriangulation); +} + +//======================================================================= +//function : collectTriangles +//purpose : +//======================================================================= +Handle(Poly_Triangulation) BRepMesh_BaseMeshAlgo::collectTriangles() +{ + const IMeshData::MapOfInteger& aTriangles = myStructure->ElementsOfDomain(); + if (aTriangles.IsEmpty()) + { + return Handle(Poly_Triangulation)(); + } + + Poly_Array1OfTriangle aPolyTrianges(1, aTriangles.Extent()); + IMeshData::IteratorOfMapOfInteger aTriIt(aTriangles); + for (Standard_Integer aTriangeId = 1; aTriIt.More(); aTriIt.Next(), ++aTriangeId) + { + const BRepMesh_Triangle& aCurElem = myStructure->GetElement(aTriIt.Key()); + + Standard_Integer aNode[3]; + myStructure->ElementNodes(aCurElem, aNode); + + for (Standard_Integer i = 0; i < 3; ++i) + { + if (!myUsedNodes->IsBound(aNode[i])) + { + myUsedNodes->Bind(aNode[i], myUsedNodes->Size() + 1); + } + + aNode[i] = myUsedNodes->Find(aNode[i]); + } + + aPolyTrianges(aTriangeId).Set(aNode[0], aNode[1], aNode[2]); + } + + Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation( + myUsedNodes->Extent(), aTriangles.Extent(), Standard_True); + + aTriangulation->ChangeTriangles() = aPolyTrianges; + return aTriangulation; +} + +//======================================================================= +//function : collectNodes +//purpose : +//======================================================================= +void BRepMesh_BaseMeshAlgo::collectNodes( + const Handle(Poly_Triangulation)& theTriangulation) +{ + // Store mesh nodes + TColgp_Array1OfPnt& aNodes = theTriangulation->ChangeNodes(); + TColgp_Array1OfPnt2d& aNodes2d = theTriangulation->ChangeUVNodes(); + + for (Standard_Integer i = 1; i <= myNodesMap->Size(); ++i) + { + if (myUsedNodes->IsBound(i)) + { + const BRepMesh_Vertex& aVertex = myStructure->GetNode(i); + + const Standard_Integer aNodeIndex = myUsedNodes->Find(i); + aNodes(aNodeIndex) = myNodesMap->Value(aVertex.Location3d()); + aNodes2d(aNodeIndex) = getNodePoint2d(aVertex); + } + } +} + +//======================================================================= +// Function: getNodePoint2d +// Purpose : +//======================================================================= +gp_Pnt2d BRepMesh_BaseMeshAlgo::getNodePoint2d( + const BRepMesh_Vertex& theVertex) const +{ + return theVertex.Coord(); +} diff --git a/src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx new file mode 100644 index 0000000000..56c03b2e8a --- /dev/null +++ b/src/BRepMesh/BRepMesh_BaseMeshAlgo.hxx @@ -0,0 +1,143 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_BaseMeshAlgo_HeaderFile +#define _BRepMesh_BaseMeshAlgo_HeaderFile + +#include +#include +#include +#include +#include + +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 > 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 > DMapOfIntegerInteger; + + IMeshData::IFaceHandle myDFace; + IMeshTools_Parameters myParameters; + Handle(NCollection_IncAllocator) myAllocator; + Handle(BRepMesh_DataStructureOfDelaun) myStructure; + Handle(VectorOfPnt) myNodesMap; + Handle(DMapOfIntegerInteger) myUsedNodes; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx b/src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx new file mode 100644 index 0000000000..95e05348aa --- /dev/null +++ b/src/BRepMesh/BRepMesh_BoundaryParamsRangeSplitter.hxx @@ -0,0 +1,53 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_BoundaryParamsRangeSplitter_HeaderFile +#define _BRepMesh_BoundaryParamsRangeSplitter_HeaderFile + +#include + +//! Auxiliary class extending UV range splitter in order to generate +//! internal nodes for NURBS surface. +class BRepMesh_BoundaryParamsRangeSplitter : public BRepMesh_NURBSRangeSplitter +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_BoundaryParamsRangeSplitter() + { + } + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_BoundaryParamsRangeSplitter() + { + } + + //! Registers border point. + Standard_EXPORT virtual void AddPoint(const gp_Pnt2d& thePoint) + { + BRepMesh_NURBSRangeSplitter::AddPoint(thePoint); + GetParametersU().Add(thePoint.X()); + GetParametersV().Add(thePoint.Y()); + } + +protected: + + //! Initializes U and V parameters lists using CN continuity intervals. + Standard_EXPORT virtual void initParameters() const + { + } +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx b/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx new file mode 100644 index 0000000000..f0bc5df828 --- /dev/null +++ b/src/BRepMesh/BRepMesh_ConeRangeSplitter.hxx @@ -0,0 +1,80 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ConeRangeSplitter_HeaderFile +#define _BRepMesh_ConeRangeSplitter_HeaderFile + +#include +#include +#include + +//! 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& aRangeU = GetRangeU(); + const std::pair& aRangeV = GetRangeV(); + + gp_Cone aCone = GetDFace()->GetSurface()->Cone(); + Standard_Real aRefR = aCone.RefRadius(); + Standard_Real aSAng = aCone.SemiAngle(); + Standard_Real aRadius = Max(Abs(aRefR + aRangeV.first * Sin(aSAng)), + Abs(aRefR + aRangeV.second * Sin(aSAng))); + + Standard_Real Dv, Du = GCPnts_TangentialDeflection::ArcAngularStep( + aRadius, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize); + + const Standard_Real aDiffU = aRangeU.second - aRangeU.first; + const Standard_Real aDiffV = aRangeV.second - aRangeV.first; + Standard_Integer nbU = (Standard_Integer) (aDiffU / Du); + Standard_Integer nbV = (Standard_Integer) (nbU * (aDiffV) / (aDiffU * aRadius)); + Du = aDiffU / (nbU + 1); + Dv = aDiffV / (nbV + 1); + + const Handle(NCollection_IncAllocator) aTmpAlloc = + new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE); + Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc); + + const Standard_Real aPasMaxV = aRangeV.second - Dv*0.5; + const Standard_Real aPasMaxU = aRangeU.second - Du*0.5; + for (Standard_Real aPasV = aRangeV.first + Dv; aPasV < aPasMaxV; aPasV += Dv) + { + for (Standard_Real aPasU = aRangeV.first + Du; aPasU < aPasMaxU; aPasU += Du) + { + aNodes->Append(gp_Pnt2d(aPasU, aPasV)); + } + } + + return aNodes; + } +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_Context.cxx b/src/BRepMesh/BRepMesh_Context.cxx new file mode 100644 index 0000000000..e48d038467 --- /dev/null +++ b/src/BRepMesh/BRepMesh_Context.cxx @@ -0,0 +1,45 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_Context::BRepMesh_Context () +{ + SetModelBuilder (new BRepMesh_ModelBuilder); + SetEdgeDiscret (new BRepMesh_EdgeDiscret); + SetModelHealer (new BRepMesh_ModelHealer); + SetPreProcessor (new BRepMesh_ModelPreProcessor); + SetFaceDiscret (new BRepMesh_FaceDiscret(new BRepMesh_MeshAlgoFactory)); + SetPostProcessor(new BRepMesh_ModelPostProcessor); +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_Context::~BRepMesh_Context () +{ +} diff --git a/src/BRepMesh/BRepMesh_Context.hxx b/src/BRepMesh/BRepMesh_Context.hxx new file mode 100644 index 0000000000..a802a6b44b --- /dev/null +++ b/src/BRepMesh/BRepMesh_Context.hxx @@ -0,0 +1,36 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_Context_HeaderFile +#define _BRepMesh_Context_HeaderFile + +#include + +//! Class implemeting default context of BRepMesh algorithm. +//! Initializes context by default algorithms. +class BRepMesh_Context : public IMeshTools_Context +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_Context (); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_Context (); + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Context, IMeshTools_Context) +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.cxx b/src/BRepMesh/BRepMesh_CurveTessellator.cxx new file mode 100644 index 0000000000..e6b5fa3d39 --- /dev/null +++ b/src/BRepMesh/BRepMesh_CurveTessellator.cxx @@ -0,0 +1,318 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +BRepMesh_CurveTessellator::BRepMesh_CurveTessellator( + const IMeshData::IEdgeHandle& theEdge, + const IMeshTools_Parameters& theParameters) + : myDEdge(theEdge), + myParameters(theParameters), + myEdge(theEdge->GetEdge()), + myCurve(myEdge) +{ + init(); +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +BRepMesh_CurveTessellator::BRepMesh_CurveTessellator ( + const IMeshData::IEdgeHandle& theEdge, + const TopAbs_Orientation theOrientation, + const IMeshData::IFaceHandle& theFace, + const IMeshTools_Parameters& theParameters) + : myDEdge(theEdge), + myParameters(theParameters), + myEdge(TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation))), + myCurve(myEdge, theFace->GetFace()) +{ + init(); +} + +//======================================================================= +//function : init +//purpose : +//======================================================================= +void BRepMesh_CurveTessellator::init() +{ + TopExp::Vertices(myEdge, myFirstVertex, myLastVertex); + + Standard_Real aPreciseAngDef = 0.5 * myDEdge->GetAngularDeflection(); + Standard_Real aPreciseLinDef = 0.5 * myDEdge->GetDeflection(); + if (myEdge.Orientation() == TopAbs_INTERNAL) + { + aPreciseLinDef *= 0.5; + } + + mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef; + mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize); + + myEdgeSqTol = BRep_Tool::Tolerance(myEdge); + myEdgeSqTol *= myEdgeSqTol; + + const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287 + + myDiscretTool.Initialize(myCurve, + myCurve.FirstParameter(), myCurve.LastParameter(), + aPreciseAngDef, aPreciseLinDef, aMinPntNb, + Precision::PConfusion(), myParameters.MinSize); + + if (myCurve.IsCurveOnSurface()) + { + const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface(); + const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface(); + + const Standard_Real aTol = Precision::Confusion(); + const Standard_Real aDu = aSurface->UResolution(aTol); + const Standard_Real aDv = aSurface->VResolution(aTol); + + myFaceRangeU[0] = aSurface->FirstUParameter() - aDu; + myFaceRangeU[1] = aSurface->LastUParameter() + aDu; + + myFaceRangeV[0] = aSurface->FirstVParameter() - aDv; + myFaceRangeV[1] = aSurface->LastVParameter() + aDv; + } + + addInternalVertices(); + splitByDeflection2d(); +} + +//======================================================================= +//function : Destructor +//purpose : +//======================================================================= +BRepMesh_CurveTessellator::~BRepMesh_CurveTessellator () +{ +} + +//======================================================================= +//function : NbPoints +//purpose : +//======================================================================= +Standard_Integer BRepMesh_CurveTessellator::PointsNb () const +{ + return myDiscretTool.NbPoints (); +} + +//======================================================================= +//function : splitByDeflection2d +//purpose : +//======================================================================= +void BRepMesh_CurveTessellator::splitByDeflection2d () +{ + const Standard_Integer aNodesNb = myDiscretTool.NbPoints (); + if (!myDEdge->IsFree () && + myDEdge->GetSameParam () && + myDEdge->GetSameRange () && + aNodesNb > 1) + { + for (Standard_Integer aPCurveIt = 0; aPCurveIt < myDEdge->PCurvesNb (); ++aPCurveIt) + { + TopLoc_Location aLoc; + const IMeshData::IPCurveHandle& aPCurve = myDEdge->GetPCurve(aPCurveIt); + const TopoDS_Face& aFace = aPCurve->GetFace ().lock ()->GetFace (); + const Handle (Geom_Surface)& aSurface = BRep_Tool::Surface (aFace, aLoc); + if (aSurface->IsInstance(STANDARD_TYPE(Geom_Plane))) + { + continue; + } + + const TopoDS_Edge aCurrEdge = TopoDS::Edge(myEdge.Oriented(aPCurve->GetOrientation())); + + Standard_Real aF, aL; + Handle (Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface (aCurrEdge, aFace, aF, aL); + TColStd_Array1OfReal aParamArray (1, aNodesNb); + for (Standard_Integer i = 1; i <= aNodesNb; ++i) + aParamArray.SetValue (i, myDiscretTool.Parameter (i)); + + for (Standard_Integer i = 1; i < aNodesNb; ++i) + splitSegment (aSurface, aCurve2d, aParamArray (i), aParamArray (i + 1), 1); + } + } +} + +//======================================================================= +//function : addInternalVertices +//purpose : +//======================================================================= +void BRepMesh_CurveTessellator::addInternalVertices () +{ + // PTv, chl/922/G9, Take into account internal vertices + // it is necessary for internal edges, which do not split other edges, by their vertex + TopExp_Explorer aVertexIt (myEdge, TopAbs_VERTEX); + for (; aVertexIt.More (); aVertexIt.Next ()) + { + const TopoDS_Vertex& aVertex = TopoDS::Vertex (aVertexIt.Current ()); + if (aVertex.Orientation() != TopAbs_INTERNAL) + { + continue; + } + + myDiscretTool.AddPoint (BRep_Tool::Pnt (aVertex), + BRep_Tool::Parameter (aVertex, myEdge), Standard_True); + } +} + +//======================================================================= +//function : isInToleranceOfVertex +//purpose : +//======================================================================= +Standard_Boolean BRepMesh_CurveTessellator::isInToleranceOfVertex ( + const gp_Pnt& thePoint, + const TopoDS_Vertex& theVertex) const +{ + const gp_Pnt aPoint = BRep_Tool::Pnt(theVertex); + const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex); + + return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance); +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean BRepMesh_CurveTessellator::Value ( + const Standard_Integer theIndex, + gp_Pnt& thePoint, + Standard_Real& theParameter) const +{ + thePoint = myDiscretTool.Value (theIndex); + theParameter = myDiscretTool.Parameter (theIndex); + + /*if (!isInToleranceOfVertex(thePoint, myFirstVertex) && + !isInToleranceOfVertex(thePoint, myLastVertex)) + {*/ + if (!myCurve.IsCurveOnSurface()) + { + return Standard_True; + } + + // If point coordinates are out of surface range, + // it is necessary to re-project point. + const Adaptor3d_CurveOnSurface& aCurve = myCurve.CurveOnSurface(); + const Handle(Adaptor3d_HSurface)& aSurface = aCurve.GetSurface(); + if (aSurface->GetType() != GeomAbs_BSplineSurface && + aSurface->GetType() != GeomAbs_BezierSurface && + aSurface->GetType() != GeomAbs_OtherSurface) + { + return Standard_True; + } + + // Let skip periodic case. + if (aSurface->IsUPeriodic() || aSurface->IsVPeriodic()) + { + return Standard_True; + } + + gp_Pnt2d aUV; + aCurve.GetCurve()->D0(theParameter, aUV); + // Point lies within the surface range - nothing to do. + if (aUV.X() > myFaceRangeU[0] && aUV.X() < myFaceRangeU[1] && + aUV.Y() > myFaceRangeV[0] && aUV.Y() < myFaceRangeV[1]) + { + return Standard_True; + } + + gp_Pnt aPntOnSurf; + aSurface->D0(aUV.X(), aUV.Y(), aPntOnSurf); + + return (thePoint.SquareDistance(aPntOnSurf) < myEdgeSqTol); + /*} + + return Standard_False;*/ +} + +//======================================================================= +//function : splitSegment +//purpose : +//======================================================================= +void BRepMesh_CurveTessellator::splitSegment ( + const Handle (Geom_Surface)& theSurf, + const Handle (Geom2d_Curve)& theCurve2d, + const Standard_Real theFirst, + const Standard_Real theLast, + const Standard_Integer theNbIter) +{ + // limit iteration depth + if (theNbIter > 10) + { + return; + } + + gp_Pnt2d uvf, uvl, uvm; + gp_Pnt P3dF, P3dL, midP3d, midP3dFromSurf; + Standard_Real midpar; + + if (Abs(theLast - theFirst) < 2 * Precision::PConfusion()) + { + return; + } + + theCurve2d->D0 (theFirst, uvf); + theCurve2d->D0 (theLast, uvl); + + P3dF = theSurf->Value (uvf.X (), uvf.Y ()); + P3dL = theSurf->Value (uvl.X (), uvl.Y ()); + + if (P3dF.SquareDistance(P3dL) < mySquareMinSize) + { + return; + } + + uvm = gp_Pnt2d ((uvf.XY () + uvl.XY ())*0.5); + midP3dFromSurf = theSurf->Value (uvm.X (), uvm.Y ()); + + gp_XYZ Vec1 = midP3dFromSurf.XYZ () - P3dF.XYZ (); + if (Vec1.SquareModulus() < mySquareMinSize) + { + return; + } + + gp_XYZ aVec = P3dL.XYZ () - P3dF.XYZ (); + aVec.Normalize (); + + Standard_Real aModulus = Vec1.Dot (aVec); + gp_XYZ aProj = aVec * aModulus; + gp_XYZ aDist = Vec1 - aProj; + + if (aDist.SquareModulus() < mySquareEdgeDef) + { + return; + } + + midpar = (theFirst + theLast) * 0.5; + myCurve.D0 (midpar, midP3d); + myDiscretTool.AddPoint (midP3d, midpar, Standard_False); + + splitSegment (theSurf, theCurve2d, theFirst, midpar, theNbIter + 1); + splitSegment (theSurf, theCurve2d, midpar, theLast, theNbIter + 1); +} diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.hxx b/src/BRepMesh/BRepMesh_CurveTessellator.hxx new file mode 100644 index 0000000000..4a666be6b8 --- /dev/null +++ b/src/BRepMesh/BRepMesh_CurveTessellator.hxx @@ -0,0 +1,110 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_EdgeTessellator_HeaderFile +#define _BRepMesh_EdgeTessellator_HeaderFile + +#include +#include +#include +#include +#include + +class TopoDS_Face; +class Geom_Surface; +class Geom2d_Curve; +struct IMeshTools_Parameters; + +//! Auxiliary class performing tessellation of passed edge according to specified parameters. +class BRepMesh_CurveTessellator : public IMeshTools_CurveTessellator +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_CurveTessellator( + const IMeshData::IEdgeHandle& theEdge, + const IMeshTools_Parameters& theParameters); + + //! Constructor. + Standard_EXPORT BRepMesh_CurveTessellator ( + const IMeshData::IEdgeHandle& theEdge, + const TopAbs_Orientation theOrientation, + const IMeshData::IFaceHandle& theFace, + const IMeshTools_Parameters& theParameters); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_CurveTessellator (); + + //! Returns number of tessellation points. + Standard_EXPORT virtual Standard_Integer PointsNb () const Standard_OVERRIDE; + + //! Returns parameters of solution with the given index. + //! @param theIndex index of tessellation point. + //! @param theParameter parameters on PCurve corresponded to the solution. + //! @param thePoint tessellation point. + //! @return True in case of valid result, false elewhere. + Standard_EXPORT virtual Standard_Boolean Value ( + const Standard_Integer theIndex, + gp_Pnt& thePoint, + Standard_Real& theParameter) const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_CurveTessellator, IMeshTools_CurveTessellator) + +private: + + //! Performs initialization of this tool. + void init(); + + //! Adds internal vertices to discrete polygon. + void addInternalVertices (); + + //Check deflection in 2d space for improvement of edge tesselation. + void splitByDeflection2d (); + + void splitSegment ( + const Handle (Geom_Surface)& theSurf, + const Handle (Geom2d_Curve)& theCurve2d, + const Standard_Real theFirst, + const Standard_Real theLast, + const Standard_Integer theNbIter); + + //! Checks whether the given point lies within tolerance of the vertex. + Standard_Boolean isInToleranceOfVertex ( + const gp_Pnt& thePoint, + const TopoDS_Vertex& theVertex) const; + +private: + + BRepMesh_CurveTessellator (const BRepMesh_CurveTessellator& theOther); + + void operator=(const BRepMesh_CurveTessellator& theOther); + +private: + + const IMeshData::IEdgeHandle& myDEdge; + const IMeshTools_Parameters& myParameters; + TopoDS_Edge myEdge; + BRepAdaptor_Curve myCurve; + GCPnts_TangentialDeflection myDiscretTool; + TopoDS_Vertex myFirstVertex; + TopoDS_Vertex myLastVertex; + Standard_Real mySquareEdgeDef; + Standard_Real mySquareMinSize; + Standard_Real myEdgeSqTol; + Standard_Real myFaceRangeU[2]; + Standard_Real myFaceRangeV[2]; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx b/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx new file mode 100644 index 0000000000..131f110cd0 --- /dev/null +++ b/src/BRepMesh/BRepMesh_CylinderRangeSplitter.hxx @@ -0,0 +1,118 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_CylinderRangeSplitter_HeaderFile +#define _BRepMesh_CylinderRangeSplitter_HeaderFile + +#include +#include +#include + +//! 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& aRangeU = GetRangeU(); + const std::pair& 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 (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& aRangeV = GetRangeV(); + myDelta.first = myDu / Max(theLengthV, aRangeV.second - aRangeV.first); + myDelta.second = 1.; + } + +private: + + Standard_Real myDu; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx b/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx new file mode 100644 index 0000000000..37d0bad75e --- /dev/null +++ b/src/BRepMesh/BRepMesh_DefaultRangeSplitter.hxx @@ -0,0 +1,289 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_DefaultRangeSplitter_HeaderFile +#define _BRepMesh_DefaultRangeSplitter_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include + +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& GetRangeU() const + { + return myRangeU; + } + + //! Returns V range. + inline const std::pair& GetRangeV() const + { + return myRangeV; + } + + //! Returns delta. + inline const std::pair& GetDelta () const + { + return myDelta; + } + + inline const std::pair& 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 myRangeU; + std::pair myRangeV; + std::pair myDelta; + std::pair myTolerance; + Standard_Boolean myIsValid; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_Deflection.cxx b/src/BRepMesh/BRepMesh_Deflection.cxx new file mode 100644 index 0000000000..94258f8375 --- /dev/null +++ b/src/BRepMesh/BRepMesh_Deflection.cxx @@ -0,0 +1,157 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : RelativeEdgeDeflection +//purpose : +//======================================================================= +Standard_Real BRepMesh_Deflection::RelativeEdgeDeflection( + const TopoDS_Edge& theEdge, + const Standard_Real theDeflection, + const Standard_Real theMaxShapeSize, + Standard_Real& theAdjustmentCoefficient) +{ + theAdjustmentCoefficient = 1.; + Standard_Real aEdgeDeflection = theDeflection; + if (theEdge.IsNull()) + { + return aEdgeDeflection; + } + + Bnd_Box aBox; + BRepBndLib::Add (theEdge, aBox, Standard_False); + BRepMesh_ShapeTool::BoxMaxDimension (aBox, aEdgeDeflection); + + // Adjust resulting value in relation to the total size + theAdjustmentCoefficient = theMaxShapeSize / (2 * aEdgeDeflection); + if (theAdjustmentCoefficient < 0.5) + { + theAdjustmentCoefficient = 0.5; + } + else if (theAdjustmentCoefficient > 2.) + { + theAdjustmentCoefficient = 2.; + } + + return (theAdjustmentCoefficient * aEdgeDeflection * theDeflection); +} + +//======================================================================= +// Function: ComputeDeflection (edge) +// Purpose : +//======================================================================= +void BRepMesh_Deflection::ComputeDeflection ( + const IMeshData::IEdgeHandle& theDEdge, + const Standard_Real theMaxShapeSize, + const IMeshTools_Parameters& theParameters) +{ + Standard_Real aLinDeflection; + Standard_Real aAngDeflection; + if (theParameters.Relative) + { + Standard_Real aScale; + aLinDeflection = RelativeEdgeDeflection (theDEdge->GetEdge (), + theParameters.Deflection, theMaxShapeSize, aScale); + aAngDeflection = theParameters.Angle * aScale; + } + else + { + aLinDeflection = theParameters.Deflection; + aAngDeflection = theParameters.Angle; + } + + TopoDS_Vertex aFirstVertex, aLastVertex; + TopExp::Vertices(theDEdge->GetEdge(), aFirstVertex, aLastVertex); + + Handle(Geom_Curve) aCurve; + Standard_Real aFirstParam, aLastParam; + if (BRepMesh_ShapeTool::Range(theDEdge->GetEdge(), aCurve, aFirstParam, aLastParam)) + { + const Standard_Real aVertexAdjustDistance = + Max(BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam)), + BRep_Tool::Pnt(aLastVertex ).Distance(aCurve->Value(aLastParam))); + + aLinDeflection = Max(aVertexAdjustDistance, aLinDeflection); + } + + theDEdge->SetDeflection (aLinDeflection); + theDEdge->SetAngularDeflection (aAngDeflection); +} + +//======================================================================= +// Function: ComputeDeflection (wire) +// Purpose : +//======================================================================= +void BRepMesh_Deflection::ComputeDeflection ( + const IMeshData::IWireHandle& theDWire, + const IMeshTools_Parameters& theParameters) +{ + Standard_Real aWireDeflection = 0.; + if (theDWire->EdgesNb () > 0) + { + for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt) + { + aWireDeflection += theDWire->GetEdge(aEdgeIt).lock()->GetDeflection(); + } + + aWireDeflection /= theDWire->EdgesNb (); + } + else + { + aWireDeflection = theParameters.Deflection; + } + + theDWire->SetDeflection (aWireDeflection); +} + +//======================================================================= +// Function: ComputeDeflection (face) +// Purpose : +//======================================================================= +void BRepMesh_Deflection::ComputeDeflection ( + const IMeshData::IFaceHandle& theDFace, + const IMeshTools_Parameters& theParameters) +{ + Standard_Real aFaceDeflection = 0.; + if (theDFace->WiresNb () > 0) + { + for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt) + { + aFaceDeflection += theDFace->GetWire(aWireIt)->GetDeflection(); + } + + aFaceDeflection /= theDFace->WiresNb (); + } + else + { + aFaceDeflection = theParameters.Deflection; + } + + theDFace->SetDeflection (Max(2.* BRepMesh_ShapeTool::MaxFaceTolerance( + theDFace->GetFace()), aFaceDeflection)); +} diff --git a/src/BRepMesh/BRepMesh_Deflection.hxx b/src/BRepMesh/BRepMesh_Deflection.hxx new file mode 100644 index 0000000000..7c3b5aed77 --- /dev/null +++ b/src/BRepMesh/BRepMesh_Deflection.hxx @@ -0,0 +1,66 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_Deflection_HeaderFile +#define _BRepMesh_Deflection_HeaderFile + +#include +#include +#include +#include + +class Bnd_Box; +class TopoDS_Face; +class TopoDS_Edge; +struct IMeshTools_Parameters; + +//! Auxiliary tool encompassing methods to compute deflection of shapes. +class BRepMesh_Deflection : public Standard_Transient +{ +public: + + //! Returns relative deflection for edge with respect to shape size. + //! @param theEdge edge for which relative deflection should be computed. + //! @param theDeflection absolute deflection. + //! @param theMaxShapeSize maximum size of a shape. + //! @param theAdjustmentCoefficient coefficient of adjustment between maximum + //! size of shape and calculated relative deflection. + //! @return relative deflection for the edge. + Standard_EXPORT static Standard_Real RelativeEdgeDeflection ( + const TopoDS_Edge& theEdge, + const Standard_Real theDeflection, + const Standard_Real theMaxShapeSize, + Standard_Real& theAdjustmentCoefficient); + + //! Computes and updates deflection of the given discrete edge. + Standard_EXPORT static void ComputeDeflection ( + const IMeshData::IEdgeHandle& theDEdge, + const Standard_Real theMaxShapeSize, + const IMeshTools_Parameters& theParameters); + + //! Computes and updates deflection of the given discrete wire. + Standard_EXPORT static void ComputeDeflection ( + const IMeshData::IWireHandle& theDWire, + const IMeshTools_Parameters& theParameters); + + //! Computes and updates deflection of the given discrete face. + Standard_EXPORT static void ComputeDeflection ( + const IMeshData::IFaceHandle& theDFace, + const IMeshTools_Parameters& theParameters); + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Deflection, Standard_Transient) +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx new file mode 100644 index 0000000000..c130094f9c --- /dev/null +++ b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.cxx @@ -0,0 +1,56 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_DelaunayBaseMeshAlgo::BRepMesh_DelaunayBaseMeshAlgo() +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_DelaunayBaseMeshAlgo::~BRepMesh_DelaunayBaseMeshAlgo() +{ +} + +//======================================================================= +//function : generateMesh +//purpose : +//======================================================================= +void BRepMesh_DelaunayBaseMeshAlgo::generateMesh() +{ + const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = getStructure(); + const Handle(VectorOfPnt)& aNodesMap = getNodesMap(); + + IMeshData::VectorOfInteger aVerticesOrder(aNodesMap->Size(), getAllocator()); + for (Standard_Integer i = 1; i <= aNodesMap->Size(); ++i) + { + aVerticesOrder.Append(i); + } + + BRepMesh_Delaun aMesher(aStructure, aVerticesOrder); + BRepMesh_MeshTool aCleaner(aStructure); + aCleaner.EraseFreeLinks(); + + postProcessMesh(aMesher); +} diff --git a/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx new file mode 100644 index 0000000000..864ae35ada --- /dev/null +++ b/src/BRepMesh/BRepMesh_DelaunayBaseMeshAlgo.hxx @@ -0,0 +1,52 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile +#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile + +#include +#include +#include + +class BRepMesh_DataStructureOfDelaun; +class BRepMesh_Delaun; + +//! Class provides base fuctionality to build face triangulation using Dealunay approach. +//! Performs generation of mesh using raw data from model. +class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_DelaunayBaseMeshAlgo(); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo(); + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo) + +protected: + + //! Generates mesh for the contour stored in data structure. + Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE; + + //! Perfroms processing of generated mesh. + //! By default does nothing. + Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/) + { + } +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx new file mode 100644 index 0000000000..c7c62f7373 --- /dev/null +++ b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx @@ -0,0 +1,414 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshTools_DelaunayDeflectionControlMeshAlgo_HeaderFile +#define _BRepMeshTools_DelaunayDeflectionControlMeshAlgo_HeaderFile + +#include +#include + +//! Extends node insertion Delaunay meshing algo in order to control +//! deflection of generated trianges. Splits triangles failing the check. +template +class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo +{ +private: + // Typedef for OCCT RTTI + typedef BRepMesh_DelaunayNodeInsertionMeshAlgo 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 + 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(*myCircles).Select( + this->getRangeSplitter().Scale(thePnt2d, Standard_True).XY()); + + IMeshData::ListOfInteger::Iterator aCircleIt(aCirclesList); + for (; aCircleIt.More(); aCircleIt.Next()) + { + const BRepMesh_Triangle& aTriangle = this->getStructure()->GetElement(aCircleIt.Value()); + + Standard_Integer aNodes[3]; + this->getStructure()->ElementNodes(aTriangle, aNodes); + + for (Standard_Integer i = 0; i < 3; ++i) + { + if (!aUsedNodes.Contains(aNodes[i])) + { + aUsedNodes.Add(aNodes[i]); + const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]); + const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d()); + + if (thePnt3d.SquareDistance(aPoint) < aSqMinSize) + { + return Standard_True; + } + } + } + } + + return Standard_False; + } + +private: + Standard_Real myMaxSqDeflection; + Standard_Boolean myIsAllDegenerated; + Handle(IMeshData::MapOfOrientedEdges) myCouplesMap; + Handle(IMeshData::ListOfPnt2d) myControlNodes; + const BRepMesh_CircleTool* myCircles; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx new file mode 100644 index 0000000000..e15cd5397a --- /dev/null +++ b/src/BRepMesh/BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx @@ -0,0 +1,82 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile +#define _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile + +#include + +//! Extends base Delaunay meshing algo in order to enable possibility +//! of addition of free vertices and internal nodes into the mesh. +template +class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo +{ +private: + // Typedef for OCCT RTTI + typedef BRepMesh_NodeInsertionMeshAlgo InsertionBaseClass; + +public: + + //! Constructor. + Standard_EXPORT BRepMesh_DelaunayNodeInsertionMeshAlgo() + { + } + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_DelaunayNodeInsertionMeshAlgo() + { + } + +protected: + + //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure. + Standard_EXPORT virtual void postProcessMesh(BRepMesh_Delaun& theMesher) Standard_OVERRIDE + { + InsertionBaseClass::postProcessMesh(theMesher); + + const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes = + this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters()); + + insertNodes(aSurfaceNodes, theMesher); + } + + //! Inserts nodes into mesh. + Standard_EXPORT Standard_Boolean insertNodes( + const Handle(IMeshData::ListOfPnt2d)& theNodes, + BRepMesh_Delaun& theMesher) + { + if (theNodes.IsNull() || theNodes->IsEmpty()) + { + return Standard_False; + } + + IMeshData::VectorOfInteger aVertexIndexes(theNodes->Size(), this->getAllocator()); + IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes); + for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt) + { + const gp_Pnt2d& aPnt2d = aNodesIt.Value(); + if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN) + { + aVertexIndexes.Append(this->registerNode(this->getRangeSplitter().Point(aPnt2d), + aPnt2d, BRepMesh_Free, Standard_False)); + } + } + + theMesher.AddVertices(aVertexIndexes); + return !aVertexIndexes.IsEmpty(); + } +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.cxx b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx new file mode 100644 index 0000000000..ecf3fc9518 --- /dev/null +++ b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx @@ -0,0 +1,317 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// 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 aProvider( + theDEdge, aPCurve->GetOrientation(), aPCurve->GetFace().lock(), aCurveArray); + + const Handle(Adaptor2d_HCurve2d)& aGeomPCurve = aProvider.GetPCurve(); + + Standard_Integer aParamIdx, aParamNb; + if (theUpdateEnds) + { + aParamIdx = 0; + aParamNb = aCurve->ParametersNb(); + } + else + { + aParamIdx = 1; + aParamNb = aCurve->ParametersNb() - 1; + } + + for (; aParamIdx < aParamNb; ++aParamIdx) + { + const Standard_Real aParam = aProvider.Parameter(aParamIdx, aCurve->GetPoint(aParamIdx)); + + gp_Pnt2d aPoint2d; + aGeomPCurve->D0(aParam, aPoint2d); + if (theUpdateEnds) + { + aPCurve->AddPoint(aPoint2d, aParam); + } + else + { + aPCurve->InsertPoint(aPCurve->ParametersNb() - 1, aPoint2d, aParam); + } + } + } +} diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.hxx b/src/BRepMesh/BRepMesh_EdgeDiscret.hxx new file mode 100644 index 0000000000..0793d01cdb --- /dev/null +++ b/src/BRepMesh/BRepMesh_EdgeDiscret.hxx @@ -0,0 +1,96 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_EdgeDiscret_HeaderFile +#define _BRepMesh_EdgeDiscret_HeaderFile + +#include +#include +#include + +class IMeshTools_CurveTessellator; + +//! Class implements functionality of edge discret tool. +//! Performs check of the edges for existing Poly_PolygonOnTriangulation. +//! In case if it fits specified deflection, restores data structure using +//! it, else clears edges from outdated data. +class BRepMesh_EdgeDiscret : public IMeshTools_ModelAlgo +{ +public: + //! Constructor. + Standard_EXPORT BRepMesh_EdgeDiscret (); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_EdgeDiscret (); + + //! Creates instance of free edge tessellator. + Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellator( + const IMeshData::IEdgeHandle& theDEdge, + const IMeshTools_Parameters& theParameters); + + //! Creates instance of edge tessellator. + Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellator( + const IMeshData::IEdgeHandle& theDEdge, + const TopAbs_Orientation theOrientation, + const IMeshData::IFaceHandle& theDFace, + const IMeshTools_Parameters& theParameters); + + //! Creates instance of tessellation extractor. + Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellationExtractor( + const IMeshData::IEdgeHandle& theDEdge, + const IMeshData::IFaceHandle& theDFace); + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform ( + const Handle (IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + //! Functor API to discretize the given edge. + inline void operator() (const Standard_Integer theEdgeIndex) const { + process (theEdgeIndex); + } + + //! Updates 3d discrete edge model using the given tessellation tool. + Standard_EXPORT static void Tessellate3d( + const IMeshData::IEdgeHandle& theDEdge, + const Handle(IMeshTools_CurveTessellator)& theTessellator, + const Standard_Boolean theUpdateEnds); + + //! Updates 2d discrete edge model using tessellation of 3D curve. + Standard_EXPORT static void Tessellate2d( + const IMeshData::IEdgeHandle& theDEdge, + const Standard_Boolean theUpdateEnds); + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo) + +private: + + //! Checks existing discretization of the edge and updates data model. + void process (const Standard_Integer theEdgeIndex) const; + + //! Checks existing polygon on triangulation does it fit edge deflection or not. + //! @return deflection of polygon or RealLast () in case if edge has no polygon + //! or it was dropped. + Standard_Real checkExistingPolygonAndUpdateStatus( + const IMeshData::IEdgeHandle& theDEdge, + const IMeshData::IPCurveHandle& thePCurve) const; + +private: + + Handle (IMeshData_Model) myModel; + IMeshTools_Parameters myParameters; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_FaceChecker.cxx b/src/BRepMesh/BRepMesh_FaceChecker.cxx new file mode 100644 index 0000000000..0a2c73f7a4 --- /dev/null +++ b/src/BRepMesh/BRepMesh_FaceChecker.cxx @@ -0,0 +1,317 @@ +// Created on: 2016-07-04 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include + +namespace +{ + const Standard_Real MaxTangentAngle = 5. * M_PI / 180.; + + //! Functor to be used to fill segments and bounding box tree in parallel. + class SegmentsFiller + { + public: + //! Constructor. + SegmentsFiller(const IMeshData::IFaceHandle& theDFace, + Handle(BRepMesh_FaceChecker::ArrayOfSegments)& theWiresSegments, + Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& theWiresBndBoxTree) + : myDFace(theDFace), + myWiresSegments(theWiresSegments), + myWiresBndBoxTree(theWiresBndBoxTree) + { + myWiresSegments = new BRepMesh_FaceChecker::ArrayOfSegments (0, myDFace->WiresNb() - 1); + myWiresBndBoxTree = new BRepMesh_FaceChecker::ArrayOfBndBoxTree (0, myDFace->WiresNb() - 1); + } + + //! Performs initialization of wire with the given index. + void operator()(const Standard_Integer theWireIndex) const + { + const IMeshData::IWireHandle& aDWire = myDFace->GetWire(theWireIndex); + + Handle(NCollection_IncAllocator) aTmpAlloc1 = + new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE); + + Handle(BRepMesh_FaceChecker::Segments) aSegments = + new BRepMesh_FaceChecker::Segments(aDWire->EdgesNb(), aTmpAlloc1); + Handle(IMeshData::BndBox2dTree) aBndBoxTree = new IMeshData::BndBox2dTree(aTmpAlloc1); + + myWiresSegments ->ChangeValue(theWireIndex) = aSegments; + myWiresBndBoxTree->ChangeValue(theWireIndex) = aBndBoxTree; + + Handle(NCollection_IncAllocator) aTmpAlloc2 = + new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE); + IMeshData::BndBox2dTreeFiller aBndBoxTreeFiller(*aBndBoxTree, aTmpAlloc2); + + for (Standard_Integer aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt) + { + // TODO: check 2d wire for consistency. + + const IMeshData::IEdgePtr& aDEdge = aDWire->GetEdge(aEdgeIt); + const IMeshData::IPCurveHandle& aPCurve = aDEdge.lock()->GetPCurve(myDFace, aDWire->GetEdgeOrientation(aEdgeIt)); + + for (Standard_Integer aPointIt = 1; aPointIt < aPCurve->ParametersNb(); ++aPointIt) + { + gp_Pnt2d& aPnt1 = aPCurve->GetPoint(aPointIt - 1); + gp_Pnt2d& aPnt2 = aPCurve->GetPoint(aPointIt); + + Bnd_Box2d aBox; + aBox.Add(aPnt1); + aBox.Add(aPnt2); + aBox.Enlarge(Precision::Confusion()); + + aBndBoxTreeFiller.Add(aSegments->Size(), aBox); + aSegments->Append(BRepMesh_FaceChecker::Segment(aDEdge, &aPnt1, &aPnt2)); + } + } + + aBndBoxTreeFiller.Fill(); + } + + private: + + SegmentsFiller (const SegmentsFiller& theOther); + + void operator=(const SegmentsFiller& theOther); + + private: + + const IMeshData::IFaceHandle& myDFace; + Handle(BRepMesh_FaceChecker::ArrayOfSegments)& myWiresSegments; + Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree; + }; + + //! Selector. + //! Used to identify segments with overlapped bounding boxes. + //! Selector. + //! Used to identify segments with overlapped bounding boxes. + class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector + { + public: + //! Constructor. + BndBox2dTreeSelector(const Standard_Real theTolerance) + : myMaxLoopSize(M_PI * theTolerance * theTolerance), + mySelfSegmentIndex(-1), + myIndices(256, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)) + { + } + + //! Sets working set of segments. + void SetSegments(const Handle(BRepMesh_FaceChecker::Segments)& theSegments) + { + mySegments = theSegments; + } + + //! Resets current selector. + void Reset(const BRepMesh_FaceChecker::Segment* theSegment, + const Standard_Integer theSelfSegmentIndex) + { + myIndices.Clear(); + + mySelfSegmentIndex = theSelfSegmentIndex; + mySegment = theSegment; + + myBox.SetVoid(); + myBox.Add(*mySegment->Point1); + myBox.Add(*mySegment->Point2); + myBox.Enlarge(Precision::Confusion()); + } + + //! Indicates should the given box be rejected or not. + virtual Standard_Boolean Reject(const Bnd_Box2d& theBox) const + { + return myBox.IsOut(theBox); + } + + //! Accepts segment with the given index in case if it fits conditions. + virtual Standard_Boolean Accept(const Standard_Integer& theSegmentIndex) + { + const BRepMesh_FaceChecker::Segment& aSegment = mySegments->Value(theSegmentIndex); + + gp_Pnt2d aIntPnt; + const BRepMesh_GeomTool::IntFlag aIntStatus = BRepMesh_GeomTool::IntSegSeg( + mySegment->Point1->XY(), mySegment->Point2->XY(), + aSegment.Point1->XY(), aSegment.Point2->XY(), + Standard_False, Standard_False, aIntPnt); + + if (aIntStatus == BRepMesh_GeomTool::Cross) + { + const Standard_Real aAngle = gp_Vec2d(mySegment->Point1->XY(), mySegment->Point2->XY()).Angle( + gp_Vec2d(aSegment.Point1->XY(), aSegment.Point2->XY())); + + if (Abs(aAngle) < MaxTangentAngle) + { + return Standard_False; + } + + if (mySelfSegmentIndex != -1) + { + gp_XY aPrevVec; + Standard_Real aSumS = 0.; + const gp_XY& aRefPnt = aIntPnt.Coord(); + for (Standard_Integer i = mySelfSegmentIndex; i < theSegmentIndex; ++i) + { + const BRepMesh_FaceChecker::Segment& aCurrSegment = mySegments->Value(i); + gp_XY aCurVec = aCurrSegment.Point2->XY() - aRefPnt; + + if (aCurVec.SquareModulus() < gp::Resolution()) + continue; + + if (aPrevVec.SquareModulus() > gp::Resolution()) + aSumS += aPrevVec ^ aCurVec; + + aPrevVec = aCurVec; + } + + if (Abs(aSumS / 2.) < myMaxLoopSize) + { + return Standard_False; + } + } + + myIndices.Append(theSegmentIndex); + return Standard_True; + } + + return Standard_False; + } + + //! Returns indices of intersecting segments. + const IMeshData::VectorOfInteger& Indices() const + { + return myIndices; + } + + private: + + Standard_Real myMaxLoopSize; + Standard_Integer mySelfSegmentIndex; + Handle(BRepMesh_FaceChecker::Segments) mySegments; + const BRepMesh_FaceChecker::Segment* mySegment; + Bnd_Box2d myBox; + IMeshData::VectorOfInteger myIndices; + }; +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +BRepMesh_FaceChecker::BRepMesh_FaceChecker( + const IMeshData::IFaceHandle& theFace, + const IMeshTools_Parameters& theParameters) + : myDFace(theFace), + myParameters(theParameters) +{ +} + +//======================================================================= +//function : Destructor +//purpose : +//======================================================================= +BRepMesh_FaceChecker::~BRepMesh_FaceChecker() +{ +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +Standard_Boolean BRepMesh_FaceChecker::Perform() +{ + myIntersectingEdges = new IMeshData::MapOfIEdgePtr; + collectSegments(); + + OSD_Parallel::For(0, myDFace->WiresNb(), *this, !isParallel()); + collectResult(); + + myWiresBndBoxTree.Nullify(); + myWiresSegments.Nullify(); + myWiresIntersectingEdges.Nullify(); + return myIntersectingEdges->IsEmpty(); +} + +//======================================================================= +//function : collectSegments +//purpose : +//======================================================================= +void BRepMesh_FaceChecker::collectSegments() +{ + SegmentsFiller aSegmentsFiller(myDFace, myWiresSegments, myWiresBndBoxTree); + OSD_Parallel::For(0, myDFace->WiresNb(), aSegmentsFiller, !isParallel()); + + myWiresIntersectingEdges = new ArrayOfMapOfIEdgePtr(0, myDFace->WiresNb() - 1); +} + +//======================================================================= +//function : perform +//purpose : +//======================================================================= +void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const +{ + const Handle(Segments)& aSegments1 = myWiresSegments->Value(theWireIndex); + Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex); + + // TODO: Tolerance is set to twice value of face deflection in order to fit regressions. + BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection()); + for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt) + { + const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt); + const Handle(Segments)& aSegments2 = myWiresSegments->Value(aWireIt); + + aSelector.SetSegments(aSegments2); + for (Standard_Integer aSegmentIt = 0; aSegmentIt < aSegments1->Size(); ++aSegmentIt) + { + const BRepMesh_FaceChecker::Segment& aSegment1 = aSegments1->Value(aSegmentIt); + aSelector.Reset(&aSegment1, (aWireIt == theWireIndex) ? aSegmentIt : -1); + if (aBndBoxTree2->Select(aSelector) != 0) + { + if (aIntersections.IsNull()) + { + aIntersections = new IMeshData::MapOfIEdgePtr; + } + + aIntersections->Add(aSegment1.EdgePtr); + + const IMeshData::VectorOfInteger& aSegments = aSelector.Indices(); + for (Standard_Integer aSelIt = 0; aSelIt < aSegments.Size(); ++aSelIt) + { + const BRepMesh_FaceChecker::Segment& aSegment2 = aSegments2->Value(aSegments(aSelIt)); + aIntersections->Add(aSegment2.EdgePtr); + } + } + } + } +} + +//======================================================================= +//function : collectResult +//purpose : +//======================================================================= +void BRepMesh_FaceChecker::collectResult() +{ + for (Standard_Integer aWireIt = 0; aWireIt < myDFace->WiresNb(); ++aWireIt) + { + const Handle(IMeshData::MapOfIEdgePtr)& aEdges = myWiresIntersectingEdges->Value(aWireIt); + if (!aEdges.IsNull()) + { + myIntersectingEdges->Unite(*aEdges); + } + } +} diff --git a/src/BRepMesh/BRepMesh_FaceChecker.hxx b/src/BRepMesh/BRepMesh_FaceChecker.hxx new file mode 100644 index 0000000000..93f574a45d --- /dev/null +++ b/src/BRepMesh/BRepMesh_FaceChecker.hxx @@ -0,0 +1,122 @@ +// Created on: 2016-07-04 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_FaceChecker_HeaderFile +#define _BRepMesh_FaceChecker_HeaderFile + +#include +#include +#include +#include +#include + +//! 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 > Segments; + typedef NCollection_Shared > ArrayOfSegments; + typedef NCollection_Shared > ArrayOfBndBoxTree; + typedef NCollection_Shared > ArrayOfMapOfIEdgePtr; + + + //! Default constructor + Standard_EXPORT BRepMesh_FaceChecker(const IMeshData::IFaceHandle& theFace, + const IMeshTools_Parameters& theParameters); + + //! Destructor + Standard_EXPORT virtual ~BRepMesh_FaceChecker(); + + //! Performs check wires of the face for intersections. + //! @return True if there is no intersection, False elsewhere. + Standard_EXPORT Standard_Boolean Perform(); + + //! Returns intersecting edges. + const Handle(IMeshData::MapOfIEdgePtr)& GetIntersectingEdges() const + { + return myIntersectingEdges; + } + + //! Checks wire with the given index for intersection with others. + inline void operator()(const Standard_Integer theWireIndex) const + { + perform(theWireIndex); + } + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceChecker, Standard_Transient) + +private: + + //! Returns True in case if check can be performed in parallel mode. + inline Standard_Boolean isParallel() const + { + return (myParameters.InParallel && myDFace->WiresNb() > 1); + } + + //! Collects face segments. + void collectSegments(); + + //! Collects intersecting edges. + void collectResult(); + + //! Checks wire with the given index for intersection with others. + void perform(const Standard_Integer theWireIndex) const; + +private: + + BRepMesh_FaceChecker (const BRepMesh_FaceChecker& theOther); + + void operator=(const BRepMesh_FaceChecker& theOther); + +private: + + IMeshData::IFaceHandle myDFace; + const IMeshTools_Parameters& myParameters; + + Handle(ArrayOfSegments) myWiresSegments; + Handle(ArrayOfBndBoxTree) myWiresBndBoxTree; + Handle(ArrayOfMapOfIEdgePtr) myWiresIntersectingEdges; + Handle(IMeshData::MapOfIEdgePtr) myIntersectingEdges; + +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_FaceDiscret.cxx b/src/BRepMesh/BRepMesh_FaceDiscret.cxx new file mode 100644 index 0000000000..5a0688b8ff --- /dev/null +++ b/src/BRepMesh/BRepMesh_FaceDiscret.cxx @@ -0,0 +1,86 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_FaceDiscret::BRepMesh_FaceDiscret( + const Handle(IMeshTools_MeshAlgoFactory)& theAlgoFactory) + : myAlgoFactory(theAlgoFactory) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret() +{ +} + +//======================================================================= +// Function: Perform +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_FaceDiscret::Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) +{ + myModel = theModel; + myParameters = theParameters; + if (myModel.IsNull()) + { + return Standard_False; + } + + OSD_Parallel::For(0, myModel->FacesNb(), *this, !(myParameters.InParallel && myModel->FacesNb() > 1)); + + myModel.Nullify(); // Do not hold link to model. + return Standard_True; +} + +//======================================================================= +// Function: process +// Purpose : +//======================================================================= +void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const +{ + const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex); + if (aDFace->IsSet(IMeshData_Failure) || + aDFace->IsSet(IMeshData_Reused)) + { + return; + } + + Handle(IMeshTools_MeshAlgo) aMeshingAlgo = + myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters); + + if (aMeshingAlgo.IsNull()) + { + aDFace->SetStatus(IMeshData_Failure); + return; + } + + aMeshingAlgo->Perform(aDFace, myParameters); +} diff --git a/src/BRepMesh/BRepMesh_FaceDiscret.hxx b/src/BRepMesh/BRepMesh_FaceDiscret.hxx new file mode 100644 index 0000000000..cf706cb5c4 --- /dev/null +++ b/src/BRepMesh/BRepMesh_FaceDiscret.hxx @@ -0,0 +1,63 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_FaceDiscret_HeaderFile +#define _BRepMesh_FaceDiscret_HeaderFile + +#include +#include +#include +#include + +//! Class implements functionality starting triangulation of model's faces. +//! Each face is processed separately and can be executed in parallel mode. +//! Uses mesh algo factory passed as initializer to create instace of triangulation +//! algorithm according to type of surface of target face. +class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_FaceDiscret( + const Handle(IMeshTools_MeshAlgoFactory)& theAlgoFactory); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_FaceDiscret(); + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + //! Functor API to discretize the given edge. + inline void operator() (const Standard_Integer theFaceIndex) const { + process(theFaceIndex); + } + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo) + +private: + + //! Checks existing discretization of the face and updates data model. + void process(const Standard_Integer theFaceIndex) const; + +private: + + Handle(IMeshTools_MeshAlgoFactory) myAlgoFactory; + Handle(IMeshData_Model) myModel; + IMeshTools_Parameters myParameters; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_IncAllocator.hxx b/src/BRepMesh/BRepMesh_IncAllocator.hxx new file mode 100644 index 0000000000..ebe5fdacf6 --- /dev/null +++ b/src/BRepMesh/BRepMesh_IncAllocator.hxx @@ -0,0 +1,50 @@ +// Created on: 2016-06-20 +// Created by: Oleg AGASHIN +// Copyright (c) 2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_IncAllocator_HeaderFile +#define _BRepMesh_IncAllocator_HeaderFile + +#include +#include + +//! Extension for NCollection_IncAllocator implementing simple thread safety +//! by introduction of Mutex. Intended for use in couple with BRepMeshData +//! entities in order to prevent data races while building data model in +//! parallel mode. Note that this allocator is supposed for use by collections +//! which allocate memory by huge blocks at arbitrary moment, thus it should +//! not introduce significant performance slow down. +class BRepMesh_IncAllocator : public NCollection_IncAllocator +{ +public: + //! Constructor + Standard_EXPORT BRepMesh_IncAllocator(const size_t theBlockSize = DefaultBlockSize) + : NCollection_IncAllocator(theBlockSize) + { + } + + //! Allocate memory with given size. Returns NULL on failure + Standard_EXPORT virtual void* Allocate(const size_t size) Standard_OVERRIDE + { + Standard_Mutex::Sentry aSentry(myMutex); + return NCollection_IncAllocator::Allocate(size); + } + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_IncAllocator, NCollection_IncAllocator) + +private: + Standard_Mutex myMutex; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx b/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx new file mode 100644 index 0000000000..f73e95dbcd --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshAlgoFactory.cxx @@ -0,0 +1,103 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + struct BaseMeshAlgo + { + typedef BRepMesh_DelaunayBaseMeshAlgo Type; + }; + + template + struct NodeInsertionMeshAlgo + { + typedef BRepMesh_DelaunayNodeInsertionMeshAlgo Type; + }; + + template + struct DeflectionControlMeshAlgo + { + typedef BRepMesh_DelaunayDeflectionControlMeshAlgo 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::Type : + new BaseMeshAlgo::Type; + break; + + case GeomAbs_Sphere: + return new NodeInsertionMeshAlgo::Type; + break; + + case GeomAbs_Cylinder: + return new NodeInsertionMeshAlgo::Type; + break; + + case GeomAbs_Cone: + return new NodeInsertionMeshAlgo::Type; + break; + + case GeomAbs_Torus: + return new NodeInsertionMeshAlgo::Type; + break; + + case GeomAbs_SurfaceOfRevolution: + return new DeflectionControlMeshAlgo::Type; + break; + + default: + return new DeflectionControlMeshAlgo::Type; + } +} diff --git a/src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx b/src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx new file mode 100644 index 0000000000..72a27c5587 --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshAlgoFactory.hxx @@ -0,0 +1,44 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_MeshAlgoFactory_HeaderFile +#define _BRepMesh_MeshAlgoFactory_HeaderFile + +#include +#include +#include +#include + +//! Default implementation of IMeshTools_MeshAlgoFactory providing algorithms +//! of different compexity depending on type of target surface. +class BRepMesh_MeshAlgoFactory : public IMeshTools_MeshAlgoFactory +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_MeshAlgoFactory(); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_MeshAlgoFactory(); + + //! Creates instance of meshing algorithm for the given type of surface. + Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo( + const GeomAbs_SurfaceType theSurfaceType, + const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshAlgoFactory, IMeshTools_MeshAlgoFactory) +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_MeshBuilder.cxx b/src/BRepMesh/BRepMesh_MeshBuilder.cxx new file mode 100644 index 0000000000..78cd8cacaa --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshBuilder.cxx @@ -0,0 +1,118 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_MeshBuilder::BRepMesh_MeshBuilder () +{ +} + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_MeshBuilder::BRepMesh_MeshBuilder ( + const Handle (IMeshTools_Context)& theContext) + : IMeshTools_MeshBuilder (theContext) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_MeshBuilder::~BRepMesh_MeshBuilder () +{ +} + +//======================================================================= +// Function: Perform +// Purpose : +//======================================================================= +void BRepMesh_MeshBuilder::Perform () +{ + ClearStatus (); + + const Handle (IMeshTools_Context)& aContext = GetContext (); + if (aContext.IsNull ()) + { + SetStatus (Message_Fail1); + return; + } + + if (aContext->BuildModel ()) + { + if (aContext->DiscretizeEdges ()) + { + if (aContext->HealModel ()) + { + if (aContext->PreProcessModel()) + { + if (aContext->DiscretizeFaces()) + { + if (aContext->PostProcessModel()) + { + SetStatus(Message_Done1); + } + else + { + SetStatus(Message_Fail6); + } + } + else + { + SetStatus(Message_Fail5); + } + } + else + { + SetStatus(Message_Fail4); + } + } + else + { + SetStatus(Message_Fail3); + } + } + else + { + SetStatus (Message_Fail1); + } + } + else + { + const Handle (IMeshTools_ModelBuilder)& aModelBuilder = + aContext->GetModelBuilder (); + + if (aModelBuilder.IsNull ()) + { + SetStatus (Message_Fail1); + } + else + { + // Is null shape or another problem? + SetStatus (aModelBuilder->GetStatus ().IsSet (Message_Fail1) ? + Message_Warn1 : Message_Fail2); + } + } + + aContext->Clean (); +} diff --git a/src/BRepMesh/BRepMesh_MeshBuilder.hxx b/src/BRepMesh/BRepMesh_MeshBuilder.hxx new file mode 100644 index 0000000000..d35ab93942 --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshBuilder.hxx @@ -0,0 +1,52 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_MeshBuilder_HeaderFile +#define _BRepMesh_MeshBuilder_HeaderFile + +#include + +//! Builds mesh for each face of shape without triangulation. +//! In case if some faces of shape have already been triangulated +//! checks deflection of existing polygonal model and re-uses it +//! if deflection satisfies the specified parameter. Otherwise +//! nullifies existing triangulation and build triangulation anew. +//! +//! The following statuses are used: +//! Message_Done1 - algorithm has finished without errors. +//! Message_Fail1 - invalid context. +//! Message_Fail2 - algorithm has faced unexpected error. +//! Message_Fail3 - can't heal discrete model. +//! Message_Warn1 - shape contains no objects to mesh. +class BRepMesh_MeshBuilder : public IMeshTools_MeshBuilder +{ +public: //! @name mesher API + + //! Default constructor + Standard_EXPORT BRepMesh_MeshBuilder (); + + //! Default constructor + Standard_EXPORT BRepMesh_MeshBuilder (const Handle (IMeshTools_Context)& theContext); + + //! Destructor + Standard_EXPORT virtual ~BRepMesh_MeshBuilder (); + + //! Performs meshing ot the shape. + Standard_EXPORT virtual void Perform () Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_MeshBuilder, IMeshTools_MeshBuilder) +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_MeshTool.cxx b/src/BRepMesh/BRepMesh_MeshTool.cxx new file mode 100644 index 0000000000..31a304f883 --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshTool.cxx @@ -0,0 +1,368 @@ +// Created on: 2016-08-22 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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 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 aStack; + aStack.push(theStartLink); + aUsedLinks.Add(theStartLink); + + while (!aStack.empty()) + { + const Standard_Integer aLinkIndex = aStack.top(); + aStack.pop(); + + const BRepMesh_Edge& aLink = myStructure->GetLink(aLinkIndex); + if (aLink.Movability() == BRepMesh_Free && + (aLink.FirstNode() == theConstraint.FirstNode() || + aLink.LastNode () == theConstraint.FirstNode() || + aLink.FirstNode() == theConstraint.LastNode () || + aLink.LastNode () == theConstraint.LastNode ())) + { + const BRepMesh_PairOfIndex& aPair = myStructure->ElementsConnectedTo(aLinkIndex); + for (Standard_Integer aElemIt = 1; aElemIt <= aPair.Extent(); ++aElemIt) + { + const Standard_Integer aIndex = aPair.Index(aElemIt); + theTriangles.Add(aIndex); + + const BRepMesh_Triangle& aElement = myStructure->GetElement(aIndex); + const Standard_Integer(&aEdges)[3] = aElement.myEdges; + + for (Standard_Integer i = 0; i < 3; ++i) + { + if (aEdges[i] != aLinkIndex && !aUsedLinks.Contains(aEdges[i])) + { + aUsedLinks.Add(aEdges[i]); + aStack .push(aEdges[i]); + } + } + } + } + } +} + +//======================================================================= +//function : EraseFreeLinks +//purpose : +//======================================================================= +void BRepMesh_MeshTool::EraseFreeLinks( + const IMeshData::MapOfIntegerInteger& theLinks) +{ + IMeshData::MapOfIntegerInteger::Iterator aFreeEdges(theLinks); + for (; aFreeEdges.More(); aFreeEdges.Next()) + { + if (myStructure->ElementsConnectedTo(aFreeEdges.Key()).IsEmpty()) + { + myStructure->RemoveLink(aFreeEdges.Key()); + } + } +} + +//======================================================================= +//function : GetEdgesByType +//purpose : +//======================================================================= +Handle(IMeshData::MapOfInteger) BRepMesh_MeshTool::GetEdgesByType( + const BRepMesh_DegreeOfFreedom theEdgeType) const +{ + Handle(IMeshData::MapOfInteger) aResult = new IMeshData::MapOfInteger; + IMeshData::IteratorOfMapOfInteger aEdgeIt(myStructure->LinksOfDomain()); + + for (; aEdgeIt.More(); aEdgeIt.Next()) + { + const BRepMesh_Edge& aEdge = myStructure->GetLink(aEdgeIt.Key()); + if (aEdge.Movability() == theEdgeType) + { + aResult->Add(aEdgeIt.Key()); + } + } + + return aResult; +} + +//======================================================================= +//function : DumpStruct +//purpose : +//======================================================================= +void BRepMesh_MeshTool::DumpTriangles(const Standard_CString theFileName, + IMeshData::MapOfInteger* theTriangles) +{ + BRep_Builder aBuilder; + TopoDS_Compound aResult; + aBuilder.MakeCompound(aResult); + + const IMeshData::MapOfInteger& aTriangles = myStructure->ElementsOfDomain(); + for (IMeshData::IteratorOfMapOfInteger aIt(aTriangles); aIt.More(); aIt.Next()) + { + if (theTriangles != NULL && !theTriangles->Contains(aIt.Key())) + continue; + + Standard_Integer aNodes[3]; + const BRepMesh_Triangle& aTri = myStructure->GetElement(aIt.Key()); + myStructure->ElementNodes(aTri, aNodes); + + const gp_XY& aV1 = myStructure->GetNode(aNodes[0]).Coord(); + const gp_XY& aV2 = myStructure->GetNode(aNodes[1]).Coord(); + const gp_XY& aV3 = myStructure->GetNode(aNodes[2]).Coord(); + + BRepBuilderAPI_MakePolygon aPoly(gp_Pnt(aV1.X(), aV1.Y(), 0.), + gp_Pnt(aV2.X(), aV2.Y(), 0.), + gp_Pnt(aV3.X(), aV3.Y(), 0.), + Standard_True); + + BRepBuilderAPI_MakeFace aFaceBuilder(gp_Pln(gp::XOY()), aPoly.Wire()); + aBuilder.Add(aResult, aFaceBuilder.Shape()); + } + + BRepTools::Write(aResult, theFileName); +} diff --git a/src/BRepMesh/BRepMesh_MeshTool.hxx b/src/BRepMesh/BRepMesh_MeshTool.hxx new file mode 100644 index 0000000000..7ca02940aa --- /dev/null +++ b/src/BRepMesh/BRepMesh_MeshTool.hxx @@ -0,0 +1,235 @@ +// Created on: 2016-08-22 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_MeshTool_HeaderFile +#define _BRepMesh_MeshTool_HeaderFile + +#include +#include +#include +#include +#include +#include +#include + +#include + +//! 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& theStack) + { + Standard_Integer aEdges[3]; + AddTriangle(theNode0, theNode1, theNode2, aEdges); + + for (Standard_Integer i = 0; i < 3; ++i) + { + if (!theUsedLinks.Contains(aEdges[i])) + { + theStack.push(aEdges[i]); + } + } + } + + //! Iteratively erases triangles and their neighbours consisting + //! of free links using the given link as starting front. + //! Only triangles around the constraint's saddle nodes will be removed. + void collectTrianglesOnFreeLinksAroundNodesOf( + const BRepMesh_Edge& theConstraint, + const Standard_Integer theStartLink, + IMeshData::MapOfInteger& theTriangles); + +private: + + Handle(BRepMesh_DataStructureOfDelaun) myStructure; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_ModelBuilder.cxx b/src/BRepMesh/BRepMesh_ModelBuilder.cxx new file mode 100644 index 0000000000..2f4a377815 --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelBuilder.cxx @@ -0,0 +1,96 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include + +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_ModelBuilder::BRepMesh_ModelBuilder () +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder () +{ +} + +//======================================================================= +// Function: Perform +// Purpose : +//======================================================================= +Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform ( + const TopoDS_Shape& theShape, + const IMeshTools_Parameters& theParameters) +{ + ClearStatus (); + + Handle (BRepMeshData_Model) aModel; + try + { + OCC_CATCH_SIGNALS + + Bnd_Box aBox; + BRepBndLib::Add (theShape, aBox, Standard_False); + + if (!aBox.IsVoid ()) + { + // Build data model for further processing. + aModel = new BRepMeshData_Model (theShape); + + if (theParameters.Relative) + { + Standard_Real aMaxSize; + BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize); + aModel->SetMaxSize(aMaxSize); + } + else + { + aModel->SetMaxSize(theParameters.Deflection); + } + + Handle (IMeshTools_ShapeVisitor) aVisitor = + new BRepMesh_ShapeVisitor (aModel); + + Handle (IMeshTools_ShapeExplorer) aExplorer = + new BRepMesh_ShapeExplorer (theShape); + + aExplorer->Accept (aVisitor); + SetStatus (Message_Done1); + } + else + { + SetStatus(Message_Fail1); + } + } + catch (Standard_Failure&) + { + SetStatus (Message_Fail2); + } + + return aModel; +} diff --git a/src/BRepMesh/BRepMesh_ModelBuilder.hxx b/src/BRepMesh/BRepMesh_ModelBuilder.hxx new file mode 100644 index 0000000000..aa1850a710 --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelBuilder.hxx @@ -0,0 +1,48 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ModelBuilder_HeaderFile +#define _BRepMesh_ModelBuilder_HeaderFile + +#include +#include +#include + +//! Class implements interface representing tool for discrete model building. +//! +//! The following statuses should be used by default: +//! Message_Done1 - model has been sucessfully built. +//! Message_Fail1 - empty shape. +//! Message_Fail2 - model has not been build due to unexpected reason. +class BRepMesh_ModelBuilder : public IMeshTools_ModelBuilder +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ModelBuilder (); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ModelBuilder (); + + //! Creates discrete model for the given shape. + //! Returns nullptr in case of failure. + Standard_EXPORT virtual Handle (IMeshData_Model) Perform ( + const TopoDS_Shape& theShape, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder) +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_ModelHealer.cxx b/src/BRepMesh/BRepMesh_ModelHealer.cxx new file mode 100644 index 0000000000..96e37350bd --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelHealer.cxx @@ -0,0 +1,440 @@ +// Created on: 2016-06-23 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_HEALER +#include +#include +#include +#include +#endif + +namespace +{ + //! Decreases deflection of the given edge and tries to update discretization. + class EdgeAmplifier + { + public: + //! Constructor. + EdgeAmplifier(const IMeshTools_Parameters& theParameters) + : myParameters(theParameters) + { + } + + //! Main operator. + void operator()(const IMeshData::IEdgePtr& theDEdge) const + { + const IMeshData::IEdgeHandle& aDEdge = theDEdge.lock(); + aDEdge->Clear(Standard_True); + aDEdge->SetDeflection(Max(aDEdge->GetDeflection() / 3., Precision::Confusion())); + + const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0); + const IMeshData::IFaceHandle& aDFace = aPCurve->GetFace().lock(); + Handle(IMeshTools_CurveTessellator) aTessellator = + BRepMesh_EdgeDiscret::CreateEdgeTessellator( + aDEdge, aPCurve->GetOrientation(), aDFace, myParameters); + + BRepMesh_EdgeDiscret::Tessellate3d(aDEdge, aTessellator, Standard_False); + BRepMesh_EdgeDiscret::Tessellate2d(aDEdge, Standard_False); + } + + private: + + EdgeAmplifier (const EdgeAmplifier& theOther); + + void operator=(const EdgeAmplifier& theOther); + + private: + const IMeshTools_Parameters& myParameters; + }; + + //! Returns True if some of two vertcies is same with reference one. + inline Standard_Boolean isSameWithSomeOf( + const TopoDS_Vertex& theRefVertex, + const TopoDS_Vertex& theVertex1, + const TopoDS_Vertex& theVertex2) + { + return (theRefVertex.IsSame(theVertex1) || + theRefVertex.IsSame(theVertex2)); + } + + //! Returns True if some of two vertcies is within tolerance of reference one. + inline Standard_Boolean isInToleranceWithSomeOf( + const gp_Pnt& theRefPoint, + const gp_Pnt& thePoint1, + const gp_Pnt& thePoint2, + const Standard_Real theTol) + { + const Standard_Real aSqTol = theTol * theTol; + return (theRefPoint.SquareDistance(thePoint1) < aSqTol || + theRefPoint.SquareDistance(thePoint2) < aSqTol); + } +} + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_ModelHealer::BRepMesh_ModelHealer() +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_ModelHealer::~BRepMesh_ModelHealer() +{ +} + +//======================================================================= +// Function: Perform +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_ModelHealer::Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) +{ + myModel = theModel; + myParameters = theParameters; + if (myModel.IsNull()) + { + return Standard_False; + } + + myFaceIntersectingEdges = new IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs; + for (Standard_Integer aFaceIt = 0; aFaceIt < myModel->FacesNb(); ++aFaceIt) + { + myFaceIntersectingEdges->Bind(myModel->GetFace(aFaceIt), Handle(IMeshData::MapOfIEdgePtr)()); + } + + // TODO: Here we can process edges in order to remove close discrete points. + OSD_Parallel::For(0, myModel->FacesNb(), *this, !isParallel()); + amplifyEdges(); + + IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges); + for (; aFaceIt.More(); aFaceIt.Next()) + { + if (!aFaceIt.Value().IsNull()) + { + const IMeshData::IFaceHandle& aDFace = aFaceIt.Key().lock(); + aDFace->SetStatus(IMeshData_SelfIntersectingWire); + aDFace->SetStatus(IMeshData_Failure); + } + } + + myFaceIntersectingEdges.Nullify(); + myModel.Nullify(); // Do not hold link to model. + return Standard_True; +} + +//======================================================================= +// Function: amplifyEdges +// Purpose : +//======================================================================= +void BRepMesh_ModelHealer::amplifyEdges() +{ + Handle(NCollection_IncAllocator) aTmpAlloc = + new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE); + + Standard_Integer aAmpIt = 0; + const Standard_Real aIterNb = 5; + IMeshData::MapOfIEdgePtr aEdgesToUpdate(1, aTmpAlloc); + while (aAmpIt++ < aIterNb && popEdgesToUpdate(aEdgesToUpdate)) + { + // Try to update discretization by decreasing deflection of problematic edges. + OSD_Parallel::ForEach(aEdgesToUpdate.cbegin(), aEdgesToUpdate.cend(), + EdgeAmplifier(myParameters), + !(myParameters.InParallel && aEdgesToUpdate.Size() > 1)); + + IMeshData::MapOfIFacePtr aFacesToCheck(1, aTmpAlloc); + IMeshData::MapOfIEdgePtr::Iterator aEdgeIt(aEdgesToUpdate); + for (; aEdgeIt.More(); aEdgeIt.Next()) + { + const IMeshData::IEdgeHandle& aDEdge = aEdgeIt.Value().lock(); + for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt) + { + aFacesToCheck.Add(aDEdge->GetPCurve(aPCurveIt)->GetFace()); + } + } + + OSD_Parallel::ForEach(aFacesToCheck.cbegin(), aFacesToCheck.cend(), + *this, !(myParameters.InParallel && aFacesToCheck.Size() > 1)); + + aEdgesToUpdate.Clear(); + aTmpAlloc->Reset(Standard_False); + } +} + +//======================================================================= +// Function: popEdgesToUpdate +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate( + IMeshData::MapOfIEdgePtr& theEdgesToUpdate) +{ + IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs::Iterator aFaceIt(*myFaceIntersectingEdges); + for (; aFaceIt.More(); aFaceIt.Next()) + { + Handle(IMeshData::MapOfIEdgePtr)& aIntersections = aFaceIt.ChangeValue(); + if (!aIntersections.IsNull()) + { + theEdgesToUpdate.Unite(*aIntersections); + aIntersections.Nullify(); + } + } + + return !theEdgesToUpdate.IsEmpty(); +} + +//======================================================================= +// Function: process +// Purpose : +//======================================================================= +void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const +{ + Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace); + aIntersections.Nullify(); + + fixFaceBoundaries(theDFace); + + if (!theDFace->IsSet(IMeshData_Failure)) + { + BRepMesh_FaceChecker aChecker(theDFace, myParameters); + if (!aChecker.Perform()) + { +#ifdef DEBUG_HEALER + std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl; +#endif + aIntersections = aChecker.GetIntersectingEdges(); + } + } +} + +//======================================================================= +// Function: fixFaceBoundaries +// Purpose : +//======================================================================= +void BRepMesh_ModelHealer::fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const +{ +#ifdef DEBUG_HEALER + TopoDS_Compound aComp; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aComp); +#endif + + for (int aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt) + { + const IMeshData::IWireHandle& aDWire = theDFace->GetWire(aWireIt); + BRepMesh_Deflection::ComputeDeflection(aDWire, myParameters); + for (int aEdgeIt = 0; aEdgeIt < aDWire->EdgesNb(); ++aEdgeIt) + { + const int aPrevEdgeIt = (aEdgeIt + aDWire->EdgesNb() - 1) % aDWire->EdgesNb(); + const int aNextEdgeIt = (aEdgeIt + 1) % aDWire->EdgesNb(); + + const IMeshData::IEdgeHandle& aPrevEdge = aDWire->GetEdge(aPrevEdgeIt).lock(); + const IMeshData::IEdgeHandle& aCurrEdge = aDWire->GetEdge(aEdgeIt).lock(); + const IMeshData::IEdgeHandle& aNextEdge = aDWire->GetEdge(aNextEdgeIt).lock(); + + Standard_Boolean isConnected = !getCommonVertex(aCurrEdge, aNextEdge).IsNull() && + !getCommonVertex(aPrevEdge, aCurrEdge).IsNull(); + + if (isConnected) + { + const IMeshData::IPCurveHandle& aPrevPCurve = + aPrevEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aPrevEdgeIt)); + + const IMeshData::IPCurveHandle& aCurrPCurve = + aCurrEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aEdgeIt)); + + const IMeshData::IPCurveHandle& aNextPCurve = + aNextEdge->GetPCurve(theDFace, aDWire->GetEdgeOrientation(aNextEdgeIt)); + + isConnected = connectClosestPoints(aPrevPCurve, aCurrPCurve, aNextPCurve); + +#ifdef DEBUG_HEALER + BRepBuilderAPI_MakePolygon aPoly; + for (int i = 0; i < aCurrPCurve->ParametersNb(); ++i) + { + const gp_Pnt2d& aPnt = aCurrPCurve->GetPoint(i); + aPoly.Add(gp_Pnt(aPnt.X(), aPnt.Y(), 0.)); + } + + if (aPoly.IsDone()) + { + aBuilder.Add(aComp, aPoly.Shape()); + } + TCollection_AsciiString aName("face_discr.brep"); + BRepTools::Write(aComp, aName.ToCString()); +#endif + } + + if (!isConnected || aCurrEdge->IsSet(IMeshData_Outdated)) + { + // We have to clean face from triangulation. + theDFace->SetStatus(IMeshData_Outdated); + + if (!isConnected) + { + // Just mark wire as open, but continue fixing other inconsistencies + // in hope that this data could be suitable to build mesh somehow. + aDWire->SetStatus(IMeshData_OpenWire); + } + } + } + } + +#ifdef DEBUG_HEALER + TCollection_AsciiString aName ("face_discr.brep"); + TCollection_AsciiString aFaceName("face_geom.brep"); + BRepTools::Write(aComp, aName.ToCString()); + BRepTools::Write(theDFace->GetFace(), aFaceName.ToCString()); +#endif + + BRepMesh_Deflection::ComputeDeflection(theDFace, myParameters); +} + +//======================================================================= +// Function: hasCommonVertex +// Purpose : +//======================================================================= +TopoDS_Vertex BRepMesh_ModelHealer::getCommonVertex( + const IMeshData::IEdgeHandle& theEdge1, + const IMeshData::IEdgeHandle& theEdge2) const +{ + TopoDS_Vertex aVertex1_1, aVertex1_2; + TopExp::Vertices(theEdge1->GetEdge(), aVertex1_1, aVertex1_2); + if (theEdge1->GetEdge().IsSame(theEdge2->GetEdge())) + { + return aVertex1_1.IsSame(aVertex1_2) ? aVertex1_1 : TopoDS_Vertex(); + } + + TopoDS_Vertex aVertex2_1, aVertex2_2; + TopExp::Vertices(theEdge2->GetEdge(), aVertex2_1, aVertex2_2); + + if (isSameWithSomeOf(aVertex1_1, aVertex2_1, aVertex2_2)) + { + return aVertex1_1; + } + else if (isSameWithSomeOf(aVertex1_2, aVertex2_1, aVertex2_2)) + { + return aVertex1_2; + } + + const gp_Pnt aPnt1_1 = BRep_Tool::Pnt(aVertex1_1); + const gp_Pnt aPnt1_2 = BRep_Tool::Pnt(aVertex1_2); + const Standard_Real aTol1_1 = BRep_Tool::Tolerance(aVertex1_1); + const Standard_Real aTol1_2 = BRep_Tool::Tolerance(aVertex1_2); + + const gp_Pnt aPnt2_1 = BRep_Tool::Pnt(aVertex2_1); + const gp_Pnt aPnt2_2 = BRep_Tool::Pnt(aVertex2_2); + const Standard_Real aTol2_1 = BRep_Tool::Tolerance(aVertex2_1); + const Standard_Real aTol2_2 = BRep_Tool::Tolerance(aVertex2_2); + + if (isInToleranceWithSomeOf(aPnt1_1, aPnt2_1, aPnt2_2, aTol1_1 + Max(aTol2_1, aTol2_2))) + { + return aVertex1_1; + } + else if (isInToleranceWithSomeOf(aPnt1_2, aPnt2_1, aPnt2_2, aTol1_2 + Max(aTol2_1, aTol2_2))) + { + return aVertex1_2; + } + + return TopoDS_Vertex(); +} + +//======================================================================= +// Function: connectClosestPoints +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_ModelHealer::connectClosestPoints( + const IMeshData::IPCurveHandle& thePrevDEdge, + const IMeshData::IPCurveHandle& theCurrDEdge, + const IMeshData::IPCurveHandle& theNextDEdge) const +{ + if (thePrevDEdge->IsInternal() || + theCurrDEdge->IsInternal() || + theNextDEdge->IsInternal()) + { + return Standard_True; + } + + gp_Pnt2d& aPrevFirstUV = thePrevDEdge->GetPoint(0); + gp_Pnt2d& aPrevLastUV = thePrevDEdge->GetPoint(thePrevDEdge->ParametersNb() - 1); + + if (thePrevDEdge == theCurrDEdge) + { + // Wire consists of a single edge. + aPrevFirstUV = aPrevLastUV; + return Standard_True; + } + + gp_Pnt2d& aCurrFirstUV = theCurrDEdge->GetPoint(0); + gp_Pnt2d& aCurrLastUV = theCurrDEdge->GetPoint(theCurrDEdge->ParametersNb() - 1); + + gp_Pnt2d *aPrevUV = NULL, *aCurrPrevUV = NULL; + const Standard_Real aPrevSqDist = closestPoints(aPrevFirstUV, aPrevLastUV, + aCurrFirstUV, aCurrLastUV, + aPrevUV, aCurrPrevUV); + + gp_Pnt2d *aNextUV = NULL, *aCurrNextUV = NULL; + if (thePrevDEdge == theNextDEdge) + { + // Wire consists of two edges. Connect both ends. + aNextUV = (aPrevUV == &aPrevFirstUV) ? &aPrevLastUV : &aPrevFirstUV; + aCurrNextUV = (aCurrPrevUV == &aCurrFirstUV) ? &aCurrLastUV : &aCurrFirstUV; + + *aNextUV = *aCurrNextUV; + *aPrevUV = *aCurrPrevUV; + return Standard_True; + } + + gp_Pnt2d& aNextFirstUV = theNextDEdge->GetPoint(0); + gp_Pnt2d& aNextLastUV = theNextDEdge->GetPoint(theNextDEdge->ParametersNb() - 1); + + const Standard_Real aNextSqDist = closestPoints(aNextFirstUV, aNextLastUV, + aCurrFirstUV, aCurrLastUV, + aNextUV, aCurrNextUV); + +#ifdef DEBUG_HEALER + std::cout << "PrevSqDist = " << aPrevSqDist << std::endl; + std::cout << "NextSqDist = " << aNextSqDist << std::endl; +#endif + + // Connect closest points first. This can help to identify + // which ends should be connected in case of gap. + if (aPrevSqDist - aNextSqDist > gp::Resolution()) + { + adjustSamePoints(aCurrNextUV, aNextUV, aCurrPrevUV, aPrevUV, aCurrFirstUV, aCurrLastUV, aPrevFirstUV, aPrevLastUV); + } + else + { + adjustSamePoints(aCurrPrevUV, aPrevUV, aCurrNextUV, aNextUV, aCurrFirstUV, aCurrLastUV, aNextFirstUV, aNextLastUV); + } + + return Standard_True; +} diff --git a/src/BRepMesh/BRepMesh_ModelHealer.hxx b/src/BRepMesh/BRepMesh_ModelHealer.hxx new file mode 100644 index 0000000000..e6612b1add --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelHealer.hxx @@ -0,0 +1,183 @@ +// Created on: 2016-06-23 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ModelHealer_HeaderFile +#define _BRepMesh_ModelHealer_HeaderFile + +#include +#include +#include +#include +#include + +//! Class implements functionality of model healer tool. +//! Iterates over model's faces and checks consistency of their wires, +//! i.e.whether wires are closed and do not contain self - intersections. +//! In case if wire contains disconnected parts, ends of adjacent edges +//! forming the gaps are connected in parametric space forcibly. The notion +//! of this operation is to create correct discrete model defined relatively +//! parametric space of target face taking into account connectivity and +//! tolerances of 3D space only. This means that there are no specific +//! computations are made for the sake of determination of U and V tolerance. +//! Registers intersections on edges forming the faceÂ’s shape and tries to +//! amplify discrete represenation by decreasing of deflection for the target edge. +//! Checks can be performed in parallel mode. +class BRepMesh_ModelHealer : public IMeshTools_ModelAlgo +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ModelHealer(); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ModelHealer(); + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + //! Functor API to discretize the given edge. + inline void operator() (const Standard_Integer theEdgeIndex) const { + process(theEdgeIndex); + } + + //! Functor API to discretize the given edge. + inline void operator() (const IMeshData::IFacePtr& theDFace) const { + process(theDFace.lock()); + } + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo) + +private: + + //! Checks existing discretization of the face and updates data model. + inline void process(const Standard_Integer theFaceIndex) const + { + const IMeshData::IFaceHandle& aDFace = myModel->GetFace(theFaceIndex); + process(aDFace); + } + + //! Checks existing discretization of the face and updates data model. + void process(const IMeshData::IFaceHandle& theDFace) const; + + //! Amplifies discretization of edges in case if self-intersection problem has been found. + void amplifyEdges(); + + //! Returns common vertex of two edges or null ptr in case if there is no such vertex. + TopoDS_Vertex getCommonVertex( + const IMeshData::IEdgeHandle& theEdge1, + const IMeshData::IEdgeHandle& theEdge2) const; + + //! Connects pcurves of previous and current edge on the specified face + //! according to topological connectivity. Uses next edge in order to + //! identify closest point in case of signle vertex shared between both + //! ends of edge (degenerative edge) + Standard_Boolean connectClosestPoints( + const IMeshData::IPCurveHandle& thePrevDEdge, + const IMeshData::IPCurveHandle& theCurrDEdge, + const IMeshData::IPCurveHandle& theNextDEdge) const; + + //! Chooses the most closest point to reference one from the given pair. + //! Returns square distance between reference point and closest one as + //! well as pointer to closest point. + inline Standard_Real closestPoint( + gp_Pnt2d& theRefPnt, + gp_Pnt2d& theFristPnt, + gp_Pnt2d& theSecondPnt, + gp_Pnt2d*& theClosestPnt) const + { + // Find the most closest end-points. + const Standard_Real aSqDist1 = theRefPnt.SquareDistance(theFristPnt); + const Standard_Real aSqDist2 = theRefPnt.SquareDistance(theSecondPnt); + if (aSqDist1 < aSqDist2) + { + theClosestPnt = &theFristPnt; + return aSqDist1; + } + + theClosestPnt = &theSecondPnt; + return aSqDist2; + } + + //! Chooses the most closest points among the given to reference one from the given pair. + //! Returns square distance between reference point and closest one as + //! well as pointer to closest point. + inline Standard_Real closestPoints( + gp_Pnt2d& theFirstPnt1, + gp_Pnt2d& theSecondPnt1, + gp_Pnt2d& theFirstPnt2, + gp_Pnt2d& theSecondPnt2, + gp_Pnt2d*& theClosestPnt1, + gp_Pnt2d*& theClosestPnt2) const + { + gp_Pnt2d *aCurrPrevUV1 = NULL, *aCurrPrevUV2 = NULL; + const Standard_Real aSqDist1 = closestPoint(theFirstPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV1); + const Standard_Real aSqDist2 = closestPoint(theSecondPnt1, theFirstPnt2, theSecondPnt2, aCurrPrevUV2); + if (aSqDist1 - aSqDist2 < gp::Resolution()) + { + theClosestPnt1 = &theFirstPnt1; + theClosestPnt2 = aCurrPrevUV1; + return aSqDist1; + } + + theClosestPnt1 = &theSecondPnt1; + theClosestPnt2 = aCurrPrevUV2; + return aSqDist2; + } + + //! Adjusts the given pair of points supposed to be the same. + //! In addition, adjusts another end-point of an edge in order + //! to perform correct matching in case of gap. + inline void adjustSamePoints( + gp_Pnt2d*& theMajorSamePnt1, + gp_Pnt2d*& theMinorSamePnt1, + gp_Pnt2d*& theMajorSamePnt2, + gp_Pnt2d*& theMinorSamePnt2, + gp_Pnt2d& theMajorFirstPnt, + gp_Pnt2d& theMajorLastPnt, + gp_Pnt2d& theMinorFirstPnt, + gp_Pnt2d& theMinorLastPnt) const + { + if (theMajorSamePnt2 == theMajorSamePnt1) + { + theMajorSamePnt2 = (theMajorSamePnt2 == &theMajorFirstPnt) ? &theMajorLastPnt : &theMajorFirstPnt; + closestPoint(*theMajorSamePnt2, theMinorFirstPnt, theMinorLastPnt, theMinorSamePnt2); + } + + *theMajorSamePnt1 = *theMinorSamePnt1; + *theMajorSamePnt2 = *theMinorSamePnt2; + } + + //! Connects ends of pcurves of face's wires according to topological coherency. + void fixFaceBoundaries(const IMeshData::IFaceHandle& theDFace) const; + + //! Returns True if check can be done in parallel. + inline Standard_Boolean isParallel() const + { + return (myParameters.InParallel && myModel->FacesNb() > 1); + } + + //! Collects unique edges to be updated from face map. Clears data stored in face map. + Standard_Boolean popEdgesToUpdate(IMeshData::MapOfIEdgePtr& theEdgesToUpdate); + +private: + + Handle(IMeshData_Model) myModel; + IMeshTools_Parameters myParameters; + Handle(IMeshData::DMapOfIFacePtrsMapOfIEdgePtrs) myFaceIntersectingEdges; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_ModelPostProcessor.cxx b/src/BRepMesh/BRepMesh_ModelPostProcessor.cxx new file mode 100644 index 0000000000..f7a9e9327d --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelPostProcessor.cxx @@ -0,0 +1,189 @@ +// Created on: 2016-07-04 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include + +namespace +{ + //! Commits 3D polygons and polygons on triangulations for corresponding edges. + class PolygonCommitter + { + public: + //! Constructor + PolygonCommitter(const Handle(IMeshData_Model)& theModel) + : myModel(theModel) + { + } + + //! Main functor. + void operator()(const Standard_Integer theEdgeIndex) const + { + const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge(theEdgeIndex); + if (aDEdge->IsFree()) + { + if (!aDEdge->IsSet(IMeshData_Reused)) + { + commitPolygon3D(aDEdge); + } + } + else + { + commitPolygons(aDEdge); + } + } + + private: + + //! Commits 3d polygon to topological edge + void commitPolygon3D(const IMeshData::IEdgeHandle& theDEdge) const + { + const IMeshData::ICurveHandle& aCurve = theDEdge->GetCurve(); + + TColgp_Array1OfPnt aNodes (1, aCurve->ParametersNb()); + TColStd_Array1OfReal aUVNodes(1, aCurve->ParametersNb()); + for (Standard_Integer i = 1; i <= aCurve->ParametersNb(); ++i) + { + aNodes (i) = aCurve->GetPoint (i - 1); + aUVNodes(i) = aCurve->GetParameter(i - 1); + } + + Handle(Poly_Polygon3D) aPoly3D = new Poly_Polygon3D(aNodes, aUVNodes); + aPoly3D->Deflection(theDEdge->GetDeflection()); + + BRepMesh_ShapeTool::UpdateEdge(theDEdge->GetEdge(), aPoly3D); + } + + //! Commits all polygons on triangulations correspondent to the given edge. + void commitPolygons(const IMeshData::IEdgeHandle& theDEdge) const + { + // Collect pcurves associated with the given edge on the specific surface. + IMeshData::IDMapOfIFacePtrsListOfIPCurves aMapOfPCurves; + for (Standard_Integer aPCurveIt = 0; aPCurveIt < theDEdge->PCurvesNb(); ++aPCurveIt) + { + const IMeshData::IPCurveHandle& aPCurve = theDEdge->GetPCurve(aPCurveIt); + const IMeshData::IFacePtr& aDFacePtr = aPCurve->GetFace(); + const IMeshData::IFaceHandle& aDFace = aDFacePtr.lock(); + if (aDFace->IsSet(IMeshData_Failure) || + aDFace->IsSet(IMeshData_Reused)) + { + continue; + } + + if (!aMapOfPCurves.Contains(aDFacePtr)) + { + aMapOfPCurves.Add(aDFacePtr, IMeshData::ListOfIPCurves()); + } + + IMeshData::ListOfIPCurves& aPCurves = aMapOfPCurves.ChangeFromKey(aDFacePtr); + aPCurves.Append(aPCurve); + } + + // Commit polygons related to separate face. + const TopoDS_Edge& aEdge = theDEdge->GetEdge(); + IMeshData::IDMapOfIFacePtrsListOfIPCurves::Iterator aPolygonIt(aMapOfPCurves); + for (; aPolygonIt.More(); aPolygonIt.Next()) + { + const TopoDS_Face& aFace = aPolygonIt.Key().lock()->GetFace(); + + TopLoc_Location aLoc; + const Handle(Poly_Triangulation)& aTriangulation = + BRep_Tool::Triangulation(aFace, aLoc); + + if (!aTriangulation.IsNull()) + { + const IMeshData::ListOfIPCurves& aPCurves = aPolygonIt.Value(); + if (aPCurves.Size() == 2) + { + BRepMesh_ShapeTool::UpdateEdge( + aEdge, + collectPolygon(aPCurves.First(), theDEdge->GetDeflection()), + collectPolygon(aPCurves.Last (), theDEdge->GetDeflection()), + aTriangulation, aLoc); + } + else + { + BRepMesh_ShapeTool::UpdateEdge( + aEdge, + collectPolygon(aPCurves.First(), theDEdge->GetDeflection()), + aTriangulation, aLoc); + } + } + } + } + + //! Collects polygonal data for the given pcurve + Handle(Poly_PolygonOnTriangulation) collectPolygon( + const IMeshData::IPCurveHandle& thePCurve, + const Standard_Real theDeflection) const + { + TColStd_Array1OfInteger aNodes (1, thePCurve->ParametersNb()); + TColStd_Array1OfReal aParams(1, thePCurve->ParametersNb()); + for (Standard_Integer i = 1; i <= thePCurve->ParametersNb(); ++i) + { + aNodes (i) = thePCurve->GetIndex (i - 1); + aParams(i) = thePCurve->GetParameter(i - 1); + } + + Handle(Poly_PolygonOnTriangulation) aPolygon = + new Poly_PolygonOnTriangulation(aNodes, aParams); + + aPolygon->Deflection(theDeflection); + return aPolygon; + } + + private: + + Handle(IMeshData_Model) myModel; + }; +} + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_ModelPostProcessor::BRepMesh_ModelPostProcessor() +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor() +{ +} + +//======================================================================= +// Function: Perform +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_ModelPostProcessor::Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& /*theParameters*/) +{ + if (theModel.IsNull()) + { + return Standard_False; + } + + // TODO: Force single threaded solution due to data races on edges sharing the same TShape + OSD_Parallel::For(0, theModel->EdgesNb(), PolygonCommitter(theModel), Standard_True/*!theParameters.InParallel*/); + return Standard_True; +} diff --git a/src/BRepMesh/BRepMesh_ModelPostProcessor.hxx b/src/BRepMesh/BRepMesh_ModelPostProcessor.hxx new file mode 100644 index 0000000000..d47536976e --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelPostProcessor.hxx @@ -0,0 +1,43 @@ +// Created on: 2016-07-22 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ModelPostProcessor_HeaderFile +#define _BRepMesh_ModelPostProcessor_HeaderFile + +#include +#include +#include + +//! Class implements functionality of model post-processing tool. +//! Stores polygons on triangulations to TopoDS_Edge. +class BRepMesh_ModelPostProcessor : public IMeshTools_ModelAlgo +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ModelPostProcessor(); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor(); + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo) +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx b/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx new file mode 100644 index 0000000000..e963e3dbd5 --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelPreProcessor.cxx @@ -0,0 +1,172 @@ +// Created on: 2016-07-04 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include + +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 aUsedFaces(1, aTmpAlloc); + for (Standard_Integer aEdgeIt = 0; aEdgeIt < theModel->EdgesNb(); ++aEdgeIt) + { + const IMeshData::IEdgeHandle& aDEdge = theModel->GetEdge(aEdgeIt); + if (aDEdge->IsFree()) + { + if (aDEdge->IsSet(IMeshData_Outdated)) + { + TopLoc_Location aLoc; + BRep_Tool::Polygon3D(aDEdge->GetEdge(), aLoc); + BRepMesh_ShapeTool::NullifyEdge(aDEdge->GetEdge(), aLoc); + } + + continue; + } + + for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb(); ++aPCurveIt) + { + // Find adjacent outdated face. + const IMeshData::IFaceHandle& aDFace = aDEdge->GetPCurve(aPCurveIt)->GetFace().lock(); + if (!aUsedFaces.Contains(aDFace.get())) + { + aUsedFaces.Add(aDFace.get()); + if (aDFace->IsSet(IMeshData_Outdated)) + { + TopLoc_Location aLoc; + const Handle(Poly_Triangulation)& aTriangulation = + BRep_Tool::Triangulation(aDFace->GetFace(), aLoc); + + // Clean all edges of oudated face. + for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt) + { + const IMeshData::IWireHandle& aDWire = aDFace->GetWire(aWireIt); + for (Standard_Integer aWireEdgeIt = 0; aWireEdgeIt < aDWire->EdgesNb(); ++aWireEdgeIt) + { + const IMeshData::IEdgeHandle& aTmpDEdge = aDWire->GetEdge(aWireEdgeIt).lock(); + BRepMesh_ShapeTool::NullifyEdge(aTmpDEdge->GetEdge(), aTriangulation, aLoc); + } + } + + BRepMesh_ShapeTool::NullifyFace(aDFace->GetFace()); + } + } + } + } + + return Standard_True; +} + diff --git a/src/BRepMesh/BRepMesh_ModelPreProcessor.hxx b/src/BRepMesh/BRepMesh_ModelPreProcessor.hxx new file mode 100644 index 0000000000..213d8f82dc --- /dev/null +++ b/src/BRepMesh/BRepMesh_ModelPreProcessor.hxx @@ -0,0 +1,44 @@ +// Created on: 2016-07-04 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ModelPreProcessor_HeaderFile +#define _BRepMesh_ModelPreProcessor_HeaderFile + +#include +#include +#include + +//! Class implements functionality of model pre-processing tool. +//! Nullifies existing polygonal data in case if model elements +//! have IMeshData_Outdated status. +class BRepMesh_ModelPreProcessor : public IMeshTools_ModelAlgo +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ModelPreProcessor(); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor(); + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform( + const Handle(IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo) +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx new file mode 100644 index 0000000000..e3e0d3dcbd --- /dev/null +++ b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.cxx @@ -0,0 +1,476 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include + +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 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& 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& 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& aRangeU = GetRangeU(); + const std::pair& 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& aRangeU = GetRangeU(); + const std::pair& aRangeV = GetRangeV(); + const std::pair& 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 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(GetParametersU())); + + initParamsFromIntervals(aIntervals[1], GetRangeV(), isSplitIntervals, + const_cast(GetParametersV())); +} + +//======================================================================= +//function : computeGrainAndFilterParameters +//purpose : +//======================================================================= +Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::computeGrainAndFilterParameters( + const IMeshData::IMapOfReal& theSourceParams, + const Standard_Real theTol2d, + const Standard_Real theRangeDiff, + const Standard_Real theDelta, + const IMeshTools_Parameters& theParameters, + const Handle(NCollection_IncAllocator)& theAllocator) const +{ + // Sort and filter sequence of parameters + Standard_Real aMinDiff = Precision::PConfusion(); + if (theDelta < 1.) + { + aMinDiff /= theDelta; + } + + aMinDiff = Max(theParameters.MinSize, aMinDiff); + + const Standard_Real aDiffMaxLim = 0.1 * theRangeDiff; + const Standard_Real aDiffMinLim = Max(0.005 * theRangeDiff, 2. * theTol2d); + const Standard_Real aDiff = Max(theParameters.MinSize, Min(aDiffMaxLim, aDiffMinLim)); + return filterParameters(theSourceParams, aMinDiff, aDiff, theAllocator); +} + +//======================================================================= +//function : filterParameters +//purpose : +//======================================================================= +Handle(IMeshData::SequenceOfReal) BRepMesh_NURBSRangeSplitter::filterParameters( + const IMeshData::IMapOfReal& theParams, + const Standard_Real theMinDist, + const Standard_Real theFilterDist, + const Handle(NCollection_IncAllocator)& theAllocator) const +{ + Handle(IMeshData::SequenceOfReal) aResult = new IMeshData::SequenceOfReal(theAllocator); + + // Sort sequence of parameters + const Standard_Integer anInitLen = theParams.Extent(); + + TColStd_Array1OfReal aParamArray(1, anInitLen); + Standard_Integer j; + for (j = 1; j <= anInitLen; j++) + aParamArray(j) = theParams(j); + + std::sort(aParamArray.begin(), aParamArray.end()); + + // mandatory pre-filtering using the first (minimal) filter value + Standard_Integer aParamLength = 1; + for (j = 2; j <= anInitLen; j++) + { + if ((aParamArray(j) - aParamArray(aParamLength)) > theMinDist) + { + if (++aParamLength < j) + aParamArray(aParamLength) = aParamArray(j); + } + } + + //perform filtering on series + Standard_Real aLastAdded, aLastCandidate; + Standard_Boolean isCandidateDefined = Standard_False; + aLastAdded = aParamArray(1); + aLastCandidate = aLastAdded; + aResult->Append(aLastAdded); + + for (j = 2; j < aParamLength; j++) + { + Standard_Real aVal = aParamArray(j); + if (aVal - aLastAdded > theFilterDist) + { + //adds the parameter + if (isCandidateDefined) + { + aLastAdded = aLastCandidate; + isCandidateDefined = Standard_False; + j--; + } + else + { + aLastAdded = aVal; + } + aResult->Append(aLastAdded); + continue; + } + + aLastCandidate = aVal; + isCandidateDefined = Standard_True; + } + aResult->Append(aParamArray(aParamLength)); + + return aResult; +} diff --git a/src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx new file mode 100644 index 0000000000..f808e3bd15 --- /dev/null +++ b/src/BRepMesh/BRepMesh_NURBSRangeSplitter.hxx @@ -0,0 +1,74 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_NURBSRangeSplitter_HeaderFile +#define _BRepMesh_NURBSRangeSplitter_HeaderFile + +#include +#include +#include + +//! Auxiliary class extending UV range splitter in order to generate +//! internal nodes for NURBS surface. +class BRepMesh_NURBSRangeSplitter : public BRepMesh_UVParamRangeSplitter +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_NURBSRangeSplitter() + { + } + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_NURBSRangeSplitter() + { + } + + //! Updates discrete range of surface according to its geometric range. + Standard_EXPORT virtual void AdjustRange() Standard_OVERRIDE; + + //! Returns list of nodes generated using surface data and specified parameters. + Standard_EXPORT virtual Handle(IMeshData::ListOfPnt2d) GenerateSurfaceNodes( + const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE; + +protected: + + //! Initializes U and V parameters lists using CN continuity intervals. + Standard_EXPORT virtual void initParameters() const; + +private: + + //! Computes parameters of filter and applies it to the source parameters. + Handle(IMeshData::SequenceOfReal) computeGrainAndFilterParameters( + const IMeshData::IMapOfReal& theSourceParams, + const Standard_Real theTol2d, + const Standard_Real theRangeDiff, + const Standard_Real theDelta, + const IMeshTools_Parameters& theParameters, + const Handle(NCollection_IncAllocator)& theAllocator) const; + + //! Filters parameters in order to avoid too dence distribution. + Handle(IMeshData::SequenceOfReal) filterParameters( + const IMeshData::IMapOfReal& theParams, + const Standard_Real theMinDist, + const Standard_Real theFilterDist, + const Handle(NCollection_IncAllocator)& theAllocator) const; + +private: + + GeomAbs_SurfaceType mySurfaceType; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx b/src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx new file mode 100644 index 0000000000..dce21039cb --- /dev/null +++ b/src/BRepMesh/BRepMesh_NodeInsertionMeshAlgo.hxx @@ -0,0 +1,230 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_NodeInsertionMeshAlgo_HeaderFile +#define _BRepMesh_NodeInsertionMeshAlgo_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//! Extends base meshing algo in order to enable possibility +//! of addition of free vertices into the mesh. +template +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 > 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 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& aDelta = myRangeSplitter.GetDelta(); + const std::pair& aTolUV = myRangeSplitter.GetToleranceUV(); + const Standard_Real uCellSize = 14.0 * aTolUV.first; + const Standard_Real vCellSize = 14.0 * aTolUV.second; + + this->getStructure()->Data()->SetCellSize (uCellSize / aDelta.first, vCellSize / aDelta.second); + this->getStructure()->Data()->SetTolerance(aTolUV.first / aDelta.first, aTolUV.second / aDelta.second); + + for (Standard_Integer aWireIt = 0; aWireIt < aDFace->WiresNb(); ++aWireIt) + { + const Handle(SequenceOfPnt2d)& aWire = aWires(aWireIt); + if (!aWire.IsNull() && !aWire->IsEmpty()) + { + myClassifier->RegisterWire(*aWire, aTolUV, + myRangeSplitter.GetRangeU(), + myRangeSplitter.GetRangeV()); + } + } + + if (this->getParameters().InternalVerticesMode) + { + insertInternalVertices(); + } + + return BaseAlgo::initDataStructure(); + } + + //! Adds the given 2d point to mesh data structure. + //! Returns index of node in the structure. + Standard_EXPORT virtual Standard_Integer addNodeToStructure( + const gp_Pnt2d& thePoint, + const Standard_Integer theLocation3d, + const BRepMesh_DegreeOfFreedom theMovability, + const Standard_Boolean isForceAdd) Standard_OVERRIDE + { + return BaseAlgo::addNodeToStructure( + myRangeSplitter.Scale(thePoint, Standard_True), + theLocation3d, theMovability, isForceAdd); + } + + //! Returns 2d point associated to the given vertex. + Standard_EXPORT virtual gp_Pnt2d getNodePoint2d( + const BRepMesh_Vertex& theVertex) const Standard_OVERRIDE + { + return myRangeSplitter.Scale(theVertex.Coord(), Standard_False); + } + + //! Returns range splitter. + const RangeSplitter& getRangeSplitter() const + { + return myRangeSplitter; + } + + //! Returns classifier. + const Handle(BRepMesh_Classifier)& getClassifier() const + { + return myClassifier; + } + +private: + + //! Creates collection of points representing discrete wire. + Handle(SequenceOfPnt2d) collectWirePoints( + const IMeshData::IWireHandle& theDWire, + const Handle(NCollection_IncAllocator)& theAllocator) + { + Handle(SequenceOfPnt2d) aWirePoints = new SequenceOfPnt2d(theAllocator); + for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt) + { + const IMeshData::IEdgeHandle& aDEdge = theDWire->GetEdge(aEdgeIt).lock(); + const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve( + this->getDFace(), theDWire->GetEdgeOrientation(aEdgeIt)); + + Standard_Integer aPointIt, aEndIndex, aInc; + if (aPCurve->IsForward()) + { + aPointIt = 0; + aEndIndex = aPCurve->ParametersNb() - 1; + aInc = 1; + } + else + { + aPointIt = aPCurve->ParametersNb() - 1; + aEndIndex = 0; + aInc = -1; + } + + for (; aPointIt != aEndIndex; aPointIt += aInc) + { + const gp_Pnt2d& aPnt2d = aPCurve->GetPoint(aPointIt); + aWirePoints->Append(&aPnt2d); + myRangeSplitter.AddPoint(aPnt2d); + } + } + + return aWirePoints; + } + + //! Iterates over internal vertices of a face and + //! creates corresponding nodes in data structure. + void insertInternalVertices() + { + TopExp_Explorer aExplorer(this->getDFace()->GetFace(), TopAbs_VERTEX, TopAbs_EDGE); + for (; aExplorer.More(); aExplorer.Next()) + { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aExplorer.Current()); + if (aVertex.Orientation() != TopAbs_INTERNAL) + { + continue; + } + + insertInternalVertex(aVertex); + } + } + + //! Inserts the given vertex into mesh. + void insertInternalVertex(const TopoDS_Vertex& theVertex) + { + try + { + OCC_CATCH_SIGNALS + + gp_Pnt2d aPnt2d = BRep_Tool::Parameters(theVertex, this->getDFace()->GetFace()); + // check UV values for internal vertices + if (myClassifier->Perform(aPnt2d) != TopAbs_IN) + return; + + this->registerNode(BRep_Tool::Pnt(theVertex), aPnt2d, + BRepMesh_Fixed, Standard_False); + } + catch (Standard_Failure) + { + } + } + +private: + + RangeSplitter myRangeSplitter; + Handle(BRepMesh_Classifier) myClassifier; +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_ShapeExplorer.cxx b/src/BRepMesh/BRepMesh_ShapeExplorer.cxx new file mode 100644 index 0000000000..b606d612fb --- /dev/null +++ b/src/BRepMesh/BRepMesh_ShapeExplorer.cxx @@ -0,0 +1,97 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_ShapeExplorer::BRepMesh_ShapeExplorer ( + const TopoDS_Shape& theShape) + : IMeshTools_ShapeExplorer (theShape) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_ShapeExplorer::~BRepMesh_ShapeExplorer () +{ +} + +//======================================================================= +// Function: Accept +// Purpose : +//======================================================================= +void BRepMesh_ShapeExplorer::Accept ( + const Handle (IMeshTools_ShapeVisitor)& theVisitor) +{ + // Explore all edges in shape - either free or related to some face. + TopTools_IndexedMapOfShape aEdges; + TopExp::MapShapes (GetShape (), TopAbs_EDGE, aEdges); + + TopTools_IndexedMapOfShape::Iterator aEdgeIt (aEdges); + for (; aEdgeIt.More (); aEdgeIt.Next ()) + { + const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Value ()); + if (!BRep_Tool::IsGeometric(aEdge)) + { + continue; + } + + theVisitor->Visit (aEdge); + } + + // Explore faces + TopTools_ListOfShape aFaceList; + BRepLib::ReverseSortFaces (GetShape (), aFaceList); + TopTools_MapOfShape aFaceMap; + + // make array of faces suitable for processing (excluding faces without surface) + TopLoc_Location aDummyLoc; + const TopLoc_Location aEmptyLoc; + TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList); + for (; aFaceIter.More (); aFaceIter.Next ()) + { + TopoDS_Shape aFaceNoLoc = aFaceIter.Value (); + aFaceNoLoc.Location (aEmptyLoc); + if (!aFaceMap.Add(aFaceNoLoc)) + { + continue; // already processed + } + + TopoDS_Face aFace = TopoDS::Face (aFaceIter.Value ()); + const Handle (Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc); + if (aSurf.IsNull()) + { + continue; + } + + // Store only forward faces in order to prevent inverse issue. + theVisitor->Visit (TopoDS::Face (aFace.Oriented (TopAbs_FORWARD))); + } +} diff --git a/src/BRepMesh/BRepMesh_ShapeExplorer.hxx b/src/BRepMesh/BRepMesh_ShapeExplorer.hxx new file mode 100644 index 0000000000..351acaa91b --- /dev/null +++ b/src/BRepMesh/BRepMesh_ShapeExplorer.hxx @@ -0,0 +1,41 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ShapeExplorer_HeaderFile +#define _BRepMesh_ShapeExplorer_HeaderFile + +#include +#include +#include + +//! Explores TopoDS_Shape for parts to be meshed - faces and free edges. +class BRepMesh_ShapeExplorer : public IMeshTools_ShapeExplorer +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ShapeExplorer (const TopoDS_Shape& theShape); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ShapeExplorer (); + + //! Explores shape for edges to be disretized and faces to be meshed (edges first). + //! All faces passed to visitor are forced to be forward. + Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeExplorer, IMeshTools_ShapeExplorer) +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_ShapeVisitor.cxx b/src/BRepMesh/BRepMesh_ShapeVisitor.cxx new file mode 100644 index 0000000000..07accb4927 --- /dev/null +++ b/src/BRepMesh/BRepMesh_ShapeVisitor.cxx @@ -0,0 +1,148 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMesh_ShapeVisitor::BRepMesh_ShapeVisitor (const Handle (IMeshData_Model)& theModel) +: myModel (theModel), + myDEdgeMap(1, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMesh_ShapeVisitor::~BRepMesh_ShapeVisitor () +{ +} + +//======================================================================= +// Function: Visit (edge) +// Purpose : +//======================================================================= +void BRepMesh_ShapeVisitor::Visit(const TopoDS_Edge& theEdge) +{ + myModel->AddEdge(theEdge); + myDEdgeMap.Bind(theEdge, myModel->EdgesNb() - 1); +} + +//======================================================================= +// Function: Visit (face) +// Purpose : +//======================================================================= +void BRepMesh_ShapeVisitor::Visit (const TopoDS_Face& theFace) +{ + BRepTools::Update(theFace); + const IMeshData::IFaceHandle& aDFace = myModel->AddFace (theFace); + + // Outer wire should always be the first in the model. + TopoDS_Wire aOuterWire = ShapeAnalysis::OuterWire (theFace); + if (!addWire (aOuterWire, aDFace)) + { + aDFace->SetStatus (IMeshData_Failure); + return; + } + + TopExp_Explorer aWireIt (theFace, TopAbs_WIRE); + for (; aWireIt.More (); aWireIt.Next ()) + { + const TopoDS_Wire& aWire = TopoDS::Wire (aWireIt.Current ()); + if (aWire.IsSame(aOuterWire)) + { + continue; + } + + if (!addWire (aWire, aDFace)) + { + // If there is a failure on internal wire, just skip it. + // The most significant is an outer wire. + aDFace->SetStatus (IMeshData_UnorientedWire); + } + } +} + +//======================================================================= +// Function: addWire +// Purpose : +//======================================================================= +Standard_Boolean BRepMesh_ShapeVisitor::addWire ( + const TopoDS_Wire& theWire, + const IMeshData::IFaceHandle& theDFace) +{ + if (theWire.IsNull()) + { + return Standard_False; + } + + Handle(ShapeExtend_WireData) aWireData = new ShapeExtend_WireData(theWire, Standard_True, Standard_False); + ShapeAnalysis_Wire aWireTool (aWireData, theDFace->GetFace (), Precision::Confusion ()); + + ShapeAnalysis_WireOrder aOrderTool; + aWireTool.CheckOrder (aOrderTool, Standard_True, Standard_False); + if (aWireTool.LastCheckStatus(ShapeExtend_FAIL)) + { + return Standard_False; + } + + if (aWireTool.LastCheckStatus(ShapeExtend_DONE3)) + { + theDFace->SetStatus(IMeshData_UnorientedWire); + } + + const Standard_Integer aEdgesNb = aOrderTool.NbEdges (); + if (aEdgesNb != aWireData->NbEdges()) + { + return Standard_False; + } + + const IMeshData::IWireHandle& aDWire = theDFace->AddWire (theWire, aEdgesNb); + for (Standard_Integer i = 1; i <= aEdgesNb; ++i) + { + const Standard_Integer aEdgeIndex = aOrderTool.Ordered (i); + const TopoDS_Edge& aEdge = aWireData->Edge (aEdgeIndex); + if (aEdge.Orientation() != TopAbs_EXTERNAL) + { + const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (myDEdgeMap.Find (aEdge)); + + aDEdge->AddPCurve (theDFace, aEdge.Orientation()); + aDWire->AddEdge (aDEdge, aEdge.Orientation()); + } + } + + return Standard_True; +} diff --git a/src/BRepMesh/BRepMesh_ShapeVisitor.hxx b/src/BRepMesh/BRepMesh_ShapeVisitor.hxx new file mode 100644 index 0000000000..171f49c61b --- /dev/null +++ b/src/BRepMesh/BRepMesh_ShapeVisitor.hxx @@ -0,0 +1,67 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_ShapeVisitor_HeaderFile +#define _BRepMesh_ShapeVisitor_HeaderFile + +#include +#include +#include +#include +#include +#include + +class TopoDS_Face; +class TopoDS_Edge; +class TopoDS_Wire; +class IMeshTools_Context; +class IMeshData_Wire; + +//! Builds discrete model of a shape by adding faces and free edges. +//! Computes deflection for corresponded shape and checks whether it +//! fits existing polygonal representation. If not, cleans shape from +//! outdated info. +class BRepMesh_ShapeVisitor : public IMeshTools_ShapeVisitor +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_ShapeVisitor (const Handle (IMeshData_Model)& theModel); + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_ShapeVisitor (); + + //! Handles TopoDS_Face object. + Standard_EXPORT virtual void Visit (const TopoDS_Face& theFace) Standard_OVERRIDE; + + //! Handles TopoDS_Edge object. + Standard_EXPORT virtual void Visit (const TopoDS_Edge& theEdge) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ShapeVisitor, IMeshTools_ShapeVisitor) + +private: + + //! Adds wire to face discrete model. + Standard_Boolean addWire ( + const TopoDS_Wire& theWire, + const IMeshData::IFaceHandle& theDFace); + +private: + + Handle (IMeshData_Model) myModel; + IMeshData::DMapOfShapeInteger myDEdgeMap; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx b/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx new file mode 100644 index 0000000000..edd952c0f6 --- /dev/null +++ b/src/BRepMesh/BRepMesh_SphereRangeSplitter.hxx @@ -0,0 +1,92 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_SphereRangeSplitter_HeaderFile +#define _BRepMesh_SphereRangeSplitter_HeaderFile + +#include +#include +#include + +//! 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* aRange[2] = { + &GetRangeV(), + &GetRangeU() + }; + + std::pair 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& theRange, + const Standard_Real theDefaultStep, + std::pair& theStepAndOffset) const + { + const Standard_Real aDiff = theRange.second - theRange.first; + theStepAndOffset.first = aDiff / ((Standard_Integer) (aDiff / theDefaultStep) + 1); + theStepAndOffset.second = theRange.second - Precision::PConfusion(); + } +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx b/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx new file mode 100644 index 0000000000..5156f21a92 --- /dev/null +++ b/src/BRepMesh/BRepMesh_TorusRangeSplitter.hxx @@ -0,0 +1,228 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_TorusRangeSplitter_HeaderFile +#define _BRepMesh_TorusRangeSplitter_HeaderFile + +#include +#include +#include + +//! 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& aRangeU = GetRangeU(); + const std::pair& 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 + { + aParamU = fillParams(GetParametersU(), GetRangeU(), nbU, 0.5, aTmpAlloc); + } + + aParamV = fillParams(GetParametersV(), GetRangeV(), nbV, 2. / 3., aTmpAlloc); + + const std::pair aNewRangeU(aRangeU.first + Du * 0.1, + aRangeU.second - Dv * 0.1); + + const std::pair 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& theRange, + const Standard_Integer theStepsNb, + const Standard_Real theScale, + const Handle(NCollection_IncAllocator)& theAllocator) const + { + Handle(IMeshData::SequenceOfReal) aParams = + new IMeshData::SequenceOfReal(theAllocator); + + const Standard_Integer aLength = theParams.Size(); + TColStd_Array1OfReal aParamArray(1, aLength); + + for (Standard_Integer j = 1; j <= aLength; ++j) + { + aParamArray(j) = theParams(j); + } + + // Calculate DU, leave array of parameters + const Standard_Real aDiff = Abs(theRange.second - theRange.first); + Standard_Real aStep = FUN_CalcAverageDUV(aParamArray, aLength); + aStep = Max(aStep, aDiff / (Standard_Real) theStepsNb / 2.); + + Standard_Real aStdStep = aDiff / (Standard_Real) aLength; + if (aStep > aStdStep) + { + aStdStep = aStep; + } + aStdStep *= theScale; + + // Add parameters + for (Standard_Integer j = 1; j <= aLength; ++j) + { + const Standard_Real pp = aParamArray(j); + + Standard_Boolean isToInsert = Standard_True; + const Standard_Integer aParamsLength = aParams->Length(); + for (Standard_Integer i = 1; i <= aParamsLength && isToInsert; ++i) + { + isToInsert = (Abs(aParams->Value(i) - pp) > aStdStep); + } + + if (isToInsert) + { + aParams->Append(pp); + } + } + + return aParams; + } + + inline Standard_Real FUN_CalcAverageDUV(TColStd_Array1OfReal& P, const Standard_Integer PLen) const + { + Standard_Integer i, j, n = 0; + Standard_Real p, result = 0.; + + for (i = 1; i <= PLen; i++) + { + // Sort + for (j = i + 1; j <= PLen; j++) + { + if (P(i) > P(j)) + { + p = P(i); + P(i) = P(j); + P(j) = p; + } + } + // Accumulate + if (i != 1) + { + p = Abs(P(i) - P(i - 1)); + if (p > 1.e-7) + { + result += p; + n++; + } + } + } + return (n ? (result / (Standard_Real) n) : -1.); + } +}; + +#endif diff --git a/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx b/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx new file mode 100644 index 0000000000..c7679cf450 --- /dev/null +++ b/src/BRepMesh/BRepMesh_UVParamRangeSplitter.hxx @@ -0,0 +1,81 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMesh_UVParamRangeSplitter_HeaderFile +#define _BRepMesh_UVParamRangeSplitter_HeaderFile + +#include +#include + +//! Intended to generate internal mesh nodes using UV parameters of bounday discrete points. +class BRepMesh_UVParamRangeSplitter : public BRepMesh_DefaultRangeSplitter +{ +public: + + //! Constructor. + Standard_EXPORT BRepMesh_UVParamRangeSplitter() + : myAllocator(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)), + myUParams(1, myAllocator), + myVParams(1, myAllocator) + { + } + + //! Destructor. + Standard_EXPORT virtual ~BRepMesh_UVParamRangeSplitter() + { + } + + //! Resets this splitter. + Standard_EXPORT virtual void Reset(const IMeshData::IFaceHandle& theDFace, + const IMeshTools_Parameters& theParameters) + { + BRepMesh_DefaultRangeSplitter::Reset(theDFace, theParameters); + myUParams.Clear(); + myVParams.Clear(); + myAllocator->Reset(Standard_False); + } + +public: + //! Returns U parameters. + inline const IMeshData::IMapOfReal& GetParametersU() const + { + return myUParams; + } + + //! Returns U parameters. + inline IMeshData::IMapOfReal& GetParametersU() + { + return myUParams; + } + + //! Returns V parameters. + inline const IMeshData::IMapOfReal& GetParametersV() const + { + return myVParams; + } + + //! Returns V parameters. + inline IMeshData::IMapOfReal& GetParametersV() + { + return myVParams; + } + +private: + Handle(NCollection_IncAllocator) myAllocator; + IMeshData::IMapOfReal myUParams; + IMeshData::IMapOfReal myVParams; +}; + +#endif diff --git a/src/BRepMeshData/BRepMeshData_Curve.cxx b/src/BRepMeshData/BRepMeshData_Curve.cxx new file mode 100644 index 0000000000..ac427f9946 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Curve.cxx @@ -0,0 +1,126 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMeshData_Curve::BRepMeshData_Curve (const Handle (NCollection_IncAllocator)& theAllocator) +: myPoints (NCollection_StdAllocator(theAllocator)), + myParameters (NCollection_StdAllocator(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(myParameters.size()); +} + +//======================================================================= +// Function: RemovePoint +// Purpose : +//======================================================================= +void BRepMeshData_Curve::RemovePoint (const Standard_Integer theIndex) +{ + myPoints.erase(myPoints.begin() + theIndex); + removeParameter (theIndex); +} + +//======================================================================= +// Function: removeParameter +// Purpose : +//======================================================================= +void BRepMeshData_Curve::removeParameter (const Standard_Integer theIndex) +{ + myParameters.erase(myParameters.begin() + theIndex); +} + +//======================================================================= +// Function: Clear +// Purpose : +//======================================================================= +void BRepMeshData_Curve::Clear(const Standard_Boolean isKeepEndPoints) +{ + if (!isKeepEndPoints) + { + myPoints .clear(); + myParameters.clear(); + } + else if (ParametersNb() > 2) + { + myPoints .erase(myPoints .begin() + 1, myPoints .begin() + (myPoints .size() - 1)); + myParameters.erase(myParameters.begin() + 1, myParameters.begin() + (myParameters.size() - 1)); + } +} diff --git a/src/BRepMeshData/BRepMeshData_Curve.hxx b/src/BRepMeshData/BRepMeshData_Curve.hxx new file mode 100644 index 0000000000..1566a4d916 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Curve.hxx @@ -0,0 +1,76 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_Curve_HeaderFile +#define _BRepMeshData_Curve_HeaderFile + +#include +#include +#include +#include + +//! Default implementation of curve data model entity. +class BRepMeshData_Curve : public IMeshData_Curve +{ +public: + + DEFINE_INC_ALLOC + + //! Constructor. + Standard_EXPORT BRepMeshData_Curve (const Handle (NCollection_IncAllocator)& theAllocator); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_Curve (); + + //! Inserts new discretization point at the given position. + Standard_EXPORT virtual void InsertPoint( + const Standard_Integer thePosition, + const gp_Pnt& thePoint, + const Standard_Real theParamOnPCurve) Standard_OVERRIDE; + + //! Adds new discretization point to pcurve. + Standard_EXPORT virtual void AddPoint ( + const gp_Pnt& thePoint, + const Standard_Real theParamOnCurve) Standard_OVERRIDE; + + //! Returns discretization point with the given index. + Standard_EXPORT virtual gp_Pnt& GetPoint (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Removes point with the given index. + Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Returns parameter with the given index. + Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Returns number of parameters stored in curve. + Standard_EXPORT virtual Standard_Integer ParametersNb() const Standard_OVERRIDE; + + //! Clears parameters list. + Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Curve, IMeshData_Curve) + +protected: + + //! Removes parameter with the given index. + Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) Standard_OVERRIDE; + +private: + + IMeshData::Model::SequenceOfPnt myPoints; + IMeshData::Model::SequenceOfReal myParameters; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/BRepMeshData_Edge.cxx b/src/BRepMeshData/BRepMeshData_Edge.cxx new file mode 100644 index 0000000000..67ce8228ff --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Edge.cxx @@ -0,0 +1,102 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMeshData_Edge::BRepMeshData_Edge ( + const TopoDS_Edge& theEdge, + const Handle (NCollection_IncAllocator)& theAllocator) + : IMeshData_Edge (theEdge), + myAllocator (theAllocator), + myPCurves (256, myAllocator), + myPCurvesMap(1, myAllocator) +{ + SetCurve (IMeshData::ICurveHandle (new (myAllocator) BRepMeshData_Curve (myAllocator))); +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMeshData_Edge::~BRepMeshData_Edge () +{ +} + +//======================================================================= +// Function: AddPCurve +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Edge::PCurvesNb () const +{ + return myPCurves.Size (); +} + +//======================================================================= +// Function: AddPCurve +// Purpose : +//======================================================================= +const IMeshData::IPCurveHandle& BRepMeshData_Edge::AddPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) +{ + const Standard_Integer aPCurveIndex = PCurvesNb (); + // Add pcurve to list of pcurves + IMeshData::IPCurveHandle aPCurve (new (myAllocator) BRepMeshData_PCurve (theDFace, theOrientation, myAllocator)); + myPCurves.Append (aPCurve); + + // Map pcurve to faces. + if (!myPCurvesMap.IsBound(theDFace)) + { + myPCurvesMap.Bind(theDFace, IMeshData::ListOfInteger(myAllocator)); + } + + IMeshData::ListOfInteger& aListOfPCurves = myPCurvesMap.ChangeFind(theDFace); + aListOfPCurves.Append (aPCurveIndex); + + return GetPCurve (aPCurveIndex); +} + +//======================================================================= +// Function: GetPCurve +// Purpose : +//======================================================================= +const IMeshData::IPCurveHandle& BRepMeshData_Edge::GetPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) const +{ + const IMeshData::ListOfInteger& aListOfPCurves = myPCurvesMap.Find (theDFace); + const IMeshData::IPCurveHandle& aPCurve1 = myPCurves (aListOfPCurves.First ()); + return (aPCurve1->GetOrientation () == theOrientation) ? + aPCurve1 : + myPCurves (aListOfPCurves.Last ()); +} + +//======================================================================= +// Function: GetPCurve +// Purpose : +//======================================================================= +const IMeshData::IPCurveHandle& BRepMeshData_Edge::GetPCurve ( + const Standard_Integer theIndex) const +{ + return myPCurves (theIndex); +} diff --git a/src/BRepMeshData/BRepMeshData_Edge.hxx b/src/BRepMeshData/BRepMeshData_Edge.hxx new file mode 100644 index 0000000000..d30e550da7 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Edge.hxx @@ -0,0 +1,65 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_Edge_HeaderFile +#define _BRepMeshData_Edge_HeaderFile + +#include +#include +#include +#include + +//! Default implementation of edge data model entity. +class BRepMeshData_Edge : public IMeshData_Edge +{ +public: + + DEFINE_INC_ALLOC + + //! Constructor. + Standard_EXPORT BRepMeshData_Edge ( + const TopoDS_Edge& theEdge, + const Handle (NCollection_IncAllocator)& theAllocator); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_Edge (); + + //! Returns number of pcurves assigned to current edge. + Standard_EXPORT virtual Standard_Integer PCurvesNb () const Standard_OVERRIDE; + + //! Adds disrete pcurve for the specifed discrete face. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& AddPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) Standard_OVERRIDE; + + //! Returns pcurve for the specified discrete face. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) const Standard_OVERRIDE; + + //! Returns pcurve with the given index. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve ( + const Standard_Integer theIndex) const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Edge, IMeshData_Edge) + +private: + + Handle (NCollection_IncAllocator) myAllocator; + IMeshData::VectorOfIPCurveHandles myPCurves; + IMeshData::DMapOfIFacePtrsListOfInteger myPCurvesMap; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/BRepMeshData_Face.cxx b/src/BRepMeshData/BRepMeshData_Face.cxx new file mode 100644 index 0000000000..2dca22c8a4 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Face.cxx @@ -0,0 +1,72 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMeshData_Face::BRepMeshData_Face ( + const TopoDS_Face& theFace, + const Handle (NCollection_IncAllocator)& theAllocator) + : IMeshData_Face (theFace), + myAllocator (theAllocator), + myDWires (256, myAllocator) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMeshData_Face::~BRepMeshData_Face () +{ +} + +//======================================================================= +// Function: WiresNb +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Face::WiresNb () const +{ + return myDWires.Size (); +} + +//======================================================================= +// Function: AddWire +// Purpose : +//======================================================================= +const IMeshData::IWireHandle& BRepMeshData_Face::AddWire ( + const TopoDS_Wire& theWire, + const Standard_Integer theEdgeNb) +{ + IMeshData::IWireHandle aWire (new (myAllocator) BRepMeshData_Wire (theWire, theEdgeNb, myAllocator)); + myDWires.Append (aWire); + return GetWire (WiresNb () - 1); +} + +//======================================================================= +// Function: GetWire +// Purpose : +//======================================================================= +const IMeshData::IWireHandle& BRepMeshData_Face::GetWire ( + const Standard_Integer theIndex) const +{ + return myDWires (theIndex); +} diff --git a/src/BRepMeshData/BRepMeshData_Face.hxx b/src/BRepMeshData/BRepMeshData_Face.hxx new file mode 100644 index 0000000000..1f187f7cea --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Face.hxx @@ -0,0 +1,58 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_Face_HeaderFile +#define _BRepMeshData_Face_HeaderFile + +#include +#include +#include + +//! Default implementation of face data model entity. +class BRepMeshData_Face : public IMeshData_Face +{ +public: + + DEFINE_INC_ALLOC + + //! Constructor. + Standard_EXPORT BRepMeshData_Face ( + const TopoDS_Face& theFace, + const Handle (NCollection_IncAllocator)& theAllocator); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_Face (); + + //! Gets number of children. + Standard_EXPORT virtual Standard_Integer WiresNb () const Standard_OVERRIDE; + + //! Gets wire with the given index. + Standard_EXPORT virtual const IMeshData::IWireHandle& GetWire ( + const Standard_Integer theIndex) const Standard_OVERRIDE; + + //! Adds wire to discrete model of face. + Standard_EXPORT virtual const IMeshData::IWireHandle& AddWire ( + const TopoDS_Wire& theWire, + const Standard_Integer theEdgeNb = 0) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Face, IMeshData_Face) + +private: + + Handle (NCollection_IncAllocator) myAllocator; + IMeshData::VectorOfIWireHandles myDWires; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/BRepMeshData_Model.cxx b/src/BRepMeshData/BRepMeshData_Model.cxx new file mode 100644 index 0000000000..bd2e74c120 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Model.cxx @@ -0,0 +1,100 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMeshData_Model::BRepMeshData_Model (const TopoDS_Shape& theShape) + : IMeshData_Model (theShape), + myMaxSize (0.), + myAllocator (new BRepMesh_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE)), + myDFaces (256, myAllocator), + myDEdges (256, myAllocator) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMeshData_Model::~BRepMeshData_Model () +{ +} + +//======================================================================= +// Function: FacesNb +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Model::FacesNb () const +{ + return myDFaces.Size (); +} + +//======================================================================= +// Function: AddFace +// Purpose : +//======================================================================= +const IMeshData::IFaceHandle& BRepMeshData_Model::AddFace (const TopoDS_Face& theFace) +{ + IMeshData::IFaceHandle aFace (new (myAllocator) BRepMeshData_Face (theFace, myAllocator)); + myDFaces.Append (aFace); + return myDFaces (FacesNb () - 1); +} + +//======================================================================= +// Function: GetFace +// Purpose : +//======================================================================= +const IMeshData::IFaceHandle& BRepMeshData_Model::GetFace (const Standard_Integer theIndex) const +{ + return myDFaces (theIndex); +} + +//======================================================================= +// Function: EdgesNb +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Model::EdgesNb () const +{ + return myDEdges.Size (); +} + +//======================================================================= +// Function: AddEdge +// Purpose : +//======================================================================= +const IMeshData::IEdgeHandle& BRepMeshData_Model::AddEdge (const TopoDS_Edge& theEdge) +{ + IMeshData::IEdgeHandle aEdge (new (myAllocator) BRepMeshData_Edge (theEdge, myAllocator)); + myDEdges.Append (aEdge); + return myDEdges (EdgesNb () - 1); +} + +//======================================================================= +// Function: GetEdge +// Purpose : +//======================================================================= +const IMeshData::IEdgeHandle& BRepMeshData_Model::GetEdge (const Standard_Integer theIndex) const +{ + return myDEdges (theIndex); +} diff --git a/src/BRepMeshData/BRepMeshData_Model.hxx b/src/BRepMeshData/BRepMeshData_Model.hxx new file mode 100644 index 0000000000..2b19684a73 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Model.hxx @@ -0,0 +1,81 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_Model_HeaderFile +#define _BRepMeshData_Model_HeaderFile + +#include +#include +#include +#include +#include + +//! Default implementation of model entity. +class BRepMeshData_Model : public IMeshData_Model +{ +public: + + //! Constructor. + //! Initializes empty model. + Standard_EXPORT BRepMeshData_Model (const TopoDS_Shape& theShape); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_Model (); + + //! Returns maximum size of shape's bounding box. + Standard_EXPORT virtual Standard_Real GetMaxSize () const Standard_OVERRIDE + { + return myMaxSize; + } + + //! Sets maximum size of shape's bounding box. + inline void SetMaxSize (const Standard_Real theValue) + { + myMaxSize = theValue; + } + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Model, IMeshData_Model) + +public: //! @name discrete faces + + //! Returns number of faces in discrete model. + Standard_EXPORT virtual Standard_Integer FacesNb () const Standard_OVERRIDE; + + //! Adds new face to shape model. + Standard_EXPORT virtual const IMeshData::IFaceHandle& AddFace (const TopoDS_Face& theFace) Standard_OVERRIDE; + + //! Gets model's face with the given index. + Standard_EXPORT virtual const IMeshData::IFaceHandle& GetFace (const Standard_Integer theIndex) const Standard_OVERRIDE; + +public: //! @name discrete edges + + //! Returns number of edges in discrete model. + Standard_EXPORT virtual Standard_Integer EdgesNb () const Standard_OVERRIDE; + + //! Adds new edge to shape model. + Standard_EXPORT virtual const IMeshData::IEdgeHandle& AddEdge (const TopoDS_Edge& theEdge) Standard_OVERRIDE; + + //! Gets model's edge with the given index. + Standard_EXPORT virtual const IMeshData::IEdgeHandle& GetEdge (const Standard_Integer theIndex) const Standard_OVERRIDE; + +private: + + Standard_Real myMaxSize; + Handle (NCollection_IncAllocator) myAllocator; + IMeshData::VectorOfIFaceHandles myDFaces; + IMeshData::VectorOfIEdgeHandles myDEdges; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/BRepMeshData_PCurve.cxx b/src/BRepMeshData/BRepMeshData_PCurve.cxx new file mode 100644 index 0000000000..53608a75b6 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_PCurve.cxx @@ -0,0 +1,145 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include + +//======================================================================= +// 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(theAllocator)), + myParameters (NCollection_StdAllocator(theAllocator)), + myIndices (NCollection_StdAllocator(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(myParameters.size()); +} + +//======================================================================= +// Function: RemovePoint +// Purpose : +//======================================================================= +void BRepMeshData_PCurve::RemovePoint (const Standard_Integer theIndex) +{ + myPoints2d.erase(myPoints2d.begin() + theIndex); + myIndices .erase(myIndices .begin() + theIndex); + removeParameter (theIndex); +} + +//======================================================================= +// Function: removeParameter +// Purpose : +//======================================================================= +void BRepMeshData_PCurve::removeParameter (const Standard_Integer theIndex) +{ + myParameters.erase(myParameters.begin() + theIndex); +} + +//======================================================================= +// Function: Clear +// Purpose : +//======================================================================= +void BRepMeshData_PCurve::Clear(const Standard_Boolean isKeepEndPoints) +{ + if (!isKeepEndPoints) + { + myPoints2d .clear(); + myParameters.clear(); + myIndices .clear(); + } + else if (ParametersNb() > 2) + { + myPoints2d .erase(myPoints2d .begin() + 1, myPoints2d .begin() + (myPoints2d .size() - 1)); + myParameters.erase(myParameters.begin() + 1, myParameters.begin() + (myParameters.size() - 1)); + myIndices .erase(myIndices .begin() + 1, myIndices .begin() + (myIndices .size() - 1)); + } +} diff --git a/src/BRepMeshData/BRepMeshData_PCurve.hxx b/src/BRepMeshData/BRepMeshData_PCurve.hxx new file mode 100644 index 0000000000..1189f92636 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_PCurve.hxx @@ -0,0 +1,82 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_PCurve_HeaderFile +#define _BRepMeshData_PCurve_HeaderFile + +#include +#include +#include + +//! Default implementation of pcurve data model entity. +class BRepMeshData_PCurve : public IMeshData_PCurve +{ +public: + + DEFINE_INC_ALLOC + + //! Constructor. + Standard_EXPORT BRepMeshData_PCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation, + const Handle (NCollection_IncAllocator)& theAllocator); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_PCurve (); + + //! Inserts new discretization point at the given position. + Standard_EXPORT virtual void InsertPoint( + const Standard_Integer thePosition, + const gp_Pnt2d& thePoint, + const Standard_Real theParamOnPCurve) Standard_OVERRIDE; + + //! Adds new discretization point to pcurve. + Standard_EXPORT virtual void AddPoint ( + const gp_Pnt2d& thePoint, + const Standard_Real theParamOnPCurve) Standard_OVERRIDE; + + //! Returns discretization point with the given index. + Standard_EXPORT virtual gp_Pnt2d& GetPoint (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Returns index in mesh corresponded to discretization point with the given index. + Standard_EXPORT virtual Standard_Integer& GetIndex(const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Removes point with the given index. + Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Returns parameter with the given index. + Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) Standard_OVERRIDE; + + //! Returns number of parameters stored in pcurve. + Standard_EXPORT virtual Standard_Integer ParametersNb() const Standard_OVERRIDE; + + //! Clears parameters list. + Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_PCurve, IMeshData_PCurve) + +protected: + + //! Removes parameter with the given index. + Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) Standard_OVERRIDE; + +private: + + IMeshData::Model::SequenceOfPnt2d myPoints2d; + IMeshData::Model::SequenceOfReal myParameters; + IMeshData::Model::SequenceOfInteger myIndices; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/BRepMeshData_Wire.cxx b/src/BRepMeshData/BRepMeshData_Wire.cxx new file mode 100644 index 0000000000..8139f6a84a --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Wire.cxx @@ -0,0 +1,86 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include + +//======================================================================= +// Function: Constructor +// Purpose : +//======================================================================= +BRepMeshData_Wire::BRepMeshData_Wire ( + const TopoDS_Wire& theWire, + const Standard_Integer theEdgeNb, + const Handle (NCollection_IncAllocator)& theAllocator) + : IMeshData_Wire (theWire), + myDEdges (theEdgeNb > 0 ? theEdgeNb : 256, theAllocator), + myDEdgesOri (theEdgeNb > 0 ? theEdgeNb : 256, theAllocator) +{ +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +BRepMeshData_Wire::~BRepMeshData_Wire () +{ +} + +//======================================================================= +// Function: EdgesNb +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Wire::EdgesNb () const +{ + return myDEdges.Size (); +} + +//======================================================================= +// Function: Destructor +// Purpose : +//======================================================================= +Standard_Integer BRepMeshData_Wire::AddEdge ( + const IMeshData::IEdgePtr& theDEdge, + const TopAbs_Orientation theOrientation) +{ + const Standard_Integer aIndex = EdgesNb (); + + myDEdges .Append (theDEdge); + myDEdgesOri.Append (theOrientation); + + return aIndex; +} + +//======================================================================= +// Function: GetEdge +// Purpose : +//======================================================================= +const IMeshData::IEdgePtr& BRepMeshData_Wire::GetEdge ( + const Standard_Integer theIndex) const +{ + return myDEdges (theIndex); +} + +//======================================================================= +// Function: GetEdgeOrientation +// Purpose : +//======================================================================= +TopAbs_Orientation BRepMeshData_Wire::GetEdgeOrientation ( + const Standard_Integer theIndex) const +{ + return myDEdgesOri (theIndex); +} diff --git a/src/BRepMeshData/BRepMeshData_Wire.hxx b/src/BRepMeshData/BRepMeshData_Wire.hxx new file mode 100644 index 0000000000..bf55509684 --- /dev/null +++ b/src/BRepMeshData/BRepMeshData_Wire.hxx @@ -0,0 +1,63 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepMeshData_Wire_HeaderFile +#define _BRepMeshData_Wire_HeaderFile + +#include +#include + +//! Default implementation of wire data model entity. +class BRepMeshData_Wire : public IMeshData_Wire +{ +public: + + DEFINE_INC_ALLOC + + //! Constructor. + Standard_EXPORT BRepMeshData_Wire ( + const TopoDS_Wire& theWire, + const Standard_Integer theEdgeNb, + const Handle (NCollection_IncAllocator)& theAllocator); + + //! Destructor. + Standard_EXPORT virtual ~BRepMeshData_Wire (); + + //! Gets number of children. + Standard_EXPORT virtual Standard_Integer EdgesNb () const Standard_OVERRIDE; + + //! Adds new discrete edge with specified orientation to wire chain. + //! @return index of added edge in wire chain. + Standard_EXPORT virtual Standard_Integer AddEdge ( + const IMeshData::IEdgePtr& theDEdge, + const TopAbs_Orientation theOrientation) Standard_OVERRIDE; + + //! Gets edge with the given index. + Standard_EXPORT virtual const IMeshData::IEdgePtr& GetEdge ( + const Standard_Integer theIndex) const Standard_OVERRIDE; + + //! Returns True if orientation of discrete edge with the given index is forward. + Standard_EXPORT virtual TopAbs_Orientation GetEdgeOrientation ( + const Standard_Integer theIndex) const Standard_OVERRIDE; + + DEFINE_STANDARD_RTTI_INLINE(BRepMeshData_Wire, IMeshData_Wire) + +private: + + IMeshData::VectorOfIEdgePtrs myDEdges; + IMeshData::VectorOfOrientation myDEdgesOri; +}; + +#endif \ No newline at end of file diff --git a/src/BRepMeshData/FILES b/src/BRepMeshData/FILES new file mode 100644 index 0000000000..eb27095179 --- /dev/null +++ b/src/BRepMeshData/FILES @@ -0,0 +1,12 @@ +BRepMeshData_Curve.cxx +BRepMeshData_Curve.hxx +BRepMeshData_Edge.cxx +BRepMeshData_Edge.hxx +BRepMeshData_Face.cxx +BRepMeshData_Face.hxx +BRepMeshData_Model.cxx +BRepMeshData_Model.hxx +BRepMeshData_PCurve.cxx +BRepMeshData_PCurve.hxx +BRepMeshData_Wire.cxx +BRepMeshData_Wire.hxx diff --git a/src/IMeshData/FILES b/src/IMeshData/FILES new file mode 100644 index 0000000000..1af663a2f1 --- /dev/null +++ b/src/IMeshData/FILES @@ -0,0 +1,13 @@ +IMeshData_Curve.hxx +IMeshData_Edge.hxx +IMeshData_Face.hxx +IMeshData_Model.hxx +IMeshData_ParametersList.hxx +IMeshData_ParametersListArrayAdaptor.hxx +IMeshData_PCurve.hxx +IMeshData_Shape.hxx +IMeshData_Status.hxx +IMeshData_StatusOwner.hxx +IMeshData_TessellatedShape.hxx +IMeshData_Types.hxx +IMeshData_Wire.hxx diff --git a/src/IMeshData/IMeshData_Curve.hxx b/src/IMeshData/IMeshData_Curve.hxx new file mode 100644 index 0000000000..505efad262 --- /dev/null +++ b/src/IMeshData/IMeshData_Curve.hxx @@ -0,0 +1,62 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Curve_HeaderFile +#define _IMeshData_Curve_HeaderFile + +#include +#include + +class gp_Pnt; + +//! Interface class representing discrete 3d curve of edge. +//! Indexation of points starts from zero. +class IMeshData_Curve : public IMeshData_ParametersList +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Curve() + { + } + + //! Inserts new discretization point at the given position. + Standard_EXPORT virtual void InsertPoint( + const Standard_Integer thePosition, + const gp_Pnt& thePoint, + const Standard_Real theParamOnPCurve) = 0; + + //! Adds new discretization point to curve. + Standard_EXPORT virtual void AddPoint ( + const gp_Pnt& thePoint, + const Standard_Real theParamOnCurve) = 0; + + //! Returns discretization point with the given index. + Standard_EXPORT virtual gp_Pnt& GetPoint (const Standard_Integer theIndex) = 0; + + //! Removes point with the given index. + Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Curve, IMeshData_ParametersList) + +protected: + + //! Constructor. + Standard_EXPORT IMeshData_Curve() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Edge.hxx b/src/IMeshData/IMeshData_Edge.hxx new file mode 100644 index 0000000000..162d2a20fa --- /dev/null +++ b/src/IMeshData/IMeshData_Edge.hxx @@ -0,0 +1,167 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Edge_HeaderFile +#define _IMeshData_Edge_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class IMeshData_Face; + +//! Interface class representing discrete model of an edge. +class IMeshData_Edge : public IMeshData_TessellatedShape, public IMeshData_StatusOwner +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Edge() + { + } + + //! Returns TopoDS_Edge attached to model. + inline const TopoDS_Edge& GetEdge () const + { + return TopoDS::Edge (GetShape ()); + } + + //! Returns number of pcurves assigned to current edge. + Standard_EXPORT virtual Standard_Integer PCurvesNb () const = 0; + + //! Adds discrete pcurve for the specifed discrete face. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& AddPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) = 0; + + //! Returns pcurve for the specified discrete face. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) const = 0; + + //! Returns pcurve with the given index. + Standard_EXPORT virtual const IMeshData::IPCurveHandle& GetPCurve ( + const Standard_Integer theIndex) const = 0; + + //! Clears curve and all pcurves assigned to the edge from discretization. + inline void Clear(const Standard_Boolean isKeepEndPoints) + { + myCurve->Clear(isKeepEndPoints); + for (Standard_Integer aPCurveIt = 0; aPCurveIt < PCurvesNb(); ++aPCurveIt) + { + GetPCurve(aPCurveIt)->Clear(isKeepEndPoints); + } + } + + //! Returns true in case if the edge is free one, i.e. it does not have pcurves. + inline Standard_Boolean IsFree () const + { + return (PCurvesNb () == 0); + } + + //! Sets 3d curve associated with current edge. + inline void SetCurve (const IMeshData::ICurveHandle& theCurve) + { + myCurve = theCurve; + } + + //! Returns 3d curve associated with current edge. + inline const IMeshData::ICurveHandle& GetCurve () const + { + return myCurve; + } + + //! Gets value of angular deflection for the discrete model. + inline Standard_Real GetAngularDeflection () const + { + return myAngDeflection; + } + + //! Sets value of angular deflection for the discrete model. + inline void SetAngularDeflection (const Standard_Real theValue) + { + myAngDeflection = theValue; + } + + //! Returns same param flag. + //! By default equals to flag stored in topological shape. + inline Standard_Boolean GetSameParam () const + { + return mySameParam; + } + + //! Updates same param flag. + inline void SetSameParam (const Standard_Boolean theValue) + { + mySameParam = theValue; + } + + //! Returns same range flag. + //! By default equals to flag stored in topological shape. + inline Standard_Boolean GetSameRange () const + { + return mySameRange; + } + + //! Updates same range flag. + inline void SetSameRange (const Standard_Boolean theValue) + { + mySameRange = theValue; + } + + //! Returns degenerative flag. + //! By default equals to flag stored in topological shape. + inline Standard_Boolean GetDegenerated () const + { + return myDegenerated; + } + + //! Updates degenerative flag. + inline void SetDegenerated (const Standard_Boolean theValue) + { + myDegenerated = theValue; + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Edge, IMeshData_TessellatedShape) + +protected: + + //! Constructor. + //! Initializes empty model. + Standard_EXPORT IMeshData_Edge (const TopoDS_Edge& theEdge) + : IMeshData_TessellatedShape(theEdge), + mySameParam (BRep_Tool::SameParameter(theEdge)), + mySameRange (BRep_Tool::SameRange (theEdge)), + myDegenerated(BRep_Tool::Degenerated (theEdge)), + myAngDeflection(RealLast()) + { + } + +private: + + Standard_Boolean mySameParam; + Standard_Boolean mySameRange; + Standard_Boolean myDegenerated; + Standard_Real myAngDeflection; + IMeshData::ICurveHandle myCurve; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Face.hxx b/src/IMeshData/IMeshData_Face.hxx new file mode 100644 index 0000000000..4db215de1a --- /dev/null +++ b/src/IMeshData/IMeshData_Face.hxx @@ -0,0 +1,93 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Face_HeaderFile +#define _IMeshData_Face_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include + +class IMeshData_Wire; +class TopoDS_Wire; + +//! Interface class representing discrete model of a face. +//! Face model contains one or several wires. +//! First wire is always outer one. +class IMeshData_Face : public IMeshData_TessellatedShape, public IMeshData_StatusOwner +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Face() + { + } + + //! Returns number of wires. + Standard_EXPORT virtual Standard_Integer WiresNb () const = 0; + + //! Adds wire to discrete model of face. + Standard_EXPORT virtual const IMeshData::IWireHandle& AddWire ( + const TopoDS_Wire& theWire, + const Standard_Integer theEdgeNb = 0) = 0; + + //! Returns discrete edge with the given index. + Standard_EXPORT virtual const IMeshData::IWireHandle& GetWire ( + const Standard_Integer theIndex) const = 0; + + //! Returns face's surface. + inline const Handle(BRepAdaptor_HSurface)& GetSurface() const + { + return mySurface; + } + + //! Returns TopoDS_Face attached to model. + inline const TopoDS_Face& GetFace () const + { + return TopoDS::Face (GetShape ()); + } + + //! Returns whether the face discrete model is valid. + inline Standard_Boolean IsValid () const + { + return (IsEqual(IMeshData_NoError) || + IsEqual(IMeshData_ReMesh) || + IsEqual(IMeshData_UnorientedWire)); + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Face, IMeshData_TessellatedShape) + +protected: + + //! Constructor. + //! Initializes empty model. + Standard_EXPORT IMeshData_Face (const TopoDS_Face& theFace) + : IMeshData_TessellatedShape(theFace) + { + BRepAdaptor_Surface aSurfAdaptor(GetFace(), Standard_False); + mySurface = new BRepAdaptor_HSurface(aSurfAdaptor); + } + +private: + + mutable Handle(BRepAdaptor_HSurface) mySurface; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Model.hxx b/src/IMeshData/IMeshData_Model.hxx new file mode 100644 index 0000000000..773ab6e973 --- /dev/null +++ b/src/IMeshData/IMeshData_Model.hxx @@ -0,0 +1,76 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Model_HeaderFile +#define _IMeshData_Model_HeaderFile + +#include +#include +#include +#include + +class TopoDS_Face; +class TopoDS_Edge; +class IMeshData_Face; +class IMeshData_Edge; + +//! Interface class representing discrete model of a shape. +class IMeshData_Model : public IMeshData_Shape +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Model() + { + } + + //! Returns maximum size of shape model. + Standard_EXPORT virtual Standard_Real GetMaxSize () const = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Model, IMeshData_Shape) + +public: //! @name discrete faces + + //! Returns number of faces in discrete model. + Standard_EXPORT virtual Standard_Integer FacesNb () const = 0; + + //! Adds new face to shape model. + Standard_EXPORT virtual const IMeshData::IFaceHandle& AddFace (const TopoDS_Face& theFace) = 0; + + //! Gets model's face with the given index. + Standard_EXPORT virtual const IMeshData::IFaceHandle& GetFace (const Standard_Integer theIndex) const = 0; + +public: //! @name discrete edges + + //! Returns number of edges in discrete model. + Standard_EXPORT virtual Standard_Integer EdgesNb () const = 0; + + //! Adds new edge to shape model. + Standard_EXPORT virtual const IMeshData::IEdgeHandle& AddEdge (const TopoDS_Edge& theEdge) = 0; + + //! Gets model's edge with the given index. + Standard_EXPORT virtual const IMeshData::IEdgeHandle& GetEdge (const Standard_Integer theIndex) const = 0; + +protected: + + //! Constructor. + //! Initializes empty model. + Standard_EXPORT IMeshData_Model (const TopoDS_Shape& theShape) + : IMeshData_Shape(theShape) + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_PCurve.hxx b/src/IMeshData/IMeshData_PCurve.hxx new file mode 100644 index 0000000000..4c6530cf0e --- /dev/null +++ b/src/IMeshData/IMeshData_PCurve.hxx @@ -0,0 +1,99 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_PCurve_HeaderFile +#define _IMeshData_PCurve_HeaderFile + +#include +#include +#include + +class gp_Pnt2d; + +//! Interface class representing pcurve of edge associated with discrete face. +//! Indexation of points starts from zero. +class IMeshData_PCurve : public IMeshData_ParametersList +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_PCurve() + { + } + + //! Inserts new discretization point at the given position. + Standard_EXPORT virtual void InsertPoint( + const Standard_Integer thePosition, + const gp_Pnt2d& thePoint, + const Standard_Real theParamOnPCurve) = 0; + + //! Adds new discretization point to pcurve. + Standard_EXPORT virtual void AddPoint ( + const gp_Pnt2d& thePoint, + const Standard_Real theParamOnPCurve) = 0; + + //! Returns discretization point with the given index. + Standard_EXPORT virtual gp_Pnt2d& GetPoint (const Standard_Integer theIndex) = 0; + + //! Returns index in mesh corresponded to discretization point with the given index. + Standard_EXPORT virtual Standard_Integer& GetIndex(const Standard_Integer theIndex) = 0; + + //! Removes point with the given index. + Standard_EXPORT virtual void RemovePoint (const Standard_Integer theIndex) = 0; + + //! Returns forward flag of this pcurve. + inline Standard_Boolean IsForward () const + { + return (myOrientation != TopAbs_REVERSED); + } + + //! Returns internal flag of this pcurve. + inline Standard_Boolean IsInternal() const + { + return (myOrientation == TopAbs_INTERNAL); + } + + //! Returns orientation of the edge associated with current pcurve. + inline TopAbs_Orientation GetOrientation() const + { + return myOrientation; + } + + //! Returns discrete face pcurve is associated to. + inline const IMeshData::IFacePtr& GetFace () const + { + return myDFace; + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_PCurve, IMeshData_ParametersList) + +protected: + + //! Constructor. + Standard_EXPORT IMeshData_PCurve ( + const IMeshData::IFacePtr& theDFace, + const TopAbs_Orientation theOrientation) + : myDFace(theDFace), + myOrientation(theOrientation) + { + } + +private: + + IMeshData::IFacePtr myDFace; + TopAbs_Orientation myOrientation; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_ParametersList.hxx b/src/IMeshData/IMeshData_ParametersList.hxx new file mode 100644 index 0000000000..8190fd2f32 --- /dev/null +++ b/src/IMeshData/IMeshData_ParametersList.hxx @@ -0,0 +1,54 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_ParametersList_HeaderFile +#define _IMeshData_ParametersList_HeaderFile + +#include +#include + +//! Interface class representing list of parameters on curve. +class IMeshData_ParametersList : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_ParametersList() + { + } + + //! Returns parameter with the given index. + Standard_EXPORT virtual Standard_Real& GetParameter (const Standard_Integer theIndex) = 0; + + //! Returns number of parameters. + Standard_EXPORT virtual Standard_Integer ParametersNb() const = 0; + + //! Clears parameters list. + Standard_EXPORT virtual void Clear(const Standard_Boolean isKeepEndPoints) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_ParametersList, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshData_ParametersList() + { + } + + //! Removes parameter with the given index. + Standard_EXPORT virtual void removeParameter (const Standard_Integer theIndex) = 0; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx b/src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx new file mode 100644 index 0000000000..4356961163 --- /dev/null +++ b/src/IMeshData/IMeshData_ParametersListArrayAdaptor.hxx @@ -0,0 +1,70 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_ParametersListArrayAdaptor_HeaderFile +#define _IMeshData_ParametersListArrayAdaptor_HeaderFile + +#include +#include +#include + +//! Auxiliary tool representing adaptor interface for child classes of +//! IMeshData_ParametersList to be used in tools working on NCollection_Array structure. +template +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& theOther); + + void operator=(const IMeshData_ParametersListArrayAdaptor& theOther); + + const ParametersListPtrType myParameters; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Shape.hxx b/src/IMeshData/IMeshData_Shape.hxx new file mode 100644 index 0000000000..eb5100a42a --- /dev/null +++ b/src/IMeshData/IMeshData_Shape.hxx @@ -0,0 +1,66 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Shape_HeaderFile +#define _IMeshData_Shape_HeaderFile + +#include +#include + +//! Interface class representing model with associated TopoDS_Shape. +//! Intended for inheritance by structures and algorithms keeping +//! reference TopoDS_Shape. +class IMeshData_Shape : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Shape() + { + } + + //! Assigns shape to discrete shape. + inline void SetShape (const TopoDS_Shape& theShape) + { + myShape = theShape; + } + + //! Returns shape assigned to discrete shape. + const TopoDS_Shape& GetShape () const + { + return myShape; + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Shape, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshData_Shape() + { + } + + //! Constructor. + Standard_EXPORT IMeshData_Shape (const TopoDS_Shape& theShape) + : myShape(theShape) + { + } + +private: + + TopoDS_Shape myShape; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Status.hxx b/src/IMeshData/IMeshData_Status.hxx new file mode 100644 index 0000000000..89f948f0d4 --- /dev/null +++ b/src/IMeshData/IMeshData_Status.hxx @@ -0,0 +1,33 @@ +// Created on: 2011-05-17 +// Created by: Oleg AGASHIN +// Copyright (c) 2011-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Status_HeaderFile +#define _IMeshData_Status_HeaderFile + +//! Enumerates statuses used to notify state of discrete model. +enum IMeshData_Status +{ + IMeshData_NoError = 0x0, + IMeshData_OpenWire = 0x1, + IMeshData_SelfIntersectingWire = 0x2, + IMeshData_Failure = 0x4, + IMeshData_ReMesh = 0x8, + IMeshData_UnorientedWire = 0x10, + IMeshData_TooFewPoints = 0x20, + IMeshData_Outdated = 0x40, + IMeshData_Reused = 0x80 +}; + +#endif diff --git a/src/IMeshData/IMeshData_StatusOwner.hxx b/src/IMeshData/IMeshData_StatusOwner.hxx new file mode 100644 index 0000000000..d1b54b032c --- /dev/null +++ b/src/IMeshData/IMeshData_StatusOwner.hxx @@ -0,0 +1,76 @@ +// Created on: 2016-06-23 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_StatusOwner_HeaderFile +#define _IMeshData_StatusOwner_HeaderFile + +#include +#include +#include + +//! Extension interface class providing status functionality. +class IMeshData_StatusOwner +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_StatusOwner() + { + } + + //! Returns true in case if status is strictly equal to the given value. + inline Standard_Boolean IsEqual(const IMeshData_Status theValue) const + { + return (myStatus == theValue); + } + + //! Returns true in case if status is set. + inline Standard_Boolean IsSet(const IMeshData_Status theValue) const + { + return (myStatus & theValue) != 0; + } + + //! Adds status to status flags of a face. + inline void SetStatus(const IMeshData_Status theValue) + { + myStatus |= theValue; + } + + //! Adds status to status flags of a face. + inline void UnsetStatus(const IMeshData_Status theValue) + { + myStatus &= ~theValue; + } + + //! Returns complete status mask. + inline Standard_Integer GetStatusMask() const + { + return myStatus; + } + +protected: + + //! Constructor. Initializes default status. + Standard_EXPORT IMeshData_StatusOwner() + : myStatus(IMeshData_NoError) + { + } + +private: + + Standard_Integer myStatus; +}; + +#endif diff --git a/src/IMeshData/IMeshData_TessellatedShape.hxx b/src/IMeshData/IMeshData_TessellatedShape.hxx new file mode 100644 index 0000000000..94001b032d --- /dev/null +++ b/src/IMeshData/IMeshData_TessellatedShape.hxx @@ -0,0 +1,67 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_TessellatedShape_HeaderFile +#define _IMeshData_TessellatedShape_HeaderFile + +#include +#include +#include + +//! Interface class representing shaped model with deflection. +class IMeshData_TessellatedShape : public IMeshData_Shape +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_TessellatedShape() + { + } + + //! Gets deflection value for the discrete model. + inline Standard_Real GetDeflection () const + { + return myDeflection; + } + + //! Sets deflection value for the discrete model. + inline void SetDeflection (const Standard_Real theValue) + { + myDeflection = theValue; + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_TessellatedShape, IMeshData_Shape) + +protected: + + //! Constructor. + Standard_EXPORT IMeshData_TessellatedShape () + : myDeflection(RealLast()) + { + } + + //! Constructor. + Standard_EXPORT IMeshData_TessellatedShape (const TopoDS_Shape& theShape) + : IMeshData_Shape(theShape), + myDeflection(RealLast()) + { + } + +private: + + Standard_Real myDeflection; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Types.hxx b/src/IMeshData/IMeshData_Types.hxx new file mode 100644 index 0000000000..26c9eb468d --- /dev/null +++ b/src/IMeshData/IMeshData_Types.hxx @@ -0,0 +1,175 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Types_HeaderFile +#define _IMeshData_Types_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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 IShapePtr; + typedef std::weak_ptr IEdgePtr; + typedef std::weak_ptr IWirePtr; + typedef std::weak_ptr IFacePtr; + typedef std::weak_ptr ICurvePtr; + typedef std::weak_ptr IPCurvePtr; + typedef std::weak_ptr IModelPtr; + + typedef std::shared_ptr IShapeHandle; + typedef std::shared_ptr IEdgeHandle; + typedef std::shared_ptr IWireHandle; + typedef std::shared_ptr IFaceHandle; + typedef std::shared_ptr ICurveHandle; + typedef std::shared_ptr IPCurveHandle; + typedef std::shared_ptr IModelHandle; + + typedef IMeshData_ParametersListArrayAdaptor ICurveArrayAdaptor; + typedef std::shared_ptr ICurveArrayAdaptorHandle; + + typedef NCollection_Shared > BndBox2dTree; + typedef NCollection_UBTreeFiller BndBox2dTreeFiller; + + // Vectors + typedef NCollection_Vector VectorOfIFaceHandles; + typedef NCollection_Vector VectorOfIWireHandles; + typedef NCollection_Vector VectorOfIEdgeHandles; + typedef NCollection_Vector VectorOfIPCurveHandles; + typedef NCollection_Vector VectorOfIEdgePtrs; + typedef NCollection_Vector VectorOfIShapesHandles; + typedef NCollection_Vector VectorOfBoolean; + typedef NCollection_Vector VectorOfInteger; + typedef NCollection_Vector VectorOfOrientation; + typedef NCollection_Vector VectorOfHBndBox2dTree; + typedef NCollection_Vector VectorOfElements; + typedef NCollection_Vector VectorOfCircle; + + typedef NCollection_Array1 Array1OfVertexOfDelaun; + typedef NCollection_Shared > VectorOfVertex; + + // Sequences + typedef NCollection_Shared > SequenceOfBndB2d; + typedef NCollection_Shared > SequenceOfInteger; + typedef NCollection_Shared > SequenceOfReal; + + namespace Model + { + typedef std::deque > SequenceOfPnt; + typedef std::deque > SequenceOfPnt2d; + typedef std::deque > SequenceOfReal; + typedef std::deque > SequenceOfInteger; + } + + // Lists + typedef NCollection_Shared > ListOfInteger; + typedef NCollection_Shared > ListOfPnt2d; + typedef NCollection_List ListOfIPCurves; + + typedef NCollection_Shared MapOfInteger; + typedef TColStd_MapIteratorOfPackedMapOfInteger IteratorOfMapOfInteger; + + typedef NCollection_CellFilter CircleCellFilter; + typedef NCollection_CellFilter VertexCellFilter; + + // Data Maps + template + struct WeakEqual + { + static Standard_Boolean IsEqual(const std::weak_ptr& theFirst, + const std::weak_ptr& theSecond) + { + return (theFirst.lock().get() == theSecond.lock().get()); + } + + static Standard_Integer HashCode(const std::weak_ptr& thePtr, Standard_Integer theUpper) + { + return ::HashCode(thePtr.lock().get(), theUpper); + } + }; + + typedef NCollection_Shared > DMapOfShapeInteger; + typedef NCollection_Shared > > DMapOfIFacePtrsListOfInteger; + typedef NCollection_Shared > > MapOfIEdgePtr; + typedef NCollection_Shared > > MapOfIFacePtr; + typedef NCollection_Shared > MapOfOrientedEdges; + typedef NCollection_Shared > MapOfReal; + typedef NCollection_Shared > > IDMapOfIFacePtrsListOfIPCurves; + typedef NCollection_Shared > > DMapOfIFacePtrsMapOfIEdgePtrs; + typedef NCollection_IndexedDataMap IDMapOfLink; + typedef NCollection_DataMap DMapOfIntegerListOfInteger; + typedef NCollection_DataMap MapOfIntegerInteger; + typedef NCollection_IndexedMap IMapOfReal; + + typedef NCollection_Array1 Array1OfInteger; +} + +#endif \ No newline at end of file diff --git a/src/IMeshData/IMeshData_Wire.hxx b/src/IMeshData/IMeshData_Wire.hxx new file mode 100644 index 0000000000..e2c2634f71 --- /dev/null +++ b/src/IMeshData/IMeshData_Wire.hxx @@ -0,0 +1,74 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshData_Wire_HeaderFile +#define _IMeshData_Wire_HeaderFile + +#include +#include +#include +#include +#include +#include + +class IMeshData_Edge; + +//! Interface class representing discrete model of a wire. +//! Wire should represent an ordered set of edges. +class IMeshData_Wire : public IMeshData_TessellatedShape, public IMeshData_StatusOwner +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshData_Wire() + { + } + + //! Returns TopoDS_Face attached to model. + inline const TopoDS_Wire& GetWire () const + { + return TopoDS::Wire (GetShape ()); + } + + //! Returns number of edges. + Standard_EXPORT virtual Standard_Integer EdgesNb () const = 0; + + //! Adds new discrete edge with specified orientation to wire chain. + //! @return index of added edge in wire chain. + Standard_EXPORT virtual Standard_Integer AddEdge ( + const IMeshData::IEdgePtr& theDEdge, + const TopAbs_Orientation theOrientation) = 0; + + //! Returns discrete edge with the given index. + Standard_EXPORT virtual const IMeshData::IEdgePtr& GetEdge ( + const Standard_Integer theIndex) const = 0; + + //! Returns True if orientation of discrete edge with the given index is forward. + Standard_EXPORT virtual TopAbs_Orientation GetEdgeOrientation ( + const Standard_Integer theIndex) const = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshData_Wire, IMeshData_TessellatedShape) + +protected: + + //! Constructor. + //! Initializes empty model. + Standard_EXPORT IMeshData_Wire(const TopoDS_Wire& theWire) + : IMeshData_TessellatedShape(theWire) + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/FILES b/src/IMeshTools/FILES new file mode 100644 index 0000000000..a5ba04ea11 --- /dev/null +++ b/src/IMeshTools/FILES @@ -0,0 +1,10 @@ +IMeshTools_Context.hxx +IMeshTools_CurveTessellator.hxx +IMeshTools_MeshAlgo.hxx +IMeshTools_MeshAlgoFactory.hxx +IMeshTools_MeshBuilder.hxx +IMeshTools_ModelAlgo.hxx +IMeshTools_ModelBuilder.hxx +IMeshTools_Parameters.hxx +IMeshTools_ShapeExplorer.hxx +IMeshTools_ShapeVisitor.hxx diff --git a/src/IMeshTools/IMeshTools_Context.hxx b/src/IMeshTools/IMeshTools_Context.hxx new file mode 100644 index 0000000000..fe77996c2e --- /dev/null +++ b/src/IMeshTools/IMeshTools_Context.hxx @@ -0,0 +1,240 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_Context_HeaderFile +#define _IMeshTools_Context_HeaderFile + +#include +#include +#include +#include +#include +#include + +//! Interface class representing context of BRepMesh algorithm. +//! Intended to cache discrete model and instances of tools for +//! its processing. +class IMeshTools_Context : public IMeshData_Shape +{ +public: + + //! Constructor. + Standard_EXPORT IMeshTools_Context() + { + } + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_Context() + { + } + + //! Builds model using assined model builder. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean BuildModel () + { + if (myModelBuilder.IsNull()) + { + return Standard_False; + } + + myModel = myModelBuilder->Perform(GetShape(), myParameters); + + return !myModel.IsNull(); + } + + //! Performs discretization of model edges using assigned edge discret algorithm. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean DiscretizeEdges() + { + if (myModel.IsNull() || myEdgeDiscret.IsNull()) + { + return Standard_False; + } + + // Discretize edges of a model. + return myEdgeDiscret->Perform(myModel, myParameters); + } + + //! Performs healing of discrete model built by DiscretizeEdges() method + //! using assigned healing algorithm. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean HealModel() + { + if (myModel.IsNull()) + { + return Standard_False; + } + + return myModelHealer.IsNull() ? + Standard_True : + myModelHealer->Perform(myModel, myParameters); + } + + //! Performs pre-processing of discrete model using assigned algorithm. + //! Performs auxiliary actions such as cleaning shape from old triangulation. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean PreProcessModel() + { + if (myModel.IsNull()) + { + return Standard_False; + } + + return myPreProcessor.IsNull() ? + Standard_True : + myPreProcessor->Perform(myModel, myParameters); + } + + //! Performs meshing of faces of discrete model using assigned meshing algorithm. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean DiscretizeFaces() + { + if (myModel.IsNull() || myFaceDiscret.IsNull()) + { + return Standard_False; + } + + // Discretize faces of a model. + return myFaceDiscret->Perform(myModel, myParameters); + } + + //! Performs post-processing of discrete model using assigned algorithm. + //! @return True on success, False elsewhere. + Standard_EXPORT virtual Standard_Boolean PostProcessModel() + { + if (myModel.IsNull()) + { + return Standard_False; + } + + return myPostProcessor.IsNull() ? + Standard_True : + myPostProcessor->Perform(myModel, myParameters); + } + + //! Cleans temporary context data. + Standard_EXPORT virtual void Clean() + { + if (myParameters.CleanModel) + { + myModel.Nullify(); + } + } + + //! Gets instance of a tool to be used to build discrete model. + inline const Handle (IMeshTools_ModelBuilder)& GetModelBuilder () const + { + return myModelBuilder; + } + + //! Sets instance of a tool to be used to build discrete model. + inline void SetModelBuilder (const Handle (IMeshTools_ModelBuilder)& theBuilder) + { + myModelBuilder = theBuilder; + } + + //! Gets instance of a tool to be used to discretize edges of a model. + inline const Handle (IMeshTools_ModelAlgo)& GetEdgeDiscret () const + { + return myEdgeDiscret; + } + + //! Sets instance of a tool to be used to discretize edges of a model. + inline void SetEdgeDiscret (const Handle (IMeshTools_ModelAlgo)& theEdgeDiscret) + { + myEdgeDiscret = theEdgeDiscret; + } + + //! Gets instance of a tool to be used to heal discrete model. + inline const Handle(IMeshTools_ModelAlgo)& GetModelHealer() const + { + return myModelHealer; + } + + //! Sets instance of a tool to be used to heal discrete model. + inline void SetModelHealer(const Handle(IMeshTools_ModelAlgo)& theModelHealer) + { + myModelHealer = theModelHealer; + } + + //! Gets instance of pre-processing algorithm. + inline const Handle(IMeshTools_ModelAlgo)& GetPreProcessor() const + { + return myPreProcessor; + } + + //! Sets instance of pre-processing algorithm. + inline void SetPreProcessor(const Handle(IMeshTools_ModelAlgo)& thePreProcessor) + { + myPreProcessor = thePreProcessor; + } + + //! Gets instance of meshing algorithm. + inline const Handle(IMeshTools_ModelAlgo)& GetFaceDiscret() const + { + return myFaceDiscret; + } + + //! Sets instance of meshing algorithm. + inline void SetFaceDiscret(const Handle(IMeshTools_ModelAlgo)& theFaceDiscret) + { + myFaceDiscret = theFaceDiscret; + } + + //! Gets instance of post-processing algorithm. + inline const Handle(IMeshTools_ModelAlgo)& GetPostProcessor() const + { + return myPostProcessor; + } + + //! Sets instance of post-processing algorithm. + inline void SetPostProcessor(const Handle(IMeshTools_ModelAlgo)& thePostProcessor) + { + myPostProcessor = thePostProcessor; + } + + //! Gets parameters to be used for meshing. + inline const IMeshTools_Parameters& GetParameters () const + { + return myParameters; + } + + //! Gets reference to parameters to be used for meshing. + inline IMeshTools_Parameters& ChangeParameters () + { + return myParameters; + } + + //! Returns discrete model of a shape. + inline const Handle (IMeshData_Model)& GetModel () const + { + return myModel; + } + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_Context, IMeshData_Shape) + +private: + + Handle (IMeshTools_ModelBuilder) myModelBuilder; + Handle (IMeshData_Model) myModel; + Handle (IMeshTools_ModelAlgo) myEdgeDiscret; + Handle (IMeshTools_ModelAlgo) myModelHealer; + Handle (IMeshTools_ModelAlgo) myPreProcessor; + Handle (IMeshTools_ModelAlgo) myFaceDiscret; + Handle (IMeshTools_ModelAlgo) myPostProcessor; + IMeshTools_Parameters myParameters; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_CurveTessellator.hxx b/src/IMeshTools/IMeshTools_CurveTessellator.hxx new file mode 100644 index 0000000000..2cbd66bfd6 --- /dev/null +++ b/src/IMeshTools/IMeshTools_CurveTessellator.hxx @@ -0,0 +1,57 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_EdgeTessellator_HeaderFile +#define _IMeshTools_EdgeTessellator_HeaderFile + +#include +#include + +class gp_Pnt; + +//! Interface class providing API for edge tessellation tools. +class IMeshTools_CurveTessellator : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_CurveTessellator() + { + } + + //! Returns number of tessellation points. + Standard_EXPORT virtual Standard_Integer PointsNb () const = 0; + + //! Returns parameters of solution with the given index. + //! @param theIndex index of tessellation point. + //! @param thePoint tessellation point. + //! @param theParameter parameters on PCurve corresponded to the solution. + //! @return True in case of valid result, false elewhere. + Standard_EXPORT virtual Standard_Boolean Value ( + const Standard_Integer theIndex, + gp_Pnt& thePoint, + Standard_Real& theParameter) const = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_CurveTessellator, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_CurveTessellator() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_MeshAlgo.hxx b/src/IMeshTools/IMeshTools_MeshAlgo.hxx new file mode 100644 index 0000000000..fb8e0b6d49 --- /dev/null +++ b/src/IMeshTools/IMeshTools_MeshAlgo.hxx @@ -0,0 +1,50 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_MeshAlgo_HeaderFile +#define _IMeshTools_MeshAlgo_HeaderFile + +#include +#include +#include + +struct IMeshTools_Parameters; + +//! Interface class providing API for algorithms intended to create mesh for discrete face. +class IMeshTools_MeshAlgo : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_MeshAlgo() + { + } + + //! Performs processing of the given face. + Standard_EXPORT virtual void Perform( + const IMeshData::IFaceHandle& theDFace, + const IMeshTools_Parameters& theParameters) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshAlgo, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_MeshAlgo() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx b/src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx new file mode 100644 index 0000000000..47008755bc --- /dev/null +++ b/src/IMeshTools/IMeshTools_MeshAlgoFactory.hxx @@ -0,0 +1,52 @@ +// Created on: 2016-07-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_MeshAlgoFactory_HeaderFile +#define _IMeshTools_MeshAlgoFactory_HeaderFile + +#include +#include +#include +#include + +struct IMeshTools_Parameters; + +//! Base interface for factories producing instances of triangulation +//! algorithms taking into account type of surface of target face. +class IMeshTools_MeshAlgoFactory : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_MeshAlgoFactory() + { + } + + //! Creates instance of meshing algorithm for the given type of surface. + Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo( + const GeomAbs_SurfaceType theSurfaceType, + const IMeshTools_Parameters& theParameters) const = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshAlgoFactory, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_MeshAlgoFactory() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_MeshBuilder.hxx b/src/IMeshTools/IMeshTools_MeshBuilder.hxx new file mode 100644 index 0000000000..dc7bc8cbc7 --- /dev/null +++ b/src/IMeshTools/IMeshTools_MeshBuilder.hxx @@ -0,0 +1,68 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_MeshBuilder_HeaderFile +#define _IMeshTools_MeshBuilder_HeaderFile + +#include +#include +#include + +//! Interface class providing API for mesh builder tool. +class IMeshTools_MeshBuilder : public Message_Algorithm +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_MeshBuilder() + { + } + + //! Sets context for algorithm. + inline void SetContext (const Handle (IMeshTools_Context)& theContext) + { + myContext = theContext; + } + + //! Gets context of algorithm. + inline const Handle (IMeshTools_Context)& GetContext () const + { + return myContext; + } + + //! Performs meshing ot the shape using current context. + Standard_EXPORT virtual void Perform () = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_MeshBuilder, Message_Algorithm) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_MeshBuilder() + { + } + + //! Constructor. + Standard_EXPORT IMeshTools_MeshBuilder (const Handle (IMeshTools_Context)& theContext) + : myContext(theContext) + { + } + +private: + + Handle (IMeshTools_Context) myContext; +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_ModelAlgo.hxx b/src/IMeshTools/IMeshTools_ModelAlgo.hxx new file mode 100644 index 0000000000..7e378dcdc9 --- /dev/null +++ b/src/IMeshTools/IMeshTools_ModelAlgo.hxx @@ -0,0 +1,50 @@ +// Created on: 2016-04-19 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_ModelAlgo_HeaderFile +#define _IMeshTools_ModelAlgo_HeaderFile + +#include +#include + +class IMeshData_Model; +struct IMeshTools_Parameters; + +//! Interface class providing API for algorithms intended to update or modify discrete model. +class IMeshTools_ModelAlgo : public Standard_Transient +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_ModelAlgo() + { + } + + //! Performs processing of edges of the given model. + Standard_EXPORT virtual Standard_Boolean Perform ( + const Handle (IMeshData_Model)& theModel, + const IMeshTools_Parameters& theParameters) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_ModelAlgo() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_ModelBuilder.hxx b/src/IMeshTools/IMeshTools_ModelBuilder.hxx new file mode 100644 index 0000000000..1dcdc3d821 --- /dev/null +++ b/src/IMeshTools/IMeshTools_ModelBuilder.hxx @@ -0,0 +1,57 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_ModelBuilder_HeaderFile +#define _IMeshTools_ModelBuilder_HeaderFile + +#include +#include +#include + +class IMeshData_Model; +struct IMeshTools_Parameters; + +//! Interface class represents API for tool building discrete model. +//! +//! The following statuses should be used by default: +//! Message_Done1 - model has been sucessfully built. +//! Message_Fail1 - empty shape. +//! Message_Fail2 - model has not been build due to unexpected reason. +class IMeshTools_ModelBuilder : public Message_Algorithm +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_ModelBuilder() + { + } + + //! Creates discrete model for the given shape. + //! Returns nullptr in case of failure. + Standard_EXPORT virtual Handle (IMeshData_Model) Perform ( + const TopoDS_Shape& theShape, + const IMeshTools_Parameters& theParameters) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_ModelBuilder() + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_Parameters.hxx b/src/IMeshTools/IMeshTools_Parameters.hxx new file mode 100644 index 0000000000..60acf8e0dc --- /dev/null +++ b/src/IMeshTools/IMeshTools_Parameters.hxx @@ -0,0 +1,68 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_Parameters_HeaderFile +#define _IMeshTools_Parameters_HeaderFile + +#include + +//! 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
+ //! If true, deflection used for the polygonalisation of each edge will be + //! * Size of Edge. The deflection used for the faces will be the + //! maximum deflection of their edges. + Standard_Boolean Relative; + + //! Mode to take or not to take internal face vertices into account + //! in triangulation process + Standard_Boolean InternalVerticesMode; + + //! Parameter to check the deviation of triangulation and interior of + //! the face + Standard_Boolean ControlSurfaceDeflection; + + //! Cleans temporary data model when algorithm is finished. + Standard_Boolean CleanModel; +}; + +#endif diff --git a/src/IMeshTools/IMeshTools_ShapeExplorer.hxx b/src/IMeshTools/IMeshTools_ShapeExplorer.hxx new file mode 100644 index 0000000000..a6ee59e492 --- /dev/null +++ b/src/IMeshTools/IMeshTools_ShapeExplorer.hxx @@ -0,0 +1,48 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_ShapeExplorer_HeaderFile +#define _IMeshTools_ShapeExplorer_HeaderFile + +#include +#include +#include +#include + +//! Interface class for tools exploring TopoDS_Shape. +class IMeshTools_ShapeExplorer : public IMeshData_Shape +{ +public: + + //! Destructor. + Standard_EXPORT virtual ~IMeshTools_ShapeExplorer() + { + } + + //! Starts exploring of a shape. + Standard_EXPORT virtual void Accept (const Handle (IMeshTools_ShapeVisitor)& theVisitor) = 0; + + DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ShapeExplorer, IMeshData_Shape) + +protected: + + //! Constructor. + Standard_EXPORT IMeshTools_ShapeExplorer (const TopoDS_Shape& theShape) + : IMeshData_Shape(theShape) + { + } +}; + +#endif \ No newline at end of file diff --git a/src/IMeshTools/IMeshTools_ShapeVisitor.hxx b/src/IMeshTools/IMeshTools_ShapeVisitor.hxx new file mode 100644 index 0000000000..50ee23dc49 --- /dev/null +++ b/src/IMeshTools/IMeshTools_ShapeVisitor.hxx @@ -0,0 +1,51 @@ +// Created on: 2016-04-07 +// Copyright (c) 2016 OPEN CASCADE SAS +// Created by: Oleg AGASHIN +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _IMeshTools_ShapeVisitor_HeaderFile +#define _IMeshTools_ShapeVisitor_HeaderFile + +#include +#include + +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 -- 2.39.5