Salome HOME
Fix Redesign of SMESH documentation
[modules/smesh.git] / src / SMESHUtils / SMESH_MAT2d.cxx
index 2de0cf247f4206f9b76af33ea551bfbd4c5c2880..aad6899d32debaa1f322d69d3123b24902fe804a 100644 (file)
@@ -93,8 +93,8 @@ namespace
     list< const TVDEdge* > _edges; // MA edges in CCW order within _cell
 
     InSegment( InPoint * p0, InPoint * p1, size_t iE)
-      : _p0(p0), _p1(p1), _geomEdgeInd(iE) {}
-    InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {}
+      : _p0(p0), _p1(p1), _geomEdgeInd(iE), _cell(0) {}
+    InSegment() : _p0(0), _p1(0), _geomEdgeInd(0), _cell(0) {}
 
     const InPoint& point0() const { return *_p0; }
     const InPoint& point1() const { return *_p1; }
@@ -220,9 +220,9 @@ namespace
     }
   }
 #else
-  void inSegmentsToFile( vector< InSegment>& inSegments) {}
-  void dumpEdge( const TVDEdge* edge ) {}
-  void dumpCell( const TVDCell* cell ) {}
+  #define inSegmentsToFile(arg) {}
+  //void dumpEdge( const TVDEdge* edge ) {}
+  //void dumpCell( const TVDCell* cell ) {}
 #endif
 }
 // -------------------------------------------------------------------------------------
@@ -340,7 +340,7 @@ namespace
       return ( _inSeg->getGeomEdge( _edge->twin()->cell() ) != theNoEdgeID );
     }
 
-    // check a next segment in CW order
+    // check a next segment in CCW order
     bool isSameBranch( const BndSeg& seg2 )
     {
       if ( !_edge || !seg2._edge )
@@ -662,7 +662,7 @@ namespace
     // get scale to have the same 2d proportions as in 3d
     computeProportionScale( face, uvBox, scale );
 
-    // make scale to have coordinates precise enough when converted to int
+    // make 'scale' such that to have coordinates precise enough when converted to int
 
     gp_XY uvMin = uvBox.CornerMin(), uvMax = uvBox.CornerMax();
     uvMin.ChangeCoord(1) = uvMin.X() * scale[0];
@@ -672,7 +672,7 @@ namespace
     double vMax[2] = { Max( Abs( uvMin.X() ), Abs( uvMax.X() )),
                        Max( Abs( uvMin.Y() ), Abs( uvMax.Y() )) };
     int iMax = ( vMax[0] > vMax[1] ) ? 0 : 1;
-    const double precision = 1e-5;
+    const double precision = Min( 1e-5, minSegLen * 1e-2 );
     double preciScale = Min( vMax[iMax] / precision,
                              std::numeric_limits<int>::max() / vMax[iMax] );
     preciScale /= scale[iMax];
@@ -703,6 +703,8 @@ namespace
         {
           inPoints[ iP++ ] = points[i-1].getInPoint( scale );
           inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE ));
+          if ( inPoints[ iP-2 ] == inPoints[ iP-1 ])
+            return false; // too short segment
         }
       }
     }
@@ -716,6 +718,8 @@ namespace
         {
           inPoints[ iP++ ] = points[i].getInPoint( scale );
           inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE ));
+          if ( inPoints[ iP-2 ] == inPoints[ iP-1 ])
+            return false; // too short segment
         }
       }
     }
@@ -1007,6 +1011,8 @@ namespace
     int branchID = 1; // we code orientation as branchID sign
     branchEdges.resize( branchID );
 
+    vector< std::pair< int, const TVDVertex* > > branchesToCheckEnd;
+
     for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
     {
       vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
@@ -1035,7 +1041,13 @@ namespace
         {
           branchEdges.resize(( branchID = branchEdges.size()) + 1 );
           if ( bndSegs[i]._edge && bndSegs[i]._prev )
+          {
             endType.insert( make_pair( bndSegs[i]._edge->vertex1(), SMESH_MAT2d::BE_BRANCH_POINT ));
+            if ( bndSegs[i]._prev->_branchID < 0 )
+              // 0023404: a branch-point is inside a branch
+              branchesToCheckEnd.push_back( make_pair( bndSegs[i]._prev->branchID(),
+                                                       bndSegs[i]._edge->vertex1() ));
+          }
         }
         else if ( bndSegs[i]._prev->_branchID )
         {
@@ -1059,6 +1071,37 @@ namespace
       }
     }
 
+    if ( !ignoreCorners && !branchesToCheckEnd.empty() )
+    {
+      // split branches having branch-point inside
+      // (a branch-point was not detected since another branch is joined at the opposite side)
+      for ( size_t i = 0; i < branchesToCheckEnd.size(); ++i )
+      {
+        vector<const TVDEdge*> & branch = branchEdges[ branchesToCheckEnd[i].first ];
+        const TVDVertex*    branchPoint = branchesToCheckEnd[i].second;
+        if ( branch.front()->vertex1() == branchPoint ||
+             branch.back ()->vertex0() == branchPoint )
+          continue; // OK - branchPoint is at a branch end
+
+        // find a MA edge where another branch begins
+        size_t iE;
+        for ( iE = 0; iE < branch.size(); ++iE )
+          if ( branch[iE]->vertex1() == branchPoint )
+            break;
+        if ( iE < branch.size() )
+        {
+          // split the branch
+          branchEdges.resize(( branchID = branchEdges.size()) + 1 );
+          vector<const TVDEdge*> & branch2 = branchEdges[ branchID ];
+          branch2.assign( branch.begin()+iE, branch.end() );
+          branch.resize( iE );
+          for ( iE = 0; iE < branch2.size(); ++iE )
+            if ( BndSeg* bs = BndSeg::getBndSegOfEdge( branch2[iE], bndSegsPerEdge ))
+              bs->setBranch( branchID, bndSegsPerEdge );
+        }
+      }
+    }
+
     // join the 1st and the last branch edges if it is the same branch
     // if ( bndSegs.back().branchID() != bndSegs.front().branchID() &&
     //      bndSegs.back().isSameBranch( bndSegs.front() ))
@@ -1069,10 +1112,14 @@ namespace
     //   br2.clear();
     // }
 
-    // remove branches ending at BE_ON_VERTEX
+    // remove branches ending at BE_ON_VERTEX and BE_END
 
     vector<bool> isBranchRemoved( branchEdges.size(), false );
 
+    std::set< SMESH_MAT2d::BranchEndType > endTypeToRm;
+    endTypeToRm.insert( SMESH_MAT2d::BE_ON_VERTEX );
+    endTypeToRm.insert( SMESH_MAT2d::BE_END );
+
     if ( ignoreCorners && branchEdges.size() > 2 && !branchEdges[2].empty() )
     {
       // find branches to remove
@@ -1084,10 +1131,10 @@ namespace
         const TVDVertex* v0 = branchEdges[iB][0]->vertex1();
         const TVDVertex* v1 = branchEdges[iB].back()->vertex0();
         v2et = endType.find( v0 );
-        if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
+        if ( v2et != endType.end() && endTypeToRm.count( v2et->second ))
           isBranchRemoved[ iB ] = true;
         v2et = endType.find( v1 );
-        if ( v2et != endType.end() && v2et->second == SMESH_MAT2d::BE_ON_VERTEX )
+        if ( v2et != endType.end() && endTypeToRm.count( v2et->second ))
           isBranchRemoved[ iB ] = true;
       }
       // try to join not removed branches into one