1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MAT2d.hxx
23 // Created : Thu May 28 17:49:53 2015
24 // Author : Edward AGAPOV (eap)
26 #ifndef __SMESH_MAT2d_HXX__
27 #define __SMESH_MAT2d_HXX__
29 #include "SMESH_Utils.hxx"
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Edge.hxx>
37 #include <boost/polygon/polygon.hpp>
38 #include <boost/polygon/voronoi.hpp>
40 class Adaptor3d_Curve;
42 // Medial Axis Transform 2D
45 class MedialAxis; // MedialAxis is the entry point
51 typedef boost::polygon::voronoi_diagram<double> TVD;
52 typedef TVD::cell_type TVDCell;
53 typedef TVD::edge_type TVDEdge;
54 typedef TVD::vertex_type TVDVertex;
56 //-------------------------------------------------------------------------------------
57 // type of Branch end point
58 enum BranchEndType { BE_UNDEF,
59 BE_ON_VERTEX, // branch ends at a convex VRTEX
60 BE_BRANCH_POINT, // branch meats 2 or more other branches
61 BE_END // branch end equidistant from several adjacent segments
63 //-------------------------------------------------------------------------------------
65 * \brief End point of MA Branch
67 struct SMESHUtils_EXPORT BranchEnd
69 const TVDVertex* _vertex;
71 std::vector< const Branch* > _branches;
73 BranchEnd(): _vertex(0), _type( BE_UNDEF ) {}
75 //-------------------------------------------------------------------------------------
77 * \brief Point on MA Branch
79 struct SMESHUtils_EXPORT BranchPoint
81 const Branch* _branch;
82 std::size_t _iEdge; // MA edge index within the branch
83 double _edgeParam; // normalized param within the MA edge
85 BranchPoint(): _branch(0), _iEdge(0), _edgeParam(-1) {}
87 //-------------------------------------------------------------------------------------
89 * \brief Branch is a set of MA edges enclosed between branch points and/or MA ends.
90 * It's main feature is to return two BoundaryPoint's per a point on it.
91 * Points on a Branch are defined by [0,1] parameter
93 class SMESHUtils_EXPORT Branch
96 bool getBoundaryPoints(double param, BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
97 bool getBoundaryPoints(std::size_t iMAEdge, double maEdgeParam,
98 BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
99 bool getBoundaryPoints(const BranchPoint& p,
100 BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
101 bool getParameter(const BranchPoint& p, double & u ) const;
103 std::size_t nbEdges() const { return _maEdges.size(); }
105 const BranchEnd* getEnd(bool the2nd) const { return & ( the2nd ? _endPoint2 : _endPoint1 ); }
107 bool hasEndOfType(BranchEndType type) const;
109 void getPoints( std::vector< gp_XY >& points, const double scale[2]) const;
111 void getGeomEdges( std::vector< std::size_t >& edgeIDs1,
112 std::vector< std::size_t >& edgeIDs2 ) const;
114 void getOppositeGeomEdges( std::vector< std::size_t >& edgeIDs1,
115 std::vector< std::size_t >& edgeIDs2,
116 std::vector< BranchPoint >& divPoints) const;
118 bool isRemoved() const { return _proxyPoint._branch; }
120 public: // internal: construction
122 void init( std::vector<const TVDEdge*>& maEdges,
123 const Boundary* boundary,
124 std::map< const TVDVertex*, BranchEndType > endType);
125 void setBranchesToEnds( const std::vector< Branch >& branches);
126 BranchPoint getPoint( const TVDVertex* vertex ) const;
127 void setRemoved( const BranchPoint& proxyPoint );
129 static void setGeomEdge ( std::size_t geomIndex, const TVDEdge* maEdge );
130 static std::size_t getGeomEdge ( const TVDEdge* maEdge );
131 static void setBndSegment( std::size_t segIndex, const TVDEdge* maEdge );
132 static std::size_t getBndSegment( const TVDEdge* maEdge );
136 bool addDivPntForConcaVertex( std::vector< std::size_t >& edgeIDs1,
137 std::vector< std::size_t >& edgeIDs2,
138 std::vector< BranchPoint >& divPoints,
139 const std::vector<const TVDEdge*>& maEdges,
140 const std::vector<const TVDEdge*>& maEdgesTwin,
143 // association of _maEdges with boundary segments is stored in this way:
144 // index of an EDGE: TVDEdge->cell()->color()
145 // index of a segment on EDGE: TVDEdge->color()
146 std::vector<const TVDEdge*> _maEdges; // MA edges ending at points located at _params
147 std::vector<double> _params; // params of points on MA, normalized [0;1] within this branch
148 const Boundary* _boundary; // face boundary
149 BranchEnd _endPoint1;
150 BranchEnd _endPoint2;
151 BranchPoint _proxyPoint;
154 //-------------------------------------------------------------------------------------
156 * \brief Data of a discretized EDGE allowing to get a point on MA by a parameter on EDGE
160 std::vector< double > _params; // params of discretization points on an EDGE
161 std::vector< std::pair< const Branch*, int > > _maEdges; /* index of TVDEdge in branch;
162 index sign means orientation;
163 index == Branch->nbEdges() means
164 end point of a Branch */
166 //-------------------------------------------------------------------------------------
168 * \brief Face boundary is discretized so that each its segment to correspond to
171 class SMESHUtils_EXPORT Boundary
175 Boundary( std::size_t nbEdges ): _pointsPerEdge( nbEdges ) {}
176 BndPoints& getPoints( std::size_t iEdge ) { return _pointsPerEdge[ iEdge ]; }
177 std::size_t nbEdges() const { return _pointsPerEdge.size(); }
179 bool getPoint( std::size_t iEdge, std::size_t iSeg, double u, BoundaryPoint& bp ) const;
181 bool getBranchPoint( const std::size_t iEdge, double u, BranchPoint& p ) const;
183 bool isConcaveSegment( std::size_t iEdge, std::size_t iSeg ) const;
185 bool moveToClosestEdgeEnd( BoundaryPoint& bp ) const;
188 std::vector< BndPoints > _pointsPerEdge;
191 //-------------------------------------------------------------------------------------
193 * \brief Point on FACE boundary
195 struct SMESHUtils_EXPORT BoundaryPoint
197 std::size_t _edgeIndex; // index of an EDGE in a sequence passed to MedialAxis()
198 double _param; // parameter of this EDGE
200 //-------------------------------------------------------------------------------------
202 * \brief Medial axis (MA) is defined as the loci of centres of locally
203 * maximal balls inside 2D representation of a face. This class
204 * implements a piecewise approximation of MA.
206 class SMESHUtils_EXPORT MedialAxis
209 MedialAxis(const TopoDS_Face& face,
210 const std::vector< TopoDS_Edge >& edges,
211 const double minSegLen,
212 const bool ignoreCorners = false );
213 std::size_t nbBranches() const { return _nbBranches; }
214 const Branch* getBranch(size_t i) const;
215 const std::vector< const BranchEnd* >& getBranchPoints() const { return _branchPnt; }
216 const Boundary& getBoundary() const { return _boundary; }
218 void getPoints( const Branch* branch, std::vector< gp_XY >& points) const;
219 Adaptor3d_Curve* make3DCurve(const Branch& branch) const;
226 std::vector< Branch > _branch;
227 std::size_t _nbBranches; // removed branches ignored
228 std::vector< const BranchEnd* > _branchPnt;