1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File : SMESH_2smeshpy.cxx
25 // Created : Fri Nov 18 13:20:10 2005
26 // Author : Edward AGAPOV (eap)
28 #include "SMESH_2smeshpy.hxx"
30 #include "utilities.h"
31 #include "SMESH_PythonDump.hxx"
32 #include "SMESH_NoteBook.hxx"
33 #include "SMESH_Filter_i.hxx"
35 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
37 #include "SMESH_Gen_i.hxx"
38 /* SALOME headers that include CORBA headers that include windows.h
39 * that defines GetObject symbol as GetObjectA should stand before SALOME headers
40 * that declare methods named GetObject - to apply the same rules of GetObject renaming
41 * and thus to avoid mess with GetObject symbol on Windows */
43 IMPLEMENT_STANDARD_HANDLE (_pyObject ,Standard_Transient);
44 IMPLEMENT_STANDARD_HANDLE (_pyCommand ,Standard_Transient);
45 IMPLEMENT_STANDARD_HANDLE (_pyGen ,_pyObject);
46 IMPLEMENT_STANDARD_HANDLE (_pyMesh ,_pyObject);
47 IMPLEMENT_STANDARD_HANDLE (_pySubMesh ,_pyObject);
48 IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor ,_pyObject);
49 IMPLEMENT_STANDARD_HANDLE (_pyHypothesis ,_pyObject);
50 IMPLEMENT_STANDARD_HANDLE (_pySelfEraser ,_pyObject);
51 IMPLEMENT_STANDARD_HANDLE (_pyGroup ,_pyObject);
52 IMPLEMENT_STANDARD_HANDLE (_pyFilter ,_pyObject);
53 IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
54 IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
55 IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
57 IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient);
58 IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient);
59 IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject);
60 IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject);
61 IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject);
62 IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject);
63 IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject);
64 IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject);
65 IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject);
66 IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject);
67 IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis);
68 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
69 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
70 IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
71 IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
74 using SMESH::TPythonDump;
77 * \brief Container of commands into which the initial script is split.
78 * It also contains data coresponding to SMESH_Gen contents
80 static Handle(_pyGen) theGen;
82 static TCollection_AsciiString theEmptyString;
84 //#define DUMP_CONVERSION
86 #if !defined(_DEBUG_) && defined(DUMP_CONVERSION)
87 #undef DUMP_CONVERSION
93 //================================================================================
95 * \brief Set of TCollection_AsciiString initialized by C array of C strings
97 //================================================================================
99 struct TStringSet: public set<TCollection_AsciiString>
102 * \brief Filling. The last string must be ""
104 void Insert(const char* names[]) {
105 for ( int i = 0; names[i][0] ; ++i )
106 insert( (char*) names[i] );
109 * \brief Check if a string is in
111 bool Contains(const TCollection_AsciiString& name ) {
112 return find( name ) != end();
117 //================================================================================
119 * \brief Convert python script using commands of smesh.py
120 * \param theScript - Input script
121 * \retval TCollection_AsciiString - Convertion result
123 * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx
125 //================================================================================
127 TCollection_AsciiString
128 SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
129 Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
130 Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
132 theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
134 // split theScript into separate commands
136 SMESH_NoteBook * aNoteBook = new SMESH_NoteBook();
138 int from = 1, end = theScript.Length(), to;
139 while ( from < end && ( to = theScript.Location( "\n", from, end )))
142 // cut out and store a command
143 aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
147 aNoteBook->ReplaceVariables();
149 TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript();
153 // split theScript into separate commands
154 from = 1, end = aNoteScript.Length();
155 while ( from < end && ( to = aNoteScript.Location( "\n", from, end )))
158 // cut out and store a command
159 theGen->AddCommand( aNoteScript.SubString( from, to - 1 ));
165 #ifdef DUMP_CONVERSION
166 MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl );
169 // reorder commands after conversion
170 list< Handle(_pyCommand) >::iterator cmd;
173 orderChanges = false;
174 for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
175 if ( (*cmd)->SetDependentCmdsAfter() )
177 } while ( orderChanges );
179 // concat commands back into a script
180 TCollection_AsciiString aScript;
181 for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
183 #ifdef DUMP_CONVERSION
184 MESSAGE_ADD ( "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << std::endl );
186 if ( !(*cmd)->IsEmpty() ) {
188 aScript += (*cmd)->GetString();
198 //================================================================================
200 * \brief _pyGen constructor
202 //================================================================================
204 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
205 Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
206 : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
208 myID2AccessorMethod( theEntry2AccessorMethod ),
209 myObjectNames( theObjectNames ),
212 // make that GetID() to return TPythonDump::SMESHGenName()
213 GetCreationCmd()->GetString() += "=";
216 //================================================================================
218 * \brief name of SMESH_Gen in smesh.py
220 //================================================================================
222 const char* _pyGen::AccessorMethod() const
224 return SMESH_2smeshpy::GenName();
227 //================================================================================
229 * \brief Convert a command using a specific converter
230 * \param theCommand - the command to convert
232 //================================================================================
234 Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
236 // store theCommand in the sequence
237 myCommands.push_back( new _pyCommand( theCommand, ++myNbCommands ));
239 Handle(_pyCommand) aCommand = myCommands.back();
240 #ifdef DUMP_CONVERSION
241 MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() );
244 _pyID objID = aCommand->GetObject();
246 if ( objID.IsEmpty() )
249 // Find an object to process theCommand
252 if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) {
253 this->Process( aCommand );
257 // SMESH_Mesh method?
258 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
259 if ( id_mesh != myMeshes.end() )
261 // check for mesh editor object
262 if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
263 _pyID editorID = aCommand->GetResultValue();
264 Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
265 myMeshEditors.insert( make_pair( editorID, editor ));
268 // check for SubMesh objects
269 else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
270 _pyID subMeshID = aCommand->GetResultValue();
271 Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
272 myObjects.insert( make_pair( subMeshID, subMesh ));
275 id_mesh->second->Process( aCommand );
279 // SMESH_MeshEditor method?
280 map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
281 if ( id_editor != myMeshEditors.end() )
283 id_editor->second->Process( aCommand );
284 TCollection_AsciiString processedCommand = aCommand->GetString();
285 // some commands of SMESH_MeshEditor create meshes
286 if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) {
287 Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() );
288 aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
289 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
291 if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
292 _pyID meshID = aCommand->GetResultValue(0);
293 if ( !myMeshes.count( meshID ) )
295 Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
296 aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
297 myMeshes.insert( make_pair( meshID, mesh ));
302 // SMESH_Hypothesis method?
303 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
304 for ( ; hyp != myHypos.end(); ++hyp )
305 if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
306 (*hyp)->Process( aCommand );
310 // aFilterManager.CreateFilter() ?
311 if ( aCommand->GetMethod() == "CreateFilter" )
313 // Set a more human readable name to a filter
314 // aFilter0x7fbf6c71cfb0 -> aFilter_nb
315 _pyID newID, filterID = aCommand->GetResultValue();
316 int pos = filterID.Search( "0x" );
318 newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters );
320 Handle(_pyObject) filter( new _pyFilter( aCommand, newID ));
324 // other object method?
325 map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
326 if ( id_obj != myObjects.end() ) {
327 id_obj->second->Process( aCommand );
331 // Add access to a wrapped mesh
332 AddMeshAccessorMethod( aCommand );
334 // Add access to a wrapped algorithm
335 // AddAlgoAccessorMethod( aCommand ); // ??? what if algo won't be wrapped at all ???
337 // PAL12227. PythonDump was not updated at proper time; result is
338 // aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
339 // TypeError: __init__() takes exactly 11 arguments (10 given)
340 const char wrongCommand[] = "SMESH.Filter.Criterion(";
341 if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() ))
343 _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1);
344 // there must be 10 arguments, 5-th arg ThresholdID is missing,
345 const int wrongNbArgs = 9, missingArg = 5;
346 if ( tmpCmd.GetNbArgs() == wrongNbArgs )
348 for ( int i = wrongNbArgs; i > missingArg; --i )
349 tmpCmd.SetArg( i + 1, tmpCmd.GetArg( i ));
350 tmpCmd.SetArg( missingArg, "''");
351 aCommand->GetString().Trunc( beg - 1 );
352 aCommand->GetString() += tmpCmd.GetString();
355 // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance)
357 // instead of "SMESH.Filter.Criterion(
358 // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision)
359 // 1 2 3 4 5 6 7 8 9 10
360 // in order to avoid the problem of type mismatch of long and FunctorType
361 const TCollection_AsciiString
362 SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
363 TCollection_AsciiString
364 Type = aCommand->GetArg(1), // long
365 Compare = aCommand->GetArg(2), // long
366 Threshold = aCommand->GetArg(3), // double
367 ThresholdStr = aCommand->GetArg(4), // string
368 ThresholdID = aCommand->GetArg(5), // string
369 UnaryOp = aCommand->GetArg(6), // long
370 BinaryOp = aCommand->GetArg(7), // long
371 Tolerance = aCommand->GetArg(8), // double
372 TypeOfElement = aCommand->GetArg(9), // ElementType
373 Precision = aCommand->GetArg(10); // long
374 Type = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
375 Compare = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
376 UnaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
377 BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() ));
379 aCommand->RemoveArgs();
380 aCommand->SetObject( SMESH_2smeshpy::GenName() );
381 aCommand->SetMethod( "GetCriterion" );
383 aCommand->SetArg( 1, TypeOfElement );
384 aCommand->SetArg( 2, Type );
385 aCommand->SetArg( 3, Compare );
387 if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
389 // set SMESH.GeometryType instead of a numerical Threshold
390 const char* types[SMESH::Geom_POLYHEDRA+1] = {
391 "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
392 "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_POLYHEDRA"
394 int iGeom = Threshold.IntegerValue();
395 if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
396 Threshold = SMESH + types[ iGeom ];
398 if ( ThresholdStr.Length() != 2 ) // not '' or ""
399 aCommand->SetArg( 4, ThresholdStr );
400 else if ( ThresholdID.Length() != 2 )
401 aCommand->SetArg( 4, ThresholdID );
403 aCommand->SetArg( 4, Threshold );
404 // find the last not default arg
406 if ( Tolerance == dftlTol ) {
408 if ( BinaryOp == dfltFunctor ) {
410 if ( UnaryOp == dfltFunctor )
414 if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
415 if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
416 if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
417 if ( Precision != dftlPreci )
419 TCollection_AsciiString crit = aCommand->GetResultValue();
420 aCommand->GetString() += "; ";
421 aCommand->GetString() += crit + ".Precision = " + Precision;
427 //================================================================================
429 * \brief Convert the command or remember it for later conversion
430 * \param theCommand - The python command calling a method of SMESH_Gen
432 //================================================================================
434 void _pyGen::Process( const Handle(_pyCommand)& theCommand )
436 // there are methods to convert:
437 // CreateMesh( shape )
438 // Concatenate( [mesh1, ...], ... )
439 // CreateHypothesis( theHypType, theLibName )
440 // Compute( mesh, geom )
441 // Evaluate( mesh, geom )
443 TCollection_AsciiString method = theCommand->GetMethod();
445 if ( method == "CreateMesh" || method == "CreateEmptyMesh")
447 Handle(_pyMesh) mesh = new _pyMesh( theCommand );
448 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
451 if ( method == "CreateMeshesFromUNV" ||
452 method == "CreateMeshesFromSTL" ||
453 method == "CreateMeshesFromCGNS" ||
454 method == "CopyMesh" )
456 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
457 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
460 if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
462 for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
464 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
465 myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));
469 // CreateHypothesis()
470 if ( method == "CreateHypothesis" )
472 // issue 199929, remove standard library name (default parameter)
473 const TCollection_AsciiString & aLibName = theCommand->GetArg( 2 );
474 if ( aLibName.Search( "StdMeshersEngine" ) != -1 ) {
475 // keep first argument
476 TCollection_AsciiString arg = theCommand->GetArg( 1 );
477 theCommand->RemoveArgs();
478 theCommand->SetArg( 1, arg );
481 myHypos.push_back( _pyHypothesis::NewHypothesis( theCommand ));
485 // smeshgen.Compute( mesh, geom ) --> mesh.Compute()
486 if ( method == "Compute" )
488 const _pyID& meshID = theCommand->GetArg( 1 );
489 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
490 if ( id_mesh != myMeshes.end() ) {
491 theCommand->SetObject( meshID );
492 theCommand->RemoveArgs();
493 id_mesh->second->Flush();
498 // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
499 if ( method == "Evaluate" )
501 const _pyID& meshID = theCommand->GetArg( 1 );
502 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
503 if ( id_mesh != myMeshes.end() ) {
504 theCommand->SetObject( meshID );
505 _pyID geom = theCommand->GetArg( 2 );
506 theCommand->RemoveArgs();
507 theCommand->SetArg( 1, geom );
512 // objects erasing creation command if no more it's commands invoked:
513 // SMESH_Pattern, FilterManager
514 if ( method == "GetPattern" ||
515 method == "CreateFilterManager" ||
516 method == "CreateMeasurements" ) {
517 Handle(_pyObject) obj = new _pySelfEraser( theCommand );
518 if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
519 theCommand->Clear(); // already created
522 // Concatenate( [mesh1, ...], ... )
523 if ( method == "Concatenate" || method == "ConcatenateWithGroups")
525 if ( method == "ConcatenateWithGroups" ) {
526 theCommand->SetMethod( "Concatenate" );
527 theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" );
529 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
530 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
531 AddMeshAccessorMethod( theCommand );
534 // Replace name of SMESH_Gen
536 // names of SMESH_Gen methods fully equal to methods defined in smesh.py
537 static TStringSet smeshpyMethods;
538 if ( smeshpyMethods.empty() ) {
539 const char * names[] =
540 { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy",
541 "GetPattern","GetSubShapesId",
542 "" }; // <- mark of array end
543 smeshpyMethods.Insert( names );
545 if ( smeshpyMethods.Contains( theCommand->GetMethod() ))
546 // smeshgen.Method() --> smesh.Method()
547 theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() );
549 // smeshgen.Method() --> smesh.smesh.Method()
550 theCommand->SetObject( SMESH_2smeshpy::GenName() );
553 //================================================================================
555 * \brief Convert the remembered commands
557 //================================================================================
561 // create empty command
562 myLastCommand = new _pyCommand();
564 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
565 for ( ; id_mesh != myMeshes.end(); ++id_mesh )
566 if ( ! id_mesh->second.IsNull() )
567 id_mesh->second->Flush();
569 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
570 for ( ; hyp != myHypos.end(); ++hyp )
571 if ( !hyp->IsNull() ) {
573 // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
574 if ( !(*hyp)->IsWrapped() )
575 (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
578 map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
579 for ( ; id_obj != myObjects.end(); ++id_obj )
580 if ( ! id_obj->second.IsNull() )
581 id_obj->second->Flush();
583 myLastCommand->SetOrderNb( ++myNbCommands );
584 myCommands.push_back( myLastCommand );
587 //================================================================================
589 * \brief Add access method to mesh that is an argument
590 * \param theCmd - command to add access method
591 * \retval bool - true if added
593 //================================================================================
595 bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
598 map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
599 for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
600 if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
606 //================================================================================
608 * \brief Add access method to algo that is an object or an argument
609 * \param theCmd - command to add access method
610 * \retval bool - true if added
612 //================================================================================
614 bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
617 list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
618 for ( ; hyp != myHypos.end(); ++hyp ) {
619 if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
620 theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
626 //================================================================================
628 * \brief Find hypothesis by ID (entry)
629 * \param theHypID - The hypothesis ID
630 * \retval Handle(_pyHypothesis) - The found hypothesis
632 //================================================================================
634 Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID )
636 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
637 for ( ; hyp != myHypos.end(); ++hyp )
638 if ( !hyp->IsNull() && theHypID == (*hyp)->GetID() )
640 return Handle(_pyHypothesis)();
643 //================================================================================
645 * \brief Find algorithm the created algorithm
646 * \param theGeom - The shape ID the algorithm was created on
647 * \param theMesh - The mesh ID that created the algorithm
648 * \param dim - The algo dimension
649 * \retval Handle(_pyHypothesis) - The found algo
651 //================================================================================
653 Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
654 const Handle(_pyHypothesis)& theHypothesis )
656 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
657 for ( ; hyp != myHypos.end(); ++hyp )
658 if ( !hyp->IsNull() &&
660 theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
661 (*hyp)->GetGeom() == theGeom &&
662 (*hyp)->GetMesh() == theMesh )
667 //================================================================================
669 * \brief Find subMesh by ID (entry)
670 * \param theSubMeshID - The subMesh ID
671 * \retval Handle(_pySubMesh) - The found subMesh
673 //================================================================================
675 Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
677 map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID);
678 if ( id_subMesh != myObjects.end() )
679 return Handle(_pySubMesh)::DownCast( id_subMesh->second );
680 return Handle(_pySubMesh)();
684 //================================================================================
686 * \brief Change order of commands in the script
687 * \param theCmd1 - One command
688 * \param theCmd2 - Another command
690 //================================================================================
692 void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 )
694 list< Handle(_pyCommand) >::iterator pos1, pos2;
695 pos1 = find( myCommands.begin(), myCommands.end(), theCmd1 );
696 pos2 = find( myCommands.begin(), myCommands.end(), theCmd2 );
697 myCommands.insert( pos1, theCmd2 );
698 myCommands.insert( pos2, theCmd1 );
699 myCommands.erase( pos1 );
700 myCommands.erase( pos2 );
702 int nb1 = theCmd1->GetOrderNb();
703 theCmd1->SetOrderNb( theCmd2->GetOrderNb() );
704 theCmd2->SetOrderNb( nb1 );
705 // cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl
706 // << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl;
709 //================================================================================
711 * \brief Set one command after the other
712 * \param theCmd - Command to move
713 * \param theAfterCmd - Command ater which to insert the first one
715 //================================================================================
717 void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
719 setNeighbourCommand( theCmd, theAfterCmd, true );
722 //================================================================================
724 * \brief Set one command before the other
725 * \param theCmd - Command to move
726 * \param theBeforeCmd - Command before which to insert the first one
728 //================================================================================
730 void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd )
732 setNeighbourCommand( theCmd, theBeforeCmd, false );
735 //================================================================================
737 * \brief Set one command before or after the other
738 * \param theCmd - Command to move
739 * \param theOtherCmd - Command ater or before which to insert the first one
741 //================================================================================
743 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
744 Handle(_pyCommand)& theOtherCmd,
745 const bool theIsAfter )
747 list< Handle(_pyCommand) >::iterator pos;
748 pos = find( myCommands.begin(), myCommands.end(), theCmd );
749 myCommands.erase( pos );
750 pos = find( myCommands.begin(), myCommands.end(), theOtherCmd );
751 myCommands.insert( (theIsAfter ? ++pos : pos), theCmd );
754 for ( pos = myCommands.begin(); pos != myCommands.end(); ++pos)
755 (*pos)->SetOrderNb( i++ );
758 //================================================================================
760 * \brief Set command be last in list of commands
761 * \param theCmd - Command to be last
763 //================================================================================
765 Handle(_pyCommand)& _pyGen::GetLastCommand()
767 return myLastCommand;
770 //================================================================================
772 * \brief Set method to access to object wrapped with python class
773 * \param theID - The wrapped object entry
774 * \param theMethod - The accessor method
776 //================================================================================
778 void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod )
780 myID2AccessorMethod.Bind( theID, (char*) theMethod );
783 //================================================================================
785 * \brief Generated new ID for object and assign with existing name
786 * \param theID - ID of existing object
788 //================================================================================
790 _pyID _pyGen::GenerateNewID( const _pyID& theID )
795 aNewID = theID + _pyID( ":" ) + _pyID( index++ );
797 while ( myObjectNames.IsBound( aNewID ) );
799 myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
800 ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
801 : _pyID( "A" ) + aNewID );
805 //================================================================================
807 * \brief Stores theObj in myObjects
809 //================================================================================
811 void _pyGen::AddObject( Handle(_pyObject)& theObj )
813 myObjects.insert( make_pair( theObj->GetID(), theObj ));
816 //================================================================================
818 * \brief Finds a _pyObject by ID
820 //================================================================================
822 Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID ) const
824 std::map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
825 return ( id_obj == myObjects.end() ) ? Handle(_pyObject)() : id_obj->second;
828 //================================================================================
830 * \brief Find out type of geom group
831 * \param grpID - The geom group entry
832 * \retval int - The type
834 //================================================================================
836 // static bool sameGroupType( const _pyID& grpID,
837 // const TCollection_AsciiString& theType)
839 // // define group type as smesh.Mesh.Group() does
841 // SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
842 // SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
843 // if ( !aSObj->_is_nil() ) {
844 // GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
845 // if ( !aGeomObj->_is_nil() ) {
846 // switch ( aGeomObj->GetShapeType() ) {
847 // case GEOM::VERTEX: type = SMESH::NODE; break;
848 // case GEOM::EDGE: type = SMESH::EDGE; break;
849 // case GEOM::FACE: type = SMESH::FACE; break;
851 // case GEOM::SHELL: type = SMESH::VOLUME; break;
852 // case GEOM::COMPOUND: {
853 // GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
854 // if ( !aGeomGen->_is_nil() ) {
855 // GEOM::GEOM_IGroupOperations_var aGrpOp =
856 // aGeomGen->GetIGroupOperations( study->StudyId() );
857 // if ( !aGrpOp->_is_nil() ) {
858 // switch ( aGrpOp->GetType( aGeomObj )) {
859 // case TopAbs_VERTEX: type = SMESH::NODE; break;
860 // case TopAbs_EDGE: type = SMESH::EDGE; break;
861 // case TopAbs_FACE: type = SMESH::FACE; break;
862 // case TopAbs_SOLID: type = SMESH::VOLUME; break;
873 // MESSAGE("Type of the group " << grpID << " not found");
876 // if ( theType.IsIntegerValue() )
877 // return type == theType.IntegerValue();
880 // case SMESH::NODE: return theType.Location( "NODE", 1, theType.Length() );
881 // case SMESH::EDGE: return theType.Location( "EDGE", 1, theType.Length() );
882 // case SMESH::FACE: return theType.Location( "FACE", 1, theType.Length() );
883 // case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
889 //================================================================================
892 * \param theCreationCmd -
894 //================================================================================
896 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
897 : _pyObject(theCreationCmd), myHasEditor(false)
899 // convert my creation command
900 Handle(_pyCommand) creationCmd = GetCreationCmd();
901 //TCollection_AsciiString str = creationCmd->GetMethod();
902 // if(str != "CreateMeshesFromUNV" &&
903 // str != "CreateMeshesFromMED" &&
904 // str != "CreateMeshesFromSTL")
905 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
906 creationCmd->SetMethod( "Mesh" );
908 theGen->SetAccessorMethod( GetID(), "GetMesh()" );
911 //================================================================================
914 * \param theCreationCmd -
916 //================================================================================
917 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
918 _pyObject(theCreationCmd), myHasEditor(false)
920 // convert my creation command
921 Handle(_pyCommand) creationCmd = GetCreationCmd();
922 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
923 theGen->SetAccessorMethod( id, "GetMesh()" );
926 //================================================================================
928 * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
929 * \param theCommand - Engine method called for this mesh
931 //================================================================================
933 void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
935 // some methods of SMESH_Mesh interface needs special conversion
936 // to methods of Mesh python class
938 // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo)
939 // --> in Mesh_Algorithm.Create(mesh, geom, hypo, so)
940 // 2. AddHypothesis(geom, hyp)
941 // --> in Mesh_Algorithm.Hypothesis(hyp, args, so)
942 // 3. CreateGroupFromGEOM(type, name, grp)
943 // --> in Mesh.Group(grp, name="")
944 // 4. ExportToMED(f, auto_groups, version)
945 // --> in Mesh.ExportMED( f, auto_groups, version )
948 const TCollection_AsciiString method = theCommand->GetMethod();
949 // ----------------------------------------------------------------------
950 if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
951 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
952 if ( !subMesh.IsNull() ) {
953 subMesh->SetCreator( this );
954 mySubmeshes.push_back( subMesh );
957 // ----------------------------------------------------------------------
958 else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
959 myAddHypCmds.push_back( theCommand );
961 const _pyID& hypID = theCommand->GetArg( 2 );
962 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
963 if ( !hyp.IsNull() ) {
964 myHypos.push_back( hyp );
965 if ( hyp->GetMesh().IsEmpty() )
966 hyp->SetMesh( this->GetID() );
969 // ----------------------------------------------------------------------
970 else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
971 _pyID grp = theCommand->GetArg( 3 );
972 // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
973 // next if(){...} section is commented
974 //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
975 // theCommand->SetMethod( "Group" );
976 // theCommand->RemoveArgs();
977 // theCommand->SetArg( 1, grp );
980 // ------------------------->>>>> GroupOnGeom( grp, name, typ )
981 _pyID type = theCommand->GetArg( 1 );
982 _pyID name = theCommand->GetArg( 2 );
983 theCommand->SetMethod( "GroupOnGeom" );
984 theCommand->RemoveArgs();
985 theCommand->SetArg( 1, grp );
986 theCommand->SetArg( 2, name );
987 theCommand->SetArg( 3, type );
990 // ----------------------------------------------------------------------
991 else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
993 theCommand->SetMethod( "GroupOnFilter" );
994 // GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
995 _pyID filterID = theCommand->GetArg(3);
996 Handle(_pyObject) filter = theGen->FindObject( filterID );
997 if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
998 filter->Process( theCommand );
1000 // ----------------------------------------------------------------------
1001 else if ( method == "GetIdsFromFilter" )
1003 // GetIdsFromFilter( aFilter0x4743dc0) -> GetIdsFromFilter( aFilter_1)
1004 _pyID filterID = theCommand->GetArg(1);
1005 Handle(_pyObject) filter = theGen->FindObject( filterID );
1006 if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
1007 filter->Process( theCommand );
1009 // ----------------------------------------------------------------------
1010 else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
1012 theCommand->SetMethod( "CreateEmptyGroup" );
1013 Handle(_pyGroup) group = new _pyGroup( theCommand );
1014 theGen->AddObject( group );
1016 // ----------------------------------------------------------------------
1017 else if ( method == "ExportToMED" || // ExportToMED() --> ExportMED()
1018 method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
1019 theCommand->SetMethod( "ExportMED" );
1021 // ----------------------------------------------------------------------
1022 else if ( method == "ExportCGNS" )
1023 { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
1024 _pyID partID = theCommand->GetArg( 1 );
1025 int nbArgs = theCommand->GetNbArgs();
1026 for ( int i = 2; i <= nbArgs; ++i )
1027 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1028 theCommand->SetArg( nbArgs, partID );
1030 // ----------------------------------------------------------------------
1031 else if ( method.Location( "ExportPartTo", 1, method.Length() ) == 1 )
1032 { // ExportPartTo*(part, ...) -> Export*(..., part)
1034 // remove "PartTo" from the method
1035 TCollection_AsciiString newMethod = method;
1036 newMethod.Remove( 7, 6 );
1037 theCommand->SetMethod( newMethod );
1038 // make the 1st arg be the last one
1039 _pyID partID = theCommand->GetArg( 1 );
1040 int nbArgs = theCommand->GetNbArgs();
1041 for ( int i = 2; i <= nbArgs; ++i )
1042 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1043 theCommand->SetArg( nbArgs, partID );
1045 // ----------------------------------------------------------------------
1046 else if ( method == "RemoveHypothesis" ) // (geom, hyp)
1048 _pyID hypID = theCommand->GetArg( 2 );
1050 // check if this mesh still has corresponding addition command
1051 bool hasAddCmd = false;
1052 list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
1053 while ( cmd != myAddHypCmds.end() )
1055 // AddHypothesis(geom, hyp)
1056 if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
1057 theCommand->Clear();
1059 cmd = myAddHypCmds.erase( cmd );
1066 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1067 if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
1068 // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
1069 _pyID geom = theCommand->GetArg( 1 );
1070 theCommand->RemoveArgs();
1071 theCommand->SetArg( 1, hypID );
1072 if ( geom != GetGeom() )
1073 theCommand->SetArg( 2, geom );
1075 // remove hyp from myHypos
1076 myHypos.remove( hyp );
1078 // check for SubMesh order commands
1079 else if ( theCommand->GetMethod() == "GetMeshOrder" ||
1080 theCommand->GetMethod() == "SetMeshOrder" )
1082 // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
1083 // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
1084 // commands are moved at the end of the script
1085 const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
1086 const TCollection_AsciiString& cmdStr = theCommand->GetString();
1087 int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
1088 int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
1089 if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
1090 TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
1091 Standard_Integer index = 1;
1092 TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
1093 while ( !anIDStr.IsEmpty() ) {
1094 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
1095 if ( !subMesh.IsNull() )
1096 subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
1097 anIDStr = aSubStr.Token("\t ,[]", index++);
1101 // add accessor method if necessary
1104 if ( NeedMeshAccess( theCommand ))
1105 // apply theCommand to the mesh wrapped by smeshpy mesh
1106 AddMeshAccess( theCommand );
1110 //================================================================================
1112 * \brief Return True if addition of accesor method is needed
1114 //================================================================================
1116 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
1118 // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
1119 // so no conversion is needed for them at all:
1120 static TStringSet sameMethods;
1121 if ( sameMethods.empty() ) {
1122 const char * names[] =
1123 { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
1124 "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
1125 "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
1126 "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
1127 "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes",
1128 "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder",
1129 "NbPyramids","NbPyramidsOfOrder","NbPrisms","NbPrismsOfOrder","NbPolyhedrons",
1130 "NbSubMesh","GetElementsId","GetElementsByType","GetNodesId","GetElementType",
1131 "GetSubMeshElementsId","GetSubMeshNodesId","GetSubMeshElementType","Dump","GetNodeXYZ",
1132 "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
1133 "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
1134 "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
1135 "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
1136 ,"" }; // <- mark of end
1137 sameMethods.Insert( names );
1140 return !sameMethods.Contains( theCommand->GetMethod() );
1143 //================================================================================
1145 * \brief Convert creation and addition of all algos and hypos
1147 //================================================================================
1149 void _pyMesh::Flush()
1151 list < Handle(_pyCommand) >::iterator cmd;
1153 // try to convert algo addition like this:
1154 // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo()
1155 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1157 Handle(_pyCommand) addCmd = *cmd;
1159 _pyID algoID = addCmd->GetArg( 2 );
1160 Handle(_pyHypothesis) algo = theGen->FindHyp( algoID );
1161 if ( algo.IsNull() || !algo->IsAlgo() )
1164 // check and create new algorithm instance if it is already wrapped
1165 if ( algo->IsWrapped() ) {
1166 _pyID localAlgoID = theGen->GenerateNewID( algoID );
1167 TCollection_AsciiString aNewCmdStr = localAlgoID +
1168 TCollection_AsciiString( " = " ) + theGen->GetID() +
1169 TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
1170 TCollection_AsciiString( "\" )" );
1172 Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
1173 Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
1174 if ( !newAlgo.IsNull() ) {
1175 newAlgo->Assign( algo, this->GetID() );
1176 newAlgo->SetCreationCmd( newCmd );
1178 // set algorithm creation
1179 theGen->SetCommandBefore( newCmd, addCmd );
1184 _pyID geom = addCmd->GetArg( 1 );
1185 bool isLocalAlgo = ( geom != GetGeom() );
1188 if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
1190 // wrapped algo is created atfer mesh creation
1191 GetCreationCmd()->AddDependantCmd( addCmd );
1193 if ( isLocalAlgo ) {
1194 // mesh.AddHypothesis(geom, ALGO ) --> mesh.AlgoMethod(geom)
1195 addCmd->SetArg( addCmd->GetNbArgs() + 1,
1196 TCollection_AsciiString( "geom=" ) + geom );
1197 // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
1198 list < Handle(_pySubMesh) >::iterator smIt;
1199 for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
1200 Handle(_pySubMesh) subMesh = *smIt;
1201 Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
1202 if ( geom == subCmd->GetArg( 1 )) {
1203 subCmd->SetObject( algo->GetID() );
1204 subCmd->RemoveArgs();
1205 subMesh->SetCreator( algo );
1210 else // KO - ALGO was already created
1212 // mesh.AddHypothesis(geom, ALGO) --> mesh.AddHypothesis(ALGO, geom=0)
1213 addCmd->RemoveArgs();
1214 addCmd->SetArg( 1, algoID );
1216 addCmd->SetArg( 2, geom );
1220 // try to convert hypo addition like this:
1221 // mesh.AddHypothesis(geom, HYPO ) --> HYPO = algo.Hypo()
1222 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1224 Handle(_pyCommand) addCmd = *cmd;
1225 _pyID hypID = addCmd->GetArg( 2 );
1226 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1227 if ( hyp.IsNull() || hyp->IsAlgo() )
1229 bool converted = hyp->Addition2Creation( addCmd, this->GetID() );
1231 // mesh.AddHypothesis(geom, HYP) --> mesh.AddHypothesis(HYP, geom=0)
1232 _pyID geom = addCmd->GetArg( 1 );
1233 addCmd->RemoveArgs();
1234 addCmd->SetArg( 1, hypID );
1235 if ( geom != GetGeom() )
1236 addCmd->SetArg( 2, geom );
1240 // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name)
1241 // for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) {
1242 // Handle(_pyCommand) subCmd = *cmd;
1243 // if ( subCmd->GetNbArgs() > 0 )
1244 // AddMeshAccess( subCmd );
1246 myAddHypCmds.clear();
1247 mySubmeshes.clear();
1250 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
1251 for ( ; hyp != myHypos.end(); ++hyp )
1255 //================================================================================
1257 * \brief MeshEditor convert its commands to ones of mesh
1259 //================================================================================
1261 _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
1262 _pyObject( theCreationCmd )
1264 myMesh = theCreationCmd->GetObject();
1265 myCreationCmdStr = theCreationCmd->GetString();
1266 theCreationCmd->Clear();
1269 //================================================================================
1271 * \brief convert its commands to ones of mesh
1273 //================================================================================
1275 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
1277 // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
1278 // commands calling this methods are converted to calls of methods of Mesh
1279 static TStringSet sameMethods;
1280 if ( sameMethods.empty() ) {
1281 const char * names[] = {
1282 "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
1283 "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
1284 "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
1285 "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
1286 "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
1287 "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
1288 "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
1289 "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
1290 "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
1291 "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
1292 "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
1293 "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
1294 "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
1295 "GetLastCreatedElems",
1296 "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
1297 "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
1298 ,"" }; // <- mark of the end
1299 sameMethods.Insert( names );
1302 // names of SMESH_MeshEditor methods which differ from methods of class Mesh
1303 // only by last two arguments
1304 static TStringSet diffLastTwoArgsMethods;
1305 if (diffLastTwoArgsMethods.empty() ) {
1306 const char * names[] = {
1307 "MirrorMakeGroups","MirrorObjectMakeGroups",
1308 "TranslateMakeGroups","TranslateObjectMakeGroups",
1309 "RotateMakeGroups","RotateObjectMakeGroups",
1310 ""};// <- mark of the end
1311 diffLastTwoArgsMethods.Insert( names );
1314 const TCollection_AsciiString & method = theCommand->GetMethod();
1315 bool isPyMeshMethod = sameMethods.Contains( method );
1316 if ( !isPyMeshMethod )
1318 //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
1319 //functions with the flag "theMakeGroups = True" like:
1320 //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
1321 int pos = method.Search("MakeGroups");
1324 isPyMeshMethod = true;
1326 // 1. Remove "MakeGroups" from the Command
1327 TCollection_AsciiString aMethod = theCommand->GetMethod();
1328 int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
1329 aMethod.Trunc(pos-1);
1330 theCommand->SetMethod(aMethod);
1332 // 2. And add last "True" argument(s)
1333 while(nbArgsToAdd--)
1334 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1338 // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
1339 if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
1341 isPyMeshMethod=true;
1342 theCommand->SetMethod("ExtrusionAlongPathX");
1345 // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
1346 if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
1348 isPyMeshMethod=true;
1349 theCommand->SetMethod("FindCoincidentNodesOnPart");
1351 // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
1352 // DoubleNodeGroupNew() -> DoubleNodeGroup()
1353 // DoubleNodeGroupsNew() -> DoubleNodeGroups()
1354 // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
1355 if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" ||
1356 method == "DoubleNodeElemGroupsNew" ||
1357 method == "DoubleNodeGroupNew" ||
1358 method == "DoubleNodeGroupsNew"))
1360 isPyMeshMethod=true;
1361 theCommand->SetMethod( method.SubString( 1, method.Length()-3));
1362 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1364 // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
1365 // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
1366 if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
1367 method == "ConvertFromQuadraticObject" ))
1369 isPyMeshMethod=true;
1370 theCommand->SetMethod( method.SubString( 1, method.Length()-6));
1371 // prevent moving creation of the converted sub-mesh to the end of the script
1372 bool isFromQua = ( method.Value( 8 ) == 'F' );
1373 Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
1375 sm->Process( theCommand );
1377 // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
1378 // FindElementsByPoint(x, y, z, elementType, meshPart)
1379 if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
1381 isPyMeshMethod=true;
1382 theCommand->SetMethod( "FindElementsByPoint" );
1383 // make the 1st arg be the last one
1384 _pyID partID = theCommand->GetArg( 1 );
1385 int nbArgs = theCommand->GetNbArgs();
1386 for ( int i = 2; i <= nbArgs; ++i )
1387 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1388 theCommand->SetArg( nbArgs, partID );
1391 // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
1392 // so let _pyMesh care of it (TMP?)
1393 // if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
1394 // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
1395 if ( isPyMeshMethod )
1397 theCommand->SetObject( myMesh );
1401 // editor creation command is needed only if any editor function is called
1402 theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
1403 if ( !myCreationCmdStr.IsEmpty() ) {
1404 GetCreationCmd()->GetString() = myCreationCmdStr;
1405 myCreationCmdStr.Clear();
1410 //================================================================================
1412 * \brief _pyHypothesis constructor
1413 * \param theCreationCmd -
1415 //================================================================================
1417 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
1418 _pyObject( theCreationCmd )
1420 myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
1423 //================================================================================
1425 * \brief Creates algorithm or hypothesis
1426 * \param theCreationCmd - The engine command creating a hypothesis
1427 * \retval Handle(_pyHypothesis) - Result _pyHypothesis
1429 //================================================================================
1431 Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& theCreationCmd)
1433 // theCreationCmd: CreateHypothesis( "theHypType", "theLibName" )
1434 ASSERT (( theCreationCmd->GetMethod() == "CreateHypothesis"));
1436 Handle(_pyHypothesis) hyp, algo;
1439 const TCollection_AsciiString & hypTypeQuoted = theCreationCmd->GetArg( 1 );
1440 if ( hypTypeQuoted.IsEmpty() )
1443 TCollection_AsciiString hypType =
1444 hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1446 algo = new _pyAlgorithm( theCreationCmd );
1447 hyp = new _pyHypothesis( theCreationCmd );
1449 // 1D Regular_1D ----------
1450 if ( hypType == "Regular_1D" ) {
1451 // set mesh's method creating algo,
1452 // i.e. convertion result will be "regular1d = Mesh.Segment()",
1453 // and set hypType by which algo creating a hypothesis is searched for
1454 algo->SetConvMethodAndType("Segment", hypType.ToCString());
1456 else if ( hypType == "CompositeSegment_1D" ) {
1457 algo->SetConvMethodAndType("Segment", "Regular_1D");
1458 algo->myArgs.Append( "algo=smesh.COMPOSITE");
1460 else if ( hypType == "LocalLength" ) {
1461 // set algo's method creating hyp, and algo type
1462 hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
1463 // set method whose 1 arg will become the 1-st arg of hyp creation command
1464 // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
1465 hyp->AddArgMethod( "SetLength" );
1467 else if ( hypType == "MaxLength" ) {
1468 // set algo's method creating hyp, and algo type
1469 hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
1470 // set method whose 1 arg will become the 1-st arg of hyp creation command
1471 // i.e. convertion result will be "maxsize = regular1d.MaxSize(<arg of SetLength()>)"
1472 hyp->AddArgMethod( "SetLength" );
1474 else if ( hypType == "NumberOfSegments" ) {
1475 hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
1476 hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
1477 // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
1478 hyp->AddArgMethod( "SetNumberOfSegments" );
1479 // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
1480 hyp->AddArgMethod( "SetScaleFactor" );
1481 hyp->AddArgMethod( "SetReversedEdges" );
1483 else if ( hypType == "Arithmetic1D" ) {
1484 hyp = new _pyComplexParamHypo( theCreationCmd );
1485 hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
1486 hyp->AddArgMethod( "SetStartLength" );
1487 hyp->AddArgMethod( "SetEndLength" );
1488 hyp->AddArgMethod( "SetReversedEdges" );
1490 else if ( hypType == "StartEndLength" ) {
1491 hyp = new _pyComplexParamHypo( theCreationCmd );
1492 hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
1493 hyp->AddArgMethod( "SetStartLength" );
1494 hyp->AddArgMethod( "SetEndLength" );
1495 hyp->AddArgMethod( "SetReversedEdges" );
1497 else if ( hypType == "Deflection1D" ) {
1498 hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
1499 hyp->AddArgMethod( "SetDeflection" );
1501 else if ( hypType == "Propagation" ) {
1502 hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
1504 else if ( hypType == "QuadraticMesh" ) {
1505 hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
1507 else if ( hypType == "AutomaticLength" ) {
1508 hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
1509 hyp->AddArgMethod( "SetFineness");
1511 else if ( hypType == "SegmentLengthAroundVertex" ) {
1512 hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
1513 hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
1514 hyp->AddArgMethod( "SetLength" );
1516 // 1D Python_1D ----------
1517 else if ( hypType == "Python_1D" ) {
1518 algo->SetConvMethodAndType( "Segment", hypType.ToCString());
1519 algo->myArgs.Append( "algo=smesh.PYTHON");
1521 else if ( hypType == "PythonSplit1D" ) {
1522 hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
1523 hyp->AddArgMethod( "SetNumberOfSegments");
1524 hyp->AddArgMethod( "SetPythonLog10RatioFunction");
1526 // MEFISTO_2D ----------
1527 else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D
1528 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1530 else if ( hypType == "MaxElementArea" ) {
1531 hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
1532 hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY");
1533 hyp->AddArgMethod( "SetMaxElementArea");
1535 else if ( hypType == "LengthFromEdges" ) {
1536 hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
1537 hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY");
1539 // Quadrangle_2D ----------
1540 else if ( hypType == "Quadrangle_2D" ) {
1541 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1543 else if ( hypType == "QuadranglePreference" ) {
1544 hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
1545 hyp->SetConvMethodAndType( "SetQuadAllowed", "NETGEN_2D_ONLY");
1547 else if ( hypType == "TrianglePreference" ) {
1548 hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
1550 // RadialQuadrangle_1D2D ----------
1551 else if ( hypType == "RadialQuadrangle_1D2D" ) {
1552 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1553 algo->myArgs.Append( "algo=smesh.RADIAL_QUAD" );
1555 else if ( hypType == "NumberOfLayers2D" ) {
1556 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialQuadrangle_1D2D");
1557 hyp->AddArgMethod( "SetNumberOfLayers" );
1559 else if ( hypType == "LayerDistribution2D" ) {
1560 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
1561 hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
1563 // BLSURF ----------
1564 else if ( hypType == "BLSURF" ) {
1565 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1566 algo->myArgs.Append( "algo=smesh.BLSURF" );
1568 else if ( hypType == "BLSURF_Parameters") {
1569 hyp->SetConvMethodAndType( "Parameters", "BLSURF");
1571 // NETGEN ----------
1572 else if ( hypType == "NETGEN_2D") { // 1D-2D
1573 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1574 algo->myArgs.Append( "algo=smesh.NETGEN" );
1576 else if ( hypType == "NETGEN_Parameters_2D") {
1577 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1579 else if ( hypType == "NETGEN_SimpleParameters_2D") {
1580 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1581 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1583 else if ( hypType == "NETGEN_2D3D") { // 1D-2D-3D
1584 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1585 algo->myArgs.Append( "algo=smesh.FULL_NETGEN" );
1587 else if ( hypType == "NETGEN_Parameters") {
1588 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1590 else if ( hypType == "NETGEN_SimpleParameters_3D") {
1591 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1592 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1594 else if ( hypType == "NETGEN_2D_ONLY") { // 2D
1595 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1596 algo->myArgs.Append( "algo=smesh.NETGEN_2D" );
1598 else if ( hypType == "NETGEN_3D") { // 3D
1599 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1600 algo->myArgs.Append( "algo=smesh.NETGEN" );
1602 else if ( hypType == "MaxElementVolume") {
1603 hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
1604 hyp->AddArgMethod( "SetMaxElementVolume" );
1606 // GHS3D_3D ----------
1607 else if ( hypType == "GHS3D_3D" ) {
1608 algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
1609 algo->myArgs.Append( "algo=smesh.GHS3D" );
1611 else if ( hypType == "GHS3D_Parameters") {
1612 hyp->SetConvMethodAndType( "Parameters", "GHS3D_3D");
1614 // Hexa_3D ---------
1615 else if ( hypType == "BLSURF" ) {
1616 algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
1618 // Repetitive Projection_1D ---------
1619 else if ( hypType == "Projection_1D" ) {
1620 algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
1622 else if ( hypType == "ProjectionSource1D" ) {
1623 hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
1624 hyp->AddArgMethod( "SetSourceEdge");
1625 hyp->AddArgMethod( "SetSourceMesh");
1626 // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
1627 hyp->AddArgMethod( "SetVertexAssociation", 2 );
1629 // Projection_2D ---------
1630 else if ( hypType == "Projection_2D" ) {
1631 algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
1633 else if ( hypType == "Projection_1D2D" ) {
1634 algo->SetConvMethodAndType( "Projection1D2D", hypType.ToCString());
1636 else if ( hypType == "ProjectionSource2D" ) {
1637 hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
1638 hyp->AddArgMethod( "SetSourceFace");
1639 hyp->AddArgMethod( "SetSourceMesh");
1640 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1642 // Projection_3D ---------
1643 else if ( hypType == "Projection_3D" ) {
1644 algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
1646 else if ( hypType == "ProjectionSource3D" ) {
1647 hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
1648 hyp->AddArgMethod( "SetSource3DShape");
1649 hyp->AddArgMethod( "SetSourceMesh");
1650 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1652 // Prism_3D ---------
1653 else if ( hypType == "Prism_3D" ) {
1654 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1656 // RadialPrism_3D ---------
1657 else if ( hypType == "RadialPrism_3D" ) {
1658 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1660 else if ( hypType == "NumberOfLayers" ) {
1661 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
1662 hyp->AddArgMethod( "SetNumberOfLayers" );
1664 else if ( hypType == "LayerDistribution" ) {
1665 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
1666 hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
1669 return algo->IsValid() ? algo : hyp;
1672 //================================================================================
1674 * \brief Convert the command adding a hypothesis to mesh into a smesh command
1675 * \param theCmd - The command like mesh.AddHypothesis( geom, hypo )
1676 * \param theAlgo - The algo that can create this hypo
1677 * \retval bool - false if the command cant be converted
1679 //================================================================================
1681 bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
1682 const _pyID& theMesh)
1684 ASSERT(( theCmd->GetMethod() == "AddHypothesis" ));
1686 if ( !IsWrappable( theMesh ))
1689 myGeom = theCmd->GetArg( 1 );
1691 Handle(_pyHypothesis) algo;
1693 // find algo created on myGeom in theMesh
1694 algo = theGen->FindAlgo( myGeom, theMesh, this );
1695 if ( algo.IsNull() )
1697 // attach hypothesis creation command to be after algo creation command
1698 // because it can be new created instance of algorithm
1699 algo->GetCreationCmd()->AddDependantCmd( theCmd );
1703 // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
1704 theCmd->SetResultValue( GetID() );
1705 theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
1706 theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() ));
1708 theCmd->RemoveArgs();
1709 for ( int i = 1; i <= myArgs.Length(); ++i ) {
1710 if ( !myArgs( i ).IsEmpty() )
1711 theCmd->SetArg( i, myArgs( i ));
1713 theCmd->SetArg( i, "[]");
1715 // set a new creation command
1716 GetCreationCmd()->Clear();
1717 // replace creation command by wrapped instance
1718 // please note, that hypothesis attaches to algo creation command (see upper)
1719 SetCreationCmd( theCmd );
1722 // clear commands setting arg values
1723 list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
1724 for ( ; argCmd != myArgCommands.end(); ++argCmd )
1727 // set unknown arg commands after hypo creation
1728 Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
1729 list<Handle(_pyCommand)>::iterator cmd = myUnknownCommands.begin();
1730 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1731 afterCmd->AddDependantCmd( *cmd );
1737 //================================================================================
1739 * \brief Remember hypothesis parameter values
1740 * \param theCommand - The called hypothesis method
1742 //================================================================================
1744 void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
1746 ASSERT( !myIsAlgo );
1749 for ( int i = 1; i <= myArgMethods.Length(); ++i ) {
1750 if ( myArgMethods( i ) == theCommand->GetMethod() ) {
1751 while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i ))
1752 myArgs.Append( "[]" );
1753 for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg )
1754 myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value
1755 myArgCommands.push_back( theCommand );
1758 nbArgs += myNbArgsByMethod( i );
1760 myUnknownCommands.push_back( theCommand );
1763 //================================================================================
1765 * \brief Finish conversion
1767 //================================================================================
1769 void _pyHypothesis::Flush()
1771 if ( IsWrapped() ) {
1774 list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
1775 for ( ; cmd != myArgCommands.end(); ++cmd ) {
1776 // Add access to a wrapped mesh
1777 theGen->AddMeshAccessorMethod( *cmd );
1778 // Add access to a wrapped algorithm
1779 theGen->AddAlgoAccessorMethod( *cmd );
1781 cmd = myUnknownCommands.begin();
1782 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1783 // Add access to a wrapped mesh
1784 theGen->AddMeshAccessorMethod( *cmd );
1785 // Add access to a wrapped algorithm
1786 theGen->AddAlgoAccessorMethod( *cmd );
1789 // forget previous hypothesis modifications
1790 myArgCommands.clear();
1791 myUnknownCommands.clear();
1794 //================================================================================
1796 * \brief clear creation, arg and unkown commands
1798 //================================================================================
1800 void _pyHypothesis::ClearAllCommands()
1802 GetCreationCmd()->Clear();
1803 list<Handle(_pyCommand)>::iterator cmd = myArgCommands.begin();
1804 for ( ; cmd != myArgCommands.end(); ++cmd )
1806 cmd = myUnknownCommands.begin();
1807 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1812 //================================================================================
1814 * \brief Assign fields of theOther to me except myIsWrapped
1816 //================================================================================
1818 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
1819 const _pyID& theMesh )
1821 myIsWrapped = false;
1824 // myCreationCmd = theOther->myCreationCmd;
1825 myIsAlgo = theOther->myIsAlgo;
1826 myGeom = theOther->myGeom;
1827 myType2CreationMethod = theOther->myType2CreationMethod;
1828 myArgs = theOther->myArgs;
1829 myArgMethods = theOther->myArgMethods;
1830 myNbArgsByMethod = theOther->myNbArgsByMethod;
1831 myArgCommands = theOther->myArgCommands;
1832 myUnknownCommands = theOther->myUnknownCommands;
1835 //================================================================================
1837 * \brief Remember hypothesis parameter values
1838 * \param theCommand - The called hypothesis method
1840 //================================================================================
1842 void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
1844 if( theCommand->GetMethod() == "SetLength" )
1846 // NOW it becomes OBSOLETE
1847 // ex: hyp.SetLength(start, 1)
1848 // hyp.SetLength(end, 0)
1849 ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
1850 int i = 2 - theCommand->GetArg( 2 ).IntegerValue();
1851 while ( myArgs.Length() < i )
1852 myArgs.Append( "[]" );
1853 myArgs( i ) = theCommand->GetArg( 1 ); // arg value
1854 myArgCommands.push_back( theCommand );
1858 _pyHypothesis::Process( theCommand );
1861 //================================================================================
1863 * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment
1865 //================================================================================
1867 void _pyComplexParamHypo::Flush()
1871 list < Handle(_pyCommand) >::iterator cmd = myUnknownCommands.begin();
1872 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1873 if ((*cmd)->GetMethod() == "SetObjectEntry" )
1878 //================================================================================
1880 * \brief Convert methods of 1D hypotheses to my own methods
1881 * \param theCommand - The called hypothesis method
1883 //================================================================================
1885 void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
1887 if ( theCommand->GetMethod() != "SetLayerDistribution" )
1890 _pyID newName; // name for 1D hyp = "HypType" + "_Distribution"
1892 const _pyID& hyp1dID = theCommand->GetArg( 1 );
1893 Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
1894 if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
1896 else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) {
1897 // 1D hypo is already set, so distribution changes and the old
1898 // 1D hypo is thrown away
1899 my1dHyp->ClearAllCommands();
1903 if ( !myArgCommands.empty() )
1904 myArgCommands.front()->Clear();
1905 myArgCommands.push_back( theCommand );
1908 //================================================================================
1911 * \param theAdditionCmd - command to be converted
1912 * \param theMesh - mesh instance
1913 * \retval bool - status
1915 //================================================================================
1917 bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
1918 const _pyID& theMesh)
1920 myIsWrapped = false;
1922 if ( my1dHyp.IsNull() )
1925 // set "SetLayerDistribution()" after addition cmd
1926 theAdditionCmd->AddDependantCmd( myArgCommands.front() );
1928 _pyID geom = theAdditionCmd->GetArg( 1 );
1930 Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
1931 if ( !algo.IsNull() )
1933 my1dHyp->SetMesh( theMesh );
1934 my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
1935 algo->GetAlgoType().ToCString());
1936 if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
1939 // clear "SetLayerDistribution()" cmd
1940 myArgCommands.back()->Clear();
1942 // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
1944 // find RadialPrism algo created on <geom> for theMesh
1945 GetCreationCmd()->SetObject( algo->GetID() );
1946 GetCreationCmd()->SetMethod( myAlgoMethod );
1947 GetCreationCmd()->RemoveArgs();
1948 theAdditionCmd->AddDependantCmd( GetCreationCmd() );
1954 //================================================================================
1958 //================================================================================
1960 void _pyLayerDistributionHypo::Flush()
1962 // as creation of 1D hyp was written later then it's edition,
1963 // we need to find all it's edition calls and process them
1964 if ( !my1dHyp.IsNull() )
1966 _pyID hyp1dID = my1dHyp->GetCreationCmd()->GetResultValue();
1968 // make a new name for 1D hyp = "HypType" + "_Distribution"
1970 if ( my1dHyp->IsWrapped() ) {
1971 newName = my1dHyp->GetCreationCmd()->GetMethod();
1974 TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
1975 newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1977 newName += "_Distribution";
1978 my1dHyp->GetCreationCmd()->SetResultValue( newName );
1980 list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
1981 list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
1982 for ( ; cmdIt != cmds.end(); ++cmdIt ) {
1983 const _pyID& objID = (*cmdIt)->GetObject();
1984 if ( objID == hyp1dID ) {
1985 my1dHyp->Process( *cmdIt );
1986 my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
1987 ( *cmdIt )->SetObject( newName );
1990 // Set new hyp name to SetLayerDistribution() cmd
1991 if ( !myArgCommands.empty() && !myArgCommands.back()->IsEmpty() )
1992 myArgCommands.back()->SetArg( 1, newName );
1996 //================================================================================
1998 * \brief additionally to Addition2Creation, clears SetDistrType() command
1999 * \param theCmd - AddHypothesis() command
2000 * \param theMesh - mesh to which a hypothesis is added
2001 * \retval bool - convertion result
2003 //================================================================================
2005 bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2006 const _pyID& theMesh)
2008 if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) {
2009 // scale factor (2-nd arg) is provided: clear SetDistrType(1) command
2010 bool scaleDistrType = false;
2011 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2012 for ( ; cmd != myUnknownCommands.rend(); ++cmd ) {
2013 if ( (*cmd)->GetMethod() == "SetDistrType" ) {
2014 if ( (*cmd)->GetArg( 1 ) == "1" ) {
2015 scaleDistrType = true;
2018 else if ( !scaleDistrType ) {
2019 // distribution type changed: remove scale factor from args
2020 myArgs.Remove( 2, myArgs.Length() );
2026 return _pyHypothesis::Addition2Creation( theCmd, theMesh );
2029 //================================================================================
2031 * \brief remove repeated commands defining distribution
2033 //================================================================================
2035 void _pyNumberOfSegmentsHyp::Flush()
2037 // find number of the last SetDistrType() command
2038 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2039 int distrTypeNb = 0;
2040 for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd )
2041 if ( (*cmd)->GetMethod() == "SetDistrType" )
2042 distrTypeNb = (*cmd)->GetOrderNb();
2043 else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
2046 // clear commands before the last SetDistrType()
2047 list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnknownCommands };
2048 for ( int i = 0; i < 2; ++i ) {
2049 set<TCollection_AsciiString> uniqueMethods;
2050 list<Handle(_pyCommand)> & cmdList = *cmds[i];
2051 for ( cmd = cmdList.rbegin(); cmd != cmdList.rend(); ++cmd )
2053 bool clear = ( (*cmd)->GetOrderNb() < distrTypeNb );
2054 const TCollection_AsciiString& method = (*cmd)->GetMethod();
2055 if ( !clear || method == "SetNumberOfSegments" ) {
2056 bool isNewInSet = uniqueMethods.insert( method ).second;
2057 clear = !isNewInSet;
2066 //================================================================================
2068 * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
2069 * into regular1D.LengthNearVertex( length, vertex )
2070 * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
2071 * \param theMesh - The mesh needing this hypo
2072 * \retval bool - false if the command cant be converted
2074 //================================================================================
2076 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2077 const _pyID& theMeshID)
2079 if ( IsWrappable( theMeshID )) {
2081 _pyID vertex = theCmd->GetArg( 1 );
2083 // the problem here is that segment algo will not be found
2084 // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
2085 // geometry where segment algorithm is assigned
2086 Handle(_pyHypothesis) algo;
2087 _pyID geom = vertex;
2088 while ( algo.IsNull() && !geom.IsEmpty()) {
2089 // try to find geom as a father of <vertex>
2090 geom = FatherID( geom );
2091 algo = theGen->FindAlgo( geom, theMeshID, this );
2093 if ( algo.IsNull() )
2094 return false; // also possible to find geom as brother of veretex...
2095 // set geom instead of vertex
2096 theCmd->SetArg( 1, geom );
2098 // set vertex as a second arg
2099 if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
2100 myArgs.Append( vertex );
2102 // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
2103 // theMeshID.LengthNearVertex( length, vertex )
2104 return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
2109 //================================================================================
2111 * \brief _pyAlgorithm constructor
2112 * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)"
2114 //================================================================================
2116 _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
2117 : _pyHypothesis( theCreationCmd )
2122 //================================================================================
2124 * \brief Convert the command adding an algorithm to mesh
2125 * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
2126 * \param theMesh - The mesh needing this algo
2127 * \retval bool - false if the command cant be converted
2129 //================================================================================
2131 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
2132 const _pyID& theMeshID)
2134 // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
2135 if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
2136 theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
2142 //================================================================================
2144 * \brief Return starting position of a part of python command
2145 * \param thePartIndex - The index of command part
2146 * \retval int - Part position
2148 //================================================================================
2150 int _pyCommand::GetBegPos( int thePartIndex )
2154 if ( myBegPos.Length() < thePartIndex )
2156 return myBegPos( thePartIndex );
2159 //================================================================================
2161 * \brief Store starting position of a part of python command
2162 * \param thePartIndex - The index of command part
2163 * \param thePosition - Part position
2165 //================================================================================
2167 void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
2169 while ( myBegPos.Length() < thePartIndex )
2170 myBegPos.Append( UNKNOWN );
2171 myBegPos( thePartIndex ) = thePosition;
2174 //================================================================================
2176 * \brief Returns whitespace symbols at the line beginning
2177 * \retval TCollection_AsciiString - result
2179 //================================================================================
2181 TCollection_AsciiString _pyCommand::GetIndentation()
2184 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2185 GetWord( myString, end, true );
2187 end = GetBegPos( RESULT_IND );
2188 return myString.SubString( 1, end - 1 );
2191 //================================================================================
2193 * \brief Return substring of python command looking like ResultValue = Obj.Meth()
2194 * \retval const TCollection_AsciiString & - ResultValue substring
2196 //================================================================================
2198 const TCollection_AsciiString & _pyCommand::GetResultValue()
2200 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2202 int begPos = myString.Location( "=", 1, Length() );
2204 myRes = GetWord( myString, begPos, false );
2207 SetBegPos( RESULT_IND, begPos );
2212 //================================================================================
2214 * \brief Return number of python command result value ResultValue = Obj.Meth()
2217 //================================================================================
2219 const int _pyCommand::GetNbResultValues()
2223 int endPos = myString.Location( "=", 1, Length() );
2224 TCollection_AsciiString str = "";
2225 while ( begPos < endPos) {
2226 str = GetWord( myString, begPos, true );
2227 begPos = begPos+ str.Length();
2234 //================================================================================
2236 * \brief Return substring of python command looking like
2237 * ResultValue1 , ResultValue1,... = Obj.Meth() with res index
2238 * \retval const TCollection_AsciiString & - ResultValue with res index substring
2240 //================================================================================
2241 const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
2245 int endPos = myString.Location( "=", 1, Length() );
2246 while ( begPos < endPos) {
2247 myRes = GetWord( myString, begPos, true );
2248 begPos = begPos + myRes.Length();
2251 myRes.RemoveAll('[');myRes.RemoveAll(']');
2257 return theEmptyString;
2260 //================================================================================
2262 * \brief Return substring of python command looking like ResVal = Object.Meth()
2263 * \retval const TCollection_AsciiString & - Object substring
2265 //================================================================================
2267 const TCollection_AsciiString & _pyCommand::GetObject()
2269 if ( GetBegPos( OBJECT_IND ) == UNKNOWN )
2272 int begPos = GetBegPos( RESULT_IND ) + myRes.Length();
2274 begPos = myString.Location( "=", 1, Length() ) + 1;
2275 // is '=' in the string argument (for example, name) or not
2276 int nb1 = 0; // number of ' character at the left of =
2277 int nb2 = 0; // number of " character at the left of =
2278 for ( int i = 1; i < begPos-1; i++ ) {
2279 if ( myString.Value( i )=='\'' )
2281 else if ( myString.Value( i )=='"' )
2284 // if number of ' or " is not divisible by 2,
2285 // then get an object at the start of the command
2286 if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
2289 myObj = GetWord( myString, begPos, true );
2290 // check if object is complex,
2291 // so far consider case like "smesh.smesh.Method()"
2292 if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
2293 //if ( bracketPos==0 ) bracketPos = Length();
2294 int dotPos = begPos+myObj.Length();
2295 while ( dotPos+1 < bracketPos ) {
2296 if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
2301 if ( dotPos > begPos+myObj.Length() )
2302 myObj = myString.SubString( begPos, dotPos-1 );
2305 SetBegPos( OBJECT_IND, begPos );
2311 //================================================================================
2313 * \brief Return substring of python command looking like ResVal = Obj.Method()
2314 * \retval const TCollection_AsciiString & - Method substring
2316 //================================================================================
2318 const TCollection_AsciiString & _pyCommand::GetMethod()
2320 if ( GetBegPos( METHOD_IND ) == UNKNOWN )
2323 int begPos = GetBegPos( OBJECT_IND ) + myObj.Length();
2324 bool forward = true;
2326 begPos = myString.Location( "(", 1, Length() ) - 1;
2330 myMeth = GetWord( myString, begPos, forward );
2331 SetBegPos( METHOD_IND, begPos );
2337 //================================================================================
2339 * \brief Return substring of python command looking like ResVal = Obj.Meth(Arg1,...)
2340 * \retval const TCollection_AsciiString & - Arg<index> substring
2342 //================================================================================
2344 const TCollection_AsciiString & _pyCommand::GetArg( int index )
2346 if ( GetBegPos( ARG1_IND ) == UNKNOWN )
2350 int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
2352 pos = myString.Location( "(", 1, Length() );
2356 // we are at or before '(', skip it if present
2358 while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
2359 if ( myString.Value( pos ) != '(' )
2363 SetBegPos( ARG1_IND, 0 ); // even no '('
2364 return theEmptyString;
2368 list< TCollection_AsciiString > separatorStack( 1, ",)");
2369 bool ignoreNesting = false;
2371 while ( pos <= Length() )
2373 const char chr = myString.Value( pos );
2375 if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
2377 if ( separatorStack.size() == 1 ) // ',' dividing args or a terminal ')' found
2379 while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
2381 if ( pos-1 >= prevPos ) {
2382 TCollection_AsciiString arg = myString.SubString( prevPos, pos-1 );
2383 arg.RightAdjust(); // remove spaces
2385 SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
2386 myArgs.Append( arg );
2392 else // end of nesting args found
2394 separatorStack.pop_back();
2395 ignoreNesting = false;
2398 else if ( !ignoreNesting )
2401 case '(' : separatorStack.push_back(")"); break;
2402 case '[' : separatorStack.push_back("]"); break;
2403 case '\'': separatorStack.push_back("'"); ignoreNesting=true; break;
2404 case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
2411 if ( myArgs.Length() < index )
2412 return theEmptyString;
2413 return myArgs( index );
2416 //================================================================================
2418 * \brief Check if char is a word part
2419 * \param c - The character to check
2420 * \retval bool - The check result
2422 //================================================================================
2424 static inline bool isWord(const char c, const bool dotIsWord)
2427 !isspace(c) && c != ',' && c != '=' && c != ')' && c != '(' && ( dotIsWord || c != '.');
2430 //================================================================================
2432 * \brief Looks for a word in the string and returns word's beginning
2433 * \param theString - The input string
2434 * \param theStartPos - The position to start the search, returning word's beginning
2435 * \param theForward - The search direction
2436 * \retval TCollection_AsciiString - The found word
2438 //================================================================================
2440 TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
2442 const bool theForward,
2443 const bool dotIsWord )
2445 int beg = theStartPos, end = theStartPos;
2446 theStartPos = EMPTY;
2447 if ( beg < 1 || beg > theString.Length() )
2448 return theEmptyString;
2450 if ( theForward ) { // search forward
2452 while ( beg <= theString.Length() && !isWord( theString.Value( beg ), dotIsWord))
2454 if ( beg > theString.Length() )
2455 return theEmptyString; // no word found
2458 char begChar = theString.Value( beg );
2459 if ( begChar == '"' || begChar == '\'' || begChar == '[') {
2460 char endChar = ( begChar == '[' ) ? ']' : begChar;
2461 // end is at the corresponding quoting mark or bracket
2462 while ( end < theString.Length() &&
2463 ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\'))
2467 while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
2472 else { // search backward
2474 while ( end > 0 && !isWord( theString.Value( end ), dotIsWord))
2477 return theEmptyString; // no word found
2479 char endChar = theString.Value( end );
2480 if ( endChar == '"' || endChar == '\'' ) {
2481 // beg is at the corresponding quoting mark
2483 ( theString.Value( beg ) != endChar || theString.Value( beg-1 ) == '\\'))
2487 while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
2493 //cout << theString << " ---- " << beg << " - " << end << endl;
2494 return theString.SubString( beg, end );
2497 //================================================================================
2499 * \brief Look for position where not space char is
2500 * \param theString - The string
2501 * \param thePos - The position to search from and which returns result
2502 * \retval bool - false if there are only space after thePos in theString
2506 //================================================================================
2508 bool _pyCommand::SkipSpaces( const TCollection_AsciiString & theString, int & thePos )
2510 if ( thePos < 1 || thePos > theString.Length() )
2513 while ( thePos <= theString.Length() && isspace( theString.Value( thePos )))
2516 return thePos <= theString.Length();
2519 //================================================================================
2521 * \brief Modify a part of the command
2522 * \param thePartIndex - The index of the part
2523 * \param thePart - The new part string
2524 * \param theOldPart - The old part
2526 //================================================================================
2528 void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePart,
2529 TCollection_AsciiString& theOldPart)
2531 int pos = GetBegPos( thePartIndex );
2532 if ( pos <= Length() && theOldPart != thePart)
2534 TCollection_AsciiString seperator;
2536 pos = GetBegPos( thePartIndex + 1 );
2537 if ( pos < 1 ) return;
2538 switch ( thePartIndex ) {
2539 case RESULT_IND: seperator = " = "; break;
2540 case OBJECT_IND: seperator = "."; break;
2541 case METHOD_IND: seperator = "()"; break;
2545 myString.Remove( pos, theOldPart.Length() );
2546 if ( !seperator.IsEmpty() )
2547 myString.Insert( pos , seperator );
2548 myString.Insert( pos, thePart );
2549 // update starting positions of the following parts
2550 int posDelta = thePart.Length() + seperator.Length() - theOldPart.Length();
2551 for ( int i = thePartIndex + 1; i <= myBegPos.Length(); ++i ) {
2552 if ( myBegPos( i ) > 0 )
2553 myBegPos( i ) += posDelta;
2555 theOldPart = thePart;
2559 //================================================================================
2561 * \brief Set agrument
2562 * \param index - The argument index, it counts from 1
2563 * \param theArg - The argument string
2565 //================================================================================
2567 void _pyCommand::SetArg( int index, const TCollection_AsciiString& theArg)
2570 int argInd = ARG1_IND + index - 1;
2571 int pos = GetBegPos( argInd );
2572 if ( pos < 1 ) // no index-th arg exist, append inexistent args
2574 // find a closing parenthesis
2575 if ( GetNbArgs() != 0 && index <= GetNbArgs() ) {
2576 int lastArgInd = GetNbArgs();
2577 pos = GetBegPos( ARG1_IND + lastArgInd - 1 ) + GetArg( lastArgInd ).Length();
2578 while ( pos > 0 && pos <= Length() && myString.Value( pos ) != ')' )
2583 while ( pos > 0 && myString.Value( pos ) != ')' )
2586 if ( pos < 1 || myString.Value( pos ) != ')' ) { // no parentheses at all
2590 while ( myArgs.Length() < index ) {
2591 if ( myArgs.Length() )
2592 myString.Insert( pos++, "," );
2593 myArgs.Append("None");
2594 myString.Insert( pos, myArgs.Last() );
2595 SetBegPos( ARG1_IND + myArgs.Length() - 1, pos );
2596 pos += myArgs.Last().Length();
2599 SetPart( argInd, theArg, myArgs( index ));
2602 //================================================================================
2604 * \brief Empty arg list
2606 //================================================================================
2608 void _pyCommand::RemoveArgs()
2610 if ( int pos = myString.Location( '(', 1, Length() ))
2611 myString.Trunc( pos );
2614 if ( myBegPos.Length() >= ARG1_IND )
2615 myBegPos.Remove( ARG1_IND, myBegPos.Length() );
2618 //================================================================================
2620 * \brief Set dependent commands after this one
2622 //================================================================================
2624 bool _pyCommand::SetDependentCmdsAfter() const
2626 bool orderChanged = false;
2627 list< Handle(_pyCommand)>::const_reverse_iterator cmd = myDependentCmds.rbegin();
2628 for ( ; cmd != myDependentCmds.rend(); ++cmd ) {
2629 if ( (*cmd)->GetOrderNb() < GetOrderNb() ) {
2630 orderChanged = true;
2631 theGen->SetCommandAfter( *cmd, this );
2632 (*cmd)->SetDependentCmdsAfter();
2635 return orderChanged;
2637 //================================================================================
2639 * \brief Insert accessor method after theObjectID
2640 * \param theObjectID - id of the accessed object
2641 * \param theAcsMethod - name of the method giving access to the object
2642 * \retval bool - false if theObjectID is not found in the command string
2644 //================================================================================
2646 bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod )
2648 if ( !theAcsMethod )
2650 // start object search from the object, i.e. ignore result
2652 int beg = GetBegPos( OBJECT_IND );
2653 if ( beg < 1 || beg > Length() )
2656 while (( beg = myString.Location( theObjectID, beg, Length() )))
2658 // check that theObjectID is not just a part of a longer ID
2659 int afterEnd = beg + theObjectID.Length();
2660 Standard_Character c = myString.Value( afterEnd );
2661 if ( !isalnum( c ) && c != ':' ) {
2662 // check if accessor method already present
2664 myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
2666 int oldLen = Length();
2667 myString.Insert( afterEnd, (char*) theAcsMethod );
2668 myString.Insert( afterEnd, "." );
2669 // update starting positions of the parts following the modified one
2670 int posDelta = Length() - oldLen;
2671 for ( int i = 1; i <= myBegPos.Length(); ++i ) {
2672 if ( myBegPos( i ) > afterEnd )
2673 myBegPos( i ) += posDelta;
2678 beg = afterEnd; // is a part - next search
2683 //================================================================================
2685 * \brief Return method name giving access to an interaface object wrapped by python class
2686 * \retval const char* - method name
2688 //================================================================================
2690 const char* _pyObject::AccessorMethod() const
2694 //================================================================================
2696 * \brief Return ID of a father
2698 //================================================================================
2700 _pyID _pyObject::FatherID(const _pyID & childID)
2702 int colPos = childID.SearchFromEnd(':');
2704 return childID.SubString( 1, colPos-1 );
2708 //================================================================================
2710 * \brief SelfEraser erases creation command if no more it's commands invoked
2712 //================================================================================
2714 void _pySelfEraser::Flush()
2716 if ( GetNbCalls() == 0 )
2717 GetCreationCmd()->Clear();
2720 //================================================================================
2722 * \brief count invoked commands
2724 //================================================================================
2726 void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
2728 _pyObject::Process(theCommand); // count calls of Process()
2729 GetCreationCmd()->AddDependantCmd( theCommand );
2732 //================================================================================
2734 * \brief Clear creation command if no commands invoked
2736 //================================================================================
2738 void _pySubMesh::Flush()
2740 if ( GetNbCalls() == 0 ) // move to the end of all commands
2741 theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
2742 else if ( !myCreator.IsNull() )
2743 // move to be just after creator
2744 myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
2747 //================================================================================
2749 * \brief To convert creation of a group by filter
2751 //================================================================================
2753 void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
2755 // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
2756 // group = mesh.CreateEmptyGroup( elemType, groupName )
2757 // aFilter.SetMesh(mesh)
2758 // nbAdd = group.AddFrom( aFilter )
2759 if ( theCommand->GetMethod() == "AddFrom" )
2761 _pyID idSource = theCommand->GetArg(1);
2762 // check if idSource is a filter
2763 Handle(_pyObject) filter = theGen->FindObject( idSource );
2764 if ( filter.IsNull() || !filter->IsKind(STANDARD_TYPE(_pyFilter)))
2766 // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
2767 list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin();
2768 while ( *cmdIt != theCommand ) ++cmdIt;
2769 while ( (*cmdIt)->GetOrderNb() != 1 )
2771 const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
2772 if ((setMeshCmd->GetObject() == idSource ||
2773 setMeshCmd->GetObject() == Handle(_pyFilter)::DownCast(filter)->GetNewID() )
2775 setMeshCmd->GetMethod() == "SetMesh")
2777 setMeshCmd->Clear();
2781 // replace 3 commands by one
2782 theCommand->Clear();
2783 const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
2784 TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
2785 makeGroupCmd->SetMethod( "MakeGroupByFilter" );
2786 makeGroupCmd->SetArg( 1, name );
2787 makeGroupCmd->SetArg( 2, idSource );
2788 // set new name of a filter
2789 filter->Process( makeGroupCmd );
2793 //================================================================================
2795 * \brief Constructor of _pyFilter
2797 //================================================================================
2799 _pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
2800 :_pyObject(theCreationCmd), myNewID( newID )
2804 //================================================================================
2806 * \brief To convert creation of a filter by criteria and
2807 * to replace an old name by a new one
2809 //================================================================================
2811 void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
2813 if ( theCommand->GetObject() == GetID() )
2814 _pyObject::Process(theCommand); // count commands
2816 if ( !myNewID.IsEmpty() )
2818 if ( theCommand->GetObject() == GetID() )
2819 theCommand->SetObject( myNewID );
2820 else if ( theCommand->GetResultValue() == GetID() )
2821 theCommand->SetResultValue( myNewID );
2823 for ( int i = 1, nb = theCommand->GetNbArgs(); i <= nb; ++i )
2824 if ( theCommand->GetArg( i ) == GetID() )
2826 theCommand->SetArg( i, myNewID );
2831 // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
2832 // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
2833 // aFilter0x2aaab0487080.SetCriteria(aCriteria)
2834 if ( GetNbCalls() == 0 && // none method was called before SetCriteria()
2835 theCommand->GetMethod() == "SetCriteria")
2837 // aFilter.SetCriteria(aCriteria) ->
2838 // aFilter = smesh.GetFilterFromCriteria(criteria)
2839 if ( myNewID.IsEmpty() )
2840 theCommand->SetResultValue( GetID() );
2842 theCommand->SetResultValue( myNewID );
2843 theCommand->SetObject( SMESH_2smeshpy::GenName() );
2844 theCommand->SetMethod( "GetFilterFromCriteria" );
2846 // Clear aFilterManager.CreateFilter()
2847 GetCreationCmd()->Clear();
2849 else if ( theCommand->GetMethod() == "SetMesh")
2851 theGen->AddMeshAccessorMethod( theCommand );
2855 //================================================================================
2857 * \brief Set new filter name to the creation command
2859 //================================================================================
2861 void _pyFilter::Flush()
2863 if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
2864 GetCreationCmd()->SetResultValue( myNewID );