Salome HOME
take care of a correct orientation (attempt No2 )
[modules/smesh.git] / src / StdMeshers / StdMeshers_ViscousLayers2D.cxx
index 4e4d0ed8e28e716e8e9c84a69667af733c7ecac9..1d3dd8a05bb226e135b24419eec840f656164245 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -442,7 +442,7 @@ StdMeshers_ViscousLayers2D::Compute(SMESH_Mesh&        theMesh,
       theMesh.GetSubMesh( theFace )->GetComputeError() = error;
     else if ( !pm )
       pm.reset( new SMESH_ProxyMesh( theMesh ));
-    if ( getenv("ONLY_VL2D"))
+    if ( getenv("__ONLY__VL2D__"))
       pm.reset();
   }
   else
@@ -495,7 +495,7 @@ _ViscousBuilder2D::_ViscousBuilder2D(SMESH_Mesh&                       theMesh,
   _mesh( &theMesh ), _face( theFace ), _hyp( theHyp ), _helper( theMesh )
 {
   _helper.SetSubShape( _face );
-  _helper.SetElementsOnShape(true);
+  _helper.SetElementsOnShape( true );
 
   //_face.Orientation( TopAbs_FORWARD );
   _surface = BRep_Tool::Surface( _face );
@@ -512,7 +512,6 @@ _ViscousBuilder2D::_ViscousBuilder2D(SMESH_Mesh&                       theMesh,
 
 bool _ViscousBuilder2D::error(const string& text )
 {
-  cout << "_ViscousBuilder2D::error " << text << endl;
   _error->myName    = COMPERR_ALGO_FAILED;
   _error->myComment = string("Viscous layers builder 2D: ") + text;
   if ( SMESH_subMesh* sm = _mesh->GetSubMesh( _face ) )
@@ -522,8 +521,9 @@ bool _ViscousBuilder2D::error(const string& text )
       _error->myAlgo = smError->myAlgo;
     smError = _error;
   }
-  //makeGroupOfLE(); // debug
-
+#ifdef _DEBUG_
+  cout << "_ViscousBuilder2D::error " << text << endl;
+#endif
   return false;
 }
 
@@ -573,15 +573,31 @@ bool _ViscousBuilder2D::findEdgesWithLayers()
 {
   // collect all EDGEs to ignore defined by hyp
   int nbMyEdgesIgnored = 0;
-  vector<TGeomID> ids = _hyp->GetBndShapesToIgnore();
-  for ( size_t i = 0; i < ids.size(); ++i )
+  vector<TGeomID> ids = _hyp->GetBndShapes();
+  if ( _hyp->IsToIgnoreShapes() ) // EDGEs to ignore are given
   {
-    const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[i] );
-    if ( !s.IsNull() && s.ShapeType() == TopAbs_EDGE ) {
-      _ignoreShapeIds.insert( ids[i] );
-      nbMyEdgesIgnored += ( _helper.IsSubShape( s, _face ));
+    for ( size_t i = 0; i < ids.size(); ++i )
+    {
+      const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[i] );
+      if ( !s.IsNull() && s.ShapeType() == TopAbs_EDGE ) {
+        _ignoreShapeIds.insert( ids[i] );
+        nbMyEdgesIgnored += ( _helper.IsSubShape( s, _face ));
+      }
     }
   }
+  else // EDGEs to to make the Viscous Layers on are given
+  {
+    for ( size_t iWire = 0; iWire < _faceSideVec.size(); ++iWire )
+    {
+      StdMeshers_FaceSidePtr wire = _faceSideVec[ iWire ];
+      for ( int iE = 0; iE < wire->NbEdges(); ++iE )
+        _ignoreShapeIds.insert( wire->EdgeID( iE ));
+    }
+    for ( size_t i = 0; i < ids.size(); ++i )
+      _ignoreShapeIds.erase( ids[i] );
+
+    nbMyEdgesIgnored = _ignoreShapeIds.size();
+  }
 
   // check all EDGEs of the _face
   int totalNbEdges = 0;
@@ -613,7 +629,7 @@ bool _ViscousBuilder2D::findEdgesWithLayers()
 
           set<TGeomID> neighbourIgnoreEdges;
           if (viscHyp) {
-            vector<TGeomID> ids = _hyp->GetBndShapesToIgnore();
+            vector<TGeomID> ids = _hyp->GetBndShapes();
             neighbourIgnoreEdges.insert( ids.begin(), ids.end() );
           }
           for ( int iV = 0; iV < 2; ++iV )
@@ -773,7 +789,8 @@ bool _ViscousBuilder2D::makePolyLines()
         }
       }
     }
-    _thickness = Min( _hyp->GetTotalThickness(), maxPossibleThick );
+    if ( maxPossibleThick > 0. )
+      _thickness = Min( _hyp->GetTotalThickness(), maxPossibleThick );
   }
 
   // Adjust _LayerEdge's at _PolyLine's extremities
@@ -1732,7 +1749,7 @@ bool _ViscousBuilder2D::toShrinkForAdjacent( const TopoDS_Face&   adjFace,
   }
   return false;
 }
-  
+
 //================================================================================
 /*!
  * \brief Make faces
@@ -1741,6 +1758,10 @@ bool _ViscousBuilder2D::toShrinkForAdjacent( const TopoDS_Face&   adjFace,
 
 bool _ViscousBuilder2D::refine()
 {
+  // find out orientation of faces to create
+  bool isReverse = 
+    ( _helper.GetSubShapeOri( _mesh->GetShapeToMesh(), _face ) != _face.Orientation() );
+
   // store a proxyMesh in a sub-mesh
   // make faces on each _PolyLine
   vector< double > layersHeight;
@@ -1834,16 +1855,19 @@ bool _ViscousBuilder2D::refine()
       normPar[ i - L._firstPntInd ] = ( points[i].normParam - normF ) / normDist;
 
     // Create layers of faces
-
+    
     bool hasLeftNode  = ( !L._leftLine->_rightNodes.empty() && leftEdgeShared  );
     bool hasRightNode = ( !L._rightLine->_leftNodes.empty() && rightEdgeShared );
     bool hasOwnLeftNode  = ( !L._leftNodes.empty() );
     bool hasOwnRightNode = ( !L._rightNodes.empty() );
+    bool isClosedEdge = ( outerNodes.front() == outerNodes.back() );
     size_t iS,
-      iN0 = ( hasLeftNode || hasOwnLeftNode || _polyLineVec.size() == 1 ),
+      iN0 = ( hasLeftNode || hasOwnLeftNode || isClosedEdge ),
       nbN = innerNodes.size() - ( hasRightNode || hasOwnRightNode );
     L._leftNodes .reserve( _hyp->GetNumberLayers() );
     L._rightNodes.reserve( _hyp->GetNumberLayers() );
+    int cur = 0, prev = -1; // to take into account orientation of _face
+    if ( isReverse ) std::swap( cur, prev );
     for ( int iF = 0; iF < _hyp->GetNumberLayers(); ++iF ) // loop on layers of faces
     {
       // get accumulated length of intermediate segments
@@ -1872,15 +1896,14 @@ bool _ViscousBuilder2D::refine()
       else if ( hasLeftNode )  innerNodes.front() = L._leftLine->_rightNodes[ iF ];
       if ( hasOwnRightNode )   innerNodes.back()  = L._rightNodes[ iF ];
       else if ( hasRightNode ) innerNodes.back()  = L._rightLine->_leftNodes[ iF ];
-      if ( _polyLineVec.size() == 1 ) innerNodes.front() = innerNodes.back(); // circle
+      if ( isClosedEdge )      innerNodes.front() = innerNodes.back(); // circle
       if ( !hasOwnLeftNode )  L._leftNodes.push_back( innerNodes.front() );
       if ( !hasOwnRightNode ) L._rightNodes.push_back( innerNodes.back() );
 
       // create faces
-      // TODO care of orientation
       for ( size_t i = 1; i < innerNodes.size(); ++i )
-        if ( SMDS_MeshElement* f = _helper.AddFace( outerNodes[ i-1 ], outerNodes[ i ],
-                                                    innerNodes[ i ],   innerNodes[ i-1 ]))
+        if ( SMDS_MeshElement* f = _helper.AddFace( outerNodes[ i+prev ], outerNodes[ i+cur ],
+                                                    innerNodes[ i+cur  ], innerNodes[ i+prev ]))
           L._newFaces.insert( L._newFaces.end(), f );
 
       outerNodes.swap( innerNodes );
@@ -1897,11 +1920,14 @@ bool _ViscousBuilder2D::refine()
         continue;
 
       for ( size_t i = 1; i < lNodes.size(); ++i )
-        _helper.AddFace( lNodes[ i-1 ], rNodes[ i-1 ],
-                         rNodes[ i ],   lNodes[ i ]);
+        _helper.AddFace( lNodes[ i+prev ], rNodes[ i+prev ],
+                         rNodes[ i+cur ],  lNodes[ i+cur ]);
 
       const UVPtStruct& ptOnVertex = points[ isR ? L._lastPntInd : L._firstPntInd ];
-      _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]);
+      if ( isReverse )
+        _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]);
+      else
+        _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]);
     }
 
     // Fill the _ProxyMeshOfFace