+void SMESH_Gen_i::SetOption(const char* name, const char* value)
+{
+ if ( name && value && strlen( value ) > 0 )
+ {
+ string msgToGUI;
+ if ( strcmp(name, "historical_python_dump") == 0 )
+ {
+ myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+ msgToGUI = "preferences/SMESH/historical_python_dump/";
+ msgToGUI += myIsHistoricalPythonDump ? "true" : "false";
+ }
+ else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+ {
+ myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+ msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/";
+ msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false";
+ }
+ else if ( strcmp(name, "default_grp_color") == 0 )
+ {
+ vector<int> color;
+ string str = value;
+ // color must be presented as a string of next form:
+ if ( str.at(0) == '#' && str.length() == 7 ) { // hexadecimal color ("#ffaa00", for example)
+ str = str.substr(1);
+ for ( size_t i = 0; i < str.length()/2; i++ )
+ if ( str.at(i*2) >= '0' && str.at(i*2) <= 'f' && str.at(i*2+1) >= '0' && str.at(i*2+1) <= 'f' )
+ color.push_back( strtol( str.substr( i*2, 2 ).c_str(), NULL, 16 ) );
+ }
+ else { // rgb color ("255,170,0", for example)
+ char* tempValue = strdup( value );
+ char* colorValue = strtok( tempValue, "," );
+ while ( colorValue != NULL ) {
+ int c_value = atoi( colorValue );
+ if ( c_value >= 0 && c_value <= 255 )
+ color.push_back( c_value );
+ colorValue = strtok( NULL, "," );
+ }
+ }
+ if ( color.size() == 3 ) { // color must have three valid component
+ SMESHDS_GroupBase::SetDefaultColor( Quantity_Color( color[0]/255., color[1]/255., color[2]/255., Quantity_TOC_RGB ) );
+ myDefaultGroupColor = value;
+ msgToGUI = "preferences/SMESH/default_grp_color/";
+ msgToGUI += value;
+ }
+ }
+
+ // update preferences in case if SetOption() is invoked from python console
+ if ( !msgToGUI.empty() )
+ {
+ CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" );
+ SALOME::Session_var session = SALOME::Session::_narrow( obj );
+ if ( !CORBA::is_nil( session ) )
+ session->emitMessageOneWay(msgToGUI.c_str());
+ }
+ }
+}
+
+//=============================================================================
+/*!
+ Return an option value
+*/
+//=============================================================================
+
+char* SMESH_Gen_i::GetOption(const char* name)
+{
+ if ( name )
+ {
+ if ( strcmp(name, "historical_python_dump") == 0 )
+ {
+ return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" );
+ }
+ if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+ {
+ return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" );
+ }
+ if ( strcmp(name, "default_grp_color") == 0 )
+ {
+ return CORBA::string_dup( myDefaultGroupColor.c_str() );
+ }
+ }
+ return CORBA::string_dup( "" );
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMesh
+ *
+ * Create empty mesh on a shape and publish it in the study
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = this->createMesh();
+ // set shape
+ SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
+ ASSERT( meshServant );
+ meshServant->SetShape( theShapeObject );
+
+ // publish mesh in the study
+ if ( CanPublishInStudy( mesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")";
+ }
+ }
+
+ return mesh._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateEmptyMesh
+ *
+ * Create empty mesh
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = this->createMesh();
+
+ // publish mesh in the study
+ if ( CanPublishInStudy( mesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << aSO << " = " << this << ".CreateEmptyMesh()";
+ }
+ }
+
+ return mesh._retn();
+}
+
+namespace
+{
+ //================================================================================
+ /*!
+ * \brief Throws an exception in case if the file can't be read
+ */
+ //================================================================================
+
+ void checkFileReadable( const char* theFileName ) throw ( SALOME::SALOME_Exception )
+ {
+ SMESH_File f ( theFileName );
+ if ( !f )
+ {
+ if ( !f.error().empty() )
+ THROW_SALOME_CORBA_EXCEPTION( f.error().c_str(), SALOME::BAD_PARAM);
+
+ THROW_SALOME_CORBA_EXCEPTION
+ (( SMESH_Comment("Can't open for reading the file ") << theFileName ).c_str(),
+ SALOME::BAD_PARAM );
+ }
+ }
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMeshFromUNV
+ *
+ * Create mesh and import data from UNV file
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ checkFileReadable( theFileName );
+
+ SMESH::SMESH_Mesh_var aMesh = createMesh();
+ string aFileName;
+ // publish mesh in the study
+ if ( CanPublishInStudy( aMesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')";
+ }
+ }
+
+ SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
+ ASSERT( aServant );
+ aServant->ImportUNVFile( theFileName );
+
+ // Dump creation of groups
+ SMESH::ListOfGroups_var groups = aServant->GetGroups();
+
+ aServant->GetImpl().GetMeshDS()->Modified();
+ return aMesh._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMeshFromMED
+ *
+ * Create mesh and import data from MED file
+ */
+//=============================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus,
+ const char* theCommandNameForPython,
+ const char* theFileNameForPython)
+{
+#ifdef WIN32
+ char bname[ _MAX_FNAME ];
+ _splitpath( theFileNameForPython, NULL, NULL, bname, NULL );
+ string aFileName = bname;
+#else
+ string aFileName = basename( theFileNameForPython );
+#endif
+ // Retrieve mesh names from the file
+ DriverMED_R_SMESHDS_Mesh myReader;
+ myReader.SetFile( theFileName );
+ myReader.SetMeshId( -1 );
+ Driver_Mesh::Status aStatus;
+ list<string> aNames = myReader.GetMeshNames(aStatus);
+ SMESH::mesh_array_var aResult = new SMESH::mesh_array();
+ theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
+
+ { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
+
+ // Python Dump
+ TPythonDump aPythonDump;
+ aPythonDump << "([";
+
+ if (theStatus == SMESH::DRS_OK) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder;
+ if ( GetCurrentStudyID() > -1 )
+ {
+ aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ }
+ aResult->length( aNames.size() );
+ int i = 0;
+
+ // Iterate through all meshes and create mesh objects
+ for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ )
+ {
+ // Python Dump
+ if (i > 0) aPythonDump << ", ";
+
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = createMesh();
+
+ // publish mesh in the study
+ SALOMEDS::SObject_wrap aSO;
+ if ( CanPublishInStudy( mesh ) )
+ // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV
+ // - as names of meshes are stored in MED file, we use them for data publishing
+ // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data
+ aSO = PublishMesh( myCurrentStudy, mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() );
+ if ( !aSO->_is_nil() ) {
+ // Python Dump
+ aPythonDump << aSO;
+ } else {
+ // Python Dump
+ aPythonDump << "mesh_" << i;
+ }
+
+ // Read mesh data (groups are published automatically by ImportMEDFile())
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+ ASSERT( meshServant );
+ SMESH::DriverMED_ReadStatus status1 =
+ meshServant->ImportMEDFile( theFileName, (*it).c_str() );
+ if (status1 > theStatus)
+ theStatus = status1;
+
+ aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+ meshServant->GetImpl().GetMeshDS()->Modified();
+ }
+ if ( !aStudyBuilder->_is_nil() )
+ aStudyBuilder->CommitCommand();
+ }
+
+ // Update Python script
+ aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')";
+ }
+ // Dump creation of groups
+ for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
+ SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
+
+ return aResult._retn();
+}
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ checkFileReadable( theFileName );
+
+ SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName);
+ return result;
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMeshFromSAUV
+ *
+ * Create mesh and import data from SAUV file
+ */
+//=============================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ checkFileReadable( theFileName );
+
+ std::string sauvfilename(theFileName);
+ std::string medfilename(theFileName);
+ medfilename += ".med";
+ std::string cmd;
+#ifdef WIN32
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+ SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str());
+#ifdef WIN32
+ cmd = "%PYTHONBIN% ";
+#else
+ cmd = "python ";
+#endif
+ cmd += "-c \"";
+ cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+ cmd += "\"";
+ system(cmd.c_str());
+ return result;
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::CreateMeshFromSTL
+ *
+ * Create mesh and import data from STL file
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ checkFileReadable( theFileName );
+
+ SMESH::SMESH_Mesh_var aMesh = createMesh();
+ //string aFileName;
+#ifdef WIN32
+ char bname[ _MAX_FNAME ];
+ _splitpath( theFileName, NULL, NULL, bname, NULL );
+ string aFileName = bname;
+#else
+ string aFileName = basename( theFileName );
+#endif
+ // publish mesh in the study
+ if ( CanPublishInStudy( aMesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_wrap aSO = PublishInStudy
+ ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')";
+ }
+ }
+
+ SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
+ ASSERT( aServant );
+ aServant->ImportSTLFile( theFileName );
+ aServant->GetImpl().GetMeshDS()->Modified();
+ return aMesh._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Create meshes and import data from the CGSN file
+ */
+//================================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
+ SMESH::DriverMED_ReadStatus& theStatus)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ checkFileReadable( theFileName );
+
+ SMESH::mesh_array_var aResult = new SMESH::mesh_array();
+
+#ifdef WITH_CGNS
+ // Retrieve nb meshes from the file
+ DriverCGNS_Read myReader;
+ myReader.SetFile( theFileName );
+ Driver_Mesh::Status aStatus;
+ int nbMeshes = myReader.GetNbMeshes(aStatus);
+ theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
+
+ aResult->length( nbMeshes );
+
+ { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
+
+ // Python Dump
+ TPythonDump aPythonDump;
+ aPythonDump << "([";
+
+ if (theStatus == SMESH::DRS_OK)
+ {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+
+ int i = 0;
+
+ // Iterate through all meshes and create mesh objects
+ for ( ; i < nbMeshes; ++i )
+ {
+ // Python Dump
+ if (i > 0) aPythonDump << ", ";
+
+ // create mesh
+ SMESH::SMESH_Mesh_var mesh = createMesh();
+ aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh );
+
+ // Read mesh data (groups are published automatically by ImportMEDFile())
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+ ASSERT( meshServant );
+ string meshName;
+ SMESH::DriverMED_ReadStatus status1 =
+ meshServant->ImportCGNSFile( theFileName, i, meshName );
+ if (status1 > theStatus)
+ theStatus = status1;
+
+ meshServant->GetImpl().GetMeshDS()->Modified();
+ // publish mesh in the study
+ SALOMEDS::SObject_wrap aSO;
+ if ( CanPublishInStudy( mesh ) )
+ aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() );
+
+ // Python Dump
+ if ( !aSO->_is_nil() ) {
+ aPythonDump << aSO;
+ }
+ else {
+ aPythonDump << "mesh_" << i;
+ }
+ }
+ aStudyBuilder->CommitCommand();
+ }
+
+ aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')";
+ }
+ // Dump creation of groups
+ for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
+ SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
+#else
+ THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
+#endif
+
+ return aResult._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Create a mesh and import data from a GMF file
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::CreateMeshesFromGMF( const char* theFileName,
+ CORBA::Boolean theMakeRequiredGroups,
+ SMESH::ComputeError_out theError)
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ checkFileReadable( theFileName );
+
+ SMESH::SMESH_Mesh_var aMesh = createMesh();
+#ifdef WIN32
+ char bname[ _MAX_FNAME ];
+ _splitpath( theFileName, NULL, NULL, bname, NULL );
+ string aFileName = bname;
+#else
+ string aFileName = basename( theFileName );
+#endif
+ // publish mesh in the study
+ if ( CanPublishInStudy( aMesh ) ) {
+ SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+ aStudyBuilder->NewCommand(); // There is a transaction
+ SALOMEDS::SObject_wrap aSO = PublishInStudy
+ ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
+ aStudyBuilder->CommitCommand();
+ if ( !aSO->_is_nil() ) {
+ // Update Python script
+ TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'"
+ << theFileName << "', "
+ << theMakeRequiredGroups << " )";
+ }
+ }
+ SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
+ ASSERT( aServant );
+ theError = aServant->ImportGMFFile( theFileName, theMakeRequiredGroups );
+ aServant->GetImpl().GetMeshDS()->Modified();
+ return aMesh._retn();
+}
+
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::IsReadyToCompute
+ *
+ * Returns true if mesh contains enough data to be computed
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
+
+ if ( CORBA::is_nil( theShapeObject ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ try {
+ // get mesh servant
+ SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ // get local TopoDS_Shape
+ TopoDS_Shape myLocShape = GeomObjectToShape( theShapeObject );
+ // call implementation
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ return myGen.CheckAlgoState( myLocMesh, myLocShape );
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Find SObject for an algo
+ */
+//================================================================================
+
+SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
+{
+ if ( algo ) {
+ if ( !myCurrentStudy->_is_nil() ) {
+ // find algo in the study
+ CORBA::String_var compDataType = ComponentDataType();
+ SALOMEDS::SComponent_wrap father = myCurrentStudy->FindComponent( compDataType.in() );
+ if ( !father->_is_nil() ) {
+ SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( father );
+ for ( ; itBig->More(); itBig->Next() ) {
+ SALOMEDS::SObject_wrap gotBranch = itBig->Value();
+ if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
+ SALOMEDS::ChildIterator_wrap algoIt = myCurrentStudy->NewChildIterator( gotBranch );
+ for ( ; algoIt->More(); algoIt->Next() ) {
+ SALOMEDS::SObject_wrap algoSO = algoIt->Value();
+ CORBA::Object_var algoIOR = SObjectToObject( algoSO );
+ if ( !CORBA::is_nil( algoIOR )) {
+ SMESH_Hypothesis_i* impl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
+ if ( impl && impl->GetImpl() == algo )
+ return algoSO._retn();
+ }
+ } // loop on algo SO's
+ break;
+ } // if algo tag
+ } // SMESH component iterator
+ }
+ }
+ }
+ return SALOMEDS::SObject::_nil();
+}
+
+//================================================================================
+/*!
+ * \brief Return errors of mesh computation
+ */
+//================================================================================
+
+SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theSubObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" );
+
+ if ( CORBA::is_nil( theSubObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+ SMESH::compute_error_array_var error_array = new SMESH::compute_error_array;
+ try {
+ if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
+ {
+ TopoDS_Shape shape;
+ if(theMesh->HasShapeToMesh())
+ shape = GeomObjectToShape( theSubObject );
+ else
+ shape = SMESH_Mesh::PseudoShape();
+
+ ::SMESH_Mesh& mesh = meshServant->GetImpl();
+
+ error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
+ int nbErr = 0;
+
+ SMESH_subMesh *sm = mesh.GetSubMesh(shape);
+ const bool includeSelf = true, complexShapeFirst = true;
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
+ complexShapeFirst);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ // if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
+ // break;
+ SMESH_ComputeErrorPtr error = sm->GetComputeError();
+ if ( error && !error->IsOK() )
+ {
+ if ( !( error->myAlgo ) &&
+ !( error->myAlgo = sm->GetAlgo() ))
+ continue;
+ SMESH::ComputeError & errStruct = error_array[ nbErr++ ];
+ errStruct.code = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
+ errStruct.comment = error->myComment.c_str();
+ errStruct.subShapeID = sm->GetId();
+ SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->myAlgo );
+ if ( !algoSO->_is_nil() ) {
+ CORBA::String_var algoName = algoSO->GetName();
+ errStruct.algoName = algoName;
+ }
+ else {
+ errStruct.algoName = error->myAlgo->GetName();
+ }
+ errStruct.hasBadMesh = !error->myBadElements.empty();
+ }
+ }
+ error_array->length( nbErr );
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+
+ return error_array._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Return mesh elements preventing computation of a subshape
+ */
+//================================================================================
+
+SMESH::MeshPreviewStruct*
+SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
+ CORBA::Short theSubShapeID )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetBadInputElements()" );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+ SMESH::MeshPreviewStruct_var result = new SMESH::MeshPreviewStruct;
+ try {
+ // mesh servant
+ if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
+ {
+ // mesh implementation
+ ::SMESH_Mesh& mesh = meshServant->GetImpl();
+ // submesh by subshape id
+ if ( SMESH_subMesh * sm = mesh.GetSubMeshContaining( theSubShapeID ))
+ {
+ // compute error
+ SMESH_ComputeErrorPtr error = sm->GetComputeError();
+ if ( error && !error->myBadElements.empty())
+ {
+ typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
+ typedef TNode2LocalIDMap::iterator TNodeLocalID;
+
+ // get nodes of elements and count elements
+ TNode2LocalIDMap mapNode2LocalID;
+ list< TNodeLocalID > connectivity;
+ int i, nbElements = 0, nbConnNodes = 0;
+
+ list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
+ list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
+ for ( ; elemIt != elemEnd; ++elemIt, ++nbElements )
+ {
+ SMDS_ElemIteratorPtr nIt = (*elemIt)->nodesIterator();
+ while ( nIt->more() )
+ connectivity.push_back
+ ( mapNode2LocalID.insert( make_pair( nIt->next(), ++nbConnNodes)).first );
+ }
+ // fill node coords and assign local ids to the nodes
+ int nbNodes = mapNode2LocalID.size();
+ result->nodesXYZ.length( nbNodes );
+ TNodeLocalID node2ID = mapNode2LocalID.begin();
+ for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
+ node2ID->second = i;
+ const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
+ result->nodesXYZ[i].x = node->X();
+ result->nodesXYZ[i].y = node->Y();
+ result->nodesXYZ[i].z = node->Z();
+ }
+ // fill connectivity
+ result->elementConnectivities.length( nbConnNodes );
+ list< TNodeLocalID >::iterator connIt = connectivity.begin();
+ for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
+ result->elementConnectivities[i] = (*connIt)->second;
+ }
+ // fill element types
+ result->elementTypes.length( nbElements );
+ for ( i = 0, elemIt = error->myBadElements.begin(); i <nbElements; ++i, ++elemIt )
+ {
+ const SMDS_MeshElement* elem = *elemIt;
+ result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) elem->GetType();
+ result->elementTypes[i].isPoly = elem->IsPoly();
+ result->elementTypes[i].nbNodesInElement = elem->NbNodes();
+ }
+ }
+ }
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+
+ return result._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Create a group of elements preventing computation of a sub-shape
+ */
+//================================================================================
+
+SMESH::ListOfGroups*
+SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
+ CORBA::Short theSubShapeID,
+ const char* theGroupName )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+
+ SMESH::ListOfGroups_var groups;
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+ try {
+ if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
+ {
+ groups = meshServant->MakeGroupsOfBadInputElements( theSubShapeID, theGroupName );
+ TPythonDump() << groups << " = " << this
+ << ".MakeGroupsOfBadInputElements( "
+ << theMesh << ", " << theSubShapeID << ", '" << theGroupName << "' )";
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+ return groups._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Returns errors of hypotheses definintion
+ * \param theMesh - the mesh
+ * \param theSubObject - the main or sub- shape
+ * \retval SMESH::algo_error_array* - sequence of errors
+ */
+//================================================================================
+
+SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theSubObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" );
+
+ if ( CORBA::is_nil( theSubObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+ SMESH::algo_error_array_var error_array = new SMESH::algo_error_array;
+ try {
+ SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
+ ASSERT( meshServant );
+ if ( meshServant ) {
+ TopoDS_Shape myLocShape;
+ if(theMesh->HasShapeToMesh())
+ myLocShape = GeomObjectToShape( theSubObject );
+ else
+ myLocShape = SMESH_Mesh::PseudoShape();
+
+ ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+ list< ::SMESH_Gen::TAlgoStateError > error_list;
+ list< ::SMESH_Gen::TAlgoStateError >::iterator error;
+ // call ::SMESH_Gen::GetAlgoState()
+ myGen.GetAlgoState( myLocMesh, myLocShape, error_list );
+ error_array->length( error_list.size() );
+ int i = 0;
+ for ( error = error_list.begin(); error != error_list.end(); ++error )
+ {
+ // fill AlgoStateError structure
+ SMESH::AlgoStateError & errStruct = error_array[ i++ ];
+ errStruct.state = SMESH_Mesh_i::ConvertHypothesisStatus( error->_name );
+ errStruct.algoDim = error->_algoDim;
+ errStruct.isGlobalAlgo = error->_isGlobalAlgo;
+ errStruct.algoName = "";
+ SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->_algo );
+ if ( !algoSO->_is_nil() ) {
+ CORBA::String_var algoName = algoSO->GetName();
+ errStruct.algoName = algoName.in();
+ }
+ }
+ }
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ INFOS( "catch exception "<< S_ex.what() );
+ }
+ return error_array._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::GetSubShapesId
+ *
+ * Get sub-shapes unique ID's list
+ */
+//=============================================================================
+
+SMESH::long_array*
+SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject,
+ const SMESH::object_array& theListOfSubShapeObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
+
+ SMESH::long_array_var shapesId = new SMESH::long_array;
+ set<int> setId;
+
+ if ( CORBA::is_nil( theMainShapeObject ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
+
+ try
+ {
+ TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
+ TopTools_IndexedMapOfShape myIndexToShape;
+ TopExp::MapShapes(myMainShape,myIndexToShape);
+
+ for ( CORBA::ULong i = 0; i < theListOfSubShapeObject.length(); i++ )
+ {
+ GEOM::GEOM_Object_var aShapeObject
+ = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]);
+ if ( CORBA::is_nil( aShapeObject ) )
+ THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \
+ SALOME::BAD_PARAM );
+
+ TopoDS_Shape locShape = GeomObjectToShape(aShapeObject);
+ for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
+ {
+ const TopoDS_Face& F = TopoDS::Face(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(F));
+ if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F));
+ }
+ for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next())
+ {
+ const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(E));
+ if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E));
+ }
+ for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next())
+ {
+ const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
+ setId.insert(myIndexToShape.FindIndex(V));
+ if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V));
+ }
+ }
+ shapesId->length(setId.size());
+ set<int>::iterator iind;
+ int i=0;
+ for (iind = setId.begin(); iind != setId.end(); iind++)
+ {
+ if(MYDEBUG) SCRUTE((*iind));
+ shapesId[i] = (*iind);
+ if(MYDEBUG) SCRUTE(shapesId[i]);
+ i++;
+ }
+ }
+ catch (SALOME_Exception& S_ex)
+ {
+ THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+ }
+
+ return shapesId._retn();
+}
+
+//=============================================================================
+/*!
+ * SMESH_Gen_i::Compute
+ *
+ * Compute mesh on a shape
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
+ GEOM::GEOM_Object_ptr theShapeObject )
+ throw ( SALOME::SALOME_Exception )
+{
+ //MEMOSTAT;
+ Unexpect aCatch(SALOME_SalomeException);
+ if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
+
+ if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+ THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+ SALOME::BAD_PARAM );
+
+ if ( CORBA::is_nil( theMesh ) )
+ THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+ SALOME::BAD_PARAM );
+
+ // Update Python script
+ TPythonDump() << "isDone = " << this << ".Compute( "
+ << theMesh << ", " << theShapeObject << ")";
+
+ try {