Salome HOME
[HYDRO module - Feature #523] river, channel, embankment meshing
[modules/smesh.git] / src / SMESHUtils / SMESH_MAT2d.hxx
diff --git a/src/SMESHUtils/SMESH_MAT2d.hxx b/src/SMESHUtils/SMESH_MAT2d.hxx
new file mode 100644 (file)
index 0000000..7e1061d
--- /dev/null
@@ -0,0 +1,224 @@
+// Copyright (C) 2007-2015  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(): _branch(0), _iEdge(0), _edgeParam(-1) {}
+  };
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \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.
+   */
+  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;
+
+    // construction
+    void init( std::vector<const TVDEdge*>&                maEdges,
+               const Boundary*                             boundary,
+               std::map< const TVDVertex*, BranchEndType > endType);
+    void setBranchesToEnds( const std::vector< Branch >&   branches);
+
+    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,
+                                  size_t &                           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;
+  };
+
+  //-------------------------------------------------------------------------------------
+  /*!
+   * \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 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 IsConcaveSegment( std::size_t iEdge, std::size_t iSeg ) 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 );
+    const Boundary&                        getBoundary() const { return _boundary; }
+    const std::vector< Branch >&           getBranches() const { return _branch; }
+    const std::vector< const BranchEnd* >& getBranchPoints() const { return _branchPnt; }
+
+    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::vector< const BranchEnd* > _branchPnt;
+    Boundary                        _boundary;
+    double                          _scale[2];
+  };
+
+}
+
+#endif