Salome HOME
Fix size of the returned vector in planar case
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index 7b7c1a40e290cce76224da5c6deedb995817c5e7..a3d2b226e49a9f2ffb7b73fa9e297d0347c7e835 100644 (file)
@@ -12867,9 +12867,23 @@ namespace // utils for MakePolyLine
 
     bool Extend( const gp_XYZ& plnNorm, const gp_XYZ& plnOrig );
 
+    bool ReachSamePoint( const Path& other );
+
     static void Remove( std::vector< Path > & paths, size_t& i );
   };
 
+  //================================================================================
+  /*!
+   * \brief Return true if this Path meats another
+   */
+  //================================================================================
+
+  bool Path::ReachSamePoint( const Path& other )
+  {
+    return ( mySrcPntInd != other.mySrcPntInd &&
+             myFace == other.myFace );
+  }
+
   //================================================================================
   /*!
    * \brief Remove a path from a vector
@@ -12878,19 +12892,26 @@ namespace // utils for MakePolyLine
 
   void Path::Remove( std::vector< Path > & paths, size_t& i )
   {
-    size_t j = paths.size() - 1; // last item to be removed
-    if ( i < j )
+    if ( paths.size() > 1 )
     {
-      paths[ i ].myPoints.swap( paths[ j ].myPoints );
-      paths[ i ].myFace     = paths[ j ].myFace;
-      paths[ i ].myNodeInd1 = paths[ j ].myNodeInd1;
-      paths[ i ].myNodeInd2 = paths[ j ].myNodeInd2;
-      paths[ i ].myNode1    = paths[ j ].myNode1;
-      paths[ i ].myNode2    = paths[ j ].myNode2;
-      paths[ i ].myLength   = paths[ j ].myLength;
+      size_t j = paths.size() - 1; // last item to be removed
+      if ( i < j )
+      {
+        paths[ i ].myPoints.swap( paths[ j ].myPoints );
+        paths[ i ].myLength    = paths[ j ].myLength;
+        paths[ i ].mySrcPntInd = paths[ j ].mySrcPntInd;
+        paths[ i ].myFace      = paths[ j ].myFace;
+        paths[ i ].myNode1     = paths[ j ].myNode1;
+        paths[ i ].myNode2     = paths[ j ].myNode2;
+        paths[ i ].myNodeInd1  = paths[ j ].myNodeInd1;
+        paths[ i ].myNodeInd2  = paths[ j ].myNodeInd2;
+        paths[ i ].myDot1      = paths[ j ].myDot1;
+        paths[ i ].myDot2      = paths[ j ].myDot2;
+      }
     }
     paths.pop_back();
-    --i;
+    if ( i > 0 )
+      --i;
   }
 
   //================================================================================
@@ -12921,8 +12942,7 @@ namespace // utils for MakePolyLine
     {
       ok = ( myDot1 != myDot2 );
       if ( ok && myFace )
-        ok = ( myFace->GetNodeIndex( myNode1._node ) < 0 &&
-               myFace->GetNodeIndex( myNode2._node ) < 0 );
+        ok = ( myFace->GetNodeIndex(( myDot1 == 0 ? myNode1 : myNode2 )._node ) < 0 );
     }
     if ( ok )
     {
@@ -13053,7 +13073,7 @@ namespace // utils for MakePolyLine
       if ( polySeg.myNode2[1] ) p2 = 0.5 * ( p2 + SMESH_NodeXYZ( polySeg.myNode2[1] ));
 
       gp_XYZ plnNorm = ( p1 - p2 ) ^ polySeg.myVector.XYZ();
-      gp_XYZ plnOrig = SMESH_NodeXYZ( polySeg.myNode1[0] );
+      gp_XYZ plnOrig = p2;
 
       // find paths connecting the 2 end points of polySeg
 
@@ -13136,9 +13156,7 @@ namespace // utils for MakePolyLine
           // join paths that reach same point
           for ( size_t j = 0; j < paths.size(); ++j )
           {
-            if ( i != j &&
-                 paths[i].myFace == paths[j].myFace &&
-                 paths[i].mySrcPntInd != paths[j].mySrcPntInd )
+            if ( i != j && paths[i].ReachSamePoint( paths[j] ))
             {
               double   distLast = ( paths[i].myPoints.back() - paths[j].myPoints.back() ).Modulus();
               double fullLength = ( paths[i].myLength + paths[j].myLength + distLast );
@@ -13184,13 +13202,14 @@ void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments&   theSegments,
   SMESHUtils::Deleter<SMESH_ElementSearcher> delSearcher;
   if ( !searcher )
   {
-    searcher = SMESH_MeshAlgos::GetElementSearcher( *myMesh->GetMeshDS() );
+    searcher = SMESH_MeshAlgos::GetElementSearcher( *GetMeshDS() );
     delSearcher._obj = searcher;
   }
 
   // get cutting planes
 
   std::vector< bool > isVectorOK( theSegments.size(), true );
+  const double planarCoef = 0.333; // plane height in planar case
 
   for ( size_t iSeg = 0; iSeg < theSegments.size(); ++iSeg )
   {
@@ -13213,11 +13232,22 @@ void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments&   theSegments,
       if ( polySeg.myMidProjPoint.Distance( pMid ) < Precision::Confusion() )
       {
         SMESH_MeshAlgos::FaceNormal( face, const_cast< gp_XYZ& >( polySeg.myVector.XYZ() ));
-        polySeg.myMidProjPoint = pMid + polySeg.myVector.XYZ();
+        polySeg.myMidProjPoint = pMid + polySeg.myVector.XYZ() * ( p1 - p2 ).Modulus() * planarCoef;
       }
+      else
+      {
+        polySeg.myVector = polySeg.myMidProjPoint.XYZ() - pMid;
+      }
+    }
+    else
+    {
+      polySeg.myVector = plnNorm ^ ( p1 - p2 );
     }
   }
 
+  // assure that inverse elements are constructed, avoid their concurrent building in threads
+  GetMeshDS()->nodesIterator()->next()->NbInverseElements();
+
   // find paths
 
   PolyPathCompute algo( theSegments, segPaths, myMesh );
@@ -13259,21 +13289,24 @@ void SMESH_MeshEditor::MakePolyLine( TListOfPolySegments&   theSegments,
 
     // return a vector
 
+    gp_XYZ pMid = 0.5 * ( path.myPoints[0] + path.myPoints.back() );
     if ( isVectorOK[ iSeg ])
     {
       // find the most distance point of a path
       double maxDist = 0;
       for ( size_t iP = 1; iP < path.myPoints.size(); ++iP )
       {
-        double dist = theSegments[iSeg].myVector * ( path.myPoints[iP] - path.myPoints[0] );
+        double dist = Abs( theSegments[iSeg].myVector * ( path.myPoints[iP] - path.myPoints[0] ));
         if ( dist > maxDist )
         {
           maxDist = dist;
           theSegments[iSeg].myMidProjPoint = path.myPoints[iP];
         }
       }
+      if ( maxDist < Precision::Confusion() ) // planar case
+        theSegments[iSeg].myMidProjPoint =
+          pMid + theSegments[iSeg].myVector.XYZ().Normalized() * path.myLength * planarCoef;
     }
-    gp_XYZ pMid = 0.5 * ( path.myPoints[0] + path.myPoints.back() );
     theSegments[iSeg].myVector = gp_Vec( pMid, theSegments[iSeg].myMidProjPoint );
   }