X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGHS3DPlugin%2FMG_Tetra_API.cxx;h=69391d9b585523da68203e46f9f48e8e69b1c794;hb=ac2d9a39f715f3cdfd4d1678df1ed65e3f42ea59;hp=1ccd80730eee280102db349d7caa1a03faf77703;hpb=dd492f9ab4f7f9e26d56b1770b144dd0d5d9326d;p=plugins%2Fghs3dplugin.git diff --git a/src/GHS3DPlugin/MG_Tetra_API.cxx b/src/GHS3DPlugin/MG_Tetra_API.cxx index 1ccd807..69391d9 100644 --- a/src/GHS3DPlugin/MG_Tetra_API.cxx +++ b/src/GHS3DPlugin/MG_Tetra_API.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// Copyright (C) 2004-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,13 +19,19 @@ #include "MG_Tetra_API.hxx" +#ifdef WIN32 +#define NOMINMAX +#endif + #include #include +#include #include -#include -#include #include +#include +#include +#include #ifdef USE_MG_LIBS @@ -50,16 +56,18 @@ struct MG_Tetra_API::LibData int _nbRequiredEdges; std::vector _triaNodes; int _nbRequiredTria; + std::vector _tetraNodes; int _count; volatile bool& _cancelled_flag; std::string _errorStr; double& _progress; + bool _progressInCallBack; LibData( volatile bool & cancelled_flag, double& progress ) : _context(0), _session(0), _tria_mesh(0), _sizemap(0), _tetra_mesh(0), _nbRequiredEdges(0), _nbRequiredTria(0), - _cancelled_flag( cancelled_flag ), _progress( progress ) + _cancelled_flag( cancelled_flag ), _progress( progress ), _progressInCallBack( false ) { } // methods setting callbacks implemented after callback definitions @@ -326,6 +334,11 @@ struct MG_Tetra_API::LibData _triaNodes.reserve( nb * 3 ); } + void SetNbTetra( int nb ) + { + _tetraNodes.reserve( nb * 4 ); + } + void SetNbReqVertices( int nb ) { _nodeSize.reserve( nb ); @@ -341,7 +354,7 @@ struct MG_Tetra_API::LibData _nbRequiredTria = nb; } - void AddNode( double x, double y, double z, int domain ) + void AddNode( double x, double y, double z, int /*domain*/ ) { _xyz.push_back( x ); _xyz.push_back( y ); @@ -353,19 +366,27 @@ struct MG_Tetra_API::LibData _nodeSize.push_back( size ); } - void AddEdgeNodes( int node1, int node2, int domain ) + void AddEdgeNodes( int node1, int node2, int /*domain*/ ) { _edgeNodes.push_back( node1 ); _edgeNodes.push_back( node2 ); } - void AddTriaNodes( int node1, int node2, int node3, int domain ) + void AddTriaNodes( int node1, int node2, int node3, int /*domain*/ ) { _triaNodes.push_back( node1 ); _triaNodes.push_back( node2 ); _triaNodes.push_back( node3 ); } + void AddTetraNodes( int node1, int node2, int node3, int node4, int /*domain*/ ) + { + _tetraNodes.push_back( node1 ); + _tetraNodes.push_back( node2 ); + _tetraNodes.push_back( node3 ); + _tetraNodes.push_back( node4 ); + } + int NbNodes() { return _xyz.size() / 3; @@ -391,11 +412,21 @@ struct MG_Tetra_API::LibData return _triaNodes.size() / 3; } + int NbTetra() + { + return _tetraNodes.size() / 4; + } + int * GetTriaNodes( int iTria ) { return & _triaNodes[ iTria * 3 ]; } + int * GetTetraNodes( int iTet ) + { + return & _tetraNodes[ iTet * 4 ]; + } + int IsVertexRequired( int iNode ) { return ! ( iNode < int( NbNodes() - _nodeSize.size() )); @@ -482,26 +513,25 @@ namespace // functions called by MG library to exchange with the application // return STATUS_OK; // } - // status_t get_tetrahedron_count(integer * nbtetra, void *user_data) - // { - // MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; - - // *nbtetra = 0; /* the number of tetra in your input mesh (0 if you describe a surface mesh) */ - - // return STATUS_OK; - // } + status_t get_tetrahedron_count(integer * nbtetra, void *user_data) + { + MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + *nbtetra = data->NbTetra(); - // status_t get_tetrahedron_vertices(integer itetra, integer * vtetra, - // void *user_data) - // { - // int j; - // MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + return STATUS_OK; + } - // for (j = 0; j < 4; j++) - // vtetra[j] = 0; /* the j'th vertex index of the itetra'th tetrahedron */ + status_t get_tetrahedron_vertices(integer itetra, integer * vtetra, + void *user_data) + { + int j; + MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + int* nodes = data->GetTetraNodes( itetra-1 ); + for (j = 0; j < 4; j++) + vtetra[j] = nodes[j]; - // return STATUS_OK; - // } + return STATUS_OK; + } status_t get_vertex_required_property(integer ivtx, integer * rvtx, void *user_data) { @@ -531,26 +561,37 @@ namespace // functions called by MG library to exchange with the application //std::cout << desc << std::endl; #endif - // Compute progress - // corresponding messages are: - // " -- PHASE 1 COMPLETED" => 10 % - // " -- PHASE 2 COMPLETED" => 25 % - // " ** ITERATION 1" => 25.* % - // " ** ITERATION 2" => 25.* % - // " -- PHASE 3 COMPLETED" => 70 % - // " -- PHASE 4 COMPLETED" => 98 % - - if ( strncmp( "-- PHASE ", desc + 2, 9 ) == 0 && desc[ 13 ] == 'C' ) + if ( strncmp( "MGMESSAGE 1009001 ", desc, 19 ) == 0 ) { - const double progress[] = { 10., 25., 70., 98., 100., 100., 100. }; - int phase = atoi( desc + 11 ); - data->_progress = std::max( data->_progress, progress[ phase - 1 ] / 100. ); + // progress message (10%): "MGMESSAGE 1009001 0 1 1.000000e+01" + data->_progress = atof( desc + 24 ); + + data->_progressInCallBack = true; } - else if ( strncmp( "** ITERATION ", desc + 5, 13 ) == 0 ) + + if ( !data->_progressInCallBack ) { - int iter = atoi( desc + 20 ); - double percent = 25. + iter * ( 70 - 25 ) / 20.; - data->_progress = std::max( data->_progress, ( percent / 100. )); + // Compute progress + // corresponding messages are: + // " -- PHASE 1 COMPLETED" => 10 % + // " -- PHASE 2 COMPLETED" => 25 % + // " ** ITERATION 1" => 25.* % + // " ** ITERATION 2" => 25.* % + // " -- PHASE 3 COMPLETED" => 70 % + // " -- PHASE 4 COMPLETED" => 98 % + + if ( strncmp( "-- PHASE ", desc + 2, 9 ) == 0 && desc[ 13 ] == 'C' ) + { + const double progress[] = { 10., 25., 70., 98., 100., 100., 100. }; + int phase = atoi( desc + 11 ); + data->_progress = std::max( data->_progress, progress[ phase - 1 ] / 100. ); + } + else if ( strncmp( "** ITERATION ", desc + 5, 13 ) == 0 ) + { + int iter = atoi( desc + 20 ); + double percent = 25. + iter * ( 70 - 25 ) / 20.; + data->_progress = std::max( data->_progress, ( percent / 100. )); + } } return STATUS_OK; @@ -592,6 +633,8 @@ void MG_Tetra_API::LibData::Init() mesh_set_get_edge_vertices( _tria_mesh, get_edge_vertices, this ); mesh_set_get_triangle_count( _tria_mesh, get_triangle_count, this ); mesh_set_get_triangle_vertices( _tria_mesh, get_triangle_vertices, this ); + mesh_set_get_tetrahedron_count( _tria_mesh, get_tetrahedron_count, this ); + mesh_set_get_tetrahedron_vertices( _tria_mesh, get_tetrahedron_vertices, this ); // Create a tetra session _session = tetra_session_new( _context ); @@ -604,9 +647,34 @@ void MG_Tetra_API::LibData::Init() bool MG_Tetra_API::LibData::Compute() { - // Set surface mesh - status_t ret = tetra_set_surface_mesh( _session, _tria_mesh ); - if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh"); + status_t ret; + std::string errorTxt; + + if ( _tetraNodes.empty() ) + { + // Sign the surface mesh + if ( !SMESHUtils_MGLicenseKeyGen::SignMesh( _tria_mesh, "tetra", errorTxt )) + { + AddError( SMESH_Comment( "Problem with library SalomeMeshGemsKeyGenerator: ") << errorTxt ); + return false; + } + // Set surface mesh + ret = tetra_set_surface_mesh( _session, _tria_mesh ); + if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh"); + } + else + { + // Sign the volume mesh + // TOOD: check if there is a typo here. Should be _tetra_mesh ? + if ( !SMESHUtils_MGLicenseKeyGen::SignMesh( _tria_mesh, "tetra", errorTxt )) + { + AddError( SMESH_Comment( "Problem with library SalomeMeshGemsKeyGenerator: ") << errorTxt ); + return false; + } + // TOOD: check if there is a typo here. Should be _tetra_mesh ? + ret = tetra_set_volume_mesh( _session, _tria_mesh ); + if ( ret != STATUS_OK ) MG_Error( "unable to set volume mesh"); + } // Set a sizemap if ( !_nodeSize.empty() ) @@ -631,13 +699,24 @@ bool MG_Tetra_API::LibData::Compute() if (ret != STATUS_OK) MG_Error( "unable to get resulting mesh"); ////////////////////////////////////////////////////////////////////////////////////////// - // file = "/tmp/ghs3d_OUT.mesh"; - // mesh_write_mesh( _tetra_mesh,file); - // std::cout << std::endl << std::endl << "Write " << file << std::endl << std::endl << std::endl; - + // { + // const char* file = "/tmp/ghs3d_OUT.mesh"; + // mesh_write_mesh( _tetra_mesh,file); + // std::cout << std::endl << std::endl << "Write " << file << std::endl << std::endl << std::endl; + // } return true; } +#else // ifdef USE_MG_LIBS + +struct MG_Tetra_API::LibData // to avoid compiler warnings +{ + volatile bool& _cancelled_flag; + double& _progress; + LibData(volatile bool& cancelled_flag, double& progress): + _cancelled_flag{cancelled_flag}, _progress{progress} + {} +}; #endif // ifdef USE_MG_LIBS @@ -648,15 +727,17 @@ bool MG_Tetra_API::LibData::Compute() */ //================================================================================ -MG_Tetra_API::MG_Tetra_API(volatile bool& cancelled_flag, double& progress) +MG_Tetra_API::MG_Tetra_API(volatile bool& cancelled_flag, double& progress): + _nbNodes(0), _nbEdges(0), _nbFaces(0), _nbVolumes(0) { + _useLib = false; + _libData = new LibData( cancelled_flag, progress ); #ifdef USE_MG_LIBS _useLib = true; - _libData = new LibData( cancelled_flag, progress ); _libData->Init(); -#endif if ( getenv("MG_TETRA_USE_EXE")) _useLib = false; +#endif } //================================================================================ @@ -731,6 +812,8 @@ bool MG_Tetra_API::Compute( const std::string& cmdLine, std::string& errStr ) value = ""; while ( i+1 < args.size() && args[i+1][0] != '-' ) { + if ( strncmp( "1>", args[i+1].c_str(), 2 ) == 0 ) + break; if ( !value.empty() ) value += " "; value += args[++i]; } @@ -739,7 +822,7 @@ bool MG_Tetra_API::Compute( const std::string& cmdLine, std::string& errStr ) } // compute - bool ok = _libData->Compute(); + bool ok = _libData->Compute(); GetLog(); // write a log file _logFile = ""; // not to write it again @@ -748,6 +831,22 @@ bool MG_Tetra_API::Compute( const std::string& cmdLine, std::string& errStr ) #endif } + // add MG license key + { + std::string errorTxt, meshIn; + std::string key = SMESHUtils_MGLicenseKeyGen::GetKey( meshIn, + _nbNodes, _nbEdges, _nbFaces, _nbVolumes, + errorTxt ); + if ( key.empty() ) + { + errStr = "Problem with library SalomeMeshGemsKeyGenerator: " + errorTxt; + return false; + } + + if ( key != "0") + const_cast< std::string& >( cmdLine ) += " --key " + key; + } + int err = system( cmdLine.c_str() ); // run if ( err ) @@ -834,7 +933,7 @@ void MG_Tetra_API::GmfGotoKwd( int iMesh, GmfKwdCod what ) */ //================================================================================ -void MG_Tetra_API::GmfGetLin( int iMesh, GmfKwdCod what, int* nbNodes, int* faceInd, int* ori, int* domain, int dummy ) +void MG_Tetra_API::GmfGetLin( int iMesh, GmfKwdCod what, int* nbNodes, int* faceInd, int* ori, int* domain, int /*dummy*/ ) { if ( _useLib ) { #ifdef USE_MG_LIBS @@ -1005,6 +1104,17 @@ int MG_Tetra_API::GmfOpenMesh(const char* theFile, int rdOrWr, int ver, int dim void MG_Tetra_API::GmfSetKwd(int iMesh, GmfKwdCod what, int nb ) { + //if ( iMesh == 1 ) + { + switch ( what ) { + case GmfVertices: _nbNodes += nb; break; + case GmfEdges: _nbEdges += nb; break; + case GmfTriangles: _nbFaces += nb; break; + case GmfTetrahedra: _nbVolumes += nb; break; + default:; + } + } + if ( _useLib ) { #ifdef USE_MG_LIBS switch ( what ) { @@ -1129,6 +1239,24 @@ void MG_Tetra_API::GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, in ::GmfSetLin(iMesh, what, node1, node2, node3, domain ); } +//================================================================================ +/*! + * \brief Add tetra nodes + */ +//================================================================================ + +void MG_Tetra_API::GmfSetLin(int iMesh, GmfKwdCod what, + int node1, int node2, int node3, int node4, int domain ) +{ + if ( _useLib ) { +#ifdef USE_MG_LIBS + _libData->AddTetraNodes( node1, node2, node3, node4, domain ); + return; +#endif + } + ::GmfSetLin(iMesh, what, node1, node2, node3, node4, domain ); +} + //================================================================================ /*! * \brief Close a file