Salome HOME
54355: 'Compute' button is absent for 'Number of the double nodes' value in 'Mesh...
[modules/smesh.git] / src / StdMeshers / StdMeshers_QuadFromMedialAxis_1D2D.cxx
index 2fcf21902b20fc09f65c5d2d624824b9986286fc..0b9005bcaa07fadefbd9c679a0774c0900a7bf3c 100644 (file)
@@ -71,8 +71,8 @@ using namespace std;
 class StdMeshers_QuadFromMedialAxis_1D2D::Algo1D : public StdMeshers_Regular_1D
 {
 public:
-  Algo1D(int studyId, SMESH_Gen* gen):
-    StdMeshers_Regular_1D( gen->GetANewId(), studyId, gen )
+  Algo1D(SMESH_Gen* gen):
+    StdMeshers_Regular_1D( gen->GetANewId(), gen )
   {
   }
   void SetSegmentLength( double len )
@@ -152,9 +152,8 @@ public:
 //================================================================================
 
 StdMeshers_QuadFromMedialAxis_1D2D::StdMeshers_QuadFromMedialAxis_1D2D(int        hypId,
-                                                                       int        studyId,
                                                                        SMESH_Gen* gen)
-  : StdMeshers_Quadrangle_2D(hypId, studyId, gen),
+  : StdMeshers_Quadrangle_2D(hypId, gen),
     _regular1D( 0 )
 {
   _name = "QuadFromMedialAxis_1D2D";
@@ -383,7 +382,7 @@ namespace
         tmpMesh.ShapeToMesh( theEdges[i] );
         try {
           if ( !mesh->GetGen() ) continue; // tmp mesh
-          mesh->GetGen()->Compute( tmpMesh, theEdges[i], true, true ); // make nodes on VERTEXes
+          mesh->GetGen()->Compute( tmpMesh, theEdges[i], SMESH_Gen::SHAPE_ONLY_UPWARD ); // make nodes on VERTEXes
           if ( !algo->Compute( tmpMesh, theEdges[i] ))
             continue;
         }
@@ -604,7 +603,7 @@ namespace
              theSinuEdges [0].size() > 0 && theSinuEdges [1].size() > 0 );
 
     // the sinuous EDGEs can be composite and C0 continuous,
-    // therefor we use a complex criterion to find TWO short non-sinuous EDGEs
+    // therefore we use a complex criterion to find TWO short non-sinuous EDGEs
     // and the rest EDGEs will be treated as sinuous.
     // A short edge should have the following features:
     // a) straight
@@ -741,7 +740,7 @@ namespace
     }
 
     // cout << "from salome.geom import geomBuilder" << endl;
-    // cout << "geompy = geomBuilder.New(salome.myStudy)" << endl;
+    // cout << "geompy = geomBuilder.New()" << endl;
     Handle(TColgp_HArray1OfPnt) points = new TColgp_HArray1OfPnt(1, pnt.size());
     for ( size_t i = 0; i < pnt.size(); ++i )
     {
@@ -868,7 +867,7 @@ namespace
     TmpMesh tmpMesh;
     tmpMesh.ShapeToMesh( branchEdge );
     try {
-      mesh->GetGen()->Compute( tmpMesh, branchEdge, true, true ); // make nodes on VERTEXes
+      mesh->GetGen()->Compute( tmpMesh, branchEdge, SMESH_Gen::SHAPE_ONLY_UPWARD ); // make nodes on VERTEXes
       if ( !algo->Compute( tmpMesh, branchEdge ))
         return false;
     }
@@ -1019,7 +1018,7 @@ namespace
    *  \param [in] theDivPoints - projections of VERTEXes to MA
    *  \param [in] theSinuEdges - the sinuous EDGEs
    *  \param [in] theSideEdgeIDs - indices of sinuous EDGEs per side
-   *  \param [in] theIsEdgeComputed - is sinuous EGDE is meshed
+   *  \param [in] theIsEdgeComputed - is sinuous EDGE is meshed
    *  \param [in,out] thePointsOnE - the map to fill
    *  \param [out] theNodes2Merge - the map of nodes to merge
    */
@@ -1072,7 +1071,7 @@ namespace
       if ( ! ( theDivPoints[0]._iEdge     == 0 &&
                theDivPoints[0]._edgeParam == 0. )) // recursive call
       {
-        SMESH_MAT2d::BranchPoint brp( &branch, 0, 0 );
+        SMESH_MAT2d::BranchPoint brp( &branch, 0, 0. );
         vector< SMESH_MAT2d::BranchPoint > divPoint( 1, brp );
         vector< std::size_t > edgeIDs1(2), edgeIDs2(2);
         edgeIDs1[0] = theEdgeIDs1.back();
@@ -1084,9 +1083,10 @@ namespace
       }
     }
 
-    // project theDivPoints
+    // project theDivPoints and keep projections to merge
 
     TMAPar2NPoints::iterator u2NP;
+    vector< TMAPar2NPoints::iterator > projToMerge;
     for ( size_t i = 0; i < theDivPoints.size(); ++i )
     {
       if ( !branch.getParameter( theDivPoints[i], uMA ))
@@ -1129,9 +1129,18 @@ namespace
       if ( isVertex[0] && isVertex[1] )
         continue;
 
-      bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
-      if ( !isOppComputed )
-        continue;
+      // bool isOppComputed = theIsEdgeComputed[ np[ iNode ]._edgeInd ];
+      // if ( isOppComputed )
+        projToMerge.push_back( u2NP );
+    }
+
+    // merge projections
+
+    for ( size_t i = 0; i < projToMerge.size(); ++i )
+    {
+      u2NP = projToMerge[i];
+      const size_t iVert = get( u2NP->second, 0 )._node ? 0 : 1; // side with a VERTEX
+      const size_t iNode = 1 - iVert;                            // opposite (meshed?) side
 
       // a VERTEX is projected on a meshed EDGE; there are two options:
       // 1) a projected point is joined with a closet node if a strip between this and neighbor
@@ -1145,10 +1154,8 @@ namespace
       bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
       TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
       --u2NPPrev; ++u2NPNext;
-      // bool hasPrev = ( u2NP     != thePointsOnE.begin() );
-      // bool hasNext = ( u2NPNext != thePointsOnE.end() );
-      // if ( !hasPrev ) u2NPPrev = u2NP0;
-      // if ( !hasNext ) u2NPNext = u2NP1;
+      if ( u2NPNext == thePointsOnE.end() )
+        u2NPNext = thePointsOnE.begin(); // hope theSinuFace.IsRing()
       for ( int iS = 0; iS < 2; ++iS ) // side with Vertex and side with Nodes
       {
         NodePoint np     = get( u2NP->second,     iS );
@@ -1161,11 +1168,9 @@ namespace
         double  distNext = p.Distance( pNext );
         double         r = distPrev / ( distPrev + distNext );
         isShortPrev [iS] = ( r < rShort );
-        isShortNext [iS] = (( 1 - r ) > ( 1 - rShort ));
-        isPrevCloser[iS] = (( r < 0.5 ) && ( u2NPPrev->first > 0 ));
+        isShortNext [iS] = (( 1 - r ) < rShort );
+        isPrevCloser[iS] = (( r < 0.5 ) && ( theSinuFace.IsRing() || u2NPPrev->first > 0 ));
       }
-      // if ( !hasPrev ) isShortPrev[0] = isShortPrev[1] = false;
-      // if ( !hasNext ) isShortNext[0] = isShortNext[1] = false;
 
       TMAPar2NPoints::iterator u2NPClose;
 
@@ -1174,17 +1179,18 @@ namespace
       {
         u2NPClose = isPrevCloser[0] ? u2NPPrev : u2NPNext;
         NodePoint& npProj  = get( u2NP->second,      iNode ); // NP of VERTEX projection
+        NodePoint& npVert  = get( u2NP->second,      iVert ); // NP of VERTEX
         NodePoint npCloseN = get( u2NPClose->second, iNode ); // NP close to npProj
-        NodePoint npCloseV = get( u2NPClose->second, iVert ); // NP close to VERTEX
-        if ( !npCloseV._node )
+        NodePoint npCloseV = get( u2NPClose->second, iVert ); // NP close to npVert
+        if ( !npCloseV._node || npCloseV._node == npVert._node )
         {
           npProj = npCloseN;
-          thePointsOnE.erase( isPrevCloser[0] ? u2NPPrev : u2NPNext );
+          thePointsOnE.erase( u2NPClose );
           continue;
         }
         else
         {
-          // can't remove the neighbor projection as it is also from VERTEX, -> option 1)
+          // can't remove the neighbor projection as it is also from VERTEX -> option 1)
         }
       }
       // else: option 1) - wide enough -> "duplicate" existing node
@@ -1379,10 +1385,13 @@ namespace
                    const SMESH_MAT2d::MedialAxis& theMA,
                    TMAPar2NPoints &               thePointsOnE )
   {
+    SMESH_Mesh*     mesh = theHelper.GetMesh();
+    SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+
     list< TopoDS_Edge > ee1( theSinuFace._sinuSide [0].begin(), theSinuFace._sinuSide [0].end() );
     list< TopoDS_Edge > ee2( theSinuFace._sinuSide [1].begin(), theSinuFace._sinuSide [1].end() );
-    StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, theHelper.GetMesh(), true, true );
-    StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, theHelper.GetMesh(), true, true );
+    StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, mesh, true, true, &theHelper );
+    StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, mesh, true, true, &theHelper );
     const UVPtStructVec& uvsOut = sideOut.GetUVPtStruct();
     const UVPtStructVec& uvsIn  = sideIn.GetUVPtStruct();
     // if ( uvs1.size() != uvs2.size() )
@@ -1391,7 +1400,6 @@ namespace
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     SMESH_MAT2d::BoundaryPoint bp[2];
     SMESH_MAT2d::BranchPoint   brp;
-    SMESHDS_Mesh*              meshDS = theHelper.GetMeshDS();
 
     map< double, const SMDS_MeshNode* > nodeParams; // params of existing nodes
     map< double, const SMDS_MeshNode* >::iterator u2n;
@@ -1505,7 +1513,8 @@ namespace
     for ( int i = 0; i < 4; ++i )
     {
       theFace._quad->side[i] = StdMeshers_FaceSide::New( face, side[i], mesh, i < QUAD_TOP_SIDE,
-                                                         /*skipMediumNodes=*/true, proxyMesh );
+                                                         /*skipMediumNodes=*/true,
+                                                         &theHelper, proxyMesh );
     }
 
     if ( theFace.IsRing() )
@@ -1634,7 +1643,7 @@ namespace
   //================================================================================
   /*!
    * \brief Divide the sinuous EDGEs by projecting the division point of Medial
-   *        Axis to the EGDEs
+   *        Axis to the EDGEs
    *  \param [in] theHelper - the helper
    *  \param [in] theMinSegLen - minimal segment length
    *  \param [in] theMA - the Medial Axis
@@ -1887,7 +1896,7 @@ namespace
           continue;
 
         StdMeshers_FaceSide side( face, theSinuEdges[i], mesh,
-                                  /*isFwd=*/true, /*skipMediumNodes=*/true );
+                                  /*isFwd=*/true, /*skipMediumNodes=*/true, &theHelper );
         vector<const SMDS_MeshNode*> nodes = side.GetOrderedNodes();
         for ( size_t in = 1; in < nodes.size(); ++in )
         {
@@ -1930,7 +1939,8 @@ namespace
     {
       if ( !theHasRadialHyp )
         // use global hyps
-        theHelper.GetGen()->Compute( *theHelper.GetMesh(), theShortEdges[i], true, true );
+        theHelper.GetGen()->Compute( *theHelper.GetMesh(), theShortEdges[i],
+                                     SMESH_Gen::SHAPE_ONLY_UPWARD );
 
       SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh(theShortEdges[i] );
       if ( sm->IsEmpty() )
@@ -2157,7 +2167,7 @@ bool StdMeshers_QuadFromMedialAxis_1D2D::Compute(SMESH_Mesh&         theMesh,
     SMESH_MAT2d::MedialAxis ma( F, sinuFace._sinuEdges, minSegLen, /*ignoreCorners=*/true );
 
     if ( !_regular1D )
-      _regular1D = new Algo1D( _studyId, _gen );
+      _regular1D = new Algo1D( _gen );
     _regular1D->SetSegmentLength( minSegLen );
 
     vector<double> maParams;