Salome HOME
53057: NETGEN-1D2D3D issues "Ignored" warning for faces of a sub-mesh
[modules/smesh.git] / src / SMESH_I / SMESH_subMesh_i.cxx
index ac64d86ad9ef83f867a07c05297571559956d147..bc0fa18c8ca73036cc3b6c228aa5ea84fc4a7efe 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -35,8 +35,9 @@
 #include "OpUtil.hxx"
 #include "Utils_ExceptHandlers.hxx"
 
-#include <TopoDS_Iterator.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS_Iterator.hxx>
 
 using namespace std;
 
@@ -94,55 +95,95 @@ typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
 bool getSubMeshes(::SMESH_subMesh*  theSubMesh,
                   TListOfSubMeshes& theSubMeshList)
 {
-  int size = theSubMeshList.size();
+  size_t size = theSubMeshList.size();
 
   SMESH_Mesh*      aMesh      = theSubMesh->GetFather();
   SMESHDS_Mesh*    aMeshDS    = aMesh->GetMeshDS();
   SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
+  ::SMESH_subMesh* sm;
 
   // nodes can be bound to either vertex, edge, face or solid_or_shell
-  TopoDS_Shape aShape = theSubMesh->GetSubShape();
-  switch ( aShape.ShapeType() )
+  TopoDS_Shape         aShape = theSubMesh->GetSubShape();
+  TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
+
+  // IPAL18558: Wrong information of the created sub-mesh is shown. (Sub-mesh on a FACE
+  // with only 1D algo assigned)
+  // Find dimension of sub-meshes to return as highest dimension of the assigned algorithm
+  if (( theSubMesh->IsEmpty() || ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )) &&
+      ( !theSubMesh->GetAlgo() ))
   {
-  case TopAbs_SOLID: {
-    // add submesh of solid itself
-    aSubMeshDS = aMeshDS->MeshElements( aShape );
-    if ( aSubMeshDS )
+    // on father sub-meshes, check presence of an algo which will mesh this sub-mesh
+    // even if no algo is assigned to this sub-mesh
+    bool topAlgoPresent = false;
+    TopTools_ListIteratorOfListOfShape ancestors( aMesh->GetAncestors( aShape ));
+    for ( ; ancestors.More() && !topAlgoPresent; ancestors.Next() )
+      if (( sm = aMesh->GetSubMeshContaining( ancestors.Value() )))
+        topAlgoPresent = ( sm->GetAlgo() && !sm->GetAlgo()->NeedDiscreteBoundary() );
+
+    if ( !topAlgoPresent )
+    {
+      // find max dimension of an assigned algo
+      TopAbs_ShapeEnum algoShape = TopAbs_SHAPE;
+      const std::list <const SMESHDS_Hypothesis * >& hyps = aMesh->GetHypothesisList( aShape );
+      std::list <const SMESHDS_Hypothesis * >::const_iterator hypIt = hyps.begin();
+      for ( ; hypIt != hyps.end(); ++hypIt )
+        if ( const SMESH_Algo* algo = dynamic_cast< const SMESH_Algo* >( *hypIt ))
+          switch ( algo->GetDim() ) {
+          case 1: algoShape = TopAbs_EDGE; break;
+          case 2: algoShape = TopAbs_FACE; break;
+          case 3: algoShape = TopAbs_SOLID; break;
+          case 0: algoShape = TopAbs_VERTEX; break;
+          }
+      if ( algoShape != TopAbs_SHAPE )
+      {
+        // return all sub-meshes on this dimension
+        SMESH_subMeshIteratorPtr smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/false);
+        while ( smIt->more() )
+        {
+          sm = smIt->next();
+          if ( sm->GetSubShape().ShapeType() == algoShape && sm->GetSubMeshDS() )
+            theSubMeshList.push_back( sm->GetSubMeshDS() );
+        }
+        return size < theSubMeshList.size();
+      }
+    }
+  }
+
+  switch ( aShapeType )
+  {
+  case TopAbs_SOLID:
+  {
+    // add sub-mesh of solid itself
+    if (( aSubMeshDS = aMeshDS->MeshElements( aShape )))
       theSubMeshList.push_back( aSubMeshDS );
+
     // and of the first shell
     TopExp_Explorer exp( aShape, TopAbs_SHELL );
-    if ( exp.More() ) {
-      aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
-      if ( aSubMeshDS )
+    if ( exp.More() )
+      if (( aSubMeshDS = aMeshDS->MeshElements( exp.Current() )))
         theSubMeshList.push_back( aSubMeshDS );
-    }
     break;
   }
   case TopAbs_WIRE:
   case TopAbs_COMPOUND:
-  case TopAbs_COMPSOLID: {
+  case TopAbs_COMPSOLID:
+  {
     // call getSubMeshes() for sub-shapes
     list<TopoDS_Shape> shapeList;
     shapeList.push_back( aShape );
     list<TopoDS_Shape>::iterator sh = shapeList.begin();
     for ( ; sh != shapeList.end(); ++sh ) {
       for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
-        if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
-          getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
+        if (( sm = aMesh->GetSubMeshContaining( it.Value() )))
+          getSubMeshes( sm, theSubMeshList ); // add found sub-mesh or explore deeper
         else
           // no submesh for a compound inside compound
           shapeList.push_back( it.Value() );
       }
     }
-    // return only unique submeshes
-    set<SMESHDS_SubMesh*> smSet;
-    TListOfSubMeshes::iterator sm = theSubMeshList.begin();
-    while ( sm != theSubMeshList.end() ) {
-      if ( !smSet.insert( *sm ).second )
-        sm = theSubMeshList.erase( sm );
-      else
-        ++sm;
-    }
+    // return only unique sub-meshes
+    set<SMESHDS_SubMesh*> smSet( theSubMeshList.begin(), theSubMeshList.end() );
+    theSubMeshList.assign( smSet.begin(), smSet.end() );
     break;
   }
   default:
@@ -171,6 +212,8 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
 
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+  if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
+    aSubMeshDS = 0;
 
   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
 
@@ -206,6 +249,8 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
   }
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+  if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
+    aSubMeshDS = 0;
 
   if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
   {
@@ -254,6 +299,8 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId()
 
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+  if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
+    aSubMeshDS = 0;
 
   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
   TListOfSubMeshes smList;
@@ -304,6 +351,8 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
 
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+  if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
+    aSubMeshDS = 0;
 
   // PAL5440, return all nodes belonging to elements of submesh
   set<int> nodeIds;
@@ -607,3 +656,14 @@ bool SMESH_subMesh_i::IsMeshInfoCorrect()
 {
   return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
 }
+
+//=======================================================================
+//function : GetVtkUgStream
+//purpose  : Return data vtk unstructured grid (not implemented)
+//=======================================================================
+
+SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
+{
+  SALOMEDS::TMPFile_var SeqFile;
+  return SeqFile._retn();
+}