X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_2smeshpy.cxx;h=b36b31c13ea6f5d95e6836ef8329aeba6a9ed0f3;hp=e7155c2157326b01eca798cf5cf649af80d2fbf4;hb=HEAD;hpb=7a713be33b27d6a8c77f983460f0e97e52c6ff7c diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index e7155c215..1e73de97a 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -33,8 +33,11 @@ #include #include +#include #include +#if OCC_VERSION_LARGE < 0x07050000 #include +#endif #include "SMESH_Gen_i.hxx" /* SALOME headers that include CORBA headers that include windows.h @@ -50,22 +53,22 @@ #include #endif -IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient); -IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient); -IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient); -IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject); -IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis); -IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis); -IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis); -IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis); -IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis); +IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject) +IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis) +IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis) +IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis) +IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis) +IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis) using namespace std; using SMESH::TPythonDump; @@ -185,7 +188,7 @@ namespace { _AString comment; _pyID obj = cmd->GetObject(); - if ( obj.Search( "print " ) == 1 ) + if ( obj.Search( "print(" ) == 1 ) return; // print statement if ( !obj.IsEmpty() && obj.Value( obj.Length() ) == ')' ) @@ -296,6 +299,12 @@ namespace { // - FT_NodeConnectivityNumber= 22 // v 8.5.0: FT_Undefined == 49, new items: // - FT_Deflection2D = 22 + // v 9.3.0: FT_Undefined == 50, new items: + // - FT_Length3D = 22 + // v 9.12.0: FT_Undefined == 51, new items: + // - FT_ScaledJacobian = 8 + // v 9.12.0: FT_Undefined == 52, new items: + // - FT_Warping3D = 4 // // It's necessary to continue recording this history and to fill // undef2newItems (see below) accordingly. @@ -319,6 +328,9 @@ namespace { undef2newItems[ 47 ].push_back( 22 ); undef2newItems[ 48 ].push_back( 22 ); undef2newItems[ 49 ].push_back( 22 ); + undef2newItems[ 50 ].push_back( 22 ); + undef2newItems[ 51 ].push_back( 8 ); + undef2newItems[ 52 ].push_back( 4 ); ASSERT( undef2newItems.rbegin()->first == SMESH::FT_Undefined ); } @@ -360,7 +372,7 @@ namespace { //================================================================================ /*! * \brief Replaces "SMESH.PointStruct(x,y,z)" and "SMESH.DirStruct( SMESH.PointStruct(x,y,z))" - * arguments of a given command by a list "[x,y,z]" if the list is accesible + * arguments of a given command by a list "[x,y,z]" if the list is accessible * type of argument. */ //================================================================================ @@ -412,7 +424,7 @@ namespace { //================================================================================ /*! * \brief Replaces "mesh.GetIDSource([id1,id2])" argument of a given command by - * a list "[id1,id2]" if the list is an accesible type of argument. + * a list "[id1,id2]" if the list is an accessible type of argument. */ //================================================================================ @@ -443,6 +455,18 @@ namespace { } } } + + bool _FilterArg( const _AString& theArg ) + { + static std::list<_AString> filteredArgs; + static bool initialized = false; + if ( !initialized ) { + initialized = true; + filteredArgs.push_back( "SMESH.MED_V2_1" ); + filteredArgs.push_back( "SMESH.MED_V2_2" ); + } + return std::find( filteredArgs.begin(), filteredArgs.end(), theArg ) != filteredArgs.end(); + } } //================================================================================ @@ -464,7 +488,6 @@ SMESH_2smeshpy::ConvertScript(std::list< TCollection_AsciiString >& theScrip Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, std::set< TCollection_AsciiString >& theRemovedObjIDs, - SALOMEDS::Study_ptr& theStudy, const bool theToKeepAllCommands) { std::list< TCollection_AsciiString >::iterator lineIt; @@ -487,7 +510,6 @@ SMESH_2smeshpy::ConvertScript(std::list< TCollection_AsciiString >& theScrip theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames, theRemovedObjIDs, - theStudy, theToKeepAllCommands ); for ( lineIt = theScriptLines.begin(); lineIt != theScriptLines.end(); ++lineIt ) @@ -519,7 +541,6 @@ SMESH_2smeshpy::ConvertScript(std::list< TCollection_AsciiString >& theScrip set<_pyID> createdObjects; createdObjects.insert( "smeshBuilder" ); createdObjects.insert( "smesh" ); - createdObjects.insert( "theStudy" ); for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd ) { #ifdef DUMP_CONVERSION @@ -547,7 +568,6 @@ SMESH_2smeshpy::ConvertScript(std::list< TCollection_AsciiString >& theScrip _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod, Resource_DataMapOfAsciiStringAsciiString& theObjectNames, std::set< TCollection_AsciiString >& theRemovedObjIDs, - SALOMEDS::Study_ptr& theStudy, const bool theToKeepAllCommands) : _pyObject( new _pyCommand( "", 0 )), myNbCommands( 0 ), @@ -556,8 +576,8 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod myRemovedObjIDs( theRemovedObjIDs ), myNbFilters( 0 ), myToKeepAllCommands( theToKeepAllCommands ), - myStudy( SALOMEDS::Study::_duplicate( theStudy )), - myGeomIDNb(0), myGeomIDIndex(-1) + myGeomIDNb(0), myGeomIDIndex(-1), + myShaperIDNb(0), myShaperIDIndex(-1) { // make that GetID() to return TPythonDump::SMESHGenName() GetCreationCmd()->Clear(); @@ -565,30 +585,38 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod GetCreationCmd()->GetString() += "="; // Find 1st digit of study entry by which a GEOM object differs from a SMESH object - if ( !theObjectNames.IsEmpty() && !CORBA::is_nil( theStudy )) + if (!theObjectNames.IsEmpty()) { - // find a GEOM entry - _pyID geomID; - SALOMEDS::SComponent_wrap geomComp = theStudy->FindComponent("GEOM"); - if ( geomComp->_is_nil() ) return; - CORBA::String_var entry = geomComp->GetID(); - geomID = entry.in(); - - // find a SMESH entry - _pyID smeshID; - Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString e2n( theObjectNames ); - for ( ; e2n.More() && smeshID.IsEmpty(); e2n.Next() ) - if ( _pyCommand::IsStudyEntry( e2n.Key() )) - smeshID = e2n.Key(); - - // find 1st difference between smeshID and geomID - if ( !geomID.IsEmpty() && !smeshID.IsEmpty() ) - for ( int i = 1; i <= geomID.Length() && i <= smeshID.Length(); ++i ) - if ( geomID.Value( i ) != smeshID.Value( i )) - { - myGeomIDNb = geomID.Value( i ); - myGeomIDIndex = i; - } + // find a GEOM (aPass == 0) and SHAPERSTUDY (aPass == 1) entries + for(int aPass = 0; aPass < 2; aPass++) { + _pyID geomID; + SALOMEDS::SComponent_wrap geomComp = SMESH_Gen_i::GetSMESHGen()->getStudyServant()-> + FindComponent(aPass == 0 ? "GEOM" : "SHAPERSTUDY"); + if (geomComp->_is_nil()) continue; + CORBA::String_var entry = geomComp->GetID(); + geomID = entry.in(); + + // find a SMESH entry + _pyID smeshID; + Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString e2n(theObjectNames); + for (; e2n.More() && smeshID.IsEmpty(); e2n.Next()) + if (_pyCommand::IsStudyEntry(e2n.Key())) + smeshID = e2n.Key(); + + // find 1st difference between smeshID and geomID + if (!geomID.IsEmpty() && !smeshID.IsEmpty()) + for (int i = 1; i <= geomID.Length() && i <= smeshID.Length(); ++i) + if (geomID.Value(i) != smeshID.Value(i)) + { + if (aPass == 0) { + myGeomIDNb = geomID.Value(i); + myGeomIDIndex = i; + } else { + myShaperIDNb = geomID.Value(i); + myShaperIDIndex = i; + } + } + } } } @@ -672,6 +700,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) { this->Process( aCommand ); + //addFilterUser( aCommand, theGen ); // protect filters from clearing return aCommand; } @@ -691,7 +720,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand _AString newCmd = indent + tab + ( aCommand->GetString().ToCString() + indent.Length() ); _AString pasCmd = indent + tab + "pass"; // to keep valid if newCmd is erased _AString excStr = indent + "except:"; - _AString msgStr = indent + "\tprint '"; msgStr += method + "() failed. Invalid file name?'"; + _AString msgStr = indent + "\tprint('"; msgStr += method + "() failed. Invalid file name?')"; myCommands.insert( --myCommands.end(), new _pyCommand( tryStr, myNbCommands )); aCommand->Clear(); @@ -740,7 +769,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand meshID = aCommand->GetResultValue(); else if ( method == "MakeBoundaryMesh") meshID = aCommand->GetResultValue(1); - else if ( method == "MakeBoundaryElements") + else if ( method == "MakeBoundaryElements" || method == "MakeBoundaryOfEachElement" ) meshID = aCommand->GetResultValue(2); if ( method.Search("MakeGroups") != -1 || @@ -757,7 +786,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand groups = aCommand->GetResultValue(); else if ( method == "MakeBoundaryMesh" ) groups = aCommand->GetResultValue(2); - else if ( method == "MakeBoundaryElements") + else if ( method == "MakeBoundaryElements" || method == "MakeBoundaryOfEachElement" ) groups = aCommand->GetResultValue(3); else if ( method == "Create0DElementsOnAllNodes" && aCommand->GetArg(2).Length() > 2 ) // group name != '' @@ -910,10 +939,13 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand "Geom_POLYHEDRA", "Geom_BALL" }; if ( -1 < iGeom && iGeom < nbTypes ) Threshold = SMESH + types[ iGeom ]; -#ifdef _DEBUG_ - // is types complete? (compilation failure mains that enum GeometryType changed) - int _asrt[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 2 : -1 ]; _asrt[0]=_asrt[1]; -#endif + + if (SALOME::VerbosityActivated()) + { + // is types complete? (compilation failure means that enum GeometryType changed) + static_assert( sizeof(types) / sizeof(const char*) == nbTypes, + "Update names of GeometryType's!!!" ); + } } if (Type == "SMESH.FT_EntityType") { @@ -930,10 +962,13 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" }; if ( -1 < iGeom && iGeom < nbTypes ) Threshold = SMESH + types[ iGeom ]; -#ifdef _DEBUG_ - // is 'types' complete? (compilation failure mains that enum EntityType changed) - int _asrt[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 2 : -1 ]; _asrt[0]=_asrt[1]; -#endif + + if (SALOME::VerbosityActivated()) + { + // is 'types' complete? (compilation failure means that enum EntityType changed) + static_assert( sizeof(types) / sizeof(const char*) == nbTypes, + "Update names of EntityType's!!!" ); + } } } if ( ThresholdID.Length() != 2 ) // neither '' nor "" @@ -981,6 +1016,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) // Concatenate( [mesh1, ...], ... ) // CreateHypothesis( theHypType, theLibName ) // Compute( mesh, geom ) + // CheckCompute( mesh ) // Evaluate( mesh, geom ) // mesh creation TCollection_AsciiString method = theCommand->GetMethod(); @@ -989,20 +1025,25 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) { Handle(_pyMesh) mesh = new _pyMesh( theCommand ); AddObject( mesh ); + // set mesh name + _pyID id = mesh->GetID(), comma("'"); + if ( myObjectNames.IsBound( id )) + theCommand->SetArg( theCommand->GetNbArgs() + 1, + comma + myObjectNames( id ) + comma); return; } if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || + method == "CreateDualMesh" || method == "CopyMesh" ) // command result is a mesh { Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() ); AddObject( mesh ); return; } - if( method == "CreateMeshesFromMED" || - method == "CreateMeshesFromSAUV"|| - method == "CreateMeshesFromCGNS" || - method == "CreateMeshesFromGMF" ) // command result is ( [mesh1,mesh2], status ) + if ( method == "CreateMeshesFromMED" || + method == "CreateMeshesFromCGNS" || + method == "CreateMeshesFromGMF" ) // command result is ( [mesh1,mesh2], status ) { std::list< _pyID > meshIDs = theCommand->GetStudyEntries( theCommand->GetResultValue() ); std::list< _pyID >::iterator meshID = meshIDs.begin(); @@ -1020,6 +1061,12 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) theCommand->SetArg( 1, file ); } } + if ( method == "CopyMeshWithGeom" ) + { + std::list< _pyID > entries = theCommand->GetStudyEntries( theCommand->GetResultValue() ); + Handle(_pyMesh) mesh = new _pyMesh( theCommand, entries.front() ); + AddObject( mesh ); + } // CreateHypothesis() if ( method == "CreateHypothesis" ) @@ -1054,6 +1101,21 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) } } + // smeshgen.CheckCompute( mesh ) --> mesh.CheckCompute() + if ( method == "CheckCompute" ) + { + const _pyID& meshID = theCommand->GetArg( 1 ); + map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID ); + if ( id_mesh != myMeshes.end() ) { + theCommand->SetObject( meshID ); + theCommand->RemoveArgs(); + id_mesh->second->Process( theCommand ); + id_mesh->second->AddProcessedCmd( theCommand ); + return; + } + } + + // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom) if ( method == "Evaluate" ) { @@ -1082,9 +1144,21 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) // Concatenate( [mesh1, ...], ... ) else if ( method == "Concatenate" || method == "ConcatenateWithGroups") { + // OLD IDL: ( meshes, uniteGroups, toMerge, tol ) + // IDL: ( meshes, uniteGroups, toMerge, tol, meshToAppendTo ) + // PY: ( meshes, uniteGroups, toMerge, tol, allGroups=False, name="", meshToAppendTo=None ) + _pyID appendMesh = theCommand->GetArg( 5 ); if ( method == "ConcatenateWithGroups" ) { theCommand->SetMethod( "Concatenate" ); - theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" ); + theCommand->SetArg( 5, "True" ); + } + else { + theCommand->SetArg( 5, "False" ); + } + if ( !appendMesh.IsEmpty() && appendMesh != "None" ) + { + appendMesh.Insert( 1, "meshToAppendTo=" ); + theCommand->SetArg( theCommand->GetNbArgs() + 1, appendMesh ); } Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() ); AddObject( mesh ); @@ -1105,7 +1179,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) static TStringSet smeshpyMethods; if ( smeshpyMethods.empty() ) { const char * names[] = - { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy", + { "SetEmbeddedMode","IsEmbeddedMode","UpdateStudy","GetStudy", "GetPattern","GetSubShapesId", "" }; // <- mark of array end smeshpyMethods.Insert( names ); @@ -1193,7 +1267,7 @@ void _pyGen::Flush() */ //================================================================================ -void _pyGen::PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const +void _pyGen::PlaceSubmeshAfterItsCreation( Handle(_pyCommand) /*theCmdUsingSubmesh*/ ) const { // map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.begin(); // for ( ; id_obj != myObjects.end(); ++id_obj ) @@ -1652,13 +1726,11 @@ Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID ) const bool _pyGen::IsGeomObject(const _pyID& theObjID) const { - if ( myGeomIDNb ) - { - return ( myGeomIDIndex <= theObjID.Length() && - int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb && - _pyCommand::IsStudyEntry( theObjID )); - } - return false; + bool isGeom = myGeomIDNb && myGeomIDIndex <= theObjID.Length() && + int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb; + bool isShaper = myShaperIDNb && myShaperIDIndex <= theObjID.Length() && + int( theObjID.Value( myShaperIDIndex )) == myShaperIDNb; + return ((isGeom || isShaper) && _pyCommand::IsStudyEntry( theObjID )); } //================================================================================ @@ -1677,7 +1749,7 @@ bool _pyGen::IsNotPublished(const _pyID& theObjID) const // either the SMESH object is not in study or it is a GEOM object if ( IsGeomObject( theObjID )) { - SALOMEDS::SObject_wrap so = myStudy->FindObjectID( theObjID.ToCString() ); + SALOMEDS::SObject_wrap so = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( theObjID.ToCString() ); if ( so->_is_nil() ) return true; CORBA::Object_var obj = so->GetObject(); return CORBA::is_nil( obj ); @@ -1776,14 +1848,15 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId): } else if ( theCreationCmd->GetMethod().Search("MakeMesh") != -1 || theCreationCmd->GetMethod() == "MakeBoundaryMesh" || - theCreationCmd->GetMethod() == "MakeBoundaryElements" ) + theCreationCmd->GetMethod() == "MakeBoundaryElements" || + theCreationCmd->GetMethod() == "MakeBoundaryOfEachElement" ) { // this mesh depends on a source mesh // (theCreationCmd is already Process()ed by _pyMeshEditor) const _pyID& meshID = theCreationCmd->GetObject(); addFatherMesh( meshID ); } - + // convert my creation command Handle(_pyCommand) creationCmd = GetCreationCmd(); creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); @@ -1799,7 +1872,7 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId): void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) { - // some methods of SMESH_Mesh interface needs special conversion + // some methods of SMESH_Mesh interface need special conversion // to methods of Mesh python class // // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo) @@ -1852,6 +1925,31 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) } Flush(); } + // in snapshot mode, clear the previous CheckCompute() + else if ( method == "CheckCompute" ) + { + if ( !theGen->IsToKeepAllCommands() ) // !historical + { + if ( !myLastCheckCmd.IsNull() ) + { + // check if the previously computed mesh has been edited, + // if so then we do not clear the previous Compute() + bool toClear = true; + list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin(); + for ( ; e != myEditors.end() && toClear; ++e ) + { + list< Handle(_pyCommand)>& cmds = (*e)->GetProcessedCmds(); + list< Handle(_pyCommand) >::reverse_iterator cmd = cmds.rbegin(); + if ( cmd != cmds.rend() && + (*cmd)->GetOrderNb() > myLastCheckCmd->GetOrderNb() ) + toClear = false; + } + if ( toClear ) + myLastCheckCmd->Clear(); + } + myLastCheckCmd = theCommand; + } + } // ---------------------------------------------------------------------- else if ( method == "Clear" ) // in snapshot mode, clear all previous commands { @@ -1943,7 +2041,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) if ( !obj->CanClear() ) allGroupsRemoved = false; } - if ( nbGroupsBefore == myGroups.size() ) // no new _pyGroup created + if ( nbGroupsBefore == myGroups.size() && !obj.IsNull() ) // no new _pyGroup created obj->AddProcessedCmd( theCommand ); // to clear theCommand if all groups are removed if ( !allGroupsRemoved && !theGen->IsToKeepAllCommands() ) @@ -1952,7 +2050,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) // if GetGroups() is just after Compute(), this can mean that the groups // were created by some algorithm and hence Compute() should not be discarded std::list< Handle(_pyCommand) >& cmdList = theGen->GetCommands(); - std::list< Handle(_pyCommand) >::iterator cmd = cmdList.begin(); + std::list< Handle(_pyCommand) >::reverse_iterator cmd = cmdList.rbegin(); while ( (*cmd)->GetMethod() == "GetGroups" ) ++cmd; if ( myLastComputeCmd == (*cmd)) @@ -1980,16 +2078,26 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) // ---------------------------------------------------------------------- else if ( theCommand->MethodStartsFrom( "Export" )) { - if ( method == "ExportToMED" || // ExportToMED() --> ExportMED() - method == "ExportToMEDX" ) // ExportToMEDX() --> ExportMED() + if ( method == "ExportToMED" || // ExportToMED() --> ExportMED() + method == "ExportToMEDX" || // ExportToMEDX() --> ExportMED() + method == "ExportMED" ) { theCommand->SetMethod( "ExportMED" ); - if ( theCommand->GetNbArgs() == 5 ) + // filter out deprecated version parameter + vector< _AString > args; + for ( int i = 1; i <= theCommand->GetNbArgs(); i++ ) { + if ( !_FilterArg( theCommand->GetArg( i ) ) ) + args.push_back( theCommand->GetArg( i ) ); + } + theCommand->RemoveArgs(); + for ( unsigned int i = 0; i < args.size(); i++ ) + theCommand->SetArg( i+1, args[i] ); + if ( theCommand->GetNbArgs() == 4 ) { // ExportToMEDX(...,autoDimension) -> ExportToMEDX(...,meshPart=None,autoDimension) - _AString autoDimension = theCommand->GetArg( 5 ); - theCommand->SetArg( 5, "None" ); - theCommand->SetArg( 6, autoDimension ); + _AString autoDimension = theCommand->GetArg( 4 ); + theCommand->SetArg( 4, "None" ); + theCommand->SetArg( 5, autoDimension ); } } else if ( method == "ExportCGNS" ) @@ -2015,12 +2123,32 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) TCollection_AsciiString newMethod = method; newMethod.Remove( /*where=*/7, /*howmany=*/6 ); theCommand->SetMethod( newMethod ); - // make the 1st arg be the last one (or last but three for ExportMED()) - _pyID partID = theCommand->GetArg( 1 ); - int nbArgs = theCommand->GetNbArgs() - 3 * (newMethod == "ExportMED"); - for ( int i = 2; i <= nbArgs; ++i ) - theCommand->SetArg( i-1, theCommand->GetArg( i )); - theCommand->SetArg( nbArgs, partID ); + // replace version parameter by minor + std::list< _AString > args; + for ( int i = 1; i <= theCommand->GetNbArgs(); i++ ) { + if ( _FilterArg( theCommand->GetArg( i ))) + args.push_back( "minor=0"); + else + args.push_back( theCommand->GetArg( i )); + } + // check the 1st arg meshPart, it must be SMESH_IDSource + _AString meshPart = args.front(); + if ( _pyCommand::IsStudyEntry( meshPart ) || + meshPart.Search( "Filter" ) > 0 || + meshPart.Search( "GetIDSource" ) > 0 || + meshPart.Search( "meshPart" ) > 0 ) + { + // set the 1st arg meshPart + // - to 5th place for ExportMED command + // - to last place for the rest commands + std::list< _AString >::iterator newPos = args.end(); + if ( newMethod == "ExportMED" ) + std::advance( newPos = args.begin(), 5 ); + args.splice( newPos, args, args.begin() ); + } + std::list< _AString >::iterator a = args.begin(); + for ( unsigned int i = 1; a != args.end(); ++i, ++a ) + theCommand->SetArg( i, *a ); } // remember file name theGen->AddExportedMesh( theCommand->GetArg( 1 ), @@ -2089,7 +2217,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) else if ( method == "GetMeshOrder" || method == "SetMeshOrder" ) { // make commands GetSubMesh() returning sub-meshes be before using sub-meshes - // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh() + // by GetMeshOrder() and SetMeshOrder(), since by default GetSubMesh() // commands are moved at the end of the script TCollection_AsciiString subIDs = ( method == "SetMeshOrder" ) ? theCommand->GetArg(1) : theCommand->GetResultValue(); @@ -2124,9 +2252,9 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = - { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents", + { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents", "GetGroups","UnionGroups","IntersectGroups","CutGroups","CreateDimGroup","GetLog","GetId", - "ClearLog","GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements", + "ClearLog","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements", "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles", "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes", "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder", @@ -2137,7 +2265,8 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", + "SetNbThreads", "CheckCompute" ,"" }; // <- mark of end sameMethods.Insert( names ); } @@ -2173,7 +2302,7 @@ void _pyMesh::Flush() list < Handle(_pyCommand) >::iterator cmd; // try to convert algo addition like this: - // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo() + // mesh.AddHypothesis( geom, ALGO ) --> ALGO = mesh.Algo() for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd ) { Handle(_pyCommand) addCmd = *cmd; @@ -2345,7 +2474,7 @@ void _pyMesh::ClearCommands() list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin(); for ( ; sm != mySubmeshes.end(); ++sm ) (*sm)->ClearCommands(); - + list< Handle(_pyGroup) >::iterator gr = myGroups.begin(); for ( ; gr != myGroups.end(); ++gr ) (*gr)->ClearCommands(); @@ -2417,11 +2546,11 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = { - "RemoveElements","RemoveNodes","RemoveOrphanNodes", + "RemoveElements","RemoveNodes","RemoveOrphanNodes","RemoveNodeWithReconnection", "AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall", - "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces", - "MoveNode", "MoveClosestNodeToPoint", - "InverseDiag","DeleteDiag","Reorient","ReorientObject","Reorient2DBy3D", + "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","AddNodeOnSegment", + "MoveNode", "MoveClosestNodeToPoint","InverseDiag","DeleteDiag","AddNodeOnFace", + "Reorient","ReorientObject","Reorient2DBy3D","Reorient2DByNeighbours", "TriToQuad","TriToQuadObject", "QuadTo4Tri", "SplitQuad","SplitQuadObject", "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject", "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements", @@ -2430,15 +2559,15 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) "ExtrusionByNormal", "ExtrusionSweepObject2D","ExtrusionAlongPath","ExtrusionAlongPathObject", "ExtrusionAlongPathX","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D", "ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects", - "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject", + "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject","Offset", "FindCoincidentNodes","MergeNodes","FindEqualElements","FillHole", "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders", "FindCoincidentFreeBorders", "SewCoincidentFreeBorders", "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes", - "GetLastCreatedElems", + "GetLastCreatedElems", "FaceGroupsSeparatedByEdges", "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh", "Scale","ScaleMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh", - "MakeBoundaryElements", "SplitVolumesIntoTetra","SplitHexahedraIntoPrisms", + "MakeBoundaryElements", "MakeBoundaryOfEachElement", "SplitVolumesIntoTetra","SplitHexahedraIntoPrisms", "DoubleElements","DoubleNodes","DoubleNode","DoubleNodeGroup","DoubleNodeGroups", "DoubleNodeElem","DoubleNodeElemInRegion","DoubleNodeElemGroup","AffectedElemGroupsInRegion", "DoubleNodeElemGroupInRegion","DoubleNodeElemGroups","DoubleNodeElemGroupsInRegion", @@ -2505,7 +2634,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) // 1. Remove "MakeGroups" from the Command TCollection_AsciiString aMethod = theCommand->GetMethod(); int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1; - + if(is0DmethObj) pos = pos-2; //Remove "0D" from the Command too aMethod.Trunc(pos-1); @@ -3015,7 +3144,7 @@ void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theComman // parameters are discriminated by method name _AString method = theCommand->GetMethod(); if ( myAccumulativeMethods.count( method )) - return; // this method adds values and not override the previus value + return; // this method adds values and not override the previous value // discriminate commands setting different parameters via one method // by passing parameter names like e.g. SetOption("size", "0.2") @@ -3047,7 +3176,7 @@ void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theComman //================================================================================ /*! - * \brief Return true if a setting parameter command ha been used to compute mesh + * \brief Return true if a setting parameter command has been used to compute mesh */ //================================================================================ @@ -3100,8 +3229,7 @@ void _pyHypothesis::ComputeDiscarded( const Handle(_pyCommand)& theComputeCmd ) continue; // check if a cmd is a sole command setting its parameter; // don't use method name for search as it can change - map >::iterator - m2cmds = myMeth2Commands.begin(); + map<_AString, list >::iterator m2cmds = myMeth2Commands.begin(); for ( ; m2cmds != myMeth2Commands.end(); ++m2cmds ) { list< Handle(_pyCommand)>& cmds = m2cmds->second; @@ -3337,7 +3465,7 @@ void _pyLayerDistributionHypo::Flush() list< Handle(_pyCommand) >::iterator cmd = myArgCommands.begin(); _pyID prevNewName; for ( cmd = myArgCommands.begin(); cmd != myArgCommands.end(); ++cmd ) - { + { const _pyID& hyp1dID = (*cmd)->GetArg( 1 ); if ( hyp1dID.IsEmpty() ) continue; @@ -3361,7 +3489,7 @@ void _pyLayerDistributionHypo::Flush() } newName += "_Distribution"; prevNewName = newName; - + hyp1d->GetCreationCmd()->SetResultValue( newName ); } list< Handle(_pyCommand) >& cmds = theGen->GetCommands(); @@ -3686,17 +3814,17 @@ const TCollection_AsciiString & _pyCommand::GetObject() if ( begPos < 1 ) { begPos = myString.Location( "=", 1, Length() ) + 1; // is '=' in the string argument (for example, name) or not - int nb1 = 0; // number of ' character at the left of = - int nb2 = 0; // number of " character at the left of = - for ( int i = 1; i < begPos-1; i++ ) { - if ( myString.Value( i )=='\'' ) - nb1 += 1; - else if ( myString.Value( i )=='"' ) - nb2 += 1; - } - // if number of ' or " is not divisible by 2, + int nb[4] = { 0, 0, 0, 0 }; // number of '"() character at the left of = + for ( int i = 1; i < begPos-1; i++ ) + switch ( myString.Value( i )) { + case '\'': nb[0]++; break; + case '"' : nb[1]++; break; + case '(' : nb[2]++; break; + case ')' : nb[3]++; break; + } + // if = is inside a string or a list // then get an object at the start of the command - if ( nb1 % 2 != 0 || nb2 % 2 != 0 ) + if ( nb[0] % 2 != 0 || nb[1] % 2 != 0 || nb[2] != nb[3]) begPos = 1; } else { @@ -3772,6 +3900,10 @@ bool _pyCommand::IsMethodCall() { if ( GetMethod().IsEmpty() ) return false; + if ( myString.StartsWith("#") ) + return false; + if ( myString.StartsWith("SHAPERSTUDY") ) // skip shaperstudy specific dump string analysis + return false; const char* s = myString.ToCString() + GetBegPos( METHOD_IND ) + myMeth.Length() - 1; return ( s[0] == '(' || s[1] == '(' ); } @@ -3871,7 +4003,7 @@ int _pyCommand::GetArgBeginning() const if ( pos == UNKNOWN ) { pos = GetBegPos( METHOD_IND ) + myMeth.Length(); - if ( pos < 1 ) + if ( pos < 1 && Length() >= 4 ) pos = myString.Location( "(", 4, Length() ); // 4 = strlen("b.c(") } return pos; @@ -3956,6 +4088,11 @@ TCollection_AsciiString _pyCommand::GetWord( const _AString & theString, } theStartPos = beg; //cout << theString << " ---- " << beg << " - " << end << endl; + if ( end > theString.Length() ) + { + theStartPos = EMPTY; + return theEmptyString; + } return theString.SubString( beg, end ); } @@ -4002,7 +4139,7 @@ bool _pyCommand::IsID( const TCollection_AsciiString& str ) //================================================================================ /*! - * \brief Finds entries in a sting + * \brief Finds entries in a string */ //================================================================================ @@ -4409,7 +4546,7 @@ _pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd, bool toKeepAgrC */ //================================================================================ -bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName) +bool _pySubMesh::CanBeArgOfMethod(const _AString& /*theMethodName*/) { return false; // names of all methods where a sub-mesh can be used as argument @@ -4549,7 +4686,7 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id) //================================================================================ /*! - * \brief Check if "[ group1, group2 ] = mesh.GetGroups()" creation command + * \brief Check if "[ group1, group2 ] = mesh.GetGroups()" creation command * can be cleared */ //================================================================================ @@ -4720,7 +4857,7 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand) if ( !myNewID.IsEmpty() ) theCommand->SetObject( myNewID ); - + // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria) // aFilter0x2aaab0487080 = aFilterManager.CreateFilter() // aFilter0x2aaab0487080.SetCriteria(aCriteria) @@ -4763,7 +4900,7 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand) void _pyFilter::Flush() { if ( myNewID.IsEmpty() ) return; - + list< Handle(_pyCommand) >::iterator cmd = myArgCmds.begin(); for ( ; cmd != myArgCmds.end(); ++cmd ) if ( !(*cmd)->IsEmpty() ) @@ -4900,7 +5037,7 @@ _pyHypothesisReader::_pyHypothesisReader() // ... // dim="2"> // - // + // // SetEnforcedVertex, // SetEnforcedVertexNamed // @@ -5000,40 +5137,33 @@ bool _pyStringFamily::Add( const char* str ) const int minPrefixSize = 4; // count "smaller" strings with the same prefix - std::list< _AString >::iterator itLess = itStr; --itLess; int nbLess = 0; - for ( ; itLess != _strings.end(); --itLess ) + std::list< _AString >::iterator itLess = itStr; + while ( itLess != _strings.begin() ) + { + --itLess; if ( strncmp( str, itLess->ToCString(), minPrefixSize ) == 0 ) ++nbLess; else + { + ++itLess; break; - ++itLess; + } + } + // itLess points to the 1st string with same prefix + // count "greater" strings with the same prefix - std::list< _AString >::iterator itMore = itStr; int nbMore = 0; + std::list< _AString >::iterator itMore = itStr; for ( ; itMore != _strings.end(); ++itMore ) if ( strncmp( str, itMore->ToCString(), minPrefixSize ) == 0 ) ++nbMore; else break; - --itMore; + // itMore points to the 1st string with greater prefix + if ( nbLess + nbMore > 1 ) // ------- ADD a NEW CHILD FAMILY ------------- { - // look for a maximal prefix length - // int lessPrefSize = 3, morePrefSize = 3; - // if ( nbLess > 0 ) - // while( itLess->ToCString()[ lessPrefSize ] == str[ lessPrefSize ] ) - // ++lessPrefSize; - // if ( nbMore > 0 ) - // while ( itMore->ToCString()[ morePrefSize ] == str[ morePrefSize ] ) - // ++morePrefSize; - // int prefixSize = 3; - // if ( nbLess == 0 ) - // prefixSize = morePrefSize; - // else if ( nbMore == 0 ) - // prefixSize = lessPrefSize; - // else - // prefixSize = Min( lessPrefSize, morePrefSize ); int prefixSize = minPrefixSize; _AString newPrefix ( str, prefixSize ); @@ -5054,9 +5184,9 @@ bool _pyStringFamily::Add( const char* str ) for ( ; nbMore > 0; --nbMore, ++itStr ) newSubFam._strings.push_back( itStr->ToCString() + prefixSize ); - _strings.erase( itLess, ++itMore ); + _strings.erase( itLess, itMore ); } - else // to few string to make a family fot them + else // too few string to make a family for them { _strings.insert( itStr, str ); } @@ -5130,7 +5260,7 @@ int _pyStringFamily::isIn( const char* str ) if (( len = itSub->isIn( str + itSub->_prefix.Length() )) >= 0 ) return itSub->_prefix.Length() + len; } - else if ( cmp > 0 ) + else if ( cmp < 0 ) break; } if ( !_strings.empty() )