Salome HOME
Merge multi-study removal branch.
[plugins/ghs3dplugin.git] / src / GHS3DPlugin / GHS3DPlugin_GHS3D.cxx
index daad21397b37f8bf56b1acfebc326f61289403b9..fd943e4bdfeac4d8f608f372ef27a2a401c236d9 100644 (file)
@@ -135,7 +135,6 @@ static void removeFile( const TCollection_AsciiString& fileName )
 GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, SMESH_Gen* gen)
   : SMESH_3D_Algo(hypId, gen), _isLibUsed( false )
 {
-  MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D");
   _name = Name();
   _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
   _onlyUnaryInput = false; // Compute() will be called on a compound of solids
@@ -151,18 +150,17 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, SMESH_Gen* gen)
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
 GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D()
 {
-  MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D");
 }
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
@@ -190,8 +188,8 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh&         aMesh,
   }
   if ( _hyp )
   {
-    _keepFiles = _hyp->GetKeepFiles();
-    _removeLogOnSuccess = _hyp->GetRemoveLogOnSuccess();
+    _keepFiles           = _hyp->GetKeepFiles();
+    _removeLogOnSuccess  = _hyp->GetRemoveLogOnSuccess();
     _logInStandardOutput = _hyp->GetStandardOutputLog();
   }
 
@@ -209,7 +207,8 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh&         aMesh,
 
 TopoDS_Shape GHS3DPlugin_GHS3D::entryToShape(std::string entry)
 {
-  MESSAGE("GHS3DPlugin_GHS3D::entryToShape "<<entry );
+  if ( SMESH_Gen_i::getStudyServant()->_is_nil() )
+    throw SALOME_Exception("MG-Tetra plugin can't work w/o publishing in the study");
 
   GEOM::GEOM_Object_var aGeomObj;
   TopoDS_Shape S = TopoDS_Shape();
@@ -226,8 +225,9 @@ TopoDS_Shape GHS3DPlugin_GHS3D::entryToShape(std::string entry)
 
 //================================================================================
 /*!
- * \brief returns id of a solid if a triangle defined by the nodes is a temporary face on a
- * side facet of pyramid and defines sub-domian outside the pyramid; else returns HOLE_ID
+ * \brief returns id of a solid if a triangle defined by the nodes is a temporary face
+ * either on a side facet of pyramid or a top of pentahedron and defines sub-domian
+ * outside the volume; else returns HOLE_ID
  */
 //================================================================================
 
@@ -239,26 +239,34 @@ static int checkTmpFace(const SMDS_MeshNode* node1,
   SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume);
   while ( vIt1->more() )
   {
-    const SMDS_MeshElement* pyram = vIt1->next();
-    if ( pyram->NbCornerNodes() != 5 ) continue;
+    const SMDS_MeshElement* vol = vIt1->next();
+    const int           nbNodes = vol->NbCornerNodes();
+    if ( nbNodes != 5 && nbNodes != 6 ) continue;
     int i2, i3;
-    if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 &&
-         (i3 = pyram->GetNodeIndex( node3 )) >= 0 )
+    if ( (i2 = vol->GetNodeIndex( node2 )) >= 0 &&
+         (i3 = vol->GetNodeIndex( node3 )) >= 0 )
     {
-      // Triangle defines sub-domian inside the pyramid if it's
-      // normal points out of the pyram
-
-      // make i2 and i3 hold indices of base nodes of the pyram while
-      // keeping the nodes order in the triangle
-      const int iApex = 4;
-      if ( i2 == iApex )
-        i2 = i3, i3 = pyram->GetNodeIndex( node1 );
-      else if ( i3 == iApex )
-        i3 = i2, i2 = pyram->GetNodeIndex( node1 );
-
-      int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
-      bool isDomainInPyramid = ( i3base != i3 );
-      return isDomainInPyramid ? HOLE_ID : pyram->getshapeId();
+      if ( nbNodes == 5 )
+      {
+        // Triangle defines sub-domian inside the pyramid if it's
+        // normal points out of the vol
+
+        // make i2 and i3 hold indices of base nodes of the vol while
+        // keeping the nodes order in the triangle
+        const int iApex = 4;
+        if ( i2 == iApex )
+          i2 = i3, i3 = vol->GetNodeIndex( node1 );
+        else if ( i3 == iApex )
+          i3 = i2, i2 = vol->GetNodeIndex( node1 );
+
+        int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
+        bool isDomainInPyramid = ( i3base != i3 );
+        return isDomainInPyramid ? HOLE_ID : vol->getshapeId();
+      }
+      else
+      {
+        return vol->getshapeId(); // triangle is a prism top
+      }
     }
   }
   return HOLE_ID;
@@ -290,7 +298,7 @@ static int findShapeID(SMESH_Mesh&          mesh,
   const SMDS_MeshElement * face = meshDS->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/true);
   if ( !face )
     return checkTmpFace(node1, node2, node3);
-#ifdef _DEBUG_
+#ifdef _MY_DEBUG_
   std::cout << "bnd face " << face->GetID() << " - ";
 #endif
   // geom face the face assigned to
@@ -441,7 +449,6 @@ static void addElemInMeshGroup(SMESH_Mesh*             theMesh,
       SMESHDS_Group* aGroupDS = static_cast<SMESHDS_Group*>( groupDS );
       aGroupDS->SMDSGroup().Add(anElem);
       groupDone = true;
-//       MESSAGE("Successfully added enforced element to existing group " << groupName);
       break;
     }
   }
@@ -453,7 +460,6 @@ static void addElemInMeshGroup(SMESH_Mesh*             theMesh,
     aGroup->SetName( groupName.c_str() );
     SMESHDS_Group* aGroupDS = static_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
     aGroupDS->SMDSGroup().Add(anElem);
-//     MESSAGE("Successfully created enforced vertex group " << groupName);
     groupDone = true;
   }
   if (!groupDone)
@@ -477,7 +483,6 @@ static void updateMeshGroups(SMESH_Mesh* theMesh, std::set<std::string> groupsTo
     std::string currentGroupName = (string)group->GetName();
     if (groupDS->IsEmpty() && groupsToRemove.find(currentGroupName) != groupsToRemove.end()) {
       // Previous group created by enforced elements
-      MESSAGE("Delete previous group created by removed enforced elements: " << group->GetName())
       theMesh->RemoveGroup(groupDS->GetID());
     }
   }
@@ -588,16 +593,14 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
   const bool hasGeom = ( theHelper->GetMesh()->HasShapeToMesh() );
 
   int nbInitialNodes = theNodeByGhs3dId.size();
-  int nbMeshNodes = theMeshDS->NbNodes();
   
+#ifdef _MY_DEBUG_
   const bool isQuadMesh = 
     theHelper->GetMesh()->NbEdges( ORDER_QUADRATIC ) ||
     theHelper->GetMesh()->NbFaces( ORDER_QUADRATIC ) ||
     theHelper->GetMesh()->NbVolumes( ORDER_QUADRATIC );
-    
-#ifdef _DEBUG_
   std::cout << "theNodeByGhs3dId.size(): " << nbInitialNodes << std::endl;
-  std::cout << "theHelper->GetMesh()->NbNodes(): " << nbMeshNodes << std::endl;
+  std::cout << "theHelper->GetMesh()->NbNodes(): " << theMeshDS->NbNodes() << std::endl;
   std::cout << "isQuadMesh: " << isQuadMesh << std::endl;
 #endif
   
@@ -608,7 +611,7 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
   int nbElem = 0, nbRef = 0;
   int aGMFNodeID = 0;
   std::vector< const SMDS_MeshNode*> GMFNode;
-#ifdef _DEBUG_
+#ifdef _MY_DEBUG_
   std::map<int, std::set<int> > subdomainId2tetraId;
 #endif
   std::map <GmfKwdCod,int> tabRef;
@@ -625,11 +628,9 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
   tabRef[GmfHexahedra]      = 8;
 
   int ver, dim;
-  MESSAGE("Read " << theFile << " file");
   int InpMsh = MGOutput->GmfOpenMesh( theFile, GmfRead, &ver, &dim);
   if (!InpMsh)
     return false;
-  MESSAGE("Done ");
 
   // Read ids of domains
   vector< int > solidIDByDomain;
@@ -666,7 +667,7 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
             findShapeID( *theHelper->GetMesh(), nn[0], nn[1], nn[2], toMeshHoles );
           if ( solidIDByDomain[ domainNb ] > 0 )
           {
-#ifdef _DEBUG_
+#ifdef _MY_DEBUG_
             std::cout << "solid " << solidIDByDomain[ domainNb ] << std::endl;
 #endif
             const TopoDS_Shape& foundShape = theMeshDS->IndexToShape( solidIDByDomain[ domainNb ] );
@@ -796,7 +797,7 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
       (nbElem <= 1) ? tmpStr = " Tetrahedron" : tmpStr = " Tetrahedra";
       for ( int iElem = 0; iElem < nbElem; iElem++ ) {
         MGOutput->GmfGetLin( InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &domainID[iElem]);
-#ifdef _DEBUG_
+#ifdef _MY_DEBUG_
         subdomainId2tetraId[dummy].insert(iElem+1);
 #endif
       }
@@ -969,8 +970,7 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
   if ( toMakeGroupsOfDomains )
     makeDomainGroups( elemsOfDomain, theHelper );
 
-#ifdef _DEBUG_
-  MESSAGE("Nb subdomains " << subdomainId2tetraId.size());
+#ifdef _MY_DEBUG_
   std::map<int, std::set<int> >::const_iterator subdomainIt = subdomainId2tetraId.begin();
   TCollection_AsciiString aSubdomainFileName = theFile;
   aSubdomainFileName = aSubdomainFileName + ".subdomain";
@@ -980,7 +980,6 @@ static bool readGMFFile(MG_Tetra_API*                   MGOutput,
   for(;subdomainIt != subdomainId2tetraId.end() ; ++subdomainIt) {
     int subdomainId = subdomainIt->first;
     std::set<int> tetraIds = subdomainIt->second;
-    MESSAGE("Subdomain #"<<subdomainId<<": "<<tetraIds.size()<<" tetrahedrons");
     std::set<int>::const_iterator tetraIdsIt = tetraIds.begin();
     aSubdomainFile << subdomainId << std::endl;
     for(;tetraIdsIt != tetraIds.end() ; ++tetraIdsIt) {
@@ -1014,7 +1013,6 @@ static bool writeGMFFile(MG_Tetra_API*                                   MGInput
                          GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues & theEnforcedVertices,
                          int &                                           theInvalidEnforcedFlags)
 {
-  MESSAGE("writeGMFFile w/o geometry");
   std::string tmpStr;
   int idx, idxRequired = 0, idxSol = 0;
   const int dummyint = 0;
@@ -1650,8 +1648,8 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   // MG-Tetra for domain indication
   SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh ));
 
-  // make prisms on quadrangles
-  if ( theMesh.NbQuadrangles() > 0 )
+  // make prisms on quadrangles and viscous layers
+  if ( theMesh.NbQuadrangles() > 0 || _viscousLayersHyp )
   {
     vector<SMESH_ProxyMesh::Ptr> components;
     for (expBox.ReInit(); expBox.More(); expBox.Next())
@@ -1662,21 +1660,24 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
         if ( !proxyMesh )
           return false;
       }
-      StdMeshers_QuadToTriaAdaptor* q2t = new StdMeshers_QuadToTriaAdaptor;
-      Ok = q2t->Compute( theMesh, expBox.Current(), proxyMesh.get() );
-      components.push_back( SMESH_ProxyMesh::Ptr( q2t ));
-      if ( !Ok )
-        return false;
+      if ( theMesh.NbQuadrangles() > 0 )
+      {
+        StdMeshers_QuadToTriaAdaptor* q2t = new StdMeshers_QuadToTriaAdaptor;
+        Ok = q2t->Compute( theMesh, expBox.Current(), proxyMesh.get() );
+        components.push_back( SMESH_ProxyMesh::Ptr( q2t ));
+        if ( !Ok )
+          return false;
+      }
     }
     proxyMesh.reset( new SMESH_ProxyMesh( components ));
   }
   // build viscous layers
-  else if ( _viscousLayersHyp )
-  {
-    proxyMesh = _viscousLayersHyp->Compute( theMesh, theShape );
-    if ( !proxyMesh )
-      return false;
-  }
+  // else if ( _viscousLayersHyp )
+  // {
+  //   proxyMesh = _viscousLayersHyp->Compute( theMesh, theShape );
+  //   if ( !proxyMesh )
+  //     return false;
+  // }
 
   int anInvalidEnforcedFlags = 0;
   Ok = writeGMFFile(&mgTetra,
@@ -1788,10 +1789,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   }
   else if ( mgTetra.HasLog() )
   {
-    // get problem description from the log file
-    _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh );
-    storeErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(),
-                           mgTetra.GetLog(), conv );
+    if( _computeCanceled )
+      error( "interruption initiated by user" );
+    else
+    {
+      // get problem description from the log file
+      _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh );
+      error( getErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(),
+                                  mgTetra.GetLog(), conv ));
+    }
   }
   else if ( !errStr.empty() )
   {
@@ -1834,8 +1840,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
 bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
                                 SMESH_MesherHelper* theHelper)
 {
-  MESSAGE("GHS3DPlugin_GHS3D::Compute()");
-
   theHelper->IsQuadraticSubMesh( theHelper->GetSubShape() );
 
   // a unique working file name
@@ -2007,10 +2011,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   }
   else if ( mgTetra.HasLog() )
   {
-    // get problem description from the log file
-    _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh );
-    storeErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(),
-                           mgTetra.GetLog(), conv );
+    if( _computeCanceled )
+      error( "interruption initiated by user" );
+    else
+    {
+      // get problem description from the log file
+      _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh );
+      error( getErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(),
+                                  mgTetra.GetLog(), conv ));
+    }
   }
   else {
     // the log file is empty
@@ -2035,8 +2044,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
 void GHS3DPlugin_GHS3D::CancelCompute()
 {
   _computeCanceled = true;
-#ifdef WIN32
-#else
+#if !defined WIN32 && !defined __APPLE__
   std::string cmd = "ps xo pid,args | grep " + _genericName;
   //cmd += " | grep -e \"^ *[0-9]\\+ \\+" + GHS3DPlugin_Hypothesis::GetExeName() + "\"";
   cmd += " | awk '{print $1}' | xargs kill -9 > /dev/null 2>&1";
@@ -2366,17 +2374,13 @@ static char* getIds( char* ptr, int nbIds, vector<int>& ids )
  */
 //================================================================================
 
-bool GHS3DPlugin_GHS3D::storeErrorDescription(const char*                logFile,
-                                              const std::string&         log,
-                                              const _Ghs2smdsConvertor & toSmdsConvertor )
+SMESH_ComputeErrorPtr
+GHS3DPlugin_GHS3D::getErrorDescription(const char*                logFile,
+                                       const std::string&         log,
+                                       const _Ghs2smdsConvertor & toSmdsConvertor,
+                                       const bool                 isOk/* = false*/ )
 {
-  if(_computeCanceled)
-    return error(SMESH_Comment("interruption initiated by user"));
-
-  // read file
-  // SMESH_File file( logFile.ToCString() );
-  // if ( file.size() == 0 )
-  //   return error( SMESH_Comment("See ") << logFile << " for problem description");
+  SMESH_ComputeErrorPtr err = SMESH_ComputeError::New( COMPERR_ALGO_FAILED );
 
   char* ptr = const_cast<char*>( log.c_str() );
   char* buf = ptr, * bufEnd = ptr + log.size();
@@ -2414,7 +2418,7 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char*                logFile
     if ( strncmp( ptr, "ERR ", 4 ) != 0 )
       continue;
 
-    list<const SMDS_MeshElement*> badElems;
+    list<const SMDS_MeshElement*>& badElems = err->myBadElements;
     vector<int> nodeIds;
 
     ptr += 4;
@@ -2588,13 +2592,6 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char*                logFile
 //         continue; // not to report different types of errors with bad elements
 //     }
 
-    // store bad elements
-    //if ( allElemsOk ) {
-      list<const SMDS_MeshElement*>::iterator elem = badElems.begin();
-      for ( ; elem != badElems.end(); ++elem )
-        addBadInputElement( *elem );
-      //}
-
     // make error text
     string text = translateError( errNum );
     if ( errDescription.find( text ) == text.npos ) {
@@ -2619,14 +2616,20 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char*                logFile
     }
   }
 
-  if ( logFile && logFile[0] )
+  if ( !isOk && logFile && logFile[0] )
   {
     if ( errDescription.empty() )
       errDescription << "See " << logFile << " for problem description";
     else
       errDescription << "\nSee " << logFile << " for more information";
   }
-  return error( errDescription );
+
+  err->myComment = errDescription;
+
+  if ( err->myComment.empty() && err->myBadElements.empty() )
+    err = SMESH_ComputeError::New(); // OK
+
+  return err;
 }
 
 //================================================================================
@@ -2924,7 +2927,7 @@ double GHS3DPlugin_GHS3D::GetProgress() const
   if ( _isLibUsed )
   {
     // this->_progress is advanced by MG_Tetra_API according to messages from MG library
-    // but sharply. Advanced it a bit to get smoother advancement.
+    // but sharply. Advance it a bit to get smoother advancement.
     GHS3DPlugin_GHS3D* me = const_cast<GHS3DPlugin_GHS3D*>( this );
     if ( _progress < 0.1 ) // the first message is at 10%
       me->_progress = GetProgressByTic();