-// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012 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
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : SMESH_2smeshpy.cxx
// Created : Fri Nov 18 13:20:10 2005
// Author : Edward AGAPOV (eap)
//
#include "SMESH_2smeshpy.hxx"
-#include "utilities.h"
#include "SMESH_PythonDump.hxx"
#include "SMESH_NoteBook.hxx"
#include "SMESH_Filter_i.hxx"
+#include <SALOMEDS_wrap.hxx>
+#include <utilities.h>
+
#include <Resource_DataMapOfAsciiStringAsciiString.hxx>
#include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
}
};
+ //================================================================================
+ /*!
+ * \brief Map of TCollection_AsciiString initialized by C array of C strings.
+ * Odd items of the C array are map keys, and even items are values
+ */
+ //================================================================================
+
+ struct TStringMap: public map<TCollection_AsciiString,TCollection_AsciiString>
+ {
+ /*!
+ * \brief Filling. The last string must be ""
+ */
+ void Insert(const char* names_values[]) {
+ for ( int i = 0; names_values[i][0] ; i += 2 )
+ insert( make_pair( (char*) names_values[i], names_values[i+1] ));
+ }
+ /*!
+ * \brief Check if a string is in
+ */
+ TCollection_AsciiString Value(const TCollection_AsciiString& name ) {
+ map< _AString, _AString >::iterator it = find( name );
+ return it == end() ? "" : it->second;
+ }
+ };
+
//================================================================================
/*!
* \brief Returns a mesh by object
for ( ; id != idList.end(); ++id )
presentObjects.insert( *id );
}
+
+ //================================================================================
+ /*!
+ * \brief Fix SMESH::FunctorType arguments of SMESH::Filter::Criterion()
+ */
+ //================================================================================
+
+ void fixFunctorType( TCollection_AsciiString& Type,
+ TCollection_AsciiString& Compare,
+ TCollection_AsciiString& UnaryOp,
+ TCollection_AsciiString& BinaryOp )
+ {
+ // The problem is that dumps of old studies created using filters becomes invalid
+ // when new items are inserted in the enum SMESH::FunctorType since values
+ // of this enum are dumped as integer values.
+ // This function corrects enum values of old studies given as args (Type,Compare,...)
+ // We can find out how to correct them by value of BinaryOp which can have only two
+ // values: FT_Undefined or FT_LogicalNOT.
+ // Hereafter is the history of the enum SMESH::FunctorType since v3.0.0
+ // where PythonDump appeared
+ // v 3.0.0: FT_Undefined == 25
+ // v 3.1.0: FT_Undefined == 26, new items:
+ // - FT_Volume3D = 7
+ // v 4.1.2: FT_Undefined == 27, new items:
+ // - FT_BelongToGenSurface = 17
+ // v 5.1.1: FT_Undefined == 32, new items:
+ // - FT_FreeNodes = 10
+ // - FT_FreeFaces = 11
+ // - FT_LinearOrQuadratic = 23
+ // - FT_GroupColor = 24
+ // - FT_ElemGeomType = 25
+ // v 5.1.5: FT_Undefined == 33, new items:
+ // - FT_CoplanarFaces = 26
+ // v 6.2.0: FT_Undefined == 39, new items:
+ // - FT_MaxElementLength2D = 8
+ // - FT_MaxElementLength3D = 9
+ // - FT_BareBorderVolume = 25
+ // - FT_BareBorderFace = 26
+ // - FT_OverConstrainedVolume = 27
+ // - FT_OverConstrainedFace = 28
+ // v 6.5.0: FT_Undefined == 43, new items:
+ // - FT_EqualNodes = 14
+ // - FT_EqualEdges = 15
+ // - FT_EqualFaces = 16
+ // - FT_EqualVolumes = 17
+ // v 6.6.0: FT_Undefined == 44, new items:
+ // - FT_BallDiameter = 37
+ //
+ // It's necessary to continue recording this history and to fill
+ // undef2newItems (see below) accordingly.
+
+ typedef map< int, vector< int > > TUndef2newItems;
+ static TUndef2newItems undef2newItems;
+ if ( undef2newItems.empty() )
+ {
+ undef2newItems[ 26 ].push_back( 7 );
+ undef2newItems[ 27 ].push_back( 17 );
+ { int items[] = { 10, 11, 23, 24, 25 };
+ undef2newItems[ 32 ].assign( items, items+5 ); }
+ undef2newItems[ 33 ].push_back( 26 );
+ { int items[] = { 8, 9, 25, 26, 27, 28 };
+ undef2newItems[ 39 ].assign( items, items+6 ); }
+ { int items[] = { 14, 15, 16, 17 };
+ undef2newItems[ 43 ].assign( items, items+4 ); }
+ { int items[] = { 37 };
+ undef2newItems[ 44 ].assign( items, items+1 ); }
+ }
+
+ int iType = Type.IntegerValue();
+ int iCompare = Compare.IntegerValue();
+ int iUnaryOp = UnaryOp.IntegerValue();
+ int iBinaryOp = BinaryOp.IntegerValue();
+
+ // find out integer value of FT_Undefined at the moment of dump
+ int oldUndefined = iBinaryOp;
+ if ( iBinaryOp < iUnaryOp ) // BinaryOp was FT_LogicalNOT
+ oldUndefined += 3;
+
+ // apply history to args
+ TUndef2newItems::const_iterator undef_items =
+ undef2newItems.upper_bound( oldUndefined );
+ if ( undef_items != undef2newItems.end() )
+ {
+ int* pArg[4] = { &iType, &iCompare, &iUnaryOp, &iBinaryOp };
+ for ( ; undef_items != undef2newItems.end(); ++undef_items )
+ {
+ const vector< int > & addedItems = undef_items->second;
+ for ( size_t i = 0; i < addedItems.size(); ++i )
+ for ( int iArg = 0; iArg < 4; ++iArg )
+ {
+ int& arg = *pArg[iArg];
+ if ( arg >= addedItems[i] )
+ arg++;
+ }
+ }
+ Type = TCollection_AsciiString( iType );
+ Compare = TCollection_AsciiString( iCompare );
+ UnaryOp = TCollection_AsciiString( iUnaryOp );
+ BinaryOp = TCollection_AsciiString( iBinaryOp );
+ }
+ }
}
//================================================================================
{
// find a GEOM entry
_pyID geomID;
- SALOMEDS::SComponent_var geomComp = theStudy->FindComponent("GEOM");
+ SALOMEDS::SComponent_wrap geomComp = theStudy->FindComponent("GEOM");
if ( geomComp->_is_nil() ) return;
CORBA::String_var entry = geomComp->GetID();
geomID = entry.in();
if ( objID.IsEmpty() )
return aCommand;
+ // Prevent moving a command creating a sub-mesh to the end of the script
+ // if the sub-mesh is used in theCommand as argument
+ if ( _pySubMesh::CanBeArgOfMethod( aCommand->GetMethod() ))
+ {
+ PlaceSubmeshAfterItsCreation( aCommand );
+ }
+
// Find an object to process theCommand
// SMESH_Gen method?
method == "DoubleNodeGroupNew" ||
method == "DoubleNodeGroupsNew" ||
method == "DoubleNodeElemGroupNew" ||
- method == "DoubleNodeElemGroupsNew" )
+ method == "DoubleNodeElemGroupsNew"||
+ method == "DoubleNodeElemGroup2New"||
+ method == "DoubleNodeElemGroups2New"
+ )
groups = aCommand->GetResultValue();
else if ( method == "MakeBoundaryMesh" )
groups = aCommand->GetResultValue(2);
else if ( method == "MakeBoundaryElements")
groups = aCommand->GetResultValue(3);
+ else if ( method == "Create0DElementsOnAllNodes" &&
+ aCommand->GetArg(2).Length() > 2 ) // group name != ''
+ groups = aCommand->GetResultValue();
id_editor->second->Process( aCommand );
id_editor->second->AddProcessedCmd( aCommand );
+ // create meshes
if ( !meshID.IsEmpty() &&
!myMeshes.count( meshID ) &&
aCommand->IsStudyEntry( meshID ))
aCommand->Clear();
aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
}
+ // create groups
if ( !groups.IsEmpty() )
{
if ( !aCommand->IsStudyEntry( meshID ))
Tolerance = aCommand->GetArg(8), // double
TypeOfElement = aCommand->GetArg(9), // ElementType
Precision = aCommand->GetArg(10); // long
+ fixFunctorType( Type, Compare, UnaryOp, BinaryOp );
Type = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
Compare = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
UnaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
{
// set SMESH.GeometryType instead of a numerical Threshold
- const char* types[SMESH::Geom_POLYHEDRA+1] = {
+ const char* types[SMESH::Geom_BALL+1] = {
"Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
"Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM",
- "Geom_POLYHEDRA"
+ "Geom_POLYHEDRA", "Geom_BALL"
};
int iGeom = Threshold.IntegerValue();
if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
return;
}
- if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
+ if( method == "CreateMeshesFromMED" ||
+ method == "CreateMeshesFromSAUV"||
+ method == "CreateMeshesFromGMF" )
{
for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
{
- const _pyID& meshID = theCommand->GetResultValue(ind+1);
+ _pyID meshID = theCommand->GetResultValue(ind+1);
if ( !theCommand->IsStudyEntry( meshID ) ) continue;
Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind+1));
myMeshes.insert( make_pair( mesh->GetID(), mesh ));
}
}
- // objects erasing creation command if no more it's commands invoked:
+ // objects erasing creation command if no more its commands invoked:
// SMESH_Pattern, FilterManager
if ( method == "GetPattern" ||
method == "CreateFilterManager" ||
myCommands.push_back( myLastCommand );
}
+//================================================================================
+/*!
+ * \brief Prevent moving a command creating a sub-mesh to the end of the script
+ * if the sub-mesh is used in theCmdUsingSubmesh as argument
+ */
+//================================================================================
+
+void _pyGen::PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const
+{
+ map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.begin();
+ for ( ; id_obj != myObjects.end(); ++id_obj )
+ {
+ if ( !id_obj->second->IsKind( STANDARD_TYPE( _pySubMesh ))) continue;
+ for ( int iArg = theCmdUsingSubmesh->GetNbArgs(); iArg; --iArg )
+ {
+ const _pyID& arg = theCmdUsingSubmesh->GetArg( iArg );
+ if ( arg.IsEmpty() || arg.Value( 1 ) == '"' || arg.Value( 1 ) == '\'' )
+ continue;
+ list< _pyID > idList = theCmdUsingSubmesh->GetStudyEntries( arg );
+ list< _pyID >::iterator id = idList.begin();
+ for ( ; id != idList.end(); ++id )
+ if ( id_obj->first == *id )
+ // _pySubMesh::Process() does what we need
+ Handle(_pySubMesh)::DownCast( id_obj->second )->Process( theCmdUsingSubmesh );
+ }
+ }
+}
+
//================================================================================
/*!
* \brief Clean commmands of removed objects depending on myIsPublished flag
myObjects.insert( make_pair( theObj->GetID(), theObj ));
}
+//================================================================================
+/*!
+ * \brief Re-register an object with other ID to make it Process() commands of
+ * other object having this ID
+ */
+//================================================================================
+
+void _pyGen::SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj )
+{
+ if ( theObj.IsNull() ) return;
+
+ if ( theObj->IsKind( STANDARD_TYPE( _pyMesh )))
+ myMeshes.insert( make_pair( theID, Handle(_pyMesh)::DownCast( theObj )));
+
+ else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor )))
+ myMeshEditors.insert( make_pair( theID, Handle(_pyMeshEditor)::DownCast( theObj )));
+
+ else
+ myObjects.insert( make_pair( theID, theObj ));
+}
+
//================================================================================
/*!
* \brief Finds a _pyObject by ID
if ( myGeomIDNb )
{
return ( myGeomIDIndex <= theObjID.Length() &&
- int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb);
+ int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb &&
+ _pyCommand::IsStudyEntry( theObjID ));
}
return false;
}
// either the SMESH object is not in study or it is a GEOM object
if ( IsGeomObject( theObjID ))
{
- SALOMEDS::SObject_var so = myStudy->FindObjectID( theObjID.ToCString() );
+ SALOMEDS::SObject_wrap so = myStudy->FindObjectID( theObjID.ToCString() );
if ( so->_is_nil() ) return true;
CORBA::Object_var obj = so->GetObject();
return CORBA::is_nil( obj );
mySubmeshes.push_back( subMesh );
}
}
- else if ( method == "RemoveSubMesh" ) { // move submesh creation before its removal
- Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetArg(1) );
- if ( !subMesh.IsNull() )
- subMesh->Process( theCommand );
- AddMeshAccess( theCommand );
- }
// ----------------------------------------------------------------------
else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
myAddHypCmds.push_back( theCommand );
}
}
// ----------------------------------------------------------------------
- else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
+ else if ( method == "CreateGroup" ||
+ method == "CreateGroupFromGEOM" ||
+ method == "CreateGroupFromFilter" )
{
- theCommand->SetMethod( "CreateEmptyGroup" );
Handle(_pyGroup) group = new _pyGroup( theCommand );
myGroups.push_back( group );
theGen->AddObject( group );
}
- // ----------------------------------------------------------------------
- else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
- _pyID grp = theCommand->GetArg( 3 );
- // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
- // next if(){...} section is commented
- //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
- // theCommand->SetMethod( "Group" );
- // theCommand->RemoveArgs();
- // theCommand->SetArg( 1, grp );
- //}
- //else {
- // ------------------------->>>>> GroupOnGeom( grp, name, typ )
- _pyID type = theCommand->GetArg( 1 );
- _pyID name = theCommand->GetArg( 2 );
- theCommand->SetMethod( "GroupOnGeom" );
- theCommand->RemoveArgs();
- theCommand->SetArg( 1, grp );
- theCommand->SetArg( 2, name );
- theCommand->SetArg( 3, type );
- //}
- Handle(_pyGroup) group = new _pyGroup( theCommand );
- myGroups.push_back( group );
- theGen->AddObject( group );
- }
- // ----------------------------------------------------------------------
- else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
+ // update list of groups
+ else if ( method == "GetGroups" )
{
- theCommand->SetMethod( "GroupOnFilter" );
- Handle(_pyGroup) group = new _pyGroup( theCommand );
- myGroups.push_back( group );
- theGen->AddObject( group );
-
- // GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
- _pyID filterID = theCommand->GetArg(3);
- Handle(_pyFilter) filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID ));
- if ( !filter.IsNull())
+ TCollection_AsciiString grIDs = theCommand->GetResultValue();
+ list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
+ list< _pyID >::iterator grID = idList.begin();
+ for ( ; grID != idList.end(); ++grID )
{
- filter->Process( theCommand );
- filter->AddUser( group );
+ Handle(_pyObject) obj = theGen->FindObject( *grID );
+ if ( obj.IsNull() )
+ {
+ Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
+ theGen->AddObject( group );
+ myGroups.push_back( group );
+ }
+ }
+ }
+ // notify a group about full removal
+ else if ( method == "RemoveGroupWithContents" )
+ {
+ if ( !theGen->IsToKeepAllCommands() ) { // snapshot mode
+ const _pyID groupID = theCommand->GetArg( 1 );
+ Handle(_pyGroup) grp = Handle(_pyGroup)::DownCast( theGen->FindObject( groupID ));
+ if ( !grp.IsNull() )
+ grp->RemovedWithContents();
}
}
// ----------------------------------------------------------------------
method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
theCommand->SetMethod( "ExportMED" );
}
- else if ( method == "ExportCGNS" )
+ else if ( method == "ExportCGNS" || method == "ExportGMF" )
{ // ExportCGNS(part, ...) -> ExportCGNS(..., part)
_pyID partID = theCommand->GetArg( 1 );
int nbArgs = theCommand->GetNbArgs();
// ----------------------------------------------------------------------
else if ( method == "RemoveHypothesis" ) // (geom, hyp)
{
- _pyID hypID = theCommand->GetArg( 2 );
+ _pyID hypID = theCommand->GetArg( 2 );
+ _pyID geomID = theCommand->GetArg( 1 );
+ bool isLocal = ( geomID != GetGeom() );
// check if this mesh still has corresponding addition command
- bool hasAddCmd = false;
- list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
- while ( cmd != myAddHypCmds.end() )
+ Handle(_pyCommand) addCmd;
+ list< Handle(_pyCommand) >::iterator cmd;
+ list< Handle(_pyCommand) >* addCmds[2] = { &myAddHypCmds, &myNotConvertedAddHypCmds };
+ for ( int i = 0; i < 2; ++i )
{
- // AddHypothesis(geom, hyp)
- if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
- theCommand->Clear();
- (*cmd)->Clear();
- cmd = myAddHypCmds.erase( cmd );
- hasAddCmd = true;
- }
- else {
- ++cmd;
+ list< Handle(_pyCommand )> & addHypCmds = *(addCmds[i]);
+ for ( cmd = addHypCmds.begin(); cmd != addHypCmds.end(); )
+ {
+ bool sameHyp = true;
+ if ( hypID != (*cmd)->GetArg( 1 ) && hypID != (*cmd)->GetArg( 2 ))
+ sameHyp = false; // other hyp
+ if ( (*cmd)->GetNbArgs() == 2 &&
+ geomID != (*cmd)->GetArg( 1 ) && geomID != (*cmd)->GetArg( 2 ))
+ sameHyp = false; // other geom
+ if ( (*cmd)->GetNbArgs() == 1 && isLocal )
+ sameHyp = false; // other geom
+ if ( sameHyp )
+ {
+ addCmd = *cmd;
+ cmd = addHypCmds.erase( cmd );
+ if ( !theGen->IsToKeepAllCommands() ) {
+ addCmd->Clear();
+ theCommand->Clear();
+ }
+ }
+ else
+ {
+ ++cmd;
+ }
}
}
Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
- if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
+ if ( !theCommand->IsEmpty() && !hypID.IsEmpty() ) {
// RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
_pyID geom = theCommand->GetArg( 1 );
theCommand->RemoveArgs();
subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
}
}
- // update list of groups
- else if ( method == "GetGroups" )
- {
- TCollection_AsciiString grIDs = theCommand->GetResultValue();
- list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
- list< _pyID >::iterator grID = idList.begin();
- for ( ; grID != idList.end(); ++grID )
- {
- Handle(_pyObject) obj = theGen->FindObject( *grID );
- if ( obj.IsNull() )
- {
- Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
- theGen->AddObject( group );
- myGroups.push_back( group );
- }
- }
- }
// add accessor method if necessary
else
{
addCmd->SetArg( 1, algoID );
if ( isLocalAlgo )
addCmd->SetArg( 2, geom );
+ myNotConvertedAddHypCmds.push_back( addCmd );
}
}
addCmd->SetArg( 1, hypID );
if ( geom != GetGeom() )
addCmd->SetArg( 2, geom );
+ myNotConvertedAddHypCmds.push_back( addCmd );
}
}
void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
{
- // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
- // commands calling this methods are converted to calls of methods of Mesh
+ // names of SMESH_MeshEditor methods fully equal to methods of the python class Mesh, so
+ // commands calling this methods are converted to calls of Mesh methods
static TStringSet sameMethods;
if ( sameMethods.empty() ) {
const char * names[] = {
- "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
+ "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
"AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
- "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
+ "InverseDiag","DeleteDiag","Reorient","ReorientObject",
+ "TriToQuad","TriToQuadObject", "SplitQuad","SplitQuadObject",
"BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
"ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
"RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
"GetLastCreatedElems",
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
"TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
- "MakeBoundaryElements"
+ "MakeBoundaryElements", "SplitVolumesIntoTetra"
,"" }; // <- mark of the end
sameMethods.Insert( names );
}
- // names of SMESH_MeshEditor methods which differ from methods of class Mesh
+ // names of SMESH_MeshEditor commands in which only a method name must be replaced
+ TStringMap diffMethods;
+ if ( diffMethods.empty() ) {
+ const char * orig2newName[] = {
+ // original name --------------> new name
+ "ExtrusionAlongPathObjX" , "ExtrusionAlongPathX",
+ "FindCoincidentNodesOnPartBut", "FindCoincidentNodesOnPart",
+ "ConvertToQuadraticObject" , "ConvertToQuadratic",
+ "ConvertFromQuadraticObject" , "ConvertFromQuadratic",
+ "Create0DElementsOnAllNodes" , "Add0DElementsToAllNodes",
+ ""};// <- mark of the end
+ diffMethods.Insert( orig2newName );
+ }
+
+ // names of SMESH_MeshEditor methods which differ from methods of Mesh class
// only by last two arguments
static TStringSet diffLastTwoArgsMethods;
if (diffLastTwoArgsMethods.empty() ) {
diffLastTwoArgsMethods.Insert( names );
}
+ // only a method name is to change?
const TCollection_AsciiString & method = theCommand->GetMethod();
bool isPyMeshMethod = sameMethods.Contains( method );
if ( !isPyMeshMethod )
{
- //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
- //functions with the flag "theMakeGroups = True" like:
- //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
+ TCollection_AsciiString newMethod = diffMethods.Value( method );
+ if (( isPyMeshMethod = ( newMethod.Length() > 0 )))
+ theCommand->SetMethod( newMethod );
+ }
+
+ if ( !isPyMeshMethod )
+ {
+ // Replace SMESH_MeshEditor "*MakeGroups" functions by the Mesh
+ // functions with the flag "theMakeGroups = True" like:
+ // SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
int pos = method.Search("MakeGroups");
if( pos != -1)
{
}
}
- // ExtrusionSweep0D() -> ExtrusionSweep()
+ // ExtrusionSweep0D() -> ExtrusionSweep()
// ExtrusionSweepObject0D() -> ExtrusionSweepObject()
if ( !isPyMeshMethod && ( method == "ExtrusionSweep0D" ||
method == "ExtrusionSweepObject0D" ))
{
- isPyMeshMethod=true;
+ isPyMeshMethod = true;
theCommand->SetMethod( method.SubString( 1, method.Length()-2));
theCommand->SetArg(theCommand->GetNbArgs()+1,"False"); //sets flag "MakeGroups = False"
theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); //sets flag "IsNode = True"
}
- // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
- if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
- {
- isPyMeshMethod=true;
- theCommand->SetMethod("ExtrusionAlongPathX");
- }
- // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
- if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
- {
- isPyMeshMethod=true;
- theCommand->SetMethod("FindCoincidentNodesOnPart");
- }
- // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
- // DoubleNodeGroupNew() -> DoubleNodeGroup()
- // DoubleNodeGroupsNew() -> DoubleNodeGroups()
- // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
+ // DoubleNode...New(...) -> DoubleNode...(...,True)
if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" ||
method == "DoubleNodeElemGroupsNew" ||
method == "DoubleNodeGroupNew" ||
- method == "DoubleNodeGroupsNew"))
+ method == "DoubleNodeGroupsNew" ||
+ method == "DoubleNodeElemGroup2New" ||
+ method == "DoubleNodeElemGroups2New"))
{
- isPyMeshMethod=true;
- theCommand->SetMethod( method.SubString( 1, method.Length()-3));
- theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
- }
- // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
- // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
- if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
- method == "ConvertFromQuadraticObject" ))
- {
- isPyMeshMethod=true;
- theCommand->SetMethod( method.SubString( 1, method.Length()-6));
- // prevent moving creation of the converted sub-mesh to the end of the script
- bool isFromQua = ( method.Value( 8 ) == 'F' );
- Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
- if ( !sm.IsNull() )
- sm->Process( theCommand );
+ isPyMeshMethod = true;
+ const int excessLen = 3 + int( method.Value( method.Length()-3 ) == '2' );
+ theCommand->SetMethod( method.SubString( 1, method.Length()-excessLen));
+ if ( excessLen == 3 )
+ {
+ theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
+ }
+ else if ( theCommand->GetArg(4) == "0" ||
+ theCommand->GetArg(5) == "0" )
+ {
+ // [ nothing, Group ] = DoubleNodeGroup2New(,,,False, True) ->
+ // Group = DoubleNodeGroup2New(,,,False, True)
+ _pyID groupID = theCommand->GetResultValue( 1 + int( theCommand->GetArg(4) == "0"));
+ theCommand->SetResultValue( groupID );
+ }
}
// FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
// FindElementsByPoint(x, y, z, elementType, meshPart)
if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
{
- isPyMeshMethod=true;
+ isPyMeshMethod = true;
theCommand->SetMethod( "FindElementsByPoint" );
// make the 1st arg be the last one
_pyID partID = theCommand->GetArg( 1 );
theCommand->SetArg( i-1, theCommand->GetArg( i ));
theCommand->SetArg( nbArgs, partID );
}
+ // Reorient2D( mesh, dir, face, point ) -> Reorient2D( mesh, dir, faceORpoint )
+ if ( !isPyMeshMethod && method == "Reorient2D" )
+ {
+ isPyMeshMethod = true;
+ _AString mesh = theCommand->GetArg( 1 );
+ _AString dir = theCommand->GetArg( 2 );
+ _AString face = theCommand->GetArg( 3 );
+ _AString point = theCommand->GetArg( 4 );
+ theCommand->RemoveArgs();
+ theCommand->SetArg( 1, mesh );
+ theCommand->SetArg( 2, dir );
+ if ( face.Value(1) == '-' || face.Value(1) == '0' ) // invalid: face <= 0
+ theCommand->SetArg( 3, point );
+ else
+ theCommand->SetArg( 3, face );
+ }
+
+ if ( method == "QuadToTri" || method == "QuadToTriObject" )
+ {
+ isPyMeshMethod = true;
+ int crit_arg = theCommand->GetNbArgs();
+ const _AString& crit = theCommand->GetArg(crit_arg);
+ if (crit.Search("MaxElementLength2D") != -1)
+ theCommand->SetArg(crit_arg, "");
+ }
- // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
- // so let _pyMesh care of it (TMP?)
- // if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
- // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
if ( isPyMeshMethod )
{
theCommand->SetObject( myMesh );
else
{
// editor creation command is needed only if any editor function is called
- theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
+ theGen->AddMeshAccessorMethod( theCommand ); // for *Object() methods
if ( !myCreationCmdStr.IsEmpty() ) {
GetCreationCmd()->GetString() = myCreationCmdStr;
myCreationCmdStr.Clear();
myGeom = theOther->myGeom;
myMesh = theMesh;
myAlgoType2CreationMethod = theOther->myAlgoType2CreationMethod;
- //myArgCommands = theOther->myArgCommands;
+ myAccumulativeMethods = theOther->myAccumulativeMethods;
//myUnusedCommands = theOther->myUnusedCommands;
// init myCurCrMethod
GetCreationMethod( theOther->GetAlgoType() );
void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theCommand )
{
// parameters are discriminated by method name
- TCollection_AsciiString method = theCommand->GetMethod();
+ _AString method = theCommand->GetMethod();
+ if ( myAccumulativeMethods.count( method ))
+ return; // this method adds values and not override the previus value
// discriminate commands setting different parameters via one method
// by passing parameter names like e.g. SetOption("size", "0.2")
}
}
// parameters are discriminated by method name
- list< Handle(_pyCommand)>& cmds = myMeth2Commands[ theCommand->GetMethod() ];
+ list< Handle(_pyCommand)>& cmds = myMeth2Commands[ method /*theCommand->GetMethod()*/ ];
if ( !cmds.empty() && !isCmdUsedForCompute( cmds.back() ))
{
cmds.back()->Clear(); // previous parameter value has not been used
//================================================================================
/*!
* \brief Return substring of python command looking like
- * ResultValue1 , ResultValue1,... = Obj.Meth() with res index
+ * ResultValue1 , ResultValue2,... = Obj.Meth() with res index
* \retval const TCollection_AsciiString & - ResultValue with res index substring
*/
//================================================================================
-const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
+TCollection_AsciiString _pyCommand::GetResultValue(int res)
{
int begPos = 1;
- int Nb=0;
+ if ( SkipSpaces( myString, begPos ) && myString.Value( begPos ) == '[' )
+ ++begPos; // skip [, else the whole list is returned
int endPos = myString.Location( "=", 1, Length() );
+ int Nb=0;
while ( begPos < endPos) {
- myRes = GetWord( myString, begPos, true );
- begPos = begPos + myRes.Length();
+ _AString result = GetWord( myString, begPos, true );
+ begPos = begPos + result.Length();
Nb++;
- if(res == Nb){
- myRes.RemoveAll('[');myRes.RemoveAll(']');
- return myRes;
+ if(res == Nb) {
+ result.RemoveAll('[');
+ result.RemoveAll(']');
+ return result;
}
if(Nb>res)
break;
*/
//================================================================================
-TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
- int & theStartPos,
- const bool theForward,
- const bool dotIsWord )
+TCollection_AsciiString _pyCommand::GetWord( const _AString & theString,
+ int & theStartPos,
+ const bool theForward,
+ const bool dotIsWord )
{
int beg = theStartPos, end = theStartPos;
theStartPos = EMPTY;
* \param theString - The string
* \param thePos - The position to search from and which returns result
* \retval bool - false if there are only space after thePos in theString
- *
- *
*/
//================================================================================
myMesh = ObjectToMesh( theGen->FindObject( theCreationCmd->GetObject() ));
}
+//================================================================================
+/*!
+ * \brief Return true if a sub-mesh can be used as argument of the given method
+ */
+//================================================================================
+
+bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName)
+{
+ // names of all methods where a sub-mesh can be used as argument
+ static TStringSet methods;
+ if ( methods.empty() ) {
+ const char * names[] = {
+ // methods of SMESH_Gen
+ "CopyMesh",
+ // methods of SMESH_Group
+ "AddFrom",
+ // methods of SMESH_Measurements
+ "MinDistance",
+ // methods of SMESH_Mesh
+ "ExportPartToMED","ExportCGNS","ExportPartToDAT","ExportPartToUNV","ExportPartToSTL",
+ "RemoveSubMesh",
+ // methods of SMESH_MeshEditor
+ "ReorientObject","Reorient2D","TriToQuadObject","QuadToTriObject","SplitQuadObject",
+ "SplitVolumesIntoTetra","SmoothObject","SmoothParametricObject","ConvertFromQuadraticObject",
+ "RotationSweepObject","RotationSweepObjectMakeGroups","RotationSweepObject1D",
+ "RotationSweepObject1DMakeGroups","RotationSweepObject2D","RotationSweepObject2DMakeGroups",
+ "ExtrusionSweepObject","ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D",
+ "ExtrusionSweepObject0DMakeGroups","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
+ "ExtrusionSweepObject1DMakeGroups","ExtrusionSweepObject2DMakeGroups",
+ "ExtrusionAlongPathObjX","ExtrusionAlongPathObject","ExtrusionAlongPathObjectMakeGroups",
+ "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject1DMakeGroups",
+ "ExtrusionAlongPathObject2D","ExtrusionAlongPathObject2DMakeGroups","MirrorObject",
+ "MirrorObjectMakeGroups","MirrorObjectMakeMesh","TranslateObject","Scale",
+ "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh",
+ "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart",
+ "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint",
+ "MakeBoundaryMesh","Create0DElementsOnAllNodes",
+ "" }; // <- mark of end
+ methods.Insert( names );
+ }
+ return methods.Contains( theMethodName );
+}
+
//================================================================================
/*!
* \brief count invoked commands
myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
}
+//================================================================================
+/*!
+ * \brief Creates _pyGroup
+ */
+//================================================================================
+
+_pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id)
+ :_pySubMesh(theCreationCmd)
+{
+ if ( !id.IsEmpty() )
+ setID( id );
+
+ myCanClearCreationCmd = true;
+
+ const _AString& method = theCreationCmd->GetMethod();
+ if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
+ {
+ theCreationCmd->SetMethod( "CreateEmptyGroup" );
+ }
+ // ----------------------------------------------------------------------
+ else if ( method == "CreateGroupFromGEOM" ) // (type, name, grp)
+ {
+ _pyID geom = theCreationCmd->GetArg( 3 );
+ // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
+ // next if(){...} section is commented
+ //if ( sameGroupType( geom, theCreationCmd->GetArg( 1 )) ) { // --> Group(geom)
+ // theCreationCmd->SetMethod( "Group" );
+ // theCreationCmd->RemoveArgs();
+ // theCreationCmd->SetArg( 1, geom );
+ //}
+ //else {
+ // ------------------------->>>>> GroupOnGeom( geom, name, typ )
+ _pyID type = theCreationCmd->GetArg( 1 );
+ _pyID name = theCreationCmd->GetArg( 2 );
+ theCreationCmd->SetMethod( "GroupOnGeom" );
+ theCreationCmd->RemoveArgs();
+ theCreationCmd->SetArg( 1, geom );
+ theCreationCmd->SetArg( 2, name );
+ theCreationCmd->SetArg( 3, type );
+ //}
+ }
+ else if ( method == "CreateGroupFromFilter" )
+ {
+ // -> GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
+ theCreationCmd->SetMethod( "GroupOnFilter" );
+
+ _pyID filterID = theCreationCmd->GetArg(3);
+ Handle(_pyFilter) filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID ));
+ if ( !filter.IsNull())
+ {
+ if ( !filter->GetNewID().IsEmpty() )
+ theCreationCmd->SetArg( 3, filter->GetNewID() );
+ filter->AddUser( this );
+ }
+ myFilter = filter;
+ }
+ else
+ {
+ // theCreationCmd does something else apart from creation of this group
+ // and thus it can't be cleared if this group is removed
+ myCanClearCreationCmd = false;
+ }
+}
+
+//================================================================================
+/*!
+ * \brief set myCanClearCreationCmd = true if the main action of the creation
+ * command is discarded
+ */
+//================================================================================
+
+void _pyGroup::RemovedWithContents()
+{
+ // this code would be appropriate if Add0DElementsToAllNodes() returned only new nodes
+ // via a created group
+ //if ( GetCreationCmd()->GetMethod() == "Add0DElementsToAllNodes")
+ // myCanClearCreationCmd = true;
+}
+
//================================================================================
/*!
* \brief To convert creation of a group by filter
theCommand->Clear();
const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
+ if ( !filter->GetNewID().IsEmpty() )
+ idSource = filter->GetNewID();
makeGroupCmd->SetMethod( "MakeGroupByFilter" );
makeGroupCmd->SetArg( 1, name );
makeGroupCmd->SetArg( 2, idSource );
- // set new name of a filter
- filter->Process( makeGroupCmd );
}
}
else if ( theCommand->GetMethod() == "SetFilter" )
{
- // set new name of a filter
+ // set new name of a filter or clear the command if the same filter is set
_pyID filterID = theCommand->GetArg(1);
filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID ));
- if ( !filter.IsNull() )
- filter->Process( theCommand );
+ if ( !myFilter.IsNull() && filter == myFilter )
+ theCommand->Clear();
+ else if ( !filter.IsNull() && !filter->GetNewID().IsEmpty() )
+ theCommand->SetArg( 1, filter->GetNewID() );
+ myFilter = filter;
+ }
+ else if ( theCommand->GetMethod() == "GetFilter" )
+ {
+ // GetFilter() returns a filter with other ID, make myFilter process
+ // calls of the returned filter
+ if ( !myFilter.IsNull() )
+ {
+ theGen->SetProxyObject( theCommand->GetResultValue(), myFilter );
+ theCommand->Clear();
+ }
}
if ( !filter.IsNull() )
theGen->AddMeshAccessorMethod( theCommand );
}
+//================================================================================
+/*!
+ * \brief Prevent clearing "DoubleNode...() command if a group created by it is removed
+ */
+//================================================================================
+
+void _pyGroup::Flush()
+{
+ if ( !theGen->IsToKeepAllCommands() &&
+ myCreationCmd && !myCanClearCreationCmd )
+ {
+ myCreationCmd.Nullify(); // this way myCreationCmd won't be cleared
+ }
+}
+
//================================================================================
/*!
* \brief Constructor of _pyFilter
_pyObject::Process(theCommand); // count commands
if ( !myNewID.IsEmpty() )
- {
- if ( theCommand->GetObject() == GetID() )
- theCommand->SetObject( myNewID );
- else if ( theCommand->GetResultValue() == GetID() )
- theCommand->SetResultValue( myNewID );
- else
- for ( int i = 1, nb = theCommand->GetNbArgs(); i <= nb; ++i )
- if ( theCommand->GetArg( i ) == GetID() )
- {
- theCommand->SetArg( i, myNewID );
- break;
- }
- }
-
+ theCommand->SetObject( myNewID );
+
// Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
// aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
// aFilter0x2aaab0487080.SetCriteria(aCriteria)
// Clear aFilterManager.CreateFilter()
GetCreationCmd()->Clear();
}
- else if ( theCommand->GetMethod() == "SetMesh")
+ else if ( theCommand->GetMethod() == "SetMesh" )
{
+ if ( myMesh == theCommand->GetArg( 1 ))
+ theCommand->Clear();
+ else
+ myMesh = theCommand->GetArg( 1 );
theGen->AddMeshAccessorMethod( theCommand );
}
}
_pyHypothesisReader::_pyHypothesisReader()
{
- // Get paths to xml files of plugins
- vector< string > xmlPaths;
- string sep;
- if ( const char* meshersList = getenv("SMESH_MeshersList") )
- {
- string meshers = meshersList, plugin;
- string::size_type from = 0, pos;
- while ( from < meshers.size() )
- {
- // cut off plugin name
- pos = meshers.find( ':', from );
- if ( pos != string::npos )
- plugin = meshers.substr( from, pos-from );
- else
- plugin = meshers.substr( from ), pos = meshers.size();
- from = pos + 1;
-
- // get PLUGIN_ROOT_DIR path
- string rootDirVar, pluginSubDir = plugin;
- if ( plugin == "StdMeshers" )
- rootDirVar = "SMESH", pluginSubDir = "smesh";
- else
- for ( pos = 0; pos < plugin.size(); ++pos )
- rootDirVar += toupper( plugin[pos] );
- rootDirVar += "_ROOT_DIR";
-
- const char* rootDir = getenv( rootDirVar.c_str() );
- if ( !rootDir || strlen(rootDir) == 0 )
- {
- rootDirVar = plugin + "_ROOT_DIR"; // HexoticPLUGIN_ROOT_DIR
- rootDir = getenv( rootDirVar.c_str() );
- if ( !rootDir || strlen(rootDir) == 0 ) continue;
- }
-
- // get a separator from rootDir
- for ( pos = strlen( rootDir )-1; pos >= 0 && sep.empty(); --pos )
- if ( rootDir[pos] == '/' || rootDir[pos] == '\\' )
- {
- sep = rootDir[pos];
- break;
- }
- if (sep.empty() ) sep = "/";
-
- // get a path to resource file
- string xmlPath = rootDir;
- if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
- xmlPath += sep;
- xmlPath += "share" + sep + "salome" + sep + "resources" + sep;
- for ( pos = 0; pos < pluginSubDir.size(); ++pos )
- xmlPath += tolower( pluginSubDir[pos] );
- xmlPath += sep + plugin + ".xml";
- bool fileOK;
-#ifdef WNT
- fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
-#else
- fileOK = (access(xmlPath.c_str(), F_OK) == 0);
-#endif
- if ( fileOK )
- xmlPaths.push_back( xmlPath );
- }
- }
-
// Read xml files
+ vector< string > xmlPaths = SMESH_Gen::GetPluginXMLPaths();
LDOMParser xmlParser;
for ( size_t i = 0; i < xmlPaths.size(); ++i )
{
LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" );
for ( int i = 0; i < algoNodeList.getLength(); ++i )
{
- LDOM_Node algoNode = algoNodeList.item( i );
+ LDOM_Node algoNode = algoNodeList.item( i );
LDOM_Element& algoElem = (LDOM_Element&) algoNode;
LDOM_NodeList pyAlgoNodeList = algoElem.getElementsByTagName( "algo" );
if ( pyAlgoNodeList.getLength() < 1 ) continue;
}
}
}
- }
+ // <hypothesis type="BLSURF_Parameters"
+ // ...
+ // dim="2">
+ // <python-wrap>
+ // <accumulative-methods>
+ // SetEnforcedVertex,
+ // SetEnforcedVertexNamed
+ // </accumulative-methods>
+ // </python-wrap>
+ // </hypothesis>
+ //
+ LDOM_NodeList hypNodeList = xmlDoc.getElementsByTagName( "hypothesis" );
+ for ( int i = 0; i < hypNodeList.getLength(); ++i )
+ {
+ LDOM_Node hypNode = hypNodeList.item( i );
+ LDOM_Element& hypElem = (LDOM_Element&) hypNode;
+ _AString hypType = hypElem.getAttribute("type");
+ LDOM_NodeList methNodeList = hypElem.getElementsByTagName( "accumulative-methods" );
+ if ( methNodeList.getLength() != 1 || hypType.IsEmpty() ) continue;
+
+ map<_AString, Handle(_pyHypothesis)>::const_iterator type2hyp = myType2Hyp.find( hypType );
+ if ( type2hyp == myType2Hyp.end() ) continue;
+
+ LDOM_Node methNode = methNodeList.item( 0 );
+ LDOM_Node textNode = methNode.getFirstChild();
+ _AString text = textNode.getNodeValue();
+ _AString method;
+ int pos = 1;
+ do {
+ method = _pyCommand::GetWord( text, pos, /*forward= */true );
+ pos += method.Length();
+ type2hyp->second->AddAccumulativeMethod( method );
+ }
+ while ( !method.IsEmpty() );
+ }
+
+ } // loop on xmlPaths
}
//================================================================================