-// 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
#ifdef WIN32
#define NOMINMAX
#endif
+
#include <SMESH_Comment.hxx>
#include <SMESH_File.hxx>
+#include <SMESH_MGLicenseKeyGen.hxx>
#include <Utils_SALOME_Exception.hxx>
-#include <vector>
-#include <iterator>
#include <cstring>
+#include <iostream>
+#include <iterator>
+#include <vector>
#ifdef USE_MG_LIBS
int _nbRequiredEdges;
std::vector<int> _triaNodes;
int _nbRequiredTria;
+ std::vector<int> _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
_triaNodes.reserve( nb * 3 );
}
+ void SetNbTetra( int nb )
+ {
+ _tetraNodes.reserve( nb * 4 );
+ }
+
void SetNbReqVertices( int nb )
{
_nodeSize.reserve( nb );
_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 );
_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;
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() ));
// 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)
{
//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;
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 );
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() )
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
*/
//================================================================================
-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
}
//================================================================================
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];
}
}
// compute
- bool ok = _libData->Compute();
+ bool ok = _libData->Compute();
GetLog(); // write a log file
_logFile = ""; // not to write it again
#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 )
*/
//================================================================================
-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
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 ) {
::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