Salome HOME
Merge branch 'V9_2_2_BR'
[plugins/hybridplugin.git] / src / HYBRIDPlugin / HYBRIDPlugin_HYBRID.cxx
index 312efe3bc71a47915492209e1a62fe6b26b57b9f..6cc4efbbf6636ffc41ab79d528ffb157ddc7cae7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -101,8 +101,8 @@ static void removeFile( const std::string& fileName )
  */
 //=============================================================================
 
-HYBRIDPlugin_HYBRID::HYBRIDPlugin_HYBRID(int hypId, int studyId, SMESH_Gen* gen)
-  : SMESH_3D_Algo(hypId, studyId, gen)
+HYBRIDPlugin_HYBRID::HYBRIDPlugin_HYBRID(int hypId, SMESH_Gen* gen)
+  : SMESH_3D_Algo(hypId, gen)
 {
   _name = Name();
   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
@@ -110,15 +110,7 @@ HYBRIDPlugin_HYBRID::HYBRIDPlugin_HYBRID(int hypId, int studyId, SMESH_Gen* gen)
   _iShape=0;
   _nbShape=0;
   _compatibleHypothesis.push_back( HYBRIDPlugin_Hypothesis::GetHypType());
-  _requireShape = false; // can work without shape_studyId
-
-  smeshGen_i = SMESH_Gen_i::GetSMESHGen();
-  CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
-  SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
-
-  myStudy = NULL;
-  myStudy = aStudyMgr->GetStudyByID(_studyId);
-  
+  _requireShape = false; // can work without shape
   _computeCanceled = false;
 }
 
@@ -175,18 +167,18 @@ bool HYBRIDPlugin_HYBRID::CheckHypothesis ( SMESH_Mesh&         aMesh,
 
 TopoDS_Shape HYBRIDPlugin_HYBRID::entryToShape(std::string entry)
 {
-  if ( myStudy->_is_nil() )
+  if ( SMESH_Gen_i::getStudyServant()->_is_nil() )
     throw SALOME_Exception("MG-HYBRID plugin can't work w/o publishing in the study");
   GEOM::GEOM_Object_var aGeomObj;
   TopoDS_Shape S = TopoDS_Shape();
-  SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
+  SALOMEDS::SObject_var aSObj = SMESH_Gen_i::getStudyServant()->FindObjectID( entry.c_str() );
   if (!aSObj->_is_nil() ) {
     CORBA::Object_var obj = aSObj->GetObject();
     aGeomObj = GEOM::GEOM_Object::_narrow(obj);
     aSObj->UnRegister();
   }
   if ( !aGeomObj->_is_nil() )
-    S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
+    S = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aGeomObj.in() );
   return S;
 }
 
@@ -219,8 +211,7 @@ static void addElemInMeshGroup(SMESH_Mesh*             theMesh,
   
   if (!groupDone)
   {
-    int groupId;
-    SMESH_Group* aGroup = theMesh->AddGroup(anElem->GetType(), groupName.c_str(), groupId);
+    SMESH_Group* aGroup = theMesh->AddGroup(anElem->GetType(), groupName.c_str());
     aGroup->SetName( groupName.c_str() );
     SMESHDS_Group* aGroupDS = static_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
     aGroupDS->SMDSGroup().Add(anElem);
@@ -311,13 +302,12 @@ static void makeDomainGroups( std::vector< std::vector< const SMDS_MeshElement*
     }
     // create and fill the groups
     size_t iElem = 0;
-    int groupID;
     do
     {
       SMESH_Group* group = groupOfType[ elems[ iElem ]->GetType() ];
       if ( !group )
         group = theHelper->GetMesh()->AddGroup( elems[ iElem ]->GetType(),
-                                                domainName.c_str(), groupID );
+                                                domainName.c_str() );
       SMDS_MeshGroup& groupDS =
         static_cast< SMESHDS_Group* >( group->GetGroupDS() )->SMDSGroup();
 
@@ -351,20 +341,57 @@ static bool readGMFFile(MG_HYBRID_API*                          MGOutput,
   SMESHDS_Mesh* theMeshDS = theHelper->GetMeshDS();
   const bool hasGeom = ( theHelper->GetMesh()->HasShapeToMesh() );
 
-  int nbInitialNodes = theNodeByHybridId.size();
+  // if imprinting, the original mesh faces are modified
+  // => we clear all the faces to retrieve them from Hybrid output mesh.
+  std::vector<int> facesWithImprinting;
+  if (theAlgo->getHyp())
+    facesWithImprinting = theAlgo->getHyp()->GetFacesWithImprinting();
+
+  if ( ! facesWithImprinting.empty() ) {
+#ifdef _DEBUG_
+    std::cout << "Imprinting => Clear original mesh" << std::endl;
+#endif
+    SMESH_subMesh* smOfSolid =
+      theHelper->GetMesh()->GetSubMesh( theHelper->GetSubShape() );
+    SMESH_subMeshIteratorPtr smIt =
+      smOfSolid->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/true);
+    while ( smIt->more() )
+    {
+      SMESH_subMesh* sm = smIt->next();
+      if ( SMESHDS_SubMesh * smDS = sm->GetSubMeshDS() )
+      {
+        SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+        while( eIt->more() )
+        {
+          theMeshDS->RemoveFreeElement( eIt->next(), smDS );
+        }
+        SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+        while ( nIt->more() )
+        {
+          const SMDS_MeshNode* n = nIt->next();
+          if ( n->NbInverseElements() == 0 )
+            theMeshDS->RemoveFreeNode( n, smDS );
+        }
+      }
+    }
+    theNodeByHybridId.clear();
+    theFaceByHybridId.clear();
+  }
+
   int nbMeshNodes = theMeshDS->NbNodes();
-  
-  const bool isQuadMesh = 
+  int nbInitialNodes = theNodeByHybridId.size();
+
+  const bool isQuadMesh =
     theHelper->GetMesh()->NbEdges( ORDER_QUADRATIC ) ||
     theHelper->GetMesh()->NbFaces( ORDER_QUADRATIC ) ||
     theHelper->GetMesh()->NbVolumes( ORDER_QUADRATIC );
-    
+
 #ifdef _DEBUG_
   std::cout << "theNodeByHybridId.size(): " << nbInitialNodes << std::endl;
   std::cout << "theHelper->GetMesh()->NbNodes(): " << nbMeshNodes << std::endl;
   std::cout << "isQuadMesh: " << isQuadMesh << std::endl;
 #endif
-  
+
   // ---------------------------------
   // Read generated elements and nodes
   // ---------------------------------
@@ -582,20 +609,38 @@ static bool readGMFFile(MG_HYBRID_API*                          MGOutput,
         case GmfEdges:
           if (fullyCreatedElement) {
             aCreatedElem = theHelper->AddEdge( node[0], node[1], noID, force3d );
-            if (anEdgeGroupByHybridId.size() && !anEdgeGroupByHybridId[iElem].empty())
+            if ( !anEdgeGroupByHybridId.empty() && !anEdgeGroupByHybridId[iElem].empty())
               addElemInMeshGroup(theHelper->GetMesh(), aCreatedElem, anEdgeGroupByHybridId[iElem], groupsToRemove);
           }
           break;
         case GmfTriangles:
           if (fullyCreatedElement) {
             aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], noID, force3d );
-            if (aFaceGroupByHybridId.size() && !aFaceGroupByHybridId[iElem].empty())
+            // add iElem < aFaceGroupByHybridId.size() to avoid crash if imprinting with hexa core with MeshGems <= 2.4-5
+            if ( iElem < (int)aFaceGroupByHybridId.size() && !aFaceGroupByHybridId[iElem].empty() ) {
               addElemInMeshGroup(theHelper->GetMesh(), aCreatedElem, aFaceGroupByHybridId[iElem], groupsToRemove);
+            }
+            // add element in shape for groups on geom to work
+            if ( domainID[iElem] > 0 )
+            {
+              theMeshDS->SetMeshElementOnShape( aCreatedElem, domainID[iElem] );
+              for ( int iN = 0; iN < 3; ++iN )
+                if ( node[iN]->getshapeId() < 1 )
+                  theMeshDS->SetNodeOnFace( node[iN], domainID[iElem] );
+            }
           }
           break;
         case GmfQuadrilaterals:
           if (fullyCreatedElement) {
             aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], node[3], noID, force3d );
+            // add element in shape for groups on geom to work
+            if ( domainID[iElem] > 0 )
+            {
+              theMeshDS->SetMeshElementOnShape( aCreatedElem, domainID[iElem] );
+              for ( int iN = 0; iN < 3; ++iN )
+                if ( node[iN]->getshapeId() < 1 )
+                  theMeshDS->SetNodeOnFace( node[iN], domainID[iElem] );
+            }
           }
           break;
         case GmfTetrahedra: