Salome HOME
23179: EDF 11603 - Problem with extrusion when path is not well oriented
[modules/smesh.git] / src / SMESHUtils / SMESH_MAT2d.hxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File      : SMESH_MAT2d.hxx
23 // Created   : Thu May 28 17:49:53 2015
24 // Author    : Edward AGAPOV (eap)
25
26 #ifndef __SMESH_MAT2d_HXX__
27 #define __SMESH_MAT2d_HXX__
28
29 #include "SMESH_Utils.hxx"
30
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Edge.hxx>
33
34 #include <vector>
35 #include <map>
36
37 #include <boost/polygon/polygon.hpp>
38 #include <boost/polygon/voronoi.hpp>
39
40 class Adaptor3d_Curve;
41
42 // Medial Axis Transform 2D
43 namespace SMESH_MAT2d
44 {
45   class MedialAxis; // MedialAxis is the entry point
46   class Branch;
47   class BranchEnd;
48   class Boundary;
49   struct BoundaryPoint;
50
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;
55
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
62   };
63   //-------------------------------------------------------------------------------------
64   /*!
65    * \brief End point of MA Branch
66    */
67   struct SMESHUtils_EXPORT BranchEnd
68   {
69     const TVDVertex*             _vertex;
70     BranchEndType                _type;
71     std::vector< const Branch* > _branches;
72
73     BranchEnd(): _vertex(0), _type( BE_UNDEF ) {}
74   };
75   //-------------------------------------------------------------------------------------
76   /*!
77    * \brief Point on MA Branch
78    */
79   struct SMESHUtils_EXPORT BranchPoint
80   {
81     const Branch* _branch;
82     std::size_t   _iEdge; // MA edge index within the branch
83     double        _edgeParam; // normalized param within the MA edge
84
85     BranchPoint( const Branch* b = 0, std::size_t e = 0, double u = -1 ):
86       _branch(b), _iEdge(e), _edgeParam(u) {}
87   };
88   //-------------------------------------------------------------------------------------
89   /*!
90    * \brief Branch is a set of MA edges enclosed between branch points and/or MA ends.
91    *        It's main feature is to return two BoundaryPoint's per a point on it.
92    *        Points on a Branch are defined by [0,1] parameter 
93    */
94   class SMESHUtils_EXPORT Branch
95   {
96   public:
97     bool getBoundaryPoints(double param, BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
98     bool getBoundaryPoints(std::size_t iMAEdge, double maEdgeParam,
99                            BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
100     bool getBoundaryPoints(const BranchPoint& p,
101                            BoundaryPoint& bp1, BoundaryPoint& bp2 ) const;
102     bool getParameter(const BranchPoint& p, double & u ) const;
103
104     std::size_t      nbEdges() const { return _maEdges.size(); }
105
106     const BranchEnd* getEnd(bool the2nd) const { return & ( the2nd ? _endPoint2 : _endPoint1 ); }
107
108     bool hasEndOfType(BranchEndType type) const;
109
110     void getPoints( std::vector< gp_XY >& points, const double scale[2]) const;
111
112     void getGeomEdges( std::vector< std::size_t >& edgeIDs1,
113                        std::vector< std::size_t >& edgeIDs2 ) const;
114
115     void getOppositeGeomEdges( std::vector< std::size_t >& edgeIDs1,
116                                std::vector< std::size_t >& edgeIDs2,
117                                std::vector< BranchPoint >& divPoints) const;
118
119     bool isRemoved() const { return _proxyPoint._branch; }
120
121   public: // internal: construction
122
123     void init( std::vector<const TVDEdge*>&                maEdges,
124                const Boundary*                             boundary,
125                std::map< const TVDVertex*, BranchEndType > endType);
126     void setBranchesToEnds( const std::vector< Branch >&   branches);
127     BranchPoint getPoint( const TVDVertex* vertex ) const;
128     void setRemoved( const BranchPoint& proxyPoint );
129
130     static void        setGeomEdge  ( std::size_t geomIndex, const TVDEdge* maEdge );
131     static std::size_t getGeomEdge  ( const TVDEdge* maEdge );
132     static void        setBndSegment( std::size_t segIndex, const TVDEdge* maEdge );
133     static std::size_t getBndSegment( const TVDEdge* maEdge );
134
135   private:
136
137     bool addDivPntForConcaVertex( std::vector< std::size_t >&        edgeIDs1,
138                                   std::vector< std::size_t >&        edgeIDs2,
139                                   std::vector< BranchPoint >&        divPoints,
140                                   const std::vector<const TVDEdge*>& maEdges,
141                                   const std::vector<const TVDEdge*>& maEdgesTwin,
142                                   int &                              i) const;
143
144     // association of _maEdges with boundary segments is stored in this way:
145     // index of an EDGE:           TVDEdge->cell()->color()
146     // index of a segment on EDGE: TVDEdge->color()
147     std::vector<const TVDEdge*> _maEdges; // MA edges ending at points located at _params
148     std::vector<double>  _params; // params of points on MA, normalized [0;1] within this branch
149     const Boundary*      _boundary; // face boundary
150     BranchEnd            _endPoint1;
151     BranchEnd            _endPoint2;
152     BranchPoint          _proxyPoint;
153   };
154
155   //-------------------------------------------------------------------------------------
156   /*!
157    * \brief Data of a discretized EDGE allowing to get a point on MA by a parameter on EDGE
158    */
159   struct BndPoints
160   {
161     std::vector< double > _params; // params of discretization points on an EDGE
162     std::vector< std::pair< const Branch*, int > > _maEdges; /* index of TVDEdge in branch;
163                                                                 index sign means orientation;
164                                                                 index == Branch->nbEdges() means
165                                                                 end point of a Branch */
166   };
167   //-------------------------------------------------------------------------------------
168   /*!
169    * \brief Face boundary is discretized so that each its segment to correspond to
170    *        an edge of MA
171    */
172   class SMESHUtils_EXPORT Boundary
173   {
174   public:
175
176     Boundary( std::size_t nbEdges ): _pointsPerEdge( nbEdges ) {}
177     BndPoints&  getPoints( std::size_t iEdge ) { return _pointsPerEdge[ iEdge ]; }
178     std::size_t nbEdges() const { return _pointsPerEdge.size(); }
179
180     bool getPoint( std::size_t iEdge, std::size_t iSeg, double u, BoundaryPoint& bp ) const;
181
182     bool getBranchPoint( const std::size_t iEdge, double u, BranchPoint& p ) const;
183
184     bool getBranchPoint( const BoundaryPoint& bp, BranchPoint& p ) const;
185
186     bool isConcaveSegment( std::size_t iEdge, std::size_t iSeg ) const;
187
188     bool moveToClosestEdgeEnd( BoundaryPoint& bp ) const;
189
190   private:
191     std::vector< BndPoints > _pointsPerEdge;
192   };
193
194   //-------------------------------------------------------------------------------------
195   /*!
196    * \brief Point on FACE boundary
197    */
198   struct SMESHUtils_EXPORT BoundaryPoint
199   {
200     std::size_t _edgeIndex; // index of an EDGE in a sequence passed to MedialAxis()
201     double      _param;     // parameter of this EDGE
202   };
203   //-------------------------------------------------------------------------------------
204   /*!
205    * \brief Medial axis (MA) is defined as the loci of centres of locally
206    *        maximal balls inside 2D representation of a face. This class
207    *        implements a piecewise approximation of MA.
208    */
209   class SMESHUtils_EXPORT MedialAxis
210   {
211   public:
212     MedialAxis(const TopoDS_Face&                face,
213                const std::vector< TopoDS_Edge >& edges,
214                const double                      minSegLen,
215                const bool                        ignoreCorners = false );
216     std::size_t                            nbBranches() const { return _nbBranches; }
217     const Branch*                          getBranch(size_t i) const;
218     const std::vector< const BranchEnd* >& getBranchPoints() const { return _branchPnt; }
219     const Boundary&                        getBoundary() const { return _boundary; }
220
221     void getPoints( const Branch* branch, std::vector< gp_XY >& points) const;
222     Adaptor3d_Curve* make3DCurve(const Branch& branch) const;
223
224   private:
225
226   private:
227     TopoDS_Face                     _face;
228     TVD                             _vd;
229     std::vector< Branch >           _branch;
230     std::size_t                     _nbBranches; // removed branches ignored
231     std::vector< const BranchEnd* > _branchPnt;
232     Boundary                        _boundary;
233     double                          _scale[2];
234   };
235
236 }
237
238 #endif