Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMESH / SMESH_MesherHelper.hxx
index fdf863f033e94d0792d75204853661e5ee932545..191c8814b9904ef3dddb7757c29af64a2121e91a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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
@@ -29,9 +29,8 @@
 
 #include "SMESH_SMESH.hxx"
 
-#include "SMESH_MeshEditor.hxx" // needed for many meshers
-#include <SMDS_MeshNode.hxx>
-#include <SMDS_QuadraticEdge.hxx>
+#include "SMESH_ComputeError.hxx"
+#include "SMESH_TypeDefs.hxx"
 
 #include <Geom_Surface.hxx>
 #include <ShapeAnalysis_Surface.hxx>
 #include <map>
 #include <vector>
 
-class GeomAPI_ProjectPointOnSurf;
 class GeomAPI_ProjectPointOnCurve;
+class GeomAPI_ProjectPointOnSurf;
+class SMDS_MeshNode;
+class SMESHDS_Hypothesis;
+class SMESHDS_Mesh;
+class SMESHDS_SubMesh;
+class SMESH_Gen;
+class SMESH_Mesh;
 class SMESH_ProxyMesh;
+class SMESH_subMesh;
+class TopoDS_Edge;
+class TopoDS_Face;
+class TopoDS_Vertex;
 
 typedef std::map<SMESH_TLink, const SMDS_MeshNode*>           TLinkNodeMap;
 typedef std::map<SMESH_TLink, const SMDS_MeshNode*>::iterator ItTLinkNode;
 
 typedef SMDS_Iterator<const TopoDS_Shape*>  PShapeIterator;
 typedef boost::shared_ptr< PShapeIterator > PShapeIteratorPtr;
-  
+
 typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
 typedef std::map< double, TNodeColumn >    TParam2ColumnMap;
 
@@ -91,7 +100,7 @@ class SMESH_EXPORT SMESH_MesherHelper
    * \brief Load nodes bound to face into a map of node columns
     * \param theParam2ColumnMap - map of node columns to fill
     * \param theFace - the face on which nodes are searched for
-    * \param theBaseSide - the edges holding nodes on which columns' bases
+    * \param theBaseSide - the edges holding nodes on which columns base
     * \param theMesh - the mesh containing nodes
     * \retval bool - false if something is wrong
    * 
@@ -118,10 +127,19 @@ class SMESH_EXPORT SMESH_MesherHelper
    */
   static bool IsStructured( SMESH_subMesh* faceSM );
 
+  /*!
+   * \brief Return true if a node is at a corner of a 2D structured mesh of FACE
+   */
+  static bool IsCornerOfStructure( const SMDS_MeshNode*   n,
+                                   const SMESHDS_SubMesh* faceSM,
+                                   SMESH_MesherHelper&    faceAnalyser );
+
   /*!
    * \brief Return true if 2D mesh on FACE is distored
    */
-  static bool IsDistorted2D( SMESH_subMesh* faceSM, bool checkUV=false );
+  static bool IsDistorted2D( SMESH_subMesh*      faceSM,
+                             bool                checkUV = false,
+                             SMESH_MesherHelper* faceHelper = NULL);
 
   /*!
    * \brief Returns true if given node is medium
@@ -186,7 +204,7 @@ class SMESH_EXPORT SMESH_MesherHelper
    * \brief Count nb of sub-shapes
     * \param shape - the shape
     * \param type - the type of sub-shapes to count
-    * \param ignoreSame - if true, use map not to count same shapes, esle use explorer
+    * \param ignoreSame - if true, use map not to count same shapes, else use explorer
     * \retval int - the calculated number
    */
   static int Count(const TopoDS_Shape&    shape,
@@ -200,11 +218,12 @@ class SMESH_EXPORT SMESH_MesherHelper
                          const SMESH_Mesh&   mesh,
                          TopAbs_ShapeEnum    ancestorType=TopAbs_SHAPE);
   /*!
-   * \brief Return iterator on ancestors of the given type
+   * \brief Return iterator on ancestors of the given type, included into a container shape
    */
   static PShapeIteratorPtr GetAncestors(const TopoDS_Shape& shape,
                                         const SMESH_Mesh&   mesh,
-                                        TopAbs_ShapeEnum    ancestorType);
+                                        TopAbs_ShapeEnum    ancestorType,
+                                        const TopoDS_Shape* container = 0);
   /*!
    * \brief Find a common ancestor, of the given type, of two shapes
    */
@@ -248,12 +267,12 @@ public:
   // constructor
   SMESH_MesherHelper(SMESH_Mesh& theMesh);
 
-  SMESH_Gen*    GetGen() const { return GetMesh()->GetGen(); }
+  SMESH_Gen*    GetGen() const;
     
   SMESH_Mesh*   GetMesh() const { return myMesh; }
     
-  SMESHDS_Mesh* GetMeshDS() const { return GetMesh()->GetMeshDS(); }
-    
+  SMESHDS_Mesh* GetMeshDS() const;
+
   /*!
    * Check submesh for given shape: if all elements on this shape are quadratic,
    * quadratic elements will be created. Also fill myTLinkNodeMap
@@ -296,7 +315,7 @@ public:
 
   /*!
    * \brief To set created elements on the shape set by IsQuadraticSubMesh()
-   *        or the next methods. By defaul elements are set on the shape if
+   *        or the next methods. By default elements are set on the shape if
    *        a mesh has no shape to be meshed
    */
   bool SetElementsOnShape(bool toSet)
@@ -316,17 +335,28 @@ public:
    * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() 
    */
   const TopoDS_Shape& GetSubShape() const  { return myShape; }
+  /*!
+   * \brief Copy shape information from another helper to improve performance
+   *        since SetSubShape() can be time consuming if there are many edges
+   */
+  void CopySubShapeInfo(const SMESH_MesherHelper& other);
+
+
+  /*!
+   * \brief Convert a shape to its index in the SMESHDS_Mesh
+   */
+  int ShapeToIndex( const TopoDS_Shape& S ) const;
 
   /*!
    * Creates a node (!Note ID before u=0.,v0.)
    */
-  SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0, double u=0., double v=0.);
+  SMDS_MeshNode* AddNode(double x, double y, double z, smIdType ID = 0, double u=0., double v=0.);
   /*!
    * Creates quadratic or linear edge
    */
   SMDS_MeshEdge* AddEdge(const SMDS_MeshNode* n1,
                          const SMDS_MeshNode* n2,
-                         const int id = 0, 
+                         const smIdType id = 0, 
                          const bool force3d = true);
   /*!
    * Creates quadratic or linear triangle
@@ -334,7 +364,7 @@ public:
   SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
                          const SMDS_MeshNode* n2,
                          const SMDS_MeshNode* n3,
-                         const int id=0, 
+                         const smIdType id=0, 
                          const bool force3d = false);
   /*!
    * Creates bi-quadratic, quadratic or linear quadrangle
@@ -343,13 +373,13 @@ public:
                          const SMDS_MeshNode* n2,
                          const SMDS_MeshNode* n3,
                          const SMDS_MeshNode* n4,
-                         const int id = 0,
+                         const smIdType id = 0,
                          const bool force3d = false);
   /*!
    * Creates polygon, with additional nodes in quadratic mesh
    */
   SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes,
-                                   const int id = 0,
+                                   const smIdType id = 0,
                                    const bool force3d = false);
   /*!
    * Creates quadratic or linear tetrahedron
@@ -358,7 +388,7 @@ public:
                              const SMDS_MeshNode* n2,
                              const SMDS_MeshNode* n3,
                              const SMDS_MeshNode* n4,
-                             const int id = 0,
+                             const smIdType id = 0,
                              const bool force3d = true);
   /*!
    * Creates quadratic or linear pyramid
@@ -368,7 +398,7 @@ public:
                              const SMDS_MeshNode* n3,
                              const SMDS_MeshNode* n4,
                              const SMDS_MeshNode* n5,
-                             const int id = 0,
+                             const smIdType id = 0,
                              const bool force3d = true);
   /*!
    * Creates quadratic or linear pentahedron
@@ -379,7 +409,7 @@ public:
                              const SMDS_MeshNode* n4,
                              const SMDS_MeshNode* n5,
                              const SMDS_MeshNode* n6,
-                             const int id = 0, 
+                             const smIdType id = 0, 
                              const bool force3d = true);
   /*!
    * Creates bi-quadratic, quadratic or linear hexahedron
@@ -392,7 +422,7 @@ public:
                              const SMDS_MeshNode* n6,
                              const SMDS_MeshNode* n7,
                              const SMDS_MeshNode* n8,
-                             const int id = 0, 
+                             const smIdType id = 0, 
                              bool force3d = true);
 
   /*!
@@ -410,7 +440,7 @@ public:
                              const SMDS_MeshNode* n10,
                              const SMDS_MeshNode* n11,
                              const SMDS_MeshNode* n12,
-                             const int id = 0, 
+                             const smIdType id = 0, 
                              bool force3d = true);
 
   /*!
@@ -418,7 +448,7 @@ public:
    */
   SMDS_MeshVolume* AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>& nodes,
                                         const std::vector<int>&                  quantities,
-                                        const int                                ID=0,
+                                        const smIdType                           ID=0,
                                         const bool                               force3d = true);
   /*!
    * \brief Enables fixing node parameters on EDGEs and FACEs by
@@ -487,7 +517,7 @@ public:
   /*!
    * \brief Define a pointer to wrapper over a function of gp_XY class,
    *       suitable to pass as xyFunPtr to ApplyIn2D().
-   *       For exaple gp_XY_FunPtr(Added) defines pointer gp_XY_Added to function
+   *       For example gp_XY_FunPtr(Added) defines pointer gp_XY_Added to function
    *       calling gp_XY::Added(gp_XY), which is to be used like following
    *       ApplyIn2D(surf, uv1, uv2, gp_XY_Added)
    */
@@ -524,11 +554,20 @@ public:
   bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
 
   /*!
-   * \brief Return projector intitialized by given face without location, which is returned
+   * \brief Return projector initialized by given face without location
    */
   GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
                                            TopLoc_Location&   loc,
-                                           double             tol=0 ) const; 
+                                           double             tol=0 ) const;
+  /*!
+   * \brief Return projector initialized by given face
+   */
+  GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
+                                           double             tol=0 ) const;
+  /*!
+   * \brief Return projector initialized by given EDGE
+   */
+  GeomAPI_ProjectPointOnCurve& GetPCProjector(const TopoDS_Edge& E ) const;
   /*!
    * \brief Return a cached ShapeAnalysis_Surface of a FACE
    */
@@ -546,9 +585,15 @@ public:
   /*!
    * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
    *        has a degenerated edges
-    * \retval bool - true if it has
+   *  \retval bool - true if there are degenerated edges
    */
   bool HasDegeneratedEdges() const { return !myDegenShapeIds.empty(); }
+  /*!
+   * \brief Return a number of degenerated edges in the shape set through
+   *        IsQuadraticSubMesh() or SetSubShape()
+   *  \retval size_t - nb edges
+   */
+  size_t NbDegeneratedEdges() const { return myDegenShapeIds.size(); }
 
   /*!
    * \brief Check if shape is a seam edge or it's vertex
@@ -556,7 +601,7 @@ public:
     * \retval bool - true if subShape is a seam shape
     *
     * It works only if IsQuadraticSubMesh() or SetSubShape() has been called.
-    * Seam shape has two 2D alternative represenations on the face
+    * Seam shape has two 2D alternative representations on the face
    */
   bool IsSeamShape(const int subShape) const
   { return mySeamShapeIds.find( subShape ) != mySeamShapeIds.end(); }
@@ -566,10 +611,10 @@ public:
     * \retval bool - true if subShape is a seam shape
     *
     * It works only if IsQuadraticSubMesh() or SetSubShape() has been called.
-    * Seam shape has two 2D alternative represenations on the face
+    * Seam shape has two 2D alternative representations on the face
    */
   bool IsSeamShape(const TopoDS_Shape& subShape) const
-  { return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
+  { return IsSeamShape( ShapeToIndex( subShape )); }
   /*!
    * \brief Return true if an edge or a vertex encounters twice in face wire
    *  \param subShape - Id of edge or vertex
@@ -581,7 +626,7 @@ public:
    *  \param subShape - edge or vertex
    */
   bool IsRealSeam(const TopoDS_Shape& subShape) const
-  { return IsRealSeam( GetMeshDS()->ShapeToIndex( subShape)); }
+  { return IsRealSeam( ShapeToIndex( subShape )); }
   /*!
    * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
    *        has a seam edge, i.e. an edge that has two parametric representations
@@ -595,15 +640,29 @@ public:
    *  \retval bool - true if it has
    */
   bool HasRealSeam() const { return HasSeam() && ( *mySeamShapeIds.begin() < 0 ); }
+  /*!
+   * \brief Return a number of real seam edges in the shape set through
+   *        IsQuadraticSubMesh() or SetSubShape(). A real seam edge encounters twice in a wire
+   *  \retval size_t - nb of real seams
+   */
+  size_t NbRealSeam() const;
   /*!
    * \brief Return index of periodic parametric direction of a closed face
    *  \retval int - 1 for U, 2 for V direction
    */
   int GetPeriodicIndex() const { return myParIndex; }
+  /*!
+   * \brief Return period in given direction [1,2]
+   */
+  double GetPeriod(int perioIndex) const { return myPar2[ perioIndex-1 ] - myPar1[ perioIndex-1 ]; }
   /*!
    * \brief Return an alternative parameter for a node on seam
    */
   double GetOtherParam(const double param) const;
+  /*!
+   * \brief Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam
+   */
+  int IsOnSeam(const gp_XY& uv) const;
 
   /*!
    * \brief Return existing or create new medium nodes between given ones
@@ -684,6 +743,9 @@ public:
   
   virtual ~SMESH_MesherHelper();
 
+  static void WriteShape(const TopoDS_Shape& s);
+
+
  protected:
 
   /*!
@@ -700,13 +762,14 @@ public:
 
   double getFaceMaxTol( const TopoDS_Shape& face ) const;
 
+
  private:
 
-  // Forbiden copy constructor
+  // forbidden copy constructor
   SMESH_MesherHelper (const SMESH_MesherHelper& theOther);
 
   // key of a map of bi-quadratic face to it's central node
-  struct TBiQuad: public std::pair<int, std::pair<int, int> >
+  struct TBiQuad: public std::pair<smIdType, std::pair<smIdType, smIdType> >
   {
     TBiQuad(const SMDS_MeshNode* n1,
             const SMDS_MeshNode* n2,