Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMESH / SMESH_MesherHelper.cxx
index d17b4e66c3556441f67e2bef135cc5331ea42237..81ed3a0fdb5fae2b652e3a160d3de7c3b373d434 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  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
@@ -51,6 +51,7 @@
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Curve.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -658,10 +659,10 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
     // corresponding EDGE from FACE, get pcurve for this
     // EDGE and retrieve value from this pcurve
     SMDS_EdgePositionPtr epos = pos;
-    const int              edgeID = n->getshapeId();
-    const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
+    const int          edgeID = n->getshapeId();
+    const TopoDS_Edge&      E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
     double f, l, u = epos->GetUParameter();
-    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
+    Handle(Geom2d_Curve)  C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
     bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l ));
     if ( validU ) uv = C2d->Value( u );
     else          uv.SetCoord( Precision::Infinite(),0.);
@@ -769,6 +770,17 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
         if ( isSeam )
           uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
       }
+      else if ( myParIndex && n2 )
+      {
+        gp_Pnt2d oldUV = uv;
+        gp_Pnt2d   uv2 = GetNodeUV( F, n2, 0 );
+        if ( myParIndex & 1 )
+          uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod( uv.X(), myPar1[0], myPar2[0]));
+        if ( myParIndex & 2 )
+          uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod( uv.Y(), myPar1[1], myPar2[1]));
+        if ( uv.SquareDistance( uv2 ) > oldUV.SquareDistance( uv2 ))
+          uv = oldUV;
+      }
     }
   }
   else
@@ -864,6 +876,51 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face&
   return *( i_proj->second );
 }
 
+//=======================================================================
+//function : GetProjector
+//purpose  : Return projector initialized by given face, which is returned
+//=======================================================================
+
+GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F,
+                                                             double             tol ) const
+{
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+  int faceID = GetMeshDS()->ShapeToIndex( F );
+  TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
+  TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
+  if ( i_proj == i2proj.end() )
+  {
+    if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
+    double U1, U2, V1, V2;
+    surface->Bounds(U1, U2, V1, V2);
+    GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf();
+    proj->Init( surface, U1, U2, V1, V2, tol );
+    i_proj = i2proj.insert( make_pair( faceID, proj )).first;
+  }
+  return *( i_proj->second );
+}
+
+//=======================================================================
+//function : GetPCProjector
+//purpose  : Return projector initialized by given EDGE
+//=======================================================================
+
+GeomAPI_ProjectPointOnCurve& SMESH_MesherHelper::GetPCProjector(const TopoDS_Edge& E ) const
+{
+  int edgeID = GetMeshDS()->ShapeToIndex( E );
+  TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
+  TID2ProjectorOnCurve::iterator i_proj = i2proj.insert( make_pair( edgeID, nullptr )).first;
+  if ( !i_proj->second  )
+  {
+    double f,l;
+    Handle(Geom_Curve) curve = BRep_Tool::Curve( E,f,l );
+    i_proj->second = new GeomAPI_ProjectPointOnCurve();
+    i_proj->second->Init( curve, f, l );
+  }
+  GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
+  return *projector;
+}
+
 //=======================================================================
 //function : GetSurface
 //purpose  : Return a cached ShapeAnalysis_Surface of a FACE
@@ -1110,27 +1167,17 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
       {
         setPosOnShapeValidity( shapeID, false );
         // u incorrect, project the node to the curve
-        int edgeID = GetMeshDS()->ShapeToIndex( E );
-        TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
-        TID2ProjectorOnCurve::iterator i_proj =
-          i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
-        if ( !i_proj->second  )
-        {
-          i_proj->second = new GeomAPI_ProjectPointOnCurve();
-          i_proj->second->Init( curve, f, l );
-        }
-        GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
-        projector->Perform( nodePnt );
-        if ( projector->NbPoints() < 1 )
-        {
-          MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
-          return false;
-        }
-        Standard_Real U = projector->LowerDistanceParameter();
-        u = double( U );
-        curvPnt = curve->Value( u );
-        dist = nodePnt.Distance( curvPnt );
+        //GeomAPI_ProjectPointOnCurve& projector = GetPCProjector( E ); -- bug in OCCT-7.5.3p1
+        GeomAdaptor_Curve curveAd( curve, f, l );
+        ShapeAnalysis_Curve projector;
+        dist = projector.Project( curveAd, nodePnt, tol, curvPnt, u, false );
+        // if ( projector.NbPoints() < 1 )
+        // {
+        //   MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
+        //   return false;
+        // }
         if ( distXYZ ) {
+          curvPnt = curve->Value( u );
           curvPnt.Transform( loc );
           distXYZ[0] = dist;
           distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
@@ -1143,7 +1190,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
         // store the fixed U on the edge
         if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters )
           const_cast<SMDS_MeshNode*>(n)->SetPosition
-            ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
+            ( SMDS_PositionPtr( new SMDS_EdgePosition( u )));
       }
       else if ( fabs( u ) > numeric_limits<double>::min() )
       {
@@ -1924,7 +1971,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_
 //purpose  : Creates a node
 //=======================================================================
 
-SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID,
+SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, smIdType ID,
                                            double u, double v)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -1953,7 +2000,7 @@ SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID,
 
 SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
-                                           const int            id,
+                                           const smIdType       id,
                                            const bool           force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -1987,7 +2034,7 @@ SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
 SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
                                            const SMDS_MeshNode* n3,
-                                           const int id,
+                                           const smIdType id,
                                            const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2037,7 +2084,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
                                            const SMDS_MeshNode* n3,
                                            const SMDS_MeshNode* n4,
-                                           const int            id,
+                                           const smIdType       id,
                                            const bool           force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2101,7 +2148,7 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
 //=======================================================================
 
 SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_MeshNode*>& nodes,
-                                                     const int                           id,
+                                                     const smIdType                      id,
                                                      const bool                          force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2147,7 +2194,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n4,
                                                const SMDS_MeshNode* n5,
                                                const SMDS_MeshNode* n6,
-                                               const int id,
+                                               const smIdType id,
                                                const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2210,7 +2257,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n2,
                                                const SMDS_MeshNode* n3,
                                                const SMDS_MeshNode* n4,
-                                               const int id,
+                                               const smIdType id,
                                                const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2251,7 +2298,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n3,
                                                const SMDS_MeshNode* n4,
                                                const SMDS_MeshNode* n5,
-                                               const int id,
+                                               const smIdType id,
                                                const bool force3d)
 {
   SMDS_MeshVolume* elem = 0;
@@ -2301,7 +2348,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n6,
                                                const SMDS_MeshNode* n7,
                                                const SMDS_MeshNode* n8,
-                                               const int id,
+                                               const smIdType id,
                                                const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2420,7 +2467,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n10,
                                                const SMDS_MeshNode* n11,
                                                const SMDS_MeshNode* n12,
-                                               const int id, 
+                                               const smIdType id, 
                                                bool /*force3d*/)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2442,7 +2489,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 SMDS_MeshVolume*
 SMESH_MesherHelper::AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>& nodes,
                                          const std::vector<int>&                  quantities,
-                                         const int                                id,
+                                         const smIdType                           id,
                                          const bool                               force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
@@ -2724,33 +2771,30 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2
            theParam2ColumnMap.begin()->second.size() == prevNbRows + expectNbRows );
 }
 
-namespace
+//================================================================================
+/*!
+ * \brief Return true if a node is at a corner of a 2D structured mesh of FACE
+ */
+//================================================================================
+
+bool SMESH_MesherHelper::IsCornerOfStructure( const SMDS_MeshNode*   n,
+                                              const SMESHDS_SubMesh* faceSM,
+                                              SMESH_MesherHelper&    faceAnalyser )
 {
-  //================================================================================
-  /*!
-   * \brief Return true if a node is at a corner of a 2D structured mesh of FACE
-   */
-  //================================================================================
+  int nbFacesInSM = 0;
+  if ( n ) {
+    SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face );
+    while ( fIt->more() )
+      nbFacesInSM += faceSM->Contains( fIt->next() );
+  }
+  if ( nbFacesInSM == 1 )
+    return true;
 
-  bool isCornerOfStructure( const SMDS_MeshNode*   n,
-                            const SMESHDS_SubMesh* faceSM,
-                            SMESH_MesherHelper&    faceAnalyser )
+  if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
   {
-    int nbFacesInSM = 0;
-    if ( n ) {
-      SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator( SMDSAbs_Face );
-      while ( fIt->more() )
-        nbFacesInSM += faceSM->Contains( fIt->next() );
-    }
-    if ( nbFacesInSM == 1 )
-      return true;
-
-    if ( nbFacesInSM == 2 && n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
-    {
-      return faceAnalyser.IsRealSeam( n->getshapeId() );
-    }
-    return false;
+    return faceAnalyser.IsRealSeam( n->getshapeId() );
   }
+  return false;
 }
 
 //=======================================================================
@@ -2785,7 +2829,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   int nbRemainEdges = nbEdgesInWires.front();
   do {
     TopoDS_Vertex V = IthVertex( 0, edges.front() );
-    isCorner = isCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
+    isCorner = IsCornerOfStructure( SMESH_Algo::VertexNode( V, meshDS ),
                                     fSM, faceAnalyser);
     if ( !isCorner ) {
       edges.splice( edges.end(), edges, edges.begin() );
@@ -2826,7 +2870,7 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
   for ( ; n != nodes.end(); ++n )
   {
     ++nbEdges;
-    if ( isCornerOfStructure( *n, fSM, faceAnalyser )) {
+    if ( IsCornerOfStructure( *n, fSM, faceAnalyser )) {
       nbEdgesInSide.push_back( nbEdges );
       nbEdges = 0;
     }
@@ -2972,7 +3016,7 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace)
   if ( !aSubMeshDSFace )
     return isReversed;
 
-  // find an element on a bounday of theFace
+  // find an element on a boundary of theFace
   SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
   const SMDS_MeshNode* nn[2];
   while ( iteratorElem->more() ) // loop on elements on theFace
@@ -3413,9 +3457,9 @@ TopoDS_Shape SMESH_MesherHelper::GetShapeOfHypothesis( const SMESHDS_Hypothesis
 
 SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh()
 {
-  int NbAllEdgsAndFaces=0;
-  int NbQuadFacesAndEdgs=0;
-  int NbFacesAndEdges=0;
+  smIdType NbAllEdgsAndFaces=0;
+  smIdType NbQuadFacesAndEdgs=0;
+  smIdType NbFacesAndEdges=0;
   //All faces and edges
   NbAllEdgsAndFaces = myMesh->NbEdges() + myMesh->NbFaces();
   if ( NbAllEdgsAndFaces == 0 )