-// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022 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
#include <TopoDS_Wire.hxx>
#include <gp_Pnt.hxx>
+// Have to be included before std headers
+#include <Python.h>
+#include <structmember.h>
+
#ifdef WIN32
#include <windows.h>
#include <process.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/string.hpp>
+#include <boost/filesystem.hpp>
+
+namespace fs = boost::filesystem;
using namespace std;
using SMESH::TPythonDump;
// copy elements
- SMESH::array_of_ElementType_var srcElemTypes = theMeshesArray[i]->GetTypes();
- if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
- continue;
std::vector< const SMDS_MeshElement* > newElems( initMeshDS->NbElements() + 1, 0 );
- elemIt = initImpl->GetElements( theMeshesArray[i], SMESH::ALL );
- while ( elemIt->more() )
+ SMESH::array_of_ElementType_var srcElemTypes = theMeshesArray[i]->GetTypes();
+ bool hasElems = (( srcElemTypes->length() > 1 ) ||
+ ( srcElemTypes->length() == 1 && srcElemTypes[0] != SMESH::NODE ));
+ if ( hasElems )
{
- const SMDS_MeshElement* elem = elemIt->next();
- elemType.myNodes.resize( elem->NbNodes() );
-
- SMDS_NodeIteratorPtr itNodes = elem->nodeIterator();
- for ( int k = 0; itNodes->more(); k++)
+ elemIt = initImpl->GetElements( theMeshesArray[i], SMESH::ALL );
+ while ( elemIt->more() )
{
- const SMDS_MeshNode* node = itNodes->next();
- elemType.myNodes[ k ] = static_cast< const SMDS_MeshNode*> ( newNodes[ node->GetID() ]);
- }
+ const SMDS_MeshElement* elem = elemIt->next();
+ elemType.myNodes.resize( elem->NbNodes() );
- // creates a corresponding element on existent nodes in new mesh
- newElems[ elem->GetID() ] =
- newEditor.AddElement( elemType.myNodes, elemType.Init( elem, /*basicOnly=*/false ));
+ SMDS_NodeIteratorPtr itNodes = elem->nodeIterator();
+ for ( int k = 0; itNodes->more(); k++)
+ {
+ const SMDS_MeshNode* node = itNodes->next();
+ elemType.myNodes[ k ] = static_cast< const SMDS_MeshNode*> ( newNodes[ node->GetID() ]);
+ }
+
+ // creates a corresponding element on existent nodes in new mesh
+ newElems[ elem->GetID() ] =
+ newEditor.AddElement( elemType.myNodes, elemType.Init( elem, /*basicOnly=*/false ));
+ }
+ newEditor.ClearLastCreated(); // forget the history
}
- newEditor.ClearLastCreated(); // forget the history
// create groups of just added elements
return newMesh._retn();
}
+
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ * \param mesh - TetraHedron mesh
+ * \param meshName Name of the created mesh
+ * \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateDualMesh(SMESH::SMESH_IDSource_ptr mesh,
+ const char* meshName,
+ CORBA::Boolean adapt_to_shape)
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ TPythonDump* pyDump = new TPythonDump(this); // prevent dump from CreateMesh()
+ std::unique_ptr<TPythonDump> pyDumpDeleter( pyDump );
+
+ // 1. Get source mesh
+
+ if ( CORBA::is_nil( mesh ))
+ THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+ SMESH::SMESH_Mesh_var srcMesh = mesh->GetMesh();
+ SMESH_Mesh_i* srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
+ if ( !srcMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+
+ CORBA::String_var mesh_var=GetORB()->object_to_string(mesh);
+ std::string mesh_ior = mesh_var.in();
+
+ //temporary folder for the generation of the med file
+ fs::path tmp_folder = fs::temp_directory_path() / fs::unique_path(fs::path("dual_mesh-%%%%"));
+ fs::create_directories(tmp_folder);
+ fs::path dual_mesh_file = tmp_folder / fs::path("tmp_dual_mesh.med");
+ std::string mesh_name(meshName);
+ MESSAGE("Working in folder" + tmp_folder.string());
+
+ // Running Python script
+ assert(Py_IsInitialized());
+ PyGILState_STATE gstate;
+ gstate = PyGILState_Ensure();
+
+
+ std::string ats;
+ if(adapt_to_shape)
+ ats = "True";
+ else
+ ats = "False";
+
+ std::string cmd="import salome.smesh.smesh_tools as smt\n";
+ cmd +="smt.smesh_create_dual_mesh(\"" + mesh_ior + "\", \"" +
+ dual_mesh_file.string() + "\", mesh_name=\"" + mesh_name + "\", adapt_to_shape=" + ats + ")";
+ MESSAGE(cmd);
+
+ PyObject *py_main = PyImport_AddModule("__main__");
+ PyObject *py_dict = PyModule_GetDict(py_main);
+
+ PyRun_String(cmd.c_str(), Py_file_input, py_dict, py_dict);
+
+ if (PyErr_Occurred()) {
+ // Restrieving python error
+ MESSAGE("Catching error")
+ PyObject *errtype, *errvalue, *traceback;
+ PyErr_Fetch(&errtype, &errvalue, &traceback);
+ if(errvalue != NULL) {
+ MESSAGE("Error has a value")
+ PyObject *s = PyObject_Str(errvalue);
+ Py_ssize_t size;
+ std::string msg = PyUnicode_AsUTF8AndSize(s, &size);
+ msg = "Issue with the execution of create_dual_mesh:\n"+msg;
+ MESSAGE("throwing exception")
+ // We need to deactivate the GIL before throwing the exception
+ PyGILState_Release(gstate);
+ THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::INTERNAL_ERROR );
+ Py_DECREF(s);
+ }
+ Py_XDECREF(errvalue);
+ Py_XDECREF(errtype);
+ Py_XDECREF(traceback);
+ }
+
+ PyGILState_Release(gstate);
+
+ MESSAGE("Mesh created in " + dual_mesh_file.string());
+
+ // Import created MED
+ SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+ SMESH_Mesh_i* newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+ if ( !newMesh_i )
+ THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+ SALOMEDS::SObject_wrap meshSO = ObjectToSObject( newMesh );
+ if ( !meshSO->_is_nil() )
+ {
+ SetName( meshSO, meshName, meshName );
+ SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+ }
+ int ret = newMesh_i->ImportMEDFile(dual_mesh_file.string().c_str(), meshName);
+ if(ret)
+ THROW_SALOME_CORBA_EXCEPTION( "Issue when importing mesh", SALOME::INTERNAL_ERROR );
+
+ /*
+ SMESH_Mesh& newMesh2 = newMesh_i->GetImpl();
+
+
+ MESSAGE("Loading file: " << dual_mesh_file.string() << " with mesh " << meshName);
+ int ret = newMesh2.MEDToMesh(dual_mesh_file.c_str(), meshName);
+ */
+
+ newMesh_i->GetImpl().GetMeshDS()->Modified();
+
+ *pyDump << newMesh << " = " << this
+ << ".CreateDualMesh("
+ << mesh << ", "
+ << "'" << mesh_name << "', "
+ << ats << ") ";
+
+ pyDumpDeleter.reset(); // allow dump in GetGroups()
+
+ if ( srcMesh_i->GetImpl().GetGroupIds().size() > 0 ) // dump created groups
+ MESSAGE("Dump of groups");
+ SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+ return newMesh._retn();
+}
+
//================================================================================
/*!
* \brief Create a mesh by copying a part of another mesh
{
if ( myStudyContext && !CORBA::is_nil( theObject )) {
CORBA::String_var iorString = GetORB()->object_to_string( theObject );
- string iorStringCpp(iorString.in());
+ string iorStringCpp(iorString.in());
return myStudyContext->findId( iorStringCpp );
}
return 0;
useCaseBuilder->AppendTo( where, sobj ); // append to the end of list
}
}
-//================================================================================
-/*!
- * \brief Returns true if algorithm can be used to mesh a given geometry
- * \param [in] theAlgoType - the algorithm type
- * \param [in] theLibName - a name of the Plug-in library implementing the algorithm
- * \param [in] theGeomObject - the geometry to mesh
- * \param [in] toCheckAll - if \c True, returns \c True if all shapes are meshable,
- * else, returns \c True if at least one shape is meshable
- * \return CORBA::Boolean - can or can't
- */
-//================================================================================
-
-CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
- const char* theLibName,
- GEOM::GEOM_Object_ptr theGeomObject,
- CORBA::Boolean toCheckAll)
-{
- SMESH_TRY;
-
- std::string aPlatformLibName;
- GenericHypothesisCreator_i* aCreator =
- getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName);
- if (aCreator)
- {
- TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
- const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType );
- return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim );
- }
- else
- {
- return false;
- }
-
- SMESH_CATCH( SMESH::doNothing );
-
-#ifdef _DEBUG_
- cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl;
-#endif
- return true;
-}
//================================================================================
/*!
}
return res;
}
+
+//================================================================================
+/*!
+ * \brief Returns true if algorithm can be used to mesh a given geometry
+ * \param [in] theAlgoType - the algorithm type
+ * \param [in] theLibName - a name of the Plug-in library implementing the algorithm
+ * \param [in] theGeomObject - the geometry to mesh
+ * \param [in] toCheckAll - if \c True, returns \c True if all shapes are meshable,
+ * else, returns \c True if at least one shape is meshable
+ * \return CORBA::Boolean - can or can't
+ */
+//================================================================================
+
+#undef SMY_OWN_CATCH
+#define SMY_OWN_CATCH // prevent re-throwing SALOME::SALOME_Exception in IsApplicable()
+
+CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char* theAlgoType,
+ const char* theLibName,
+ GEOM::GEOM_Object_ptr theGeomObject,
+ CORBA::Boolean toCheckAll)
+{
+ SMESH_TRY;
+
+ std::string aPlatformLibName;
+ GenericHypothesisCreator_i* aCreator =
+ getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName);
+ if (aCreator)
+ {
+ TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
+ const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType );
+ return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim );
+ }
+ else
+ {
+ return false;
+ }
+
+ SMESH_CATCH( SMESH::doNothing );
+
+ MESSAGE("SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : ""));
+ return true;
+}