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 ( ThresholdStr.Length() != 2 ) // not '' or ""
388 aCommand->SetArg( 4, ThresholdStr );
389 else if ( ThresholdID.Length() != 2 )
390 aCommand->SetArg( 4, ThresholdID );
392 aCommand->SetArg( 4, Threshold );
393 // find the last not default arg
395 if ( Tolerance == dftlTol ) {
397 if ( BinaryOp == dfltFunctor ) {
399 if ( UnaryOp == dfltFunctor )
403 if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
404 if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
405 if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
406 if ( Precision != dftlPreci )
408 TCollection_AsciiString crit = aCommand->GetResultValue();
409 aCommand->GetString() += "; ";
410 aCommand->GetString() += crit + ".Precision = " + Precision;
416 //================================================================================
418 * \brief Convert the command or remember it for later conversion
419 * \param theCommand - The python command calling a method of SMESH_Gen
421 //================================================================================
423 void _pyGen::Process( const Handle(_pyCommand)& theCommand )
425 // there are methods to convert:
426 // CreateMesh( shape )
427 // Concatenate( [mesh1, ...], ... )
428 // CreateHypothesis( theHypType, theLibName )
429 // Compute( mesh, geom )
430 // Evaluate( mesh, geom )
432 TCollection_AsciiString method = theCommand->GetMethod();
434 if ( method == "CreateMesh" || method == "CreateEmptyMesh")
436 Handle(_pyMesh) mesh = new _pyMesh( theCommand );
437 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
440 if ( method == "CreateMeshesFromUNV" ||
441 method == "CreateMeshesFromSTL" ||
442 method == "CreateMeshesFromCGNS" ||
443 method == "CopyMesh" )
445 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
446 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
449 if( method == "CreateMeshesFromMED")
451 for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
453 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
454 myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));
458 // CreateHypothesis()
459 if ( method == "CreateHypothesis" )
461 // issue 199929, remove standard library name (default parameter)
462 const TCollection_AsciiString & aLibName = theCommand->GetArg( 2 );
463 if ( aLibName.Search( "StdMeshersEngine" ) != -1 ) {
464 // keep first argument
465 TCollection_AsciiString arg = theCommand->GetArg( 1 );
466 theCommand->RemoveArgs();
467 theCommand->SetArg( 1, arg );
470 myHypos.push_back( _pyHypothesis::NewHypothesis( theCommand ));
474 // smeshgen.Compute( mesh, geom ) --> mesh.Compute()
475 if ( method == "Compute" )
477 const _pyID& meshID = theCommand->GetArg( 1 );
478 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
479 if ( id_mesh != myMeshes.end() ) {
480 theCommand->SetObject( meshID );
481 theCommand->RemoveArgs();
482 id_mesh->second->Flush();
487 // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
488 if ( method == "Evaluate" )
490 const _pyID& meshID = theCommand->GetArg( 1 );
491 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
492 if ( id_mesh != myMeshes.end() ) {
493 theCommand->SetObject( meshID );
494 _pyID geom = theCommand->GetArg( 2 );
495 theCommand->RemoveArgs();
496 theCommand->SetArg( 1, geom );
501 // objects erasing creation command if no more it's commands invoked:
502 // SMESH_Pattern, FilterManager
503 if ( method == "GetPattern" ||
504 method == "CreateFilterManager" ||
505 method == "CreateMeasurements" ) {
506 Handle(_pyObject) obj = new _pySelfEraser( theCommand );
507 if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
508 theCommand->Clear(); // already created
511 // Concatenate( [mesh1, ...], ... )
512 if ( method == "Concatenate" || method == "ConcatenateWithGroups")
514 if ( method == "ConcatenateWithGroups" ) {
515 theCommand->SetMethod( "Concatenate" );
516 theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" );
518 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
519 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
520 AddMeshAccessorMethod( theCommand );
523 // Replace name of SMESH_Gen
525 // names of SMESH_Gen methods fully equal to methods defined in smesh.py
526 static TStringSet smeshpyMethods;
527 if ( smeshpyMethods.empty() ) {
528 const char * names[] =
529 { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy",
530 "GetPattern","GetSubShapesId",
531 "" }; // <- mark of array end
532 smeshpyMethods.Insert( names );
534 if ( smeshpyMethods.Contains( theCommand->GetMethod() ))
535 // smeshgen.Method() --> smesh.Method()
536 theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() );
538 // smeshgen.Method() --> smesh.smesh.Method()
539 theCommand->SetObject( SMESH_2smeshpy::GenName() );
542 //================================================================================
544 * \brief Convert the remembered commands
546 //================================================================================
550 // create empty command
551 myLastCommand = new _pyCommand();
553 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
554 for ( ; id_mesh != myMeshes.end(); ++id_mesh )
555 if ( ! id_mesh->second.IsNull() )
556 id_mesh->second->Flush();
558 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
559 for ( ; hyp != myHypos.end(); ++hyp )
560 if ( !hyp->IsNull() ) {
562 // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
563 if ( !(*hyp)->IsWrapped() )
564 (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
567 map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
568 for ( ; id_obj != myObjects.end(); ++id_obj )
569 if ( ! id_obj->second.IsNull() )
570 id_obj->second->Flush();
572 myLastCommand->SetOrderNb( ++myNbCommands );
573 myCommands.push_back( myLastCommand );
576 //================================================================================
578 * \brief Add access method to mesh that is an argument
579 * \param theCmd - command to add access method
580 * \retval bool - true if added
582 //================================================================================
584 bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
587 map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
588 for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
589 if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
595 //================================================================================
597 * \brief Add access method to algo that is an object or an argument
598 * \param theCmd - command to add access method
599 * \retval bool - true if added
601 //================================================================================
603 bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
606 list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
607 for ( ; hyp != myHypos.end(); ++hyp ) {
608 if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
609 theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
615 //================================================================================
617 * \brief Find hypothesis by ID (entry)
618 * \param theHypID - The hypothesis ID
619 * \retval Handle(_pyHypothesis) - The found hypothesis
621 //================================================================================
623 Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID )
625 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
626 for ( ; hyp != myHypos.end(); ++hyp )
627 if ( !hyp->IsNull() && theHypID == (*hyp)->GetID() )
629 return Handle(_pyHypothesis)();
632 //================================================================================
634 * \brief Find algorithm the created algorithm
635 * \param theGeom - The shape ID the algorithm was created on
636 * \param theMesh - The mesh ID that created the algorithm
637 * \param dim - The algo dimension
638 * \retval Handle(_pyHypothesis) - The found algo
640 //================================================================================
642 Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
643 const Handle(_pyHypothesis)& theHypothesis )
645 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
646 for ( ; hyp != myHypos.end(); ++hyp )
647 if ( !hyp->IsNull() &&
649 theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
650 (*hyp)->GetGeom() == theGeom &&
651 (*hyp)->GetMesh() == theMesh )
656 //================================================================================
658 * \brief Find subMesh by ID (entry)
659 * \param theSubMeshID - The subMesh ID
660 * \retval Handle(_pySubMesh) - The found subMesh
662 //================================================================================
664 Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
666 map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID);
667 if ( id_subMesh != myObjects.end() )
668 return Handle(_pySubMesh)::DownCast( id_subMesh->second );
669 return Handle(_pySubMesh)();
673 //================================================================================
675 * \brief Change order of commands in the script
676 * \param theCmd1 - One command
677 * \param theCmd2 - Another command
679 //================================================================================
681 void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 )
683 list< Handle(_pyCommand) >::iterator pos1, pos2;
684 pos1 = find( myCommands.begin(), myCommands.end(), theCmd1 );
685 pos2 = find( myCommands.begin(), myCommands.end(), theCmd2 );
686 myCommands.insert( pos1, theCmd2 );
687 myCommands.insert( pos2, theCmd1 );
688 myCommands.erase( pos1 );
689 myCommands.erase( pos2 );
691 int nb1 = theCmd1->GetOrderNb();
692 theCmd1->SetOrderNb( theCmd2->GetOrderNb() );
693 theCmd2->SetOrderNb( nb1 );
694 // cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl
695 // << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl;
698 //================================================================================
700 * \brief Set one command after the other
701 * \param theCmd - Command to move
702 * \param theAfterCmd - Command ater which to insert the first one
704 //================================================================================
706 void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
708 setNeighbourCommand( theCmd, theAfterCmd, true );
711 //================================================================================
713 * \brief Set one command before the other
714 * \param theCmd - Command to move
715 * \param theBeforeCmd - Command before which to insert the first one
717 //================================================================================
719 void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd )
721 setNeighbourCommand( theCmd, theBeforeCmd, false );
724 //================================================================================
726 * \brief Set one command before or after the other
727 * \param theCmd - Command to move
728 * \param theOtherCmd - Command ater or before which to insert the first one
730 //================================================================================
732 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
733 Handle(_pyCommand)& theOtherCmd,
734 const bool theIsAfter )
736 list< Handle(_pyCommand) >::iterator pos;
737 pos = find( myCommands.begin(), myCommands.end(), theCmd );
738 myCommands.erase( pos );
739 pos = find( myCommands.begin(), myCommands.end(), theOtherCmd );
740 myCommands.insert( (theIsAfter ? ++pos : pos), theCmd );
743 for ( pos = myCommands.begin(); pos != myCommands.end(); ++pos)
744 (*pos)->SetOrderNb( i++ );
747 //================================================================================
749 * \brief Set command be last in list of commands
750 * \param theCmd - Command to be last
752 //================================================================================
754 Handle(_pyCommand)& _pyGen::GetLastCommand()
756 return myLastCommand;
759 //================================================================================
761 * \brief Set method to access to object wrapped with python class
762 * \param theID - The wrapped object entry
763 * \param theMethod - The accessor method
765 //================================================================================
767 void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod )
769 myID2AccessorMethod.Bind( theID, (char*) theMethod );
772 //================================================================================
774 * \brief Generated new ID for object and assign with existing name
775 * \param theID - ID of existing object
777 //================================================================================
779 _pyID _pyGen::GenerateNewID( const _pyID& theID )
784 aNewID = theID + _pyID( ":" ) + _pyID( index++ );
786 while ( myObjectNames.IsBound( aNewID ) );
788 myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
789 ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
790 : _pyID( "A" ) + aNewID );
794 //================================================================================
796 * \brief Stores theObj in myObjects
798 //================================================================================
800 void _pyGen::AddObject( Handle(_pyObject)& theObj )
802 myObjects.insert( make_pair( theObj->GetID(), theObj ));
805 //================================================================================
807 * \brief Find out type of geom group
808 * \param grpID - The geom group entry
809 * \retval int - The type
811 //================================================================================
813 // static bool sameGroupType( const _pyID& grpID,
814 // const TCollection_AsciiString& theType)
816 // // define group type as smesh.Mesh.Group() does
818 // SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
819 // SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
820 // if ( !aSObj->_is_nil() ) {
821 // GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
822 // if ( !aGeomObj->_is_nil() ) {
823 // switch ( aGeomObj->GetShapeType() ) {
824 // case GEOM::VERTEX: type = SMESH::NODE; break;
825 // case GEOM::EDGE: type = SMESH::EDGE; break;
826 // case GEOM::FACE: type = SMESH::FACE; break;
828 // case GEOM::SHELL: type = SMESH::VOLUME; break;
829 // case GEOM::COMPOUND: {
830 // GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
831 // if ( !aGeomGen->_is_nil() ) {
832 // GEOM::GEOM_IGroupOperations_var aGrpOp =
833 // aGeomGen->GetIGroupOperations( study->StudyId() );
834 // if ( !aGrpOp->_is_nil() ) {
835 // switch ( aGrpOp->GetType( aGeomObj )) {
836 // case TopAbs_VERTEX: type = SMESH::NODE; break;
837 // case TopAbs_EDGE: type = SMESH::EDGE; break;
838 // case TopAbs_FACE: type = SMESH::FACE; break;
839 // case TopAbs_SOLID: type = SMESH::VOLUME; break;
850 // MESSAGE("Type of the group " << grpID << " not found");
853 // if ( theType.IsIntegerValue() )
854 // return type == theType.IntegerValue();
857 // case SMESH::NODE: return theType.Location( "NODE", 1, theType.Length() );
858 // case SMESH::EDGE: return theType.Location( "EDGE", 1, theType.Length() );
859 // case SMESH::FACE: return theType.Location( "FACE", 1, theType.Length() );
860 // case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
866 //================================================================================
869 * \param theCreationCmd -
871 //================================================================================
873 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
874 : _pyObject(theCreationCmd), myHasEditor(false)
876 // convert my creation command
877 Handle(_pyCommand) creationCmd = GetCreationCmd();
878 //TCollection_AsciiString str = creationCmd->GetMethod();
879 // if(str != "CreateMeshesFromUNV" &&
880 // str != "CreateMeshesFromMED" &&
881 // str != "CreateMeshesFromSTL")
882 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
883 creationCmd->SetMethod( "Mesh" );
885 theGen->SetAccessorMethod( GetID(), "GetMesh()" );
888 //================================================================================
891 * \param theCreationCmd -
893 //================================================================================
894 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
895 _pyObject(theCreationCmd), myHasEditor(false)
897 // convert my creation command
898 Handle(_pyCommand) creationCmd = GetCreationCmd();
899 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
900 theGen->SetAccessorMethod( id, "GetMesh()" );
903 //================================================================================
905 * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
906 * \param theCommand - Engine method called for this mesh
908 //================================================================================
910 void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
912 // some methods of SMESH_Mesh interface needs special conversion
913 // to methods of Mesh python class
915 // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo)
916 // --> in Mesh_Algorithm.Create(mesh, geom, hypo, so)
917 // 2. AddHypothesis(geom, hyp)
918 // --> in Mesh_Algorithm.Hypothesis(hyp, args, so)
919 // 3. CreateGroupFromGEOM(type, name, grp)
920 // --> in Mesh.Group(grp, name="")
921 // 4. ExportToMED(f, auto_groups, version)
922 // --> in Mesh.ExportMED( f, auto_groups, version )
925 const TCollection_AsciiString method = theCommand->GetMethod();
926 // ----------------------------------------------------------------------
927 if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
928 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
929 if ( !subMesh.IsNull() ) {
930 subMesh->SetCreator( this );
931 mySubmeshes.push_back( subMesh );
934 // ----------------------------------------------------------------------
935 else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
936 myAddHypCmds.push_back( theCommand );
938 const _pyID& hypID = theCommand->GetArg( 2 );
939 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
940 if ( !hyp.IsNull() ) {
941 myHypos.push_back( hyp );
942 if ( hyp->GetMesh().IsEmpty() )
943 hyp->SetMesh( this->GetID() );
946 // ----------------------------------------------------------------------
947 else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
948 _pyID grp = theCommand->GetArg( 3 );
949 // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
950 // next if(){...} section is commented
951 //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
952 // theCommand->SetMethod( "Group" );
953 // theCommand->RemoveArgs();
954 // theCommand->SetArg( 1, grp );
957 // ------------------------->>>>> GroupOnGeom( grp, name, typ )
958 _pyID type = theCommand->GetArg( 1 );
959 _pyID name = theCommand->GetArg( 2 );
960 theCommand->SetMethod( "GroupOnGeom" );
961 theCommand->RemoveArgs();
962 theCommand->SetArg( 1, grp );
963 theCommand->SetArg( 2, name );
964 theCommand->SetArg( 3, type );
967 // ----------------------------------------------------------------------
968 else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
970 theCommand->SetMethod( "GroupOnFilter" );
972 // ----------------------------------------------------------------------
973 else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
975 theCommand->SetMethod( "CreateEmptyGroup" );
976 Handle(_pyGroup) group = new _pyGroup( theCommand );
977 theGen->AddObject( group );
979 // ----------------------------------------------------------------------
980 else if ( method == "ExportToMED" || // ExportToMED() --> ExportMED()
981 method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
982 theCommand->SetMethod( "ExportMED" );
984 // ----------------------------------------------------------------------
985 else if ( method == "ExportCGNS" )
986 { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
987 _pyID partID = theCommand->GetArg( 1 );
988 int nbArgs = theCommand->GetNbArgs();
989 for ( int i = 2; i <= nbArgs; ++i )
990 theCommand->SetArg( i-1, theCommand->GetArg( i ));
991 theCommand->SetArg( nbArgs, partID );
993 // ----------------------------------------------------------------------
994 else if ( method.Location( "ExportPartTo", 1, method.Length() ) == 1 )
995 { // ExportPartTo*(part, ...) -> Export*(..., part)
997 // remove "PartTo" from the method
998 TCollection_AsciiString newMethod = method;
999 newMethod.Remove( 7, 6 );
1000 theCommand->SetMethod( newMethod );
1001 // make the 1st arg be the last one
1002 _pyID partID = theCommand->GetArg( 1 );
1003 int nbArgs = theCommand->GetNbArgs();
1004 for ( int i = 2; i <= nbArgs; ++i )
1005 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1006 theCommand->SetArg( nbArgs, partID );
1008 // ----------------------------------------------------------------------
1009 else if ( method == "RemoveHypothesis" ) // (geom, hyp)
1011 _pyID hypID = theCommand->GetArg( 2 );
1013 // check if this mesh still has corresponding addition command
1014 bool hasAddCmd = false;
1015 list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
1016 while ( cmd != myAddHypCmds.end() )
1018 // AddHypothesis(geom, hyp)
1019 if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
1020 theCommand->Clear();
1022 cmd = myAddHypCmds.erase( cmd );
1029 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1030 if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
1031 // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
1032 _pyID geom = theCommand->GetArg( 1 );
1033 theCommand->RemoveArgs();
1034 theCommand->SetArg( 1, hypID );
1035 if ( geom != GetGeom() )
1036 theCommand->SetArg( 2, geom );
1038 // remove hyp from myHypos
1039 myHypos.remove( hyp );
1041 // check for SubMesh order commands
1042 else if ( theCommand->GetMethod() == "GetMeshOrder" ||
1043 theCommand->GetMethod() == "SetMeshOrder" )
1045 // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
1046 // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
1047 // commands are moved at the end of the script
1048 const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
1049 const TCollection_AsciiString& cmdStr = theCommand->GetString();
1050 int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
1051 int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
1052 if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
1053 TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
1054 Standard_Integer index = 1;
1055 TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
1056 while ( !anIDStr.IsEmpty() ) {
1057 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
1058 if ( !subMesh.IsNull() )
1059 subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
1060 anIDStr = aSubStr.Token("\t ,[]", index++);
1064 // add accessor method if necessary
1067 if ( NeedMeshAccess( theCommand ))
1068 // apply theCommand to the mesh wrapped by smeshpy mesh
1069 AddMeshAccess( theCommand );
1073 //================================================================================
1075 * \brief Return True if addition of accesor method is needed
1077 //================================================================================
1079 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
1081 // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
1082 // so no conversion is needed for them at all:
1083 static TStringSet sameMethods;
1084 if ( sameMethods.empty() ) {
1085 const char * names[] =
1086 { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents",
1087 "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
1088 "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
1089 "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
1090 "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes",
1091 "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder",
1092 "NbPyramids","NbPyramidsOfOrder","NbPrisms","NbPrismsOfOrder","NbPolyhedrons",
1093 "NbSubMesh","GetElementsId","GetElementsByType","GetNodesId","GetElementType",
1094 "GetSubMeshElementsId","GetSubMeshNodesId","GetSubMeshElementType","Dump","GetNodeXYZ",
1095 "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
1096 "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
1097 "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
1098 "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
1099 ,"" }; // <- mark of end
1100 sameMethods.Insert( names );
1103 return !sameMethods.Contains( theCommand->GetMethod() );
1106 //================================================================================
1108 * \brief Convert creation and addition of all algos and hypos
1110 //================================================================================
1112 void _pyMesh::Flush()
1114 list < Handle(_pyCommand) >::iterator cmd;
1116 // try to convert algo addition like this:
1117 // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo()
1118 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1120 Handle(_pyCommand) addCmd = *cmd;
1122 _pyID algoID = addCmd->GetArg( 2 );
1123 Handle(_pyHypothesis) algo = theGen->FindHyp( algoID );
1124 if ( algo.IsNull() || !algo->IsAlgo() )
1127 // check and create new algorithm instance if it is already wrapped
1128 if ( algo->IsWrapped() ) {
1129 _pyID localAlgoID = theGen->GenerateNewID( algoID );
1130 TCollection_AsciiString aNewCmdStr = localAlgoID +
1131 TCollection_AsciiString( " = " ) + theGen->GetID() +
1132 TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
1133 TCollection_AsciiString( "\" )" );
1135 Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
1136 Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
1137 if ( !newAlgo.IsNull() ) {
1138 newAlgo->Assign( algo, this->GetID() );
1139 newAlgo->SetCreationCmd( newCmd );
1141 // set algorithm creation
1142 theGen->SetCommandBefore( newCmd, addCmd );
1147 _pyID geom = addCmd->GetArg( 1 );
1148 bool isLocalAlgo = ( geom != GetGeom() );
1151 if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
1153 // wrapped algo is created atfer mesh creation
1154 GetCreationCmd()->AddDependantCmd( addCmd );
1156 if ( isLocalAlgo ) {
1157 // mesh.AddHypothesis(geom, ALGO ) --> mesh.AlgoMethod(geom)
1158 addCmd->SetArg( addCmd->GetNbArgs() + 1,
1159 TCollection_AsciiString( "geom=" ) + geom );
1160 // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
1161 list < Handle(_pySubMesh) >::iterator smIt;
1162 for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
1163 Handle(_pySubMesh) subMesh = *smIt;
1164 Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
1165 if ( geom == subCmd->GetArg( 1 )) {
1166 subCmd->SetObject( algo->GetID() );
1167 subCmd->RemoveArgs();
1168 subMesh->SetCreator( algo );
1173 else // KO - ALGO was already created
1175 // mesh.AddHypothesis(geom, ALGO) --> mesh.AddHypothesis(ALGO, geom=0)
1176 addCmd->RemoveArgs();
1177 addCmd->SetArg( 1, algoID );
1179 addCmd->SetArg( 2, geom );
1183 // try to convert hypo addition like this:
1184 // mesh.AddHypothesis(geom, HYPO ) --> HYPO = algo.Hypo()
1185 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1187 Handle(_pyCommand) addCmd = *cmd;
1188 _pyID hypID = addCmd->GetArg( 2 );
1189 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1190 if ( hyp.IsNull() || hyp->IsAlgo() )
1192 bool converted = hyp->Addition2Creation( addCmd, this->GetID() );
1194 // mesh.AddHypothesis(geom, HYP) --> mesh.AddHypothesis(HYP, geom=0)
1195 _pyID geom = addCmd->GetArg( 1 );
1196 addCmd->RemoveArgs();
1197 addCmd->SetArg( 1, hypID );
1198 if ( geom != GetGeom() )
1199 addCmd->SetArg( 2, geom );
1203 // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name)
1204 // for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) {
1205 // Handle(_pyCommand) subCmd = *cmd;
1206 // if ( subCmd->GetNbArgs() > 0 )
1207 // AddMeshAccess( subCmd );
1209 myAddHypCmds.clear();
1210 mySubmeshes.clear();
1213 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
1214 for ( ; hyp != myHypos.end(); ++hyp )
1218 //================================================================================
1220 * \brief MeshEditor convert its commands to ones of mesh
1222 //================================================================================
1224 _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
1225 _pyObject( theCreationCmd )
1227 myMesh = theCreationCmd->GetObject();
1228 myCreationCmdStr = theCreationCmd->GetString();
1229 theCreationCmd->Clear();
1232 //================================================================================
1234 * \brief convert its commands to ones of mesh
1236 //================================================================================
1238 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
1240 // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
1241 // commands calling this methods are converted to calls of methods of Mesh
1242 static TStringSet sameMethods;
1243 if ( sameMethods.empty() ) {
1244 const char * names[] = {
1245 "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
1246 "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
1247 "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
1248 "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
1249 "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
1250 "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
1251 "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
1252 "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
1253 "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
1254 "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
1255 "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
1256 "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
1257 "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
1258 "GetLastCreatedElems",
1259 "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
1260 "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
1261 ,"" }; // <- mark of the end
1262 sameMethods.Insert( names );
1265 // names of SMESH_MeshEditor methods which differ from methods of class Mesh
1266 // only by last two arguments
1267 static TStringSet diffLastTwoArgsMethods;
1268 if (diffLastTwoArgsMethods.empty() ) {
1269 const char * names[] = {
1270 "MirrorMakeGroups","MirrorObjectMakeGroups",
1271 "TranslateMakeGroups","TranslateObjectMakeGroups",
1272 "RotateMakeGroups","RotateObjectMakeGroups",
1273 ""};// <- mark of the end
1274 diffLastTwoArgsMethods.Insert( names );
1277 const TCollection_AsciiString & method = theCommand->GetMethod();
1278 bool isPyMeshMethod = sameMethods.Contains( method );
1279 if ( !isPyMeshMethod )
1281 //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
1282 //functions with the flag "theMakeGroups = True" like:
1283 //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
1284 int pos = method.Search("MakeGroups");
1287 isPyMeshMethod = true;
1289 // 1. Remove "MakeGroups" from the Command
1290 TCollection_AsciiString aMethod = theCommand->GetMethod();
1291 int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
1292 aMethod.Trunc(pos-1);
1293 theCommand->SetMethod(aMethod);
1295 // 2. And add last "True" argument(s)
1296 while(nbArgsToAdd--)
1297 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1301 // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
1302 if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
1304 isPyMeshMethod=true;
1305 theCommand->SetMethod("ExtrusionAlongPathX");
1308 // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
1309 if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
1311 isPyMeshMethod=true;
1312 theCommand->SetMethod("FindCoincidentNodesOnPart");
1314 // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
1315 // DoubleNodeGroupNew() -> DoubleNodeGroup()
1316 // DoubleNodeGroupsNew() -> DoubleNodeGroups()
1317 // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
1318 if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" ||
1319 method == "DoubleNodeElemGroupsNew" ||
1320 method == "DoubleNodeGroupNew" ||
1321 method == "DoubleNodeGroupsNew"))
1323 isPyMeshMethod=true;
1324 theCommand->SetMethod( method.SubString( 1, method.Length()-3));
1325 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1327 // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
1328 // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
1329 if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
1330 method == "ConvertFromQuadraticObject" ))
1332 isPyMeshMethod=true;
1333 theCommand->SetMethod( method.SubString( 1, method.Length()-6));
1334 // prevent moving creation of the converted sub-mesh to the end of the script
1335 bool isFromQua = ( method.Value( 8 ) == 'F' );
1336 Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
1338 sm->Process( theCommand );
1340 // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
1341 // FindElementsByPoint(x, y, z, elementType, meshPart)
1342 if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
1344 isPyMeshMethod=true;
1345 theCommand->SetMethod( "FindElementsByPoint" );
1346 // make the 1st arg be the last one
1347 _pyID partID = theCommand->GetArg( 1 );
1348 int nbArgs = theCommand->GetNbArgs();
1349 for ( int i = 2; i <= nbArgs; ++i )
1350 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1351 theCommand->SetArg( nbArgs, partID );
1354 // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
1355 // so let _pyMesh care of it (TMP?)
1356 // if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
1357 // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
1358 if ( isPyMeshMethod )
1360 theCommand->SetObject( myMesh );
1364 // editor creation command is needed only if any editor function is called
1365 theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
1366 if ( !myCreationCmdStr.IsEmpty() ) {
1367 GetCreationCmd()->GetString() = myCreationCmdStr;
1368 myCreationCmdStr.Clear();
1373 //================================================================================
1375 * \brief _pyHypothesis constructor
1376 * \param theCreationCmd -
1378 //================================================================================
1380 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
1381 _pyObject( theCreationCmd )
1383 myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
1386 //================================================================================
1388 * \brief Creates algorithm or hypothesis
1389 * \param theCreationCmd - The engine command creating a hypothesis
1390 * \retval Handle(_pyHypothesis) - Result _pyHypothesis
1392 //================================================================================
1394 Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& theCreationCmd)
1396 // theCreationCmd: CreateHypothesis( "theHypType", "theLibName" )
1397 ASSERT (( theCreationCmd->GetMethod() == "CreateHypothesis"));
1399 Handle(_pyHypothesis) hyp, algo;
1402 const TCollection_AsciiString & hypTypeQuoted = theCreationCmd->GetArg( 1 );
1403 if ( hypTypeQuoted.IsEmpty() )
1406 TCollection_AsciiString hypType =
1407 hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1409 algo = new _pyAlgorithm( theCreationCmd );
1410 hyp = new _pyHypothesis( theCreationCmd );
1412 // 1D Regular_1D ----------
1413 if ( hypType == "Regular_1D" ) {
1414 // set mesh's method creating algo,
1415 // i.e. convertion result will be "regular1d = Mesh.Segment()",
1416 // and set hypType by which algo creating a hypothesis is searched for
1417 algo->SetConvMethodAndType("Segment", hypType.ToCString());
1419 else if ( hypType == "CompositeSegment_1D" ) {
1420 algo->SetConvMethodAndType("Segment", "Regular_1D");
1421 algo->myArgs.Append( "algo=smesh.COMPOSITE");
1423 else if ( hypType == "LocalLength" ) {
1424 // set algo's method creating hyp, and algo type
1425 hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
1426 // set method whose 1 arg will become the 1-st arg of hyp creation command
1427 // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
1428 hyp->AddArgMethod( "SetLength" );
1430 else if ( hypType == "MaxLength" ) {
1431 // set algo's method creating hyp, and algo type
1432 hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
1433 // set method whose 1 arg will become the 1-st arg of hyp creation command
1434 // i.e. convertion result will be "maxsize = regular1d.MaxSize(<arg of SetLength()>)"
1435 hyp->AddArgMethod( "SetLength" );
1437 else if ( hypType == "NumberOfSegments" ) {
1438 hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
1439 hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
1440 // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
1441 hyp->AddArgMethod( "SetNumberOfSegments" );
1442 // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
1443 hyp->AddArgMethod( "SetScaleFactor" );
1444 hyp->AddArgMethod( "SetReversedEdges" );
1446 else if ( hypType == "Arithmetic1D" ) {
1447 hyp = new _pyComplexParamHypo( theCreationCmd );
1448 hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
1449 hyp->AddArgMethod( "SetStartLength" );
1450 hyp->AddArgMethod( "SetEndLength" );
1451 hyp->AddArgMethod( "SetReversedEdges" );
1453 else if ( hypType == "StartEndLength" ) {
1454 hyp = new _pyComplexParamHypo( theCreationCmd );
1455 hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
1456 hyp->AddArgMethod( "SetStartLength" );
1457 hyp->AddArgMethod( "SetEndLength" );
1458 hyp->AddArgMethod( "SetReversedEdges" );
1460 else if ( hypType == "Deflection1D" ) {
1461 hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
1462 hyp->AddArgMethod( "SetDeflection" );
1464 else if ( hypType == "Propagation" ) {
1465 hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
1467 else if ( hypType == "QuadraticMesh" ) {
1468 hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
1470 else if ( hypType == "AutomaticLength" ) {
1471 hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
1472 hyp->AddArgMethod( "SetFineness");
1474 else if ( hypType == "SegmentLengthAroundVertex" ) {
1475 hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
1476 hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
1477 hyp->AddArgMethod( "SetLength" );
1479 // 1D Python_1D ----------
1480 else if ( hypType == "Python_1D" ) {
1481 algo->SetConvMethodAndType( "Segment", hypType.ToCString());
1482 algo->myArgs.Append( "algo=smesh.PYTHON");
1484 else if ( hypType == "PythonSplit1D" ) {
1485 hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
1486 hyp->AddArgMethod( "SetNumberOfSegments");
1487 hyp->AddArgMethod( "SetPythonLog10RatioFunction");
1489 // MEFISTO_2D ----------
1490 else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D
1491 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1493 else if ( hypType == "MaxElementArea" ) {
1494 hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
1495 hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY");
1496 hyp->AddArgMethod( "SetMaxElementArea");
1498 else if ( hypType == "LengthFromEdges" ) {
1499 hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
1500 hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY");
1502 // Quadrangle_2D ----------
1503 else if ( hypType == "Quadrangle_2D" ) {
1504 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1506 else if ( hypType == "QuadranglePreference" ) {
1507 hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
1508 hyp->SetConvMethodAndType( "SetQuadAllowed", "NETGEN_2D_ONLY");
1510 else if ( hypType == "TrianglePreference" ) {
1511 hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
1513 // RadialQuadrangle_1D2D ----------
1514 else if ( hypType == "RadialQuadrangle_1D2D" ) {
1515 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1516 algo->myArgs.Append( "algo=smesh.RADIAL_QUAD" );
1518 else if ( hypType == "NumberOfLayers2D" ) {
1519 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialQuadrangle_1D2D");
1520 hyp->AddArgMethod( "SetNumberOfLayers" );
1522 else if ( hypType == "LayerDistribution2D" ) {
1523 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
1524 hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
1526 // BLSURF ----------
1527 else if ( hypType == "BLSURF" ) {
1528 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1529 algo->myArgs.Append( "algo=smesh.BLSURF" );
1531 else if ( hypType == "BLSURF_Parameters") {
1532 hyp->SetConvMethodAndType( "Parameters", "BLSURF");
1534 // NETGEN ----------
1535 else if ( hypType == "NETGEN_2D") { // 1D-2D
1536 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1537 algo->myArgs.Append( "algo=smesh.NETGEN" );
1539 else if ( hypType == "NETGEN_Parameters_2D") {
1540 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1542 else if ( hypType == "NETGEN_SimpleParameters_2D") {
1543 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1544 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1546 else if ( hypType == "NETGEN_2D3D") { // 1D-2D-3D
1547 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1548 algo->myArgs.Append( "algo=smesh.FULL_NETGEN" );
1550 else if ( hypType == "NETGEN_Parameters") {
1551 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1553 else if ( hypType == "NETGEN_SimpleParameters_3D") {
1554 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1555 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1557 else if ( hypType == "NETGEN_2D_ONLY") { // 2D
1558 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1559 algo->myArgs.Append( "algo=smesh.NETGEN_2D" );
1561 else if ( hypType == "NETGEN_3D") { // 3D
1562 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1563 algo->myArgs.Append( "algo=smesh.NETGEN" );
1565 else if ( hypType == "MaxElementVolume") {
1566 hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
1567 hyp->AddArgMethod( "SetMaxElementVolume" );
1569 // GHS3D_3D ----------
1570 else if ( hypType == "GHS3D_3D" ) {
1571 algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
1572 algo->myArgs.Append( "algo=smesh.GHS3D" );
1574 else if ( hypType == "GHS3D_Parameters") {
1575 hyp->SetConvMethodAndType( "Parameters", "GHS3D_3D");
1577 // Hexa_3D ---------
1578 else if ( hypType == "BLSURF" ) {
1579 algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
1581 // Repetitive Projection_1D ---------
1582 else if ( hypType == "Projection_1D" ) {
1583 algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
1585 else if ( hypType == "ProjectionSource1D" ) {
1586 hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
1587 hyp->AddArgMethod( "SetSourceEdge");
1588 hyp->AddArgMethod( "SetSourceMesh");
1589 // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
1590 hyp->AddArgMethod( "SetVertexAssociation", 2 );
1592 // Projection_2D ---------
1593 else if ( hypType == "Projection_2D" ) {
1594 algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
1596 else if ( hypType == "Projection_1D2D" ) {
1597 algo->SetConvMethodAndType( "Projection1D2D", hypType.ToCString());
1599 else if ( hypType == "ProjectionSource2D" ) {
1600 hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
1601 hyp->AddArgMethod( "SetSourceFace");
1602 hyp->AddArgMethod( "SetSourceMesh");
1603 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1605 // Projection_3D ---------
1606 else if ( hypType == "Projection_3D" ) {
1607 algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
1609 else if ( hypType == "ProjectionSource3D" ) {
1610 hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
1611 hyp->AddArgMethod( "SetSource3DShape");
1612 hyp->AddArgMethod( "SetSourceMesh");
1613 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1615 // Prism_3D ---------
1616 else if ( hypType == "Prism_3D" ) {
1617 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1619 // RadialPrism_3D ---------
1620 else if ( hypType == "RadialPrism_3D" ) {
1621 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1623 else if ( hypType == "NumberOfLayers" ) {
1624 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
1625 hyp->AddArgMethod( "SetNumberOfLayers" );
1627 else if ( hypType == "LayerDistribution" ) {
1628 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
1629 hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
1632 return algo->IsValid() ? algo : hyp;
1635 //================================================================================
1637 * \brief Convert the command adding a hypothesis to mesh into a smesh command
1638 * \param theCmd - The command like mesh.AddHypothesis( geom, hypo )
1639 * \param theAlgo - The algo that can create this hypo
1640 * \retval bool - false if the command cant be converted
1642 //================================================================================
1644 bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
1645 const _pyID& theMesh)
1647 ASSERT(( theCmd->GetMethod() == "AddHypothesis" ));
1649 if ( !IsWrappable( theMesh ))
1652 myGeom = theCmd->GetArg( 1 );
1654 Handle(_pyHypothesis) algo;
1656 // find algo created on myGeom in theMesh
1657 algo = theGen->FindAlgo( myGeom, theMesh, this );
1658 if ( algo.IsNull() )
1660 // attach hypothesis creation command to be after algo creation command
1661 // because it can be new created instance of algorithm
1662 algo->GetCreationCmd()->AddDependantCmd( theCmd );
1666 // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
1667 theCmd->SetResultValue( GetID() );
1668 theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
1669 theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() ));
1671 theCmd->RemoveArgs();
1672 for ( int i = 1; i <= myArgs.Length(); ++i ) {
1673 if ( !myArgs( i ).IsEmpty() )
1674 theCmd->SetArg( i, myArgs( i ));
1676 theCmd->SetArg( i, "[]");
1678 // set a new creation command
1679 GetCreationCmd()->Clear();
1680 // replace creation command by wrapped instance
1681 // please note, that hypothesis attaches to algo creation command (see upper)
1682 SetCreationCmd( theCmd );
1685 // clear commands setting arg values
1686 list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
1687 for ( ; argCmd != myArgCommands.end(); ++argCmd )
1690 // set unknown arg commands after hypo creation
1691 Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
1692 list<Handle(_pyCommand)>::iterator cmd = myUnknownCommands.begin();
1693 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1694 afterCmd->AddDependantCmd( *cmd );
1700 //================================================================================
1702 * \brief Remember hypothesis parameter values
1703 * \param theCommand - The called hypothesis method
1705 //================================================================================
1707 void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
1709 ASSERT( !myIsAlgo );
1712 for ( int i = 1; i <= myArgMethods.Length(); ++i ) {
1713 if ( myArgMethods( i ) == theCommand->GetMethod() ) {
1714 while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i ))
1715 myArgs.Append( "[]" );
1716 for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg )
1717 myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value
1718 myArgCommands.push_back( theCommand );
1721 nbArgs += myNbArgsByMethod( i );
1723 myUnknownCommands.push_back( theCommand );
1726 //================================================================================
1728 * \brief Finish conversion
1730 //================================================================================
1732 void _pyHypothesis::Flush()
1734 if ( IsWrapped() ) {
1737 list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
1738 for ( ; cmd != myArgCommands.end(); ++cmd ) {
1739 // Add access to a wrapped mesh
1740 theGen->AddMeshAccessorMethod( *cmd );
1741 // Add access to a wrapped algorithm
1742 theGen->AddAlgoAccessorMethod( *cmd );
1744 cmd = myUnknownCommands.begin();
1745 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1746 // Add access to a wrapped mesh
1747 theGen->AddMeshAccessorMethod( *cmd );
1748 // Add access to a wrapped algorithm
1749 theGen->AddAlgoAccessorMethod( *cmd );
1752 // forget previous hypothesis modifications
1753 myArgCommands.clear();
1754 myUnknownCommands.clear();
1757 //================================================================================
1759 * \brief clear creation, arg and unkown commands
1761 //================================================================================
1763 void _pyHypothesis::ClearAllCommands()
1765 GetCreationCmd()->Clear();
1766 list<Handle(_pyCommand)>::iterator cmd = myArgCommands.begin();
1767 for ( ; cmd != myArgCommands.end(); ++cmd )
1769 cmd = myUnknownCommands.begin();
1770 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1775 //================================================================================
1777 * \brief Assign fields of theOther to me except myIsWrapped
1779 //================================================================================
1781 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
1782 const _pyID& theMesh )
1784 myIsWrapped = false;
1787 // myCreationCmd = theOther->myCreationCmd;
1788 myIsAlgo = theOther->myIsAlgo;
1789 myGeom = theOther->myGeom;
1790 myType2CreationMethod = theOther->myType2CreationMethod;
1791 myArgs = theOther->myArgs;
1792 myArgMethods = theOther->myArgMethods;
1793 myNbArgsByMethod = theOther->myNbArgsByMethod;
1794 myArgCommands = theOther->myArgCommands;
1795 myUnknownCommands = theOther->myUnknownCommands;
1798 //================================================================================
1800 * \brief Remember hypothesis parameter values
1801 * \param theCommand - The called hypothesis method
1803 //================================================================================
1805 void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
1807 if( theCommand->GetMethod() == "SetLength" )
1809 // NOW it becomes OBSOLETE
1810 // ex: hyp.SetLength(start, 1)
1811 // hyp.SetLength(end, 0)
1812 ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
1813 int i = 2 - theCommand->GetArg( 2 ).IntegerValue();
1814 while ( myArgs.Length() < i )
1815 myArgs.Append( "[]" );
1816 myArgs( i ) = theCommand->GetArg( 1 ); // arg value
1817 myArgCommands.push_back( theCommand );
1821 _pyHypothesis::Process( theCommand );
1824 //================================================================================
1826 * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment
1828 //================================================================================
1830 void _pyComplexParamHypo::Flush()
1834 list < Handle(_pyCommand) >::iterator cmd = myUnknownCommands.begin();
1835 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1836 if ((*cmd)->GetMethod() == "SetObjectEntry" )
1841 //================================================================================
1843 * \brief Convert methods of 1D hypotheses to my own methods
1844 * \param theCommand - The called hypothesis method
1846 //================================================================================
1848 void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
1850 if ( theCommand->GetMethod() != "SetLayerDistribution" )
1853 _pyID newName; // name for 1D hyp = "HypType" + "_Distribution"
1855 const _pyID& hyp1dID = theCommand->GetArg( 1 );
1856 Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
1857 if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
1859 else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) {
1860 // 1D hypo is already set, so distribution changes and the old
1861 // 1D hypo is thrown away
1862 my1dHyp->ClearAllCommands();
1866 if ( !myArgCommands.empty() )
1867 myArgCommands.front()->Clear();
1868 myArgCommands.push_back( theCommand );
1871 //================================================================================
1874 * \param theAdditionCmd - command to be converted
1875 * \param theMesh - mesh instance
1876 * \retval bool - status
1878 //================================================================================
1880 bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
1881 const _pyID& theMesh)
1883 myIsWrapped = false;
1885 if ( my1dHyp.IsNull() )
1888 // set "SetLayerDistribution()" after addition cmd
1889 theAdditionCmd->AddDependantCmd( myArgCommands.front() );
1891 _pyID geom = theAdditionCmd->GetArg( 1 );
1893 Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
1894 if ( !algo.IsNull() )
1896 my1dHyp->SetMesh( theMesh );
1897 my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
1898 algo->GetAlgoType().ToCString());
1899 if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
1902 // clear "SetLayerDistribution()" cmd
1903 myArgCommands.back()->Clear();
1905 // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
1907 // find RadialPrism algo created on <geom> for theMesh
1908 GetCreationCmd()->SetObject( algo->GetID() );
1909 GetCreationCmd()->SetMethod( myAlgoMethod );
1910 GetCreationCmd()->RemoveArgs();
1911 theAdditionCmd->AddDependantCmd( GetCreationCmd() );
1917 //================================================================================
1921 //================================================================================
1923 void _pyLayerDistributionHypo::Flush()
1925 // as creation of 1D hyp was written later then it's edition,
1926 // we need to find all it's edition calls and process them
1927 if ( !my1dHyp.IsNull() )
1929 _pyID hyp1dID = my1dHyp->GetCreationCmd()->GetResultValue();
1931 // make a new name for 1D hyp = "HypType" + "_Distribution"
1933 if ( my1dHyp->IsWrapped() ) {
1934 newName = my1dHyp->GetCreationCmd()->GetMethod();
1937 TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
1938 newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1940 newName += "_Distribution";
1941 my1dHyp->GetCreationCmd()->SetResultValue( newName );
1943 list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
1944 list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
1945 for ( ; cmdIt != cmds.end(); ++cmdIt ) {
1946 const _pyID& objID = (*cmdIt)->GetObject();
1947 if ( objID == hyp1dID ) {
1948 my1dHyp->Process( *cmdIt );
1949 my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
1950 ( *cmdIt )->SetObject( newName );
1953 // Set new hyp name to SetLayerDistribution() cmd
1954 if ( !myArgCommands.empty() && !myArgCommands.back()->IsEmpty() )
1955 myArgCommands.back()->SetArg( 1, newName );
1959 //================================================================================
1961 * \brief additionally to Addition2Creation, clears SetDistrType() command
1962 * \param theCmd - AddHypothesis() command
1963 * \param theMesh - mesh to which a hypothesis is added
1964 * \retval bool - convertion result
1966 //================================================================================
1968 bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
1969 const _pyID& theMesh)
1971 if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) {
1972 // scale factor (2-nd arg) is provided: clear SetDistrType(1) command
1973 bool scaleDistrType = false;
1974 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
1975 for ( ; cmd != myUnknownCommands.rend(); ++cmd ) {
1976 if ( (*cmd)->GetMethod() == "SetDistrType" ) {
1977 if ( (*cmd)->GetArg( 1 ) == "1" ) {
1978 scaleDistrType = true;
1981 else if ( !scaleDistrType ) {
1982 // distribution type changed: remove scale factor from args
1983 myArgs.Remove( 2, myArgs.Length() );
1989 return _pyHypothesis::Addition2Creation( theCmd, theMesh );
1992 //================================================================================
1994 * \brief remove repeated commands defining distribution
1996 //================================================================================
1998 void _pyNumberOfSegmentsHyp::Flush()
2000 // find number of the last SetDistrType() command
2001 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2002 int distrTypeNb = 0;
2003 for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd )
2004 if ( (*cmd)->GetMethod() == "SetDistrType" )
2005 distrTypeNb = (*cmd)->GetOrderNb();
2006 else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
2009 // clear commands before the last SetDistrType()
2010 list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnknownCommands };
2011 for ( int i = 0; i < 2; ++i ) {
2012 set<TCollection_AsciiString> uniqueMethods;
2013 list<Handle(_pyCommand)> & cmdList = *cmds[i];
2014 for ( cmd = cmdList.rbegin(); cmd != cmdList.rend(); ++cmd )
2016 bool clear = ( (*cmd)->GetOrderNb() < distrTypeNb );
2017 const TCollection_AsciiString& method = (*cmd)->GetMethod();
2018 if ( !clear || method == "SetNumberOfSegments" ) {
2019 bool isNewInSet = uniqueMethods.insert( method ).second;
2020 clear = !isNewInSet;
2029 //================================================================================
2031 * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
2032 * into regular1D.LengthNearVertex( length, vertex )
2033 * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
2034 * \param theMesh - The mesh needing this hypo
2035 * \retval bool - false if the command cant be converted
2037 //================================================================================
2039 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2040 const _pyID& theMeshID)
2042 if ( IsWrappable( theMeshID )) {
2044 _pyID vertex = theCmd->GetArg( 1 );
2046 // the problem here is that segment algo will not be found
2047 // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
2048 // geometry where segment algorithm is assigned
2049 Handle(_pyHypothesis) algo;
2050 _pyID geom = vertex;
2051 while ( algo.IsNull() && !geom.IsEmpty()) {
2052 // try to find geom as a father of <vertex>
2053 geom = FatherID( geom );
2054 algo = theGen->FindAlgo( geom, theMeshID, this );
2056 if ( algo.IsNull() )
2057 return false; // also possible to find geom as brother of veretex...
2058 // set geom instead of vertex
2059 theCmd->SetArg( 1, geom );
2061 // set vertex as a second arg
2062 if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
2063 myArgs.Append( vertex );
2065 // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
2066 // theMeshID.LengthNearVertex( length, vertex )
2067 return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
2072 //================================================================================
2074 * \brief _pyAlgorithm constructor
2075 * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)"
2077 //================================================================================
2079 _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
2080 : _pyHypothesis( theCreationCmd )
2085 //================================================================================
2087 * \brief Convert the command adding an algorithm to mesh
2088 * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
2089 * \param theMesh - The mesh needing this algo
2090 * \retval bool - false if the command cant be converted
2092 //================================================================================
2094 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
2095 const _pyID& theMeshID)
2097 // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
2098 if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
2099 theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
2105 //================================================================================
2107 * \brief Return starting position of a part of python command
2108 * \param thePartIndex - The index of command part
2109 * \retval int - Part position
2111 //================================================================================
2113 int _pyCommand::GetBegPos( int thePartIndex )
2117 if ( myBegPos.Length() < thePartIndex )
2119 return myBegPos( thePartIndex );
2122 //================================================================================
2124 * \brief Store starting position of a part of python command
2125 * \param thePartIndex - The index of command part
2126 * \param thePosition - Part position
2128 //================================================================================
2130 void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
2132 while ( myBegPos.Length() < thePartIndex )
2133 myBegPos.Append( UNKNOWN );
2134 myBegPos( thePartIndex ) = thePosition;
2137 //================================================================================
2139 * \brief Returns whitespace symbols at the line beginning
2140 * \retval TCollection_AsciiString - result
2142 //================================================================================
2144 TCollection_AsciiString _pyCommand::GetIndentation()
2147 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2148 GetWord( myString, end, true );
2150 end = GetBegPos( RESULT_IND );
2151 return myString.SubString( 1, end - 1 );
2154 //================================================================================
2156 * \brief Return substring of python command looking like ResultValue = Obj.Meth()
2157 * \retval const TCollection_AsciiString & - ResultValue substring
2159 //================================================================================
2161 const TCollection_AsciiString & _pyCommand::GetResultValue()
2163 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2165 int begPos = myString.Location( "=", 1, Length() );
2167 myRes = GetWord( myString, begPos, false );
2170 SetBegPos( RESULT_IND, begPos );
2175 //================================================================================
2177 * \brief Return number of python command result value ResultValue = Obj.Meth()
2180 //================================================================================
2182 const int _pyCommand::GetNbResultValues()
2186 int endPos = myString.Location( "=", 1, Length() );
2187 TCollection_AsciiString str = "";
2188 while ( begPos < endPos) {
2189 str = GetWord( myString, begPos, true );
2190 begPos = begPos+ str.Length();
2197 //================================================================================
2199 * \brief Return substring of python command looking like
2200 * ResultValue1 , ResultValue1,... = Obj.Meth() with res index
2201 * \retval const TCollection_AsciiString & - ResultValue with res index substring
2203 //================================================================================
2204 const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
2208 int endPos = myString.Location( "=", 1, Length() );
2209 while ( begPos < endPos) {
2210 myRes = GetWord( myString, begPos, true );
2211 begPos = begPos + myRes.Length();
2214 myRes.RemoveAll('[');myRes.RemoveAll(']');
2220 return theEmptyString;
2223 //================================================================================
2225 * \brief Return substring of python command looking like ResVal = Object.Meth()
2226 * \retval const TCollection_AsciiString & - Object substring
2228 //================================================================================
2230 const TCollection_AsciiString & _pyCommand::GetObject()
2232 if ( GetBegPos( OBJECT_IND ) == UNKNOWN )
2235 int begPos = GetBegPos( RESULT_IND ) + myRes.Length();
2237 begPos = myString.Location( "=", 1, Length() ) + 1;
2238 // is '=' in the string argument (for example, name) or not
2239 int nb1 = 0; // number of ' character at the left of =
2240 int nb2 = 0; // number of " character at the left of =
2241 for ( int i = 1; i < begPos-1; i++ ) {
2242 if ( myString.Value( i )=='\'' )
2244 else if ( myString.Value( i )=='"' )
2247 // if number of ' or " is not divisible by 2,
2248 // then get an object at the start of the command
2249 if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
2252 myObj = GetWord( myString, begPos, true );
2253 // check if object is complex,
2254 // so far consider case like "smesh.smesh.Method()"
2255 if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
2256 //if ( bracketPos==0 ) bracketPos = Length();
2257 int dotPos = begPos+myObj.Length();
2258 while ( dotPos+1 < bracketPos ) {
2259 if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
2264 if ( dotPos > begPos+myObj.Length() )
2265 myObj = myString.SubString( begPos, dotPos-1 );
2268 SetBegPos( OBJECT_IND, begPos );
2274 //================================================================================
2276 * \brief Return substring of python command looking like ResVal = Obj.Method()
2277 * \retval const TCollection_AsciiString & - Method substring
2279 //================================================================================
2281 const TCollection_AsciiString & _pyCommand::GetMethod()
2283 if ( GetBegPos( METHOD_IND ) == UNKNOWN )
2286 int begPos = GetBegPos( OBJECT_IND ) + myObj.Length();
2287 bool forward = true;
2289 begPos = myString.Location( "(", 1, Length() ) - 1;
2293 myMeth = GetWord( myString, begPos, forward );
2294 SetBegPos( METHOD_IND, begPos );
2300 //================================================================================
2302 * \brief Return substring of python command looking like ResVal = Obj.Meth(Arg1,...)
2303 * \retval const TCollection_AsciiString & - Arg<index> substring
2305 //================================================================================
2307 const TCollection_AsciiString & _pyCommand::GetArg( int index )
2309 if ( GetBegPos( ARG1_IND ) == UNKNOWN )
2313 int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
2315 pos = myString.Location( "(", 1, Length() );
2319 // we are at or before '(', skip it if present
2321 while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
2322 if ( myString.Value( pos ) != '(' )
2326 SetBegPos( ARG1_IND, 0 ); // even no '('
2327 return theEmptyString;
2331 list< TCollection_AsciiString > separatorStack( 1, ",)");
2332 bool ignoreNesting = false;
2334 while ( pos <= Length() )
2336 const char chr = myString.Value( pos );
2338 if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
2340 if ( separatorStack.size() == 1 ) // ',' dividing args or a terminal ')' found
2342 while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
2344 if ( pos-1 >= prevPos ) {
2345 TCollection_AsciiString arg = myString.SubString( prevPos, pos-1 );
2346 arg.RightAdjust(); // remove spaces
2348 SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
2349 myArgs.Append( arg );
2355 else // end of nesting args found
2357 separatorStack.pop_back();
2358 ignoreNesting = false;
2361 else if ( !ignoreNesting )
2364 case '(' : separatorStack.push_back(")"); break;
2365 case '[' : separatorStack.push_back("]"); break;
2366 case '\'': separatorStack.push_back("'"); ignoreNesting=true; break;
2367 case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
2374 if ( myArgs.Length() < index )
2375 return theEmptyString;
2376 return myArgs( index );
2379 //================================================================================
2381 * \brief Check if char is a word part
2382 * \param c - The character to check
2383 * \retval bool - The check result
2385 //================================================================================
2387 static inline bool isWord(const char c, const bool dotIsWord)
2390 !isspace(c) && c != ',' && c != '=' && c != ')' && c != '(' && ( dotIsWord || c != '.');
2393 //================================================================================
2395 * \brief Looks for a word in the string and returns word's beginning
2396 * \param theString - The input string
2397 * \param theStartPos - The position to start the search, returning word's beginning
2398 * \param theForward - The search direction
2399 * \retval TCollection_AsciiString - The found word
2401 //================================================================================
2403 TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
2405 const bool theForward,
2406 const bool dotIsWord )
2408 int beg = theStartPos, end = theStartPos;
2409 theStartPos = EMPTY;
2410 if ( beg < 1 || beg > theString.Length() )
2411 return theEmptyString;
2413 if ( theForward ) { // search forward
2415 while ( beg <= theString.Length() && !isWord( theString.Value( beg ), dotIsWord))
2417 if ( beg > theString.Length() )
2418 return theEmptyString; // no word found
2421 char begChar = theString.Value( beg );
2422 if ( begChar == '"' || begChar == '\'' || begChar == '[') {
2423 char endChar = ( begChar == '[' ) ? ']' : begChar;
2424 // end is at the corresponding quoting mark or bracket
2425 while ( end < theString.Length() &&
2426 ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\'))
2430 while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
2435 else { // search backward
2437 while ( end > 0 && !isWord( theString.Value( end ), dotIsWord))
2440 return theEmptyString; // no word found
2442 char endChar = theString.Value( end );
2443 if ( endChar == '"' || endChar == '\'' ) {
2444 // beg is at the corresponding quoting mark
2446 ( theString.Value( beg ) != endChar || theString.Value( beg-1 ) == '\\'))
2450 while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
2456 //cout << theString << " ---- " << beg << " - " << end << endl;
2457 return theString.SubString( beg, end );
2460 //================================================================================
2462 * \brief Look for position where not space char is
2463 * \param theString - The string
2464 * \param thePos - The position to search from and which returns result
2465 * \retval bool - false if there are only space after thePos in theString
2469 //================================================================================
2471 bool _pyCommand::SkipSpaces( const TCollection_AsciiString & theString, int & thePos )
2473 if ( thePos < 1 || thePos > theString.Length() )
2476 while ( thePos <= theString.Length() && isspace( theString.Value( thePos )))
2479 return thePos <= theString.Length();
2482 //================================================================================
2484 * \brief Modify a part of the command
2485 * \param thePartIndex - The index of the part
2486 * \param thePart - The new part string
2487 * \param theOldPart - The old part
2489 //================================================================================
2491 void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePart,
2492 TCollection_AsciiString& theOldPart)
2494 int pos = GetBegPos( thePartIndex );
2495 if ( pos <= Length() && theOldPart != thePart)
2497 TCollection_AsciiString seperator;
2499 pos = GetBegPos( thePartIndex + 1 );
2500 if ( pos < 1 ) return;
2501 switch ( thePartIndex ) {
2502 case RESULT_IND: seperator = " = "; break;
2503 case OBJECT_IND: seperator = "."; break;
2504 case METHOD_IND: seperator = "()"; break;
2508 myString.Remove( pos, theOldPart.Length() );
2509 if ( !seperator.IsEmpty() )
2510 myString.Insert( pos , seperator );
2511 myString.Insert( pos, thePart );
2512 // update starting positions of the following parts
2513 int posDelta = thePart.Length() + seperator.Length() - theOldPart.Length();
2514 for ( int i = thePartIndex + 1; i <= myBegPos.Length(); ++i ) {
2515 if ( myBegPos( i ) > 0 )
2516 myBegPos( i ) += posDelta;
2518 theOldPart = thePart;
2522 //================================================================================
2524 * \brief Set agrument
2525 * \param index - The argument index, it counts from 1
2526 * \param theArg - The argument string
2528 //================================================================================
2530 void _pyCommand::SetArg( int index, const TCollection_AsciiString& theArg)
2533 int argInd = ARG1_IND + index - 1;
2534 int pos = GetBegPos( argInd );
2535 if ( pos < 1 ) // no index-th arg exist, append inexistent args
2537 // find a closing parenthesis
2538 if ( GetNbArgs() != 0 && index <= GetNbArgs() ) {
2539 int lastArgInd = GetNbArgs();
2540 pos = GetBegPos( ARG1_IND + lastArgInd - 1 ) + GetArg( lastArgInd ).Length();
2541 while ( pos > 0 && pos <= Length() && myString.Value( pos ) != ')' )
2546 while ( pos > 0 && myString.Value( pos ) != ')' )
2549 if ( pos < 1 || myString.Value( pos ) != ')' ) { // no parentheses at all
2553 while ( myArgs.Length() < index ) {
2554 if ( myArgs.Length() )
2555 myString.Insert( pos++, "," );
2556 myArgs.Append("None");
2557 myString.Insert( pos, myArgs.Last() );
2558 SetBegPos( ARG1_IND + myArgs.Length() - 1, pos );
2559 pos += myArgs.Last().Length();
2562 SetPart( argInd, theArg, myArgs( index ));
2565 //================================================================================
2567 * \brief Empty arg list
2569 //================================================================================
2571 void _pyCommand::RemoveArgs()
2573 if ( int pos = myString.Location( '(', 1, Length() ))
2574 myString.Trunc( pos );
2577 if ( myBegPos.Length() >= ARG1_IND )
2578 myBegPos.Remove( ARG1_IND, myBegPos.Length() );
2581 //================================================================================
2583 * \brief Set dependent commands after this one
2585 //================================================================================
2587 bool _pyCommand::SetDependentCmdsAfter() const
2589 bool orderChanged = false;
2590 list< Handle(_pyCommand)>::const_reverse_iterator cmd = myDependentCmds.rbegin();
2591 for ( ; cmd != myDependentCmds.rend(); ++cmd ) {
2592 if ( (*cmd)->GetOrderNb() < GetOrderNb() ) {
2593 orderChanged = true;
2594 theGen->SetCommandAfter( *cmd, this );
2595 (*cmd)->SetDependentCmdsAfter();
2598 return orderChanged;
2600 //================================================================================
2602 * \brief Insert accessor method after theObjectID
2603 * \param theObjectID - id of the accessed object
2604 * \param theAcsMethod - name of the method giving access to the object
2605 * \retval bool - false if theObjectID is not found in the command string
2607 //================================================================================
2609 bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod )
2611 if ( !theAcsMethod )
2613 // start object search from the object, i.e. ignore result
2615 int beg = GetBegPos( OBJECT_IND );
2616 if ( beg < 1 || beg > Length() )
2619 while (( beg = myString.Location( theObjectID, beg, Length() )))
2621 // check that theObjectID is not just a part of a longer ID
2622 int afterEnd = beg + theObjectID.Length();
2623 Standard_Character c = myString.Value( afterEnd );
2624 if ( !isalnum( c ) && c != ':' ) {
2625 // check if accessor method already present
2627 myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
2629 int oldLen = Length();
2630 myString.Insert( afterEnd, (char*) theAcsMethod );
2631 myString.Insert( afterEnd, "." );
2632 // update starting positions of the parts following the modified one
2633 int posDelta = Length() - oldLen;
2634 for ( int i = 1; i <= myBegPos.Length(); ++i ) {
2635 if ( myBegPos( i ) > afterEnd )
2636 myBegPos( i ) += posDelta;
2641 beg = afterEnd; // is a part - next search
2646 //================================================================================
2648 * \brief Return method name giving access to an interaface object wrapped by python class
2649 * \retval const char* - method name
2651 //================================================================================
2653 const char* _pyObject::AccessorMethod() const
2657 //================================================================================
2659 * \brief Return ID of a father
2661 //================================================================================
2663 _pyID _pyObject::FatherID(const _pyID & childID)
2665 int colPos = childID.SearchFromEnd(':');
2667 return childID.SubString( 1, colPos-1 );
2671 //================================================================================
2673 * \brief SelfEraser erases creation command if no more it's commands invoked
2675 //================================================================================
2677 void _pySelfEraser::Flush()
2679 if ( GetNbCalls() == 0 )
2680 GetCreationCmd()->Clear();
2683 //================================================================================
2685 * \brief count invoked commands
2687 //================================================================================
2689 void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
2691 _pyObject::Process(theCommand); // count calls of Process()
2692 GetCreationCmd()->AddDependantCmd( theCommand );
2695 //================================================================================
2697 * \brief Clear creation command if no commands invoked
2699 //================================================================================
2701 void _pySubMesh::Flush()
2703 if ( GetNbCalls() == 0 ) // move to the end of all commands
2704 theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
2705 else if ( !myCreator.IsNull() )
2706 // move to be just after creator
2707 myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
2709 //================================================================================
2711 * \brief To convert creation of a group by filter
2713 //================================================================================
2715 void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
2717 // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
2718 // group = mesh.CreateEmptyGroup( elemType, groupName )
2719 // aFilter.SetMesh(mesh)
2720 // nbAdd = group.AddFrom( aFilter )
2721 if ( theCommand->GetMethod() == "AddFrom" )
2723 _pyID idSource = theCommand->GetArg(1);
2724 // check if idSource is a filter: find a command creating idSource,
2725 // it should be "idSource = aFilterManager.CreateFilter()" or
2726 // "idSource = smesh.GetFilterFromCriteria(aCriteria)
2727 const list< Handle(_pyCommand) >& commands = theGen->GetCommands();
2728 list< Handle(_pyCommand) >::const_reverse_iterator cmdIt = commands.rbegin();
2729 bool isFilter = false;
2730 for ( ; cmdIt != commands.rend(); ++cmdIt )
2731 if ( (*cmdIt)->GetResultValue() == idSource )
2733 isFilter = ( (*cmdIt)->GetMethod() == "CreateFilter" ||
2734 (*cmdIt)->GetMethod() == "GetFilterFromCriteria" );
2737 if ( !isFilter ) return;
2739 // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
2740 for ( cmdIt = commands.rbegin(); cmdIt != commands.rend(); ++cmdIt )
2741 if ( *cmdIt == theCommand && (*cmdIt)->GetOrderNb() != 1 )
2743 const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
2744 if ( setMeshCmd->GetObject() == idSource &&
2745 setMeshCmd->GetMethod() == "SetMesh")
2746 setMeshCmd->Clear();
2749 // replace 3 commands by one
2750 theCommand->Clear();
2751 const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
2752 TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
2753 makeGroupCmd->SetMethod( "MakeGroupByFilter" );
2754 makeGroupCmd->SetArg( 1, name );
2755 makeGroupCmd->SetArg( 2, idSource );
2759 //================================================================================
2761 * \brief Constructor of _pyFilter
2763 //================================================================================
2765 _pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
2766 :_pyObject(theCreationCmd), myNewID( newID )
2770 //================================================================================
2772 * \brief To convert creation of a filter by criteria
2774 //================================================================================
2776 void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
2778 if ( !myNewID.IsEmpty() )
2779 theCommand->SetObject( myNewID );
2781 // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
2782 // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
2783 // aFilter0x2aaab0487080.SetCriteria(aCriteria)
2784 if ( GetNbCalls() == 0 && // none method was called before SetCriteria()
2785 theCommand->GetMethod() == "SetCriteria")
2787 // aFilter.SetCriteria(aCriteria) ->
2788 // aFilter = smesh.GetFilterFromCriteria(criteria)
2789 if ( myNewID.IsEmpty() )
2790 theCommand->SetResultValue( GetID() );
2792 theCommand->SetResultValue( myNewID );
2793 theCommand->SetObject( SMESH_2smeshpy::GenName() );
2794 theCommand->SetMethod( "GetFilterFromCriteria" );
2796 // Clear aFilterManager.CreateFilter()
2797 GetCreationCmd()->Clear();
2799 else if ( theCommand->GetMethod() == "SetMesh")
2801 theGen->AddMeshAccessorMethod( theCommand );
2805 //================================================================================
2807 * \brief Set new filter name to the creation command
2809 //================================================================================
2811 void _pyFilter::Flush()
2813 if ( !myNewID.IsEmpty() && GetCreationCmd()->IsEmpty() )
2814 GetCreationCmd()->SetResultValue( myNewID );