mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-02 21:00:34 +05:00
239 lines
9.5 KiB
C++
239 lines
9.5 KiB
C++
// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
//
|
|
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
|
|
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2.1 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
// File : SMESH_MAT2d.hxx
|
|
// Created : Thu May 28 17:49:53 2015
|
|
// Author : Edward AGAPOV (eap)
|
|
|
|
#ifndef __SMESH_MAT2d_HXX__
|
|
#define __SMESH_MAT2d_HXX__
|
|
|
|
#include "SMESH_Utils.hxx"
|
|
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include <boost/polygon/polygon.hpp>
|
|
#include <boost/polygon/voronoi.hpp>
|
|
|
|
class Adaptor3d_Curve;
|
|
|
|
// Medial Axis Transform 2D
|
|
namespace SMESH_MAT2d
|
|
{
|
|
class MedialAxis; // MedialAxis is the entry point
|
|
class Branch;
|
|
class BranchEnd;
|
|
class Boundary;
|
|
struct BoundaryPoint;
|
|
|
|
typedef boost::polygon::voronoi_diagram<double> TVD;
|
|
typedef TVD::cell_type TVDCell;
|
|
typedef TVD::edge_type TVDEdge;
|
|
typedef TVD::vertex_type TVDVertex;
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
// type of Branch end point
|
|
enum BranchEndType { BE_UNDEF,
|
|
BE_ON_VERTEX, // branch ends at a convex VRTEX
|
|
BE_BRANCH_POINT, // branch meats 2 or more other branches
|
|
BE_END // branch end equidistant from several adjacent segments
|
|
};
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief End point of MA Branch
|
|
*/
|
|
struct SMESHUtils_EXPORT BranchEnd
|
|
{
|
|
const TVDVertex* _vertex;
|
|
BranchEndType _type;
|
|
std::vector< const Branch* > _branches;
|
|
|
|
BranchEnd(): _vertex(0), _type( BE_UNDEF ) {}
|
|
};
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Point on MA Branch
|
|
*/
|
|
struct SMESHUtils_EXPORT BranchPoint
|
|
{
|
|
const Branch* _branch;
|
|
std::size_t _iEdge; // MA edge index within the branch
|
|
double _edgeParam; // normalized param within the MA edge
|
|
|
|
BranchPoint( const Branch* b = 0, std::size_t e = 0, double u = -1 ):
|
|
_branch(b), _iEdge(e), _edgeParam(u) {}
|
|
};
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Branch is a set of MA edges enclosed between branch points and/or MA ends.
|
|
* It's main feature is to return two BoundaryPoint's per a point on it.
|
|
* Points on a Branch are defined by [0,1] parameter
|
|
*/
|
|
class SMESHUtils_EXPORT Branch
|
|
{
|
|
public:
|
|
bool getBoundaryPoints(double param, BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
|
|
bool getBoundaryPoints(std::size_t iMAEdge, double maEdgeParam,
|
|
BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
|
|
bool getBoundaryPoints(const BranchPoint& p,
|
|
BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
|
|
bool getParameter(const BranchPoint& p, double & u ) const;
|
|
|
|
std::size_t nbEdges() const { return _maEdges.size(); }
|
|
|
|
const BranchEnd* getEnd(bool the2nd) const { return & ( the2nd ? _endPoint2 : _endPoint1 ); }
|
|
|
|
bool hasEndOfType(BranchEndType type) const;
|
|
|
|
void getPoints( std::vector< gp_XY >& points, const double scale[2]) const;
|
|
|
|
void getGeomEdges( std::vector< std::size_t >& edgeIDs1,
|
|
std::vector< std::size_t >& edgeIDs2 ) const;
|
|
|
|
void getOppositeGeomEdges( std::vector< std::size_t >& edgeIDs1,
|
|
std::vector< std::size_t >& edgeIDs2,
|
|
std::vector< BranchPoint >& divPoints) const;
|
|
|
|
bool isRemoved() const { return _proxyPoint._branch; }
|
|
|
|
public: // internal: construction
|
|
|
|
void init( std::vector<const TVDEdge*>& maEdges,
|
|
const Boundary* boundary,
|
|
std::map< const TVDVertex*, BranchEndType >& endType);
|
|
void setBranchesToEnds( const std::vector< Branch >& branches);
|
|
BranchPoint getPoint( const TVDVertex* vertex ) const;
|
|
void setRemoved( const BranchPoint& proxyPoint );
|
|
|
|
static void setGeomEdge ( std::size_t geomIndex, const TVDEdge* maEdge );
|
|
static std::size_t getGeomEdge ( const TVDEdge* maEdge );
|
|
static void setBndSegment( std::size_t segIndex, const TVDEdge* maEdge );
|
|
static std::size_t getBndSegment( const TVDEdge* maEdge );
|
|
|
|
private:
|
|
|
|
bool addDivPntForConcaVertex( std::vector< std::size_t >& edgeIDs1,
|
|
std::vector< std::size_t >& edgeIDs2,
|
|
std::vector< BranchPoint >& divPoints,
|
|
const std::vector<const TVDEdge*>& maEdges,
|
|
const std::vector<const TVDEdge*>& maEdgesTwin,
|
|
int & i) const;
|
|
|
|
// association of _maEdges with boundary segments is stored in this way:
|
|
// index of an EDGE: TVDEdge->cell()->color()
|
|
// index of a segment on EDGE: TVDEdge->color()
|
|
std::vector<const TVDEdge*> _maEdges; // MA edges ending at points located at _params
|
|
std::vector<double> _params; // params of points on MA, normalized [0;1] within this branch
|
|
const Boundary* _boundary; // face boundary
|
|
BranchEnd _endPoint1;
|
|
BranchEnd _endPoint2;
|
|
BranchPoint _proxyPoint;
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Data of a discretized EDGE allowing to get a point on MA by a parameter on EDGE
|
|
*/
|
|
struct BndPoints
|
|
{
|
|
std::vector< double > _params; // params of discretization points on an EDGE
|
|
std::vector< std::pair< const Branch*, int > > _maEdges; /* index of TVDEdge in branch;
|
|
index sign means orientation;
|
|
index == Branch->nbEdges() means
|
|
end point of a Branch */
|
|
};
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Face boundary is discretized so that each its segment to correspond to
|
|
* an edge of MA
|
|
*/
|
|
class SMESHUtils_EXPORT Boundary
|
|
{
|
|
public:
|
|
|
|
Boundary( std::size_t nbEdges ): _pointsPerEdge( nbEdges ) {}
|
|
BndPoints& getPoints( std::size_t iEdge ) { return _pointsPerEdge[ iEdge ]; }
|
|
std::size_t nbEdges() const { return _pointsPerEdge.size(); }
|
|
|
|
bool getPoint( std::size_t iEdge, std::size_t iSeg, double u, BoundaryPoint& bp ) const;
|
|
|
|
bool getBranchPoint( const std::size_t iEdge, double u, BranchPoint& p ) const;
|
|
|
|
bool getBranchPoint( const BoundaryPoint& bp, BranchPoint& p ) const;
|
|
|
|
bool isConcaveSegment( std::size_t iEdge, std::size_t iSeg ) const;
|
|
|
|
bool moveToClosestEdgeEnd( BoundaryPoint& bp ) const;
|
|
|
|
private:
|
|
std::vector< BndPoints > _pointsPerEdge;
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Point on FACE boundary
|
|
*/
|
|
struct SMESHUtils_EXPORT BoundaryPoint
|
|
{
|
|
std::size_t _edgeIndex; // index of an EDGE in a sequence passed to MedialAxis()
|
|
double _param; // parameter of this EDGE
|
|
};
|
|
//-------------------------------------------------------------------------------------
|
|
/*!
|
|
* \brief Medial axis (MA) is defined as the loci of centres of locally
|
|
* maximal balls inside 2D representation of a face. This class
|
|
* implements a piecewise approximation of MA.
|
|
*/
|
|
class SMESHUtils_EXPORT MedialAxis
|
|
{
|
|
public:
|
|
MedialAxis(const TopoDS_Face& face,
|
|
const std::vector< TopoDS_Edge >& edges,
|
|
const double minSegLen,
|
|
const bool ignoreCorners = false );
|
|
std::size_t nbBranches() const { return _nbBranches; }
|
|
const Branch* getBranch(size_t i) const;
|
|
const std::vector< const BranchEnd* >& getBranchPoints() const { return _branchPnt; }
|
|
const Boundary& getBoundary() const { return _boundary; }
|
|
|
|
void getPoints( const Branch* branch, std::vector< gp_XY >& points) const;
|
|
Adaptor3d_Curve* make3DCurve(const Branch& branch) const;
|
|
|
|
private:
|
|
|
|
private:
|
|
TopoDS_Face _face;
|
|
TVD _vd;
|
|
std::vector< Branch > _branch;
|
|
std::size_t _nbBranches; // removed branches ignored
|
|
std::vector< const BranchEnd* > _branchPnt;
|
|
Boundary _boundary;
|
|
double _scale[2];
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|