1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File : SMESH_2smeshpy.cxx
25 // Created : Fri Nov 18 13:20:10 2005
26 // Author : Edward AGAPOV (eap)
28 #include "SMESH_2smeshpy.hxx"
30 #include "utilities.h"
31 #include "SMESH_PythonDump.hxx"
32 #include "SMESH_NoteBook.hxx"
33 #include "SMESH_Filter_i.hxx"
35 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
37 #include "SMESH_Gen_i.hxx"
38 /* SALOME headers that include CORBA headers that include windows.h
39 * that defines GetObject symbol as GetObjectA should stand before SALOME headers
40 * that declare methods named GetObject - to apply the same rules of GetObject renaming
41 * and thus to avoid mess with GetObject symbol on Windows */
43 IMPLEMENT_STANDARD_HANDLE (_pyObject ,Standard_Transient);
44 IMPLEMENT_STANDARD_HANDLE (_pyCommand ,Standard_Transient);
45 IMPLEMENT_STANDARD_HANDLE (_pyGen ,_pyObject);
46 IMPLEMENT_STANDARD_HANDLE (_pyMesh ,_pyObject);
47 IMPLEMENT_STANDARD_HANDLE (_pySubMesh ,_pyObject);
48 IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor ,_pyObject);
49 IMPLEMENT_STANDARD_HANDLE (_pyHypothesis ,_pyObject);
50 IMPLEMENT_STANDARD_HANDLE (_pySelfEraser ,_pyObject);
51 IMPLEMENT_STANDARD_HANDLE (_pyGroup ,_pyObject);
52 IMPLEMENT_STANDARD_HANDLE (_pyFilter ,_pyObject);
53 IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
54 IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
55 IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
57 IMPLEMENT_STANDARD_RTTIEXT(_pyObject ,Standard_Transient);
58 IMPLEMENT_STANDARD_RTTIEXT(_pyCommand ,Standard_Transient);
59 IMPLEMENT_STANDARD_RTTIEXT(_pyGen ,_pyObject);
60 IMPLEMENT_STANDARD_RTTIEXT(_pyMesh ,_pyObject);
61 IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh ,_pyObject);
62 IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor ,_pyObject);
63 IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis ,_pyObject);
64 IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser ,_pyObject);
65 IMPLEMENT_STANDARD_RTTIEXT(_pyGroup ,_pyObject);
66 IMPLEMENT_STANDARD_RTTIEXT(_pyFilter ,_pyObject);
67 IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm ,_pyHypothesis);
68 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
69 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
70 IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
71 IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
74 using SMESH::TPythonDump;
77 * \brief Container of commands into which the initial script is split.
78 * It also contains data coresponding to SMESH_Gen contents
80 static Handle(_pyGen) theGen;
82 static TCollection_AsciiString theEmptyString;
84 //#define DUMP_CONVERSION
86 #if !defined(_DEBUG_) && defined(DUMP_CONVERSION)
87 #undef DUMP_CONVERSION
93 //================================================================================
95 * \brief Set of TCollection_AsciiString initialized by C array of C strings
97 //================================================================================
99 struct TStringSet: public set<TCollection_AsciiString>
102 * \brief Filling. The last string must be ""
104 void Insert(const char* names[]) {
105 for ( int i = 0; names[i][0] ; ++i )
106 insert( (char*) names[i] );
109 * \brief Check if a string is in
111 bool Contains(const TCollection_AsciiString& name ) {
112 return find( name ) != end();
117 //================================================================================
119 * \brief Convert python script using commands of smesh.py
120 * \param theScript - Input script
121 * \retval TCollection_AsciiString - Convertion result
123 * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx
125 //================================================================================
127 TCollection_AsciiString
128 SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
129 Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
130 Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
132 theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
134 // split theScript into separate commands
136 SMESH_NoteBook * aNoteBook = new SMESH_NoteBook();
138 int from = 1, end = theScript.Length(), to;
139 while ( from < end && ( to = theScript.Location( "\n", from, end )))
142 // cut out and store a command
143 aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
147 aNoteBook->ReplaceVariables();
149 TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript();
153 // split theScript into separate commands
154 from = 1, end = aNoteScript.Length();
155 while ( from < end && ( to = aNoteScript.Location( "\n", from, end )))
158 // cut out and store a command
159 theGen->AddCommand( aNoteScript.SubString( from, to - 1 ));
165 #ifdef DUMP_CONVERSION
166 MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl );
169 // reorder commands after conversion
170 list< Handle(_pyCommand) >::iterator cmd;
173 orderChanges = false;
174 for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
175 if ( (*cmd)->SetDependentCmdsAfter() )
177 } while ( orderChanges );
179 // concat commands back into a script
180 TCollection_AsciiString aScript;
181 for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
183 #ifdef DUMP_CONVERSION
184 MESSAGE_ADD ( "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << std::endl );
186 if ( !(*cmd)->IsEmpty() ) {
188 aScript += (*cmd)->GetString();
198 //================================================================================
200 * \brief _pyGen constructor
202 //================================================================================
204 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
205 Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
206 : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
208 myID2AccessorMethod( theEntry2AccessorMethod ),
209 myObjectNames( theObjectNames ),
212 // make that GetID() to return TPythonDump::SMESHGenName()
213 GetCreationCmd()->GetString() += "=";
216 //================================================================================
218 * \brief name of SMESH_Gen in smesh.py
220 //================================================================================
222 const char* _pyGen::AccessorMethod() const
224 return SMESH_2smeshpy::GenName();
227 //================================================================================
229 * \brief Convert a command using a specific converter
230 * \param theCommand - the command to convert
232 //================================================================================
234 Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
236 // store theCommand in the sequence
237 myCommands.push_back( new _pyCommand( theCommand, ++myNbCommands ));
239 Handle(_pyCommand) aCommand = myCommands.back();
240 #ifdef DUMP_CONVERSION
241 MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() );
244 _pyID objID = aCommand->GetObject();
246 if ( objID.IsEmpty() )
249 // Find an object to process theCommand
252 if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName()) {
253 this->Process( aCommand );
257 // SMESH_Mesh method?
258 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
259 if ( id_mesh != myMeshes.end() )
261 // check for mesh editor object
262 if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
263 _pyID editorID = aCommand->GetResultValue();
264 Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
265 myMeshEditors.insert( make_pair( editorID, editor ));
268 // check for SubMesh objects
269 else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
270 _pyID subMeshID = aCommand->GetResultValue();
271 Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
272 myObjects.insert( make_pair( subMeshID, subMesh ));
275 id_mesh->second->Process( aCommand );
279 // SMESH_MeshEditor method?
280 map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
281 if ( id_editor != myMeshEditors.end() )
283 id_editor->second->Process( aCommand );
284 TCollection_AsciiString processedCommand = aCommand->GetString();
285 // some commands of SMESH_MeshEditor create meshes
286 if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) {
287 Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() );
288 aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
289 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
291 if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
292 _pyID meshID = aCommand->GetResultValue(0);
293 if ( !myMeshes.count( meshID ) )
295 Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
296 aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
297 myMeshes.insert( make_pair( meshID, mesh ));
302 // SMESH_Hypothesis method?
303 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
304 for ( ; hyp != myHypos.end(); ++hyp )
305 if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
306 (*hyp)->Process( aCommand );
310 // aFilterManager.CreateFilter() ?
311 if ( aCommand->GetMethod() == "CreateFilter" )
313 // Set a more human readable name to a filter
314 // aFilter0x7fbf6c71cfb0 -> aFilter_nb
315 _pyID newID, filterID = aCommand->GetResultValue();
316 int pos = filterID.Search( "0x" );
318 newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters );
320 Handle(_pyObject) filter( new _pyFilter( aCommand, newID ));
324 // other object method?
325 map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
326 if ( id_obj != myObjects.end() ) {
327 id_obj->second->Process( aCommand );
331 // Add access to a wrapped mesh
332 AddMeshAccessorMethod( aCommand );
334 // Add access to a wrapped algorithm
335 // AddAlgoAccessorMethod( aCommand ); // ??? what if algo won't be wrapped at all ???
337 // PAL12227. PythonDump was not updated at proper time; result is
338 // aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
339 // TypeError: __init__() takes exactly 11 arguments (10 given)
340 const char wrongCommand[] = "SMESH.Filter.Criterion(";
341 if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() ))
343 _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1);
344 // there must be 10 arguments, 5-th arg ThresholdID is missing,
345 const int wrongNbArgs = 9, missingArg = 5;
346 if ( tmpCmd.GetNbArgs() == wrongNbArgs )
348 for ( int i = wrongNbArgs; i > missingArg; --i )
349 tmpCmd.SetArg( i + 1, tmpCmd.GetArg( i ));
350 tmpCmd.SetArg( missingArg, "''");
351 aCommand->GetString().Trunc( beg - 1 );
352 aCommand->GetString() += tmpCmd.GetString();
355 // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance)
357 // instead of "SMESH.Filter.Criterion(
358 // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision)
359 // 1 2 3 4 5 6 7 8 9 10
360 // in order to avoid the problem of type mismatch of long and FunctorType
361 const TCollection_AsciiString
362 SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
363 TCollection_AsciiString
364 Type = aCommand->GetArg(1), // long
365 Compare = aCommand->GetArg(2), // long
366 Threshold = aCommand->GetArg(3), // double
367 ThresholdStr = aCommand->GetArg(4), // string
368 ThresholdID = aCommand->GetArg(5), // string
369 UnaryOp = aCommand->GetArg(6), // long
370 BinaryOp = aCommand->GetArg(7), // long
371 Tolerance = aCommand->GetArg(8), // double
372 TypeOfElement = aCommand->GetArg(9), // ElementType
373 Precision = aCommand->GetArg(10); // long
374 Type = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
375 Compare = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
376 UnaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
377 BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() ));
379 aCommand->RemoveArgs();
380 aCommand->SetObject( SMESH_2smeshpy::GenName() );
381 aCommand->SetMethod( "GetCriterion" );
383 aCommand->SetArg( 1, TypeOfElement );
384 aCommand->SetArg( 2, Type );
385 aCommand->SetArg( 3, Compare );
387 if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
389 // set SMESH.GeometryType instead of a numerical Threshold
390 const char* types[SMESH::Geom_POLYHEDRA+1] = {
391 "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
392 "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_POLYHEDRA"
394 int iGeom = Threshold.IntegerValue();
395 if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
396 Threshold = SMESH + types[ iGeom ];
398 if ( ThresholdStr.Length() != 2 ) // not '' or ""
399 aCommand->SetArg( 4, ThresholdStr );
400 else if ( ThresholdID.Length() != 2 )
401 aCommand->SetArg( 4, ThresholdID );
403 aCommand->SetArg( 4, Threshold );
404 // find the last not default arg
406 if ( Tolerance == dftlTol ) {
408 if ( BinaryOp == dfltFunctor ) {
410 if ( UnaryOp == dfltFunctor )
414 if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
415 if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
416 if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
417 if ( Precision != dftlPreci )
419 TCollection_AsciiString crit = aCommand->GetResultValue();
420 aCommand->GetString() += "; ";
421 aCommand->GetString() += crit + ".Precision = " + Precision;
427 //================================================================================
429 * \brief Convert the command or remember it for later conversion
430 * \param theCommand - The python command calling a method of SMESH_Gen
432 //================================================================================
434 void _pyGen::Process( const Handle(_pyCommand)& theCommand )
436 // there are methods to convert:
437 // CreateMesh( shape )
438 // Concatenate( [mesh1, ...], ... )
439 // CreateHypothesis( theHypType, theLibName )
440 // Compute( mesh, geom )
441 // Evaluate( mesh, geom )
443 TCollection_AsciiString method = theCommand->GetMethod();
445 if ( method == "CreateMesh" || method == "CreateEmptyMesh")
447 Handle(_pyMesh) mesh = new _pyMesh( theCommand );
448 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
451 if ( method == "CreateMeshesFromUNV" ||
452 method == "CreateMeshesFromSTL" ||
453 method == "CreateMeshesFromCGNS" ||
454 method == "CopyMesh" )
456 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
457 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
460 if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
462 for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
464 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
465 myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));
469 // CreateHypothesis()
470 if ( method == "CreateHypothesis" )
472 // issue 199929, remove standard library name (default parameter)
473 const TCollection_AsciiString & aLibName = theCommand->GetArg( 2 );
474 if ( aLibName.Search( "StdMeshersEngine" ) != -1 ) {
475 // keep first argument
476 TCollection_AsciiString arg = theCommand->GetArg( 1 );
477 theCommand->RemoveArgs();
478 theCommand->SetArg( 1, arg );
481 myHypos.push_back( _pyHypothesis::NewHypothesis( theCommand ));
485 // smeshgen.Compute( mesh, geom ) --> mesh.Compute()
486 if ( method == "Compute" )
488 const _pyID& meshID = theCommand->GetArg( 1 );
489 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
490 if ( id_mesh != myMeshes.end() ) {
491 theCommand->SetObject( meshID );
492 theCommand->RemoveArgs();
493 id_mesh->second->Flush();
498 // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
499 if ( method == "Evaluate" )
501 const _pyID& meshID = theCommand->GetArg( 1 );
502 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
503 if ( id_mesh != myMeshes.end() ) {
504 theCommand->SetObject( meshID );
505 _pyID geom = theCommand->GetArg( 2 );
506 theCommand->RemoveArgs();
507 theCommand->SetArg( 1, geom );
512 // objects erasing creation command if no more it's commands invoked:
513 // SMESH_Pattern, FilterManager
514 if ( method == "GetPattern" ||
515 method == "CreateFilterManager" ||
516 method == "CreateMeasurements" ) {
517 Handle(_pyObject) obj = new _pySelfEraser( theCommand );
518 if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
519 theCommand->Clear(); // already created
522 // Concatenate( [mesh1, ...], ... )
523 if ( method == "Concatenate" || method == "ConcatenateWithGroups")
525 if ( method == "ConcatenateWithGroups" ) {
526 theCommand->SetMethod( "Concatenate" );
527 theCommand->SetArg( theCommand->GetNbArgs() + 1, "True" );
529 Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
530 myMeshes.insert( make_pair( mesh->GetID(), mesh ));
531 AddMeshAccessorMethod( theCommand );
534 // Replace name of SMESH_Gen
536 // names of SMESH_Gen methods fully equal to methods defined in smesh.py
537 static TStringSet smeshpyMethods;
538 if ( smeshpyMethods.empty() ) {
539 const char * names[] =
540 { "SetEmbeddedMode","IsEmbeddedMode","SetCurrentStudy","GetCurrentStudy",
541 "GetPattern","GetSubShapesId",
542 "" }; // <- mark of array end
543 smeshpyMethods.Insert( names );
545 if ( smeshpyMethods.Contains( theCommand->GetMethod() ))
546 // smeshgen.Method() --> smesh.Method()
547 theCommand->SetObject( SMESH_2smeshpy::SmeshpyName() );
549 // smeshgen.Method() --> smesh.smesh.Method()
550 theCommand->SetObject( SMESH_2smeshpy::GenName() );
553 //================================================================================
555 * \brief Convert the remembered commands
557 //================================================================================
561 // create empty command
562 myLastCommand = new _pyCommand();
564 map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
565 for ( ; id_mesh != myMeshes.end(); ++id_mesh )
566 if ( ! id_mesh->second.IsNull() )
567 id_mesh->second->Flush();
569 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
570 for ( ; hyp != myHypos.end(); ++hyp )
571 if ( !hyp->IsNull() ) {
573 // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
574 if ( !(*hyp)->IsWrapped() )
575 (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
578 map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
579 for ( ; id_obj != myObjects.end(); ++id_obj )
580 if ( ! id_obj->second.IsNull() )
581 id_obj->second->Flush();
583 myLastCommand->SetOrderNb( ++myNbCommands );
584 myCommands.push_back( myLastCommand );
587 //================================================================================
589 * \brief Add access method to mesh that is an argument
590 * \param theCmd - command to add access method
591 * \retval bool - true if added
593 //================================================================================
595 bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
598 map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
599 for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
600 if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
606 //================================================================================
608 * \brief Add access method to algo that is an object or an argument
609 * \param theCmd - command to add access method
610 * \retval bool - true if added
612 //================================================================================
614 bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
617 list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
618 for ( ; hyp != myHypos.end(); ++hyp ) {
619 if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
620 theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
626 //================================================================================
628 * \brief Find hypothesis by ID (entry)
629 * \param theHypID - The hypothesis ID
630 * \retval Handle(_pyHypothesis) - The found hypothesis
632 //================================================================================
634 Handle(_pyHypothesis) _pyGen::FindHyp( const _pyID& theHypID )
636 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
637 for ( ; hyp != myHypos.end(); ++hyp )
638 if ( !hyp->IsNull() && theHypID == (*hyp)->GetID() )
640 return Handle(_pyHypothesis)();
643 //================================================================================
645 * \brief Find algorithm the created algorithm
646 * \param theGeom - The shape ID the algorithm was created on
647 * \param theMesh - The mesh ID that created the algorithm
648 * \param dim - The algo dimension
649 * \retval Handle(_pyHypothesis) - The found algo
651 //================================================================================
653 Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
654 const Handle(_pyHypothesis)& theHypothesis )
656 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
657 for ( ; hyp != myHypos.end(); ++hyp )
658 if ( !hyp->IsNull() &&
660 theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
661 (*hyp)->GetGeom() == theGeom &&
662 (*hyp)->GetMesh() == theMesh )
667 //================================================================================
669 * \brief Find subMesh by ID (entry)
670 * \param theSubMeshID - The subMesh ID
671 * \retval Handle(_pySubMesh) - The found subMesh
673 //================================================================================
675 Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
677 map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID);
678 if ( id_subMesh != myObjects.end() )
679 return Handle(_pySubMesh)::DownCast( id_subMesh->second );
680 return Handle(_pySubMesh)();
684 //================================================================================
686 * \brief Change order of commands in the script
687 * \param theCmd1 - One command
688 * \param theCmd2 - Another command
690 //================================================================================
692 void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 )
694 list< Handle(_pyCommand) >::iterator pos1, pos2;
695 pos1 = find( myCommands.begin(), myCommands.end(), theCmd1 );
696 pos2 = find( myCommands.begin(), myCommands.end(), theCmd2 );
697 myCommands.insert( pos1, theCmd2 );
698 myCommands.insert( pos2, theCmd1 );
699 myCommands.erase( pos1 );
700 myCommands.erase( pos2 );
702 int nb1 = theCmd1->GetOrderNb();
703 theCmd1->SetOrderNb( theCmd2->GetOrderNb() );
704 theCmd2->SetOrderNb( nb1 );
705 // cout << "BECOME " << theCmd1->GetOrderNb() << "\t" << theCmd1->GetString() << endl
706 // << "BECOME " << theCmd2->GetOrderNb() << "\t" << theCmd2->GetString() << endl << endl;
709 //================================================================================
711 * \brief Set one command after the other
712 * \param theCmd - Command to move
713 * \param theAfterCmd - Command ater which to insert the first one
715 //================================================================================
717 void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
719 setNeighbourCommand( theCmd, theAfterCmd, true );
722 //================================================================================
724 * \brief Set one command before the other
725 * \param theCmd - Command to move
726 * \param theBeforeCmd - Command before which to insert the first one
728 //================================================================================
730 void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd )
732 setNeighbourCommand( theCmd, theBeforeCmd, false );
735 //================================================================================
737 * \brief Set one command before or after the other
738 * \param theCmd - Command to move
739 * \param theOtherCmd - Command ater or before which to insert the first one
741 //================================================================================
743 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
744 Handle(_pyCommand)& theOtherCmd,
745 const bool theIsAfter )
747 list< Handle(_pyCommand) >::iterator pos;
748 pos = find( myCommands.begin(), myCommands.end(), theCmd );
749 myCommands.erase( pos );
750 pos = find( myCommands.begin(), myCommands.end(), theOtherCmd );
751 myCommands.insert( (theIsAfter ? ++pos : pos), theCmd );
754 for ( pos = myCommands.begin(); pos != myCommands.end(); ++pos)
755 (*pos)->SetOrderNb( i++ );
758 //================================================================================
760 * \brief Set command be last in list of commands
761 * \param theCmd - Command to be last
763 //================================================================================
765 Handle(_pyCommand)& _pyGen::GetLastCommand()
767 return myLastCommand;
770 //================================================================================
772 * \brief Set method to access to object wrapped with python class
773 * \param theID - The wrapped object entry
774 * \param theMethod - The accessor method
776 //================================================================================
778 void _pyGen::SetAccessorMethod(const _pyID& theID, const char* theMethod )
780 myID2AccessorMethod.Bind( theID, (char*) theMethod );
783 //================================================================================
785 * \brief Generated new ID for object and assign with existing name
786 * \param theID - ID of existing object
788 //================================================================================
790 _pyID _pyGen::GenerateNewID( const _pyID& theID )
795 aNewID = theID + _pyID( ":" ) + _pyID( index++ );
797 while ( myObjectNames.IsBound( aNewID ) );
799 myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
800 ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
801 : _pyID( "A" ) + aNewID );
805 //================================================================================
807 * \brief Stores theObj in myObjects
809 //================================================================================
811 void _pyGen::AddObject( Handle(_pyObject)& theObj )
813 myObjects.insert( make_pair( theObj->GetID(), theObj ));
816 //================================================================================
818 * \brief Finds a _pyObject by ID
820 //================================================================================
822 Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID ) const
824 std::map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
825 return ( id_obj == myObjects.end() ) ? Handle(_pyObject)() : id_obj->second;
828 //================================================================================
830 * \brief Find out type of geom group
831 * \param grpID - The geom group entry
832 * \retval int - The type
834 //================================================================================
836 // static bool sameGroupType( const _pyID& grpID,
837 // const TCollection_AsciiString& theType)
839 // // define group type as smesh.Mesh.Group() does
841 // SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
842 // SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
843 // if ( !aSObj->_is_nil() ) {
844 // GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
845 // if ( !aGeomObj->_is_nil() ) {
846 // switch ( aGeomObj->GetShapeType() ) {
847 // case GEOM::VERTEX: type = SMESH::NODE; break;
848 // case GEOM::EDGE: type = SMESH::EDGE; break;
849 // case GEOM::FACE: type = SMESH::FACE; break;
851 // case GEOM::SHELL: type = SMESH::VOLUME; break;
852 // case GEOM::COMPOUND: {
853 // GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
854 // if ( !aGeomGen->_is_nil() ) {
855 // GEOM::GEOM_IGroupOperations_var aGrpOp =
856 // aGeomGen->GetIGroupOperations( study->StudyId() );
857 // if ( !aGrpOp->_is_nil() ) {
858 // switch ( aGrpOp->GetType( aGeomObj )) {
859 // case TopAbs_VERTEX: type = SMESH::NODE; break;
860 // case TopAbs_EDGE: type = SMESH::EDGE; break;
861 // case TopAbs_FACE: type = SMESH::FACE; break;
862 // case TopAbs_SOLID: type = SMESH::VOLUME; break;
873 // MESSAGE("Type of the group " << grpID << " not found");
876 // if ( theType.IsIntegerValue() )
877 // return type == theType.IntegerValue();
880 // case SMESH::NODE: return theType.Location( "NODE", 1, theType.Length() );
881 // case SMESH::EDGE: return theType.Location( "EDGE", 1, theType.Length() );
882 // case SMESH::FACE: return theType.Location( "FACE", 1, theType.Length() );
883 // case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
889 //================================================================================
892 * \param theCreationCmd -
894 //================================================================================
896 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
897 : _pyObject(theCreationCmd), myHasEditor(false)
899 // convert my creation command
900 Handle(_pyCommand) creationCmd = GetCreationCmd();
901 //TCollection_AsciiString str = creationCmd->GetMethod();
902 // if(str != "CreateMeshesFromUNV" &&
903 // str != "CreateMeshesFromMED" &&
904 // str != "CreateMeshesFromSTL")
905 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
906 creationCmd->SetMethod( "Mesh" );
908 theGen->SetAccessorMethod( GetID(), "GetMesh()" );
911 //================================================================================
914 * \param theCreationCmd -
916 //================================================================================
917 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
918 _pyObject(theCreationCmd), myHasEditor(false)
920 // convert my creation command
921 Handle(_pyCommand) creationCmd = GetCreationCmd();
922 creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
923 theGen->SetAccessorMethod( id, "GetMesh()" );
926 //================================================================================
928 * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
929 * \param theCommand - Engine method called for this mesh
931 //================================================================================
933 void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
935 // some methods of SMESH_Mesh interface needs special conversion
936 // to methods of Mesh python class
938 // 1. GetSubMesh(geom, name) + AddHypothesis(geom, algo)
939 // --> in Mesh_Algorithm.Create(mesh, geom, hypo, so)
940 // 2. AddHypothesis(geom, hyp)
941 // --> in Mesh_Algorithm.Hypothesis(hyp, args, so)
942 // 3. CreateGroupFromGEOM(type, name, grp)
943 // --> in Mesh.Group(grp, name="")
944 // 4. ExportToMED(f, auto_groups, version)
945 // --> in Mesh.ExportMED( f, auto_groups, version )
948 const TCollection_AsciiString method = theCommand->GetMethod();
949 // ----------------------------------------------------------------------
950 if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
951 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
952 if ( !subMesh.IsNull() ) {
953 subMesh->SetCreator( this );
954 mySubmeshes.push_back( subMesh );
957 // ----------------------------------------------------------------------
958 else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
959 myAddHypCmds.push_back( theCommand );
961 const _pyID& hypID = theCommand->GetArg( 2 );
962 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
963 if ( !hyp.IsNull() ) {
964 myHypos.push_back( hyp );
965 if ( hyp->GetMesh().IsEmpty() )
966 hyp->SetMesh( this->GetID() );
969 // ----------------------------------------------------------------------
970 else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
971 _pyID grp = theCommand->GetArg( 3 );
972 // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
973 // next if(){...} section is commented
974 //if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
975 // theCommand->SetMethod( "Group" );
976 // theCommand->RemoveArgs();
977 // theCommand->SetArg( 1, grp );
980 // ------------------------->>>>> GroupOnGeom( grp, name, typ )
981 _pyID type = theCommand->GetArg( 1 );
982 _pyID name = theCommand->GetArg( 2 );
983 theCommand->SetMethod( "GroupOnGeom" );
984 theCommand->RemoveArgs();
985 theCommand->SetArg( 1, grp );
986 theCommand->SetArg( 2, name );
987 theCommand->SetArg( 3, type );
990 // ----------------------------------------------------------------------
991 else if ( method == "CreateGroupFromFilter" ) // --> GroupOnFilter()
993 theCommand->SetMethod( "GroupOnFilter" );
994 Handle(_pyGroup) group = new _pyGroup( theCommand );
995 theGen->AddObject( group );
997 // GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
998 _pyID filterID = theCommand->GetArg(3);
999 Handle(_pyObject) filter = theGen->FindObject( filterID );
1000 if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
1001 filter->Process( theCommand );
1003 // ----------------------------------------------------------------------
1004 else if ( method == "GetIdsFromFilter" )
1006 // GetIdsFromFilter( aFilter0x4743dc0) -> GetIdsFromFilter( aFilter_1)
1007 _pyID filterID = theCommand->GetArg(1);
1008 Handle(_pyObject) filter = theGen->FindObject( filterID );
1009 if ( !filter.IsNull() && filter->IsKind(STANDARD_TYPE(_pyFilter)))
1010 filter->Process( theCommand );
1012 // ----------------------------------------------------------------------
1013 else if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
1015 theCommand->SetMethod( "CreateEmptyGroup" );
1016 Handle(_pyGroup) group = new _pyGroup( theCommand );
1017 theGen->AddObject( group );
1019 // ----------------------------------------------------------------------
1020 else if ( method == "ExportToMED" || // ExportToMED() --> ExportMED()
1021 method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
1022 theCommand->SetMethod( "ExportMED" );
1024 // ----------------------------------------------------------------------
1025 else if ( method == "ExportCGNS" )
1026 { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
1027 _pyID partID = theCommand->GetArg( 1 );
1028 int nbArgs = theCommand->GetNbArgs();
1029 for ( int i = 2; i <= nbArgs; ++i )
1030 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1031 theCommand->SetArg( nbArgs, partID );
1033 // ----------------------------------------------------------------------
1034 else if ( method.Location( "ExportPartTo", 1, method.Length() ) == 1 )
1035 { // ExportPartTo*(part, ...) -> Export*(..., part)
1037 // remove "PartTo" from the method
1038 TCollection_AsciiString newMethod = method;
1039 newMethod.Remove( 7, 6 );
1040 theCommand->SetMethod( newMethod );
1041 // make the 1st arg be the last one
1042 _pyID partID = theCommand->GetArg( 1 );
1043 int nbArgs = theCommand->GetNbArgs();
1044 for ( int i = 2; i <= nbArgs; ++i )
1045 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1046 theCommand->SetArg( nbArgs, partID );
1048 // ----------------------------------------------------------------------
1049 else if ( method == "RemoveHypothesis" ) // (geom, hyp)
1051 _pyID hypID = theCommand->GetArg( 2 );
1053 // check if this mesh still has corresponding addition command
1054 bool hasAddCmd = false;
1055 list< Handle(_pyCommand) >::iterator cmd = myAddHypCmds.begin();
1056 while ( cmd != myAddHypCmds.end() )
1058 // AddHypothesis(geom, hyp)
1059 if ( hypID == (*cmd)->GetArg( 2 )) { // erase both (add and remove) commands
1060 theCommand->Clear();
1062 cmd = myAddHypCmds.erase( cmd );
1069 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1070 if ( ! hasAddCmd && hypID.Length() != 0 ) { // hypo addition already wrapped
1071 // RemoveHypothesis(geom, hyp) --> RemoveHypothesis( hyp, geom=0 )
1072 _pyID geom = theCommand->GetArg( 1 );
1073 theCommand->RemoveArgs();
1074 theCommand->SetArg( 1, hypID );
1075 if ( geom != GetGeom() )
1076 theCommand->SetArg( 2, geom );
1078 // remove hyp from myHypos
1079 myHypos.remove( hyp );
1081 // check for SubMesh order commands
1082 else if ( theCommand->GetMethod() == "GetMeshOrder" ||
1083 theCommand->GetMethod() == "SetMeshOrder" )
1085 // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
1086 // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
1087 // commands are moved at the end of the script
1088 const bool isArg = theCommand->GetMethod() == "SetMeshOrder";
1089 const TCollection_AsciiString& cmdStr = theCommand->GetString();
1090 int begPos = (/*isArg ? cmdStr.Search( "(" ) :*/ cmdStr.Search( "[" )) + 1;
1091 int endPos = (isArg ? cmdStr.Search( ")" ) : cmdStr.Search( "=" )) - 1;
1092 if ( begPos != -1 && begPos < endPos && endPos <= cmdStr.Length() ) {
1093 TCollection_AsciiString aSubStr = cmdStr.SubString( begPos, endPos );
1094 Standard_Integer index = 1;
1095 TCollection_AsciiString anIDStr = aSubStr.Token("\t ,[]", index++);
1096 while ( !anIDStr.IsEmpty() ) {
1097 Handle(_pySubMesh) subMesh = theGen->FindSubMesh( anIDStr );
1098 if ( !subMesh.IsNull() )
1099 subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
1100 anIDStr = aSubStr.Token("\t ,[]", index++);
1104 // add accessor method if necessary
1107 if ( NeedMeshAccess( theCommand ))
1108 // apply theCommand to the mesh wrapped by smeshpy mesh
1109 AddMeshAccess( theCommand );
1113 //================================================================================
1115 * \brief Return True if addition of accesor method is needed
1117 //================================================================================
1119 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
1121 // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
1122 // so no conversion is needed for them at all:
1123 static TStringSet sameMethods;
1124 if ( sameMethods.empty() ) {
1125 const char * names[] =
1126 { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
1127 "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
1128 "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
1129 "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
1130 "NbTrianglesOfOrder","NbQuadrangles","NbQuadranglesOfOrder","NbPolygons","NbVolumes",
1131 "NbVolumesOfOrder","NbTetras","NbTetrasOfOrder","NbHexas","NbHexasOfOrder",
1132 "NbPyramids","NbPyramidsOfOrder","NbPrisms","NbPrismsOfOrder","NbPolyhedrons",
1133 "NbSubMesh","GetElementsId","GetElementsByType","GetNodesId","GetElementType",
1134 "GetSubMeshElementsId","GetSubMeshNodesId","GetSubMeshElementType","Dump","GetNodeXYZ",
1135 "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
1136 "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
1137 "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
1138 "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
1139 ,"" }; // <- mark of end
1140 sameMethods.Insert( names );
1143 return !sameMethods.Contains( theCommand->GetMethod() );
1146 //================================================================================
1148 * \brief Convert creation and addition of all algos and hypos
1150 //================================================================================
1152 void _pyMesh::Flush()
1154 list < Handle(_pyCommand) >::iterator cmd;
1156 // try to convert algo addition like this:
1157 // mesh.AddHypothesis(geom, ALGO ) --> ALGO = mesh.Algo()
1158 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1160 Handle(_pyCommand) addCmd = *cmd;
1162 _pyID algoID = addCmd->GetArg( 2 );
1163 Handle(_pyHypothesis) algo = theGen->FindHyp( algoID );
1164 if ( algo.IsNull() || !algo->IsAlgo() )
1167 // check and create new algorithm instance if it is already wrapped
1168 if ( algo->IsWrapped() ) {
1169 _pyID localAlgoID = theGen->GenerateNewID( algoID );
1170 TCollection_AsciiString aNewCmdStr = localAlgoID +
1171 TCollection_AsciiString( " = " ) + theGen->GetID() +
1172 TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
1173 TCollection_AsciiString( "\" )" );
1175 Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
1176 Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
1177 if ( !newAlgo.IsNull() ) {
1178 newAlgo->Assign( algo, this->GetID() );
1179 newAlgo->SetCreationCmd( newCmd );
1181 // set algorithm creation
1182 theGen->SetCommandBefore( newCmd, addCmd );
1187 _pyID geom = addCmd->GetArg( 1 );
1188 bool isLocalAlgo = ( geom != GetGeom() );
1191 if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
1193 // wrapped algo is created atfer mesh creation
1194 GetCreationCmd()->AddDependantCmd( addCmd );
1196 if ( isLocalAlgo ) {
1197 // mesh.AddHypothesis(geom, ALGO ) --> mesh.AlgoMethod(geom)
1198 addCmd->SetArg( addCmd->GetNbArgs() + 1,
1199 TCollection_AsciiString( "geom=" ) + geom );
1200 // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
1201 list < Handle(_pySubMesh) >::iterator smIt;
1202 for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
1203 Handle(_pySubMesh) subMesh = *smIt;
1204 Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
1205 if ( geom == subCmd->GetArg( 1 )) {
1206 subCmd->SetObject( algo->GetID() );
1207 subCmd->RemoveArgs();
1208 subMesh->SetCreator( algo );
1213 else // KO - ALGO was already created
1215 // mesh.AddHypothesis(geom, ALGO) --> mesh.AddHypothesis(ALGO, geom=0)
1216 addCmd->RemoveArgs();
1217 addCmd->SetArg( 1, algoID );
1219 addCmd->SetArg( 2, geom );
1223 // try to convert hypo addition like this:
1224 // mesh.AddHypothesis(geom, HYPO ) --> HYPO = algo.Hypo()
1225 for ( cmd = myAddHypCmds.begin(); cmd != myAddHypCmds.end(); ++cmd )
1227 Handle(_pyCommand) addCmd = *cmd;
1228 _pyID hypID = addCmd->GetArg( 2 );
1229 Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
1230 if ( hyp.IsNull() || hyp->IsAlgo() )
1232 bool converted = hyp->Addition2Creation( addCmd, this->GetID() );
1234 // mesh.AddHypothesis(geom, HYP) --> mesh.AddHypothesis(HYP, geom=0)
1235 _pyID geom = addCmd->GetArg( 1 );
1236 addCmd->RemoveArgs();
1237 addCmd->SetArg( 1, hypID );
1238 if ( geom != GetGeom() )
1239 addCmd->SetArg( 2, geom );
1243 // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name)
1244 // for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) {
1245 // Handle(_pyCommand) subCmd = *cmd;
1246 // if ( subCmd->GetNbArgs() > 0 )
1247 // AddMeshAccess( subCmd );
1249 myAddHypCmds.clear();
1250 mySubmeshes.clear();
1253 list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
1254 for ( ; hyp != myHypos.end(); ++hyp )
1258 //================================================================================
1260 * \brief MeshEditor convert its commands to ones of mesh
1262 //================================================================================
1264 _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
1265 _pyObject( theCreationCmd )
1267 myMesh = theCreationCmd->GetObject();
1268 myCreationCmdStr = theCreationCmd->GetString();
1269 theCreationCmd->Clear();
1272 //================================================================================
1274 * \brief convert its commands to ones of mesh
1276 //================================================================================
1278 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
1280 // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
1281 // commands calling this methods are converted to calls of methods of Mesh
1282 static TStringSet sameMethods;
1283 if ( sameMethods.empty() ) {
1284 const char * names[] = {
1285 "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace",
1286 "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
1287 "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
1288 "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
1289 "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
1290 "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
1291 "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
1292 "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
1293 "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
1294 "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
1295 "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
1296 "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
1297 "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
1298 "GetLastCreatedElems",
1299 "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
1300 "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
1301 "MakeBoundaryElements"
1302 ,"" }; // <- mark of the end
1303 sameMethods.Insert( names );
1306 // names of SMESH_MeshEditor methods which differ from methods of class Mesh
1307 // only by last two arguments
1308 static TStringSet diffLastTwoArgsMethods;
1309 if (diffLastTwoArgsMethods.empty() ) {
1310 const char * names[] = {
1311 "MirrorMakeGroups","MirrorObjectMakeGroups",
1312 "TranslateMakeGroups","TranslateObjectMakeGroups",
1313 "RotateMakeGroups","RotateObjectMakeGroups",
1314 ""};// <- mark of the end
1315 diffLastTwoArgsMethods.Insert( names );
1318 const TCollection_AsciiString & method = theCommand->GetMethod();
1319 bool isPyMeshMethod = sameMethods.Contains( method );
1320 if ( !isPyMeshMethod )
1322 //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
1323 //functions with the flag "theMakeGroups = True" like:
1324 //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
1325 int pos = method.Search("MakeGroups");
1328 isPyMeshMethod = true;
1330 // 1. Remove "MakeGroups" from the Command
1331 TCollection_AsciiString aMethod = theCommand->GetMethod();
1332 int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
1333 aMethod.Trunc(pos-1);
1334 theCommand->SetMethod(aMethod);
1336 // 2. And add last "True" argument(s)
1337 while(nbArgsToAdd--)
1338 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1342 // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
1343 if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
1345 isPyMeshMethod=true;
1346 theCommand->SetMethod("ExtrusionAlongPathX");
1349 // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
1350 if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
1352 isPyMeshMethod=true;
1353 theCommand->SetMethod("FindCoincidentNodesOnPart");
1355 // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup()
1356 // DoubleNodeGroupNew() -> DoubleNodeGroup()
1357 // DoubleNodeGroupsNew() -> DoubleNodeGroups()
1358 // DoubleNodeElemGroupsNew() -> DoubleNodeElemGroups()
1359 if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" ||
1360 method == "DoubleNodeElemGroupsNew" ||
1361 method == "DoubleNodeGroupNew" ||
1362 method == "DoubleNodeGroupsNew"))
1364 isPyMeshMethod=true;
1365 theCommand->SetMethod( method.SubString( 1, method.Length()-3));
1366 theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
1368 // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
1369 // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
1370 if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
1371 method == "ConvertFromQuadraticObject" ))
1373 isPyMeshMethod=true;
1374 theCommand->SetMethod( method.SubString( 1, method.Length()-6));
1375 // prevent moving creation of the converted sub-mesh to the end of the script
1376 bool isFromQua = ( method.Value( 8 ) == 'F' );
1377 Handle(_pySubMesh) sm = theGen->FindSubMesh( theCommand->GetArg( isFromQua ? 1 : 2 ));
1379 sm->Process( theCommand );
1381 // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
1382 // FindElementsByPoint(x, y, z, elementType, meshPart)
1383 if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
1385 isPyMeshMethod=true;
1386 theCommand->SetMethod( "FindElementsByPoint" );
1387 // make the 1st arg be the last one
1388 _pyID partID = theCommand->GetArg( 1 );
1389 int nbArgs = theCommand->GetNbArgs();
1390 for ( int i = 2; i <= nbArgs; ++i )
1391 theCommand->SetArg( i-1, theCommand->GetArg( i ));
1392 theCommand->SetArg( nbArgs, partID );
1395 // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
1396 // so let _pyMesh care of it (TMP?)
1397 // if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
1398 // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
1399 if ( isPyMeshMethod )
1401 theCommand->SetObject( myMesh );
1405 // editor creation command is needed only if any editor function is called
1406 theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
1407 if ( !myCreationCmdStr.IsEmpty() ) {
1408 GetCreationCmd()->GetString() = myCreationCmdStr;
1409 myCreationCmdStr.Clear();
1414 //================================================================================
1416 * \brief _pyHypothesis constructor
1417 * \param theCreationCmd -
1419 //================================================================================
1421 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
1422 _pyObject( theCreationCmd )
1424 myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
1427 //================================================================================
1429 * \brief Creates algorithm or hypothesis
1430 * \param theCreationCmd - The engine command creating a hypothesis
1431 * \retval Handle(_pyHypothesis) - Result _pyHypothesis
1433 //================================================================================
1435 Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& theCreationCmd)
1437 // theCreationCmd: CreateHypothesis( "theHypType", "theLibName" )
1438 ASSERT (( theCreationCmd->GetMethod() == "CreateHypothesis"));
1440 Handle(_pyHypothesis) hyp, algo;
1443 const TCollection_AsciiString & hypTypeQuoted = theCreationCmd->GetArg( 1 );
1444 if ( hypTypeQuoted.IsEmpty() )
1447 TCollection_AsciiString hypType =
1448 hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
1450 algo = new _pyAlgorithm( theCreationCmd );
1451 hyp = new _pyHypothesis( theCreationCmd );
1453 // 1D Regular_1D ----------
1454 if ( hypType == "Regular_1D" ) {
1455 // set mesh's method creating algo,
1456 // i.e. convertion result will be "regular1d = Mesh.Segment()",
1457 // and set hypType by which algo creating a hypothesis is searched for
1458 algo->SetConvMethodAndType("Segment", hypType.ToCString());
1460 else if ( hypType == "CompositeSegment_1D" ) {
1461 algo->SetConvMethodAndType("Segment", "Regular_1D");
1462 algo->myArgs.Append( "algo=smesh.COMPOSITE");
1464 else if ( hypType == "LocalLength" ) {
1465 // set algo's method creating hyp, and algo type
1466 hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
1467 // set method whose 1 arg will become the 1-st arg of hyp creation command
1468 // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
1469 hyp->AddArgMethod( "SetLength" );
1471 else if ( hypType == "MaxLength" ) {
1472 // set algo's method creating hyp, and algo type
1473 hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
1474 // set method whose 1 arg will become the 1-st arg of hyp creation command
1475 // i.e. convertion result will be "maxsize = regular1d.MaxSize(<arg of SetLength()>)"
1476 hyp->AddArgMethod( "SetLength" );
1478 else if ( hypType == "NumberOfSegments" ) {
1479 hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
1480 hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
1481 // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
1482 hyp->AddArgMethod( "SetNumberOfSegments" );
1483 // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
1484 hyp->AddArgMethod( "SetScaleFactor" );
1485 hyp->AddArgMethod( "SetReversedEdges" );
1487 else if ( hypType == "Arithmetic1D" ) {
1488 hyp = new _pyComplexParamHypo( theCreationCmd );
1489 hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
1490 hyp->AddArgMethod( "SetStartLength" );
1491 hyp->AddArgMethod( "SetEndLength" );
1492 hyp->AddArgMethod( "SetReversedEdges" );
1494 else if ( hypType == "StartEndLength" ) {
1495 hyp = new _pyComplexParamHypo( theCreationCmd );
1496 hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
1497 hyp->AddArgMethod( "SetStartLength" );
1498 hyp->AddArgMethod( "SetEndLength" );
1499 hyp->AddArgMethod( "SetReversedEdges" );
1501 else if ( hypType == "Deflection1D" ) {
1502 hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
1503 hyp->AddArgMethod( "SetDeflection" );
1505 else if ( hypType == "Propagation" ) {
1506 hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
1508 else if ( hypType == "QuadraticMesh" ) {
1509 hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
1511 else if ( hypType == "AutomaticLength" ) {
1512 hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
1513 hyp->AddArgMethod( "SetFineness");
1515 else if ( hypType == "SegmentLengthAroundVertex" ) {
1516 hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
1517 hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
1518 hyp->AddArgMethod( "SetLength" );
1520 // 1D Python_1D ----------
1521 else if ( hypType == "Python_1D" ) {
1522 algo->SetConvMethodAndType( "Segment", hypType.ToCString());
1523 algo->myArgs.Append( "algo=smesh.PYTHON");
1525 else if ( hypType == "PythonSplit1D" ) {
1526 hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
1527 hyp->AddArgMethod( "SetNumberOfSegments");
1528 hyp->AddArgMethod( "SetPythonLog10RatioFunction");
1530 // MEFISTO_2D ----------
1531 else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D
1532 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1534 else if ( hypType == "MaxElementArea" ) {
1535 hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
1536 hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY");
1537 hyp->AddArgMethod( "SetMaxElementArea");
1539 else if ( hypType == "LengthFromEdges" ) {
1540 hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
1541 hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY");
1543 // Quadrangle_2D ----------
1544 else if ( hypType == "Quadrangle_2D" ) {
1545 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1547 else if ( hypType == "QuadranglePreference" ) {
1548 hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
1549 hyp->SetConvMethodAndType( "SetQuadAllowed", "NETGEN_2D_ONLY");
1551 else if ( hypType == "TrianglePreference" ) {
1552 hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
1554 // RadialQuadrangle_1D2D ----------
1555 else if ( hypType == "RadialQuadrangle_1D2D" ) {
1556 algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
1557 algo->myArgs.Append( "algo=smesh.RADIAL_QUAD" );
1559 else if ( hypType == "NumberOfLayers2D" ) {
1560 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialQuadrangle_1D2D");
1561 hyp->AddArgMethod( "SetNumberOfLayers" );
1563 else if ( hypType == "LayerDistribution2D" ) {
1564 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
1565 hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
1567 // BLSURF ----------
1568 else if ( hypType == "BLSURF" ) {
1569 algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
1570 algo->myArgs.Append( "algo=smesh.BLSURF" );
1572 else if ( hypType == "BLSURF_Parameters") {
1573 hyp->SetConvMethodAndType( "Parameters", "BLSURF");
1575 // NETGEN ----------
1576 else if ( hypType == "NETGEN_2D") { // 1D-2D
1577 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1578 algo->myArgs.Append( "algo=smesh.NETGEN" );
1580 else if ( hypType == "NETGEN_Parameters_2D") {
1581 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1583 else if ( hypType == "NETGEN_SimpleParameters_2D") {
1584 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D");
1585 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1587 else if ( hypType == "NETGEN_2D3D") { // 1D-2D-3D
1588 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1589 algo->myArgs.Append( "algo=smesh.FULL_NETGEN" );
1591 else if ( hypType == "NETGEN_Parameters") {
1592 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1594 else if ( hypType == "NETGEN_SimpleParameters_3D") {
1595 hyp->SetConvMethodAndType( "Parameters", "NETGEN_2D3D");
1596 hyp->myArgs.Append( "which=smesh.SIMPLE" );
1598 else if ( hypType == "NETGEN_2D_ONLY") { // 2D
1599 algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
1600 algo->myArgs.Append( "algo=smesh.NETGEN_2D" );
1602 else if ( hypType == "NETGEN_3D") { // 3D
1603 algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
1604 algo->myArgs.Append( "algo=smesh.NETGEN" );
1606 else if ( hypType == "MaxElementVolume") {
1607 hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
1608 hyp->AddArgMethod( "SetMaxElementVolume" );
1610 // GHS3D_3D ----------
1611 else if ( hypType == "GHS3D_3D" ) {
1612 algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
1613 algo->myArgs.Append( "algo=smesh.GHS3D" );
1615 else if ( hypType == "GHS3D_Parameters") {
1616 hyp->SetConvMethodAndType( "Parameters", "GHS3D_3D");
1618 // Hexa_3D ---------
1619 else if ( hypType == "BLSURF" ) {
1620 algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
1622 // Repetitive Projection_1D ---------
1623 else if ( hypType == "Projection_1D" ) {
1624 algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
1626 else if ( hypType == "ProjectionSource1D" ) {
1627 hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
1628 hyp->AddArgMethod( "SetSourceEdge");
1629 hyp->AddArgMethod( "SetSourceMesh");
1630 // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
1631 hyp->AddArgMethod( "SetVertexAssociation", 2 );
1633 // Projection_2D ---------
1634 else if ( hypType == "Projection_2D" ) {
1635 algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
1637 else if ( hypType == "Projection_1D2D" ) {
1638 algo->SetConvMethodAndType( "Projection1D2D", hypType.ToCString());
1640 else if ( hypType == "ProjectionSource2D" ) {
1641 hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
1642 hyp->AddArgMethod( "SetSourceFace");
1643 hyp->AddArgMethod( "SetSourceMesh");
1644 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1646 // Projection_3D ---------
1647 else if ( hypType == "Projection_3D" ) {
1648 algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
1650 else if ( hypType == "ProjectionSource3D" ) {
1651 hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
1652 hyp->AddArgMethod( "SetSource3DShape");
1653 hyp->AddArgMethod( "SetSourceMesh");
1654 hyp->AddArgMethod( "SetVertexAssociation", 4 );
1656 // Prism_3D ---------
1657 else if ( hypType == "Prism_3D" ) {
1658 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1660 // RadialPrism_3D ---------
1661 else if ( hypType == "RadialPrism_3D" ) {
1662 algo->SetConvMethodAndType( "Prism", hypType.ToCString());
1664 else if ( hypType == "NumberOfLayers" ) {
1665 hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
1666 hyp->AddArgMethod( "SetNumberOfLayers" );
1668 else if ( hypType == "LayerDistribution" ) {
1669 hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
1670 hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
1672 // Cartesian 3D ---------
1673 else if ( hypType == "Cartesian_3D" ) {
1674 algo->SetConvMethodAndType( "BodyFitted", hypType.ToCString());
1676 else if ( hypType == "CartesianParameters3D" ) {
1677 hyp = new _pyComplexParamHypo( theCreationCmd );
1678 hyp->SetConvMethodAndType( "SetGrid", "Cartesian_3D");
1679 for ( int iArg = 0; iArg < 4; ++iArg )
1680 hyp->myArgs.Append("[]");
1683 return algo->IsValid() ? algo : hyp;
1686 //================================================================================
1688 * \brief Convert the command adding a hypothesis to mesh into a smesh command
1689 * \param theCmd - The command like mesh.AddHypothesis( geom, hypo )
1690 * \param theAlgo - The algo that can create this hypo
1691 * \retval bool - false if the command cant be converted
1693 //================================================================================
1695 bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
1696 const _pyID& theMesh)
1698 ASSERT(( theCmd->GetMethod() == "AddHypothesis" ));
1700 if ( !IsWrappable( theMesh ))
1703 myGeom = theCmd->GetArg( 1 );
1705 Handle(_pyHypothesis) algo;
1707 // find algo created on myGeom in theMesh
1708 algo = theGen->FindAlgo( myGeom, theMesh, this );
1709 if ( algo.IsNull() )
1711 // attach hypothesis creation command to be after algo creation command
1712 // because it can be new created instance of algorithm
1713 algo->GetCreationCmd()->AddDependantCmd( theCmd );
1717 // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
1718 theCmd->SetResultValue( GetID() );
1719 theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
1720 theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() ));
1722 theCmd->RemoveArgs();
1723 for ( int i = 1; i <= myArgs.Length(); ++i ) {
1724 if ( !myArgs( i ).IsEmpty() )
1725 theCmd->SetArg( i, myArgs( i ));
1727 theCmd->SetArg( i, "[]");
1729 // set a new creation command
1730 GetCreationCmd()->Clear();
1731 // replace creation command by wrapped instance
1732 // please note, that hypothesis attaches to algo creation command (see upper)
1733 SetCreationCmd( theCmd );
1736 // clear commands setting arg values
1737 list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
1738 for ( ; argCmd != myArgCommands.end(); ++argCmd )
1741 // set unknown arg commands after hypo creation
1742 Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
1743 list<Handle(_pyCommand)>::iterator cmd = myUnknownCommands.begin();
1744 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1745 afterCmd->AddDependantCmd( *cmd );
1751 //================================================================================
1753 * \brief Remember hypothesis parameter values
1754 * \param theCommand - The called hypothesis method
1756 //================================================================================
1758 void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
1760 ASSERT( !myIsAlgo );
1763 for ( int i = 1; i <= myArgMethods.Length(); ++i ) {
1764 if ( myArgMethods( i ) == theCommand->GetMethod() ) {
1765 while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i ))
1766 myArgs.Append( "[]" );
1767 for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg )
1768 myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value
1769 myArgCommands.push_back( theCommand );
1772 nbArgs += myNbArgsByMethod( i );
1774 myUnknownCommands.push_back( theCommand );
1777 //================================================================================
1779 * \brief Finish conversion
1781 //================================================================================
1783 void _pyHypothesis::Flush()
1785 if ( IsWrapped() ) {
1788 list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
1789 for ( ; cmd != myArgCommands.end(); ++cmd ) {
1790 // Add access to a wrapped mesh
1791 theGen->AddMeshAccessorMethod( *cmd );
1792 // Add access to a wrapped algorithm
1793 theGen->AddAlgoAccessorMethod( *cmd );
1795 cmd = myUnknownCommands.begin();
1796 for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
1797 // Add access to a wrapped mesh
1798 theGen->AddMeshAccessorMethod( *cmd );
1799 // Add access to a wrapped algorithm
1800 theGen->AddAlgoAccessorMethod( *cmd );
1803 // forget previous hypothesis modifications
1804 myArgCommands.clear();
1805 myUnknownCommands.clear();
1808 //================================================================================
1810 * \brief clear creation, arg and unkown commands
1812 //================================================================================
1814 void _pyHypothesis::ClearAllCommands()
1816 GetCreationCmd()->Clear();
1817 list<Handle(_pyCommand)>::iterator cmd = myArgCommands.begin();
1818 for ( ; cmd != myArgCommands.end(); ++cmd )
1820 cmd = myUnknownCommands.begin();
1821 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1826 //================================================================================
1828 * \brief Assign fields of theOther to me except myIsWrapped
1830 //================================================================================
1832 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
1833 const _pyID& theMesh )
1835 myIsWrapped = false;
1838 // myCreationCmd = theOther->myCreationCmd;
1839 myIsAlgo = theOther->myIsAlgo;
1840 myGeom = theOther->myGeom;
1841 myType2CreationMethod = theOther->myType2CreationMethod;
1842 myArgs = theOther->myArgs;
1843 myArgMethods = theOther->myArgMethods;
1844 myNbArgsByMethod = theOther->myNbArgsByMethod;
1845 myArgCommands = theOther->myArgCommands;
1846 myUnknownCommands = theOther->myUnknownCommands;
1849 //================================================================================
1851 * \brief Remember hypothesis parameter values
1852 * \param theCommand - The called hypothesis method
1854 //================================================================================
1856 void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
1858 if ( GetAlgoType() == "Cartesian_3D" )
1860 // CartesianParameters3D hyp
1862 if ( theCommand->GetMethod() == "SetSizeThreshold" )
1864 myArgs( 4 ) = theCommand->GetArg( 1 );
1865 myArgCommands.push_back( theCommand );
1868 if ( theCommand->GetMethod() == "SetGrid" ||
1869 theCommand->GetMethod() == "SetGridSpacing" )
1871 TCollection_AsciiString axis = theCommand->GetArg( theCommand->GetNbArgs() );
1872 int iArg = 1 + ( axis.Value(1) - '0' );
1873 if ( theCommand->GetMethod() == "SetGrid" )
1875 myArgs( iArg ) = theCommand->GetArg( 1 );
1879 myArgs( iArg ) = "[ ";
1880 myArgs( iArg ) += theCommand->GetArg( 1 );
1881 myArgs( iArg ) += ", ";
1882 myArgs( iArg ) += theCommand->GetArg( 2 );
1883 myArgs( iArg ) += "]";
1885 myArgCommands.push_back( theCommand );
1890 if( theCommand->GetMethod() == "SetLength" )
1892 // NOW it becomes OBSOLETE
1893 // ex: hyp.SetLength(start, 1)
1894 // hyp.SetLength(end, 0)
1895 ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
1896 int i = 2 - theCommand->GetArg( 2 ).IntegerValue();
1897 while ( myArgs.Length() < i )
1898 myArgs.Append( "[]" );
1899 myArgs( i ) = theCommand->GetArg( 1 ); // arg value
1900 myArgCommands.push_back( theCommand );
1904 _pyHypothesis::Process( theCommand );
1907 //================================================================================
1909 * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment
1911 //================================================================================
1913 void _pyComplexParamHypo::Flush()
1917 list < Handle(_pyCommand) >::iterator cmd = myUnknownCommands.begin();
1918 for ( ; cmd != myUnknownCommands.end(); ++cmd )
1919 if ((*cmd)->GetMethod() == "SetObjectEntry" )
1924 //================================================================================
1926 * \brief Convert methods of 1D hypotheses to my own methods
1927 * \param theCommand - The called hypothesis method
1929 //================================================================================
1931 void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
1933 if ( theCommand->GetMethod() != "SetLayerDistribution" )
1936 _pyID newName; // name for 1D hyp = "HypType" + "_Distribution"
1938 const _pyID& hyp1dID = theCommand->GetArg( 1 );
1939 Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
1940 if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
1942 else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) {
1943 // 1D hypo is already set, so distribution changes and the old
1944 // 1D hypo is thrown away
1945 my1dHyp->ClearAllCommands();
1949 if ( !myArgCommands.empty() )
1950 myArgCommands.front()->Clear();
1951 myArgCommands.push_back( theCommand );
1954 //================================================================================
1957 * \param theAdditionCmd - command to be converted
1958 * \param theMesh - mesh instance
1959 * \retval bool - status
1961 //================================================================================
1963 bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
1964 const _pyID& theMesh)
1966 myIsWrapped = false;
1968 if ( my1dHyp.IsNull() )
1971 // set "SetLayerDistribution()" after addition cmd
1972 theAdditionCmd->AddDependantCmd( myArgCommands.front() );
1974 _pyID geom = theAdditionCmd->GetArg( 1 );
1976 Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
1977 if ( !algo.IsNull() )
1979 my1dHyp->SetMesh( theMesh );
1980 my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
1981 algo->GetAlgoType().ToCString());
1982 if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
1985 // clear "SetLayerDistribution()" cmd
1986 myArgCommands.back()->Clear();
1988 // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
1990 // find RadialPrism algo created on <geom> for theMesh
1991 GetCreationCmd()->SetObject( algo->GetID() );
1992 GetCreationCmd()->SetMethod( myAlgoMethod );
1993 GetCreationCmd()->RemoveArgs();
1994 theAdditionCmd->AddDependantCmd( GetCreationCmd() );
2000 //================================================================================
2004 //================================================================================
2006 void _pyLayerDistributionHypo::Flush()
2008 // as creation of 1D hyp was written later then it's edition,
2009 // we need to find all it's edition calls and process them
2010 if ( !my1dHyp.IsNull() )
2012 _pyID hyp1dID = my1dHyp->GetCreationCmd()->GetResultValue();
2014 // make a new name for 1D hyp = "HypType" + "_Distribution"
2016 if ( my1dHyp->IsWrapped() ) {
2017 newName = my1dHyp->GetCreationCmd()->GetMethod();
2020 TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
2021 newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
2023 newName += "_Distribution";
2024 my1dHyp->GetCreationCmd()->SetResultValue( newName );
2026 list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
2027 list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
2028 for ( ; cmdIt != cmds.end(); ++cmdIt ) {
2029 const _pyID& objID = (*cmdIt)->GetObject();
2030 if ( objID == hyp1dID ) {
2031 my1dHyp->Process( *cmdIt );
2032 my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
2033 ( *cmdIt )->SetObject( newName );
2036 // Set new hyp name to SetLayerDistribution() cmd
2037 if ( !myArgCommands.empty() && !myArgCommands.back()->IsEmpty() )
2038 myArgCommands.back()->SetArg( 1, newName );
2042 //================================================================================
2044 * \brief additionally to Addition2Creation, clears SetDistrType() command
2045 * \param theCmd - AddHypothesis() command
2046 * \param theMesh - mesh to which a hypothesis is added
2047 * \retval bool - convertion result
2049 //================================================================================
2051 bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2052 const _pyID& theMesh)
2054 if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) {
2055 // scale factor (2-nd arg) is provided: clear SetDistrType(1) command
2056 bool scaleDistrType = false;
2057 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2058 for ( ; cmd != myUnknownCommands.rend(); ++cmd ) {
2059 if ( (*cmd)->GetMethod() == "SetDistrType" ) {
2060 if ( (*cmd)->GetArg( 1 ) == "1" ) {
2061 scaleDistrType = true;
2064 else if ( !scaleDistrType ) {
2065 // distribution type changed: remove scale factor from args
2066 myArgs.Remove( 2, myArgs.Length() );
2072 return _pyHypothesis::Addition2Creation( theCmd, theMesh );
2075 //================================================================================
2077 * \brief remove repeated commands defining distribution
2079 //================================================================================
2081 void _pyNumberOfSegmentsHyp::Flush()
2083 // find number of the last SetDistrType() command
2084 list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
2085 int distrTypeNb = 0;
2086 for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd )
2087 if ( (*cmd)->GetMethod() == "SetDistrType" )
2088 distrTypeNb = (*cmd)->GetOrderNb();
2089 else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
2092 // clear commands before the last SetDistrType()
2093 list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnknownCommands };
2094 for ( int i = 0; i < 2; ++i ) {
2095 set<TCollection_AsciiString> uniqueMethods;
2096 list<Handle(_pyCommand)> & cmdList = *cmds[i];
2097 for ( cmd = cmdList.rbegin(); cmd != cmdList.rend(); ++cmd )
2099 bool clear = ( (*cmd)->GetOrderNb() < distrTypeNb );
2100 const TCollection_AsciiString& method = (*cmd)->GetMethod();
2101 if ( !clear || method == "SetNumberOfSegments" ) {
2102 bool isNewInSet = uniqueMethods.insert( method ).second;
2103 clear = !isNewInSet;
2112 //================================================================================
2114 * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
2115 * into regular1D.LengthNearVertex( length, vertex )
2116 * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
2117 * \param theMesh - The mesh needing this hypo
2118 * \retval bool - false if the command cant be converted
2120 //================================================================================
2122 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
2123 const _pyID& theMeshID)
2125 if ( IsWrappable( theMeshID )) {
2127 _pyID vertex = theCmd->GetArg( 1 );
2129 // the problem here is that segment algo will not be found
2130 // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
2131 // geometry where segment algorithm is assigned
2132 Handle(_pyHypothesis) algo;
2133 _pyID geom = vertex;
2134 while ( algo.IsNull() && !geom.IsEmpty()) {
2135 // try to find geom as a father of <vertex>
2136 geom = FatherID( geom );
2137 algo = theGen->FindAlgo( geom, theMeshID, this );
2139 if ( algo.IsNull() )
2140 return false; // also possible to find geom as brother of veretex...
2141 // set geom instead of vertex
2142 theCmd->SetArg( 1, geom );
2144 // set vertex as a second arg
2145 if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
2146 myArgs.Append( vertex );
2148 // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
2149 // theMeshID.LengthNearVertex( length, vertex )
2150 return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
2155 //================================================================================
2157 * \brief _pyAlgorithm constructor
2158 * \param theCreationCmd - The command like "algo = smeshgen.CreateHypothesis(type,lib)"
2160 //================================================================================
2162 _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
2163 : _pyHypothesis( theCreationCmd )
2168 //================================================================================
2170 * \brief Convert the command adding an algorithm to mesh
2171 * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
2172 * \param theMesh - The mesh needing this algo
2173 * \retval bool - false if the command cant be converted
2175 //================================================================================
2177 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
2178 const _pyID& theMeshID)
2180 // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
2181 if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
2182 theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
2188 //================================================================================
2190 * \brief Return starting position of a part of python command
2191 * \param thePartIndex - The index of command part
2192 * \retval int - Part position
2194 //================================================================================
2196 int _pyCommand::GetBegPos( int thePartIndex )
2200 if ( myBegPos.Length() < thePartIndex )
2202 return myBegPos( thePartIndex );
2205 //================================================================================
2207 * \brief Store starting position of a part of python command
2208 * \param thePartIndex - The index of command part
2209 * \param thePosition - Part position
2211 //================================================================================
2213 void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
2215 while ( myBegPos.Length() < thePartIndex )
2216 myBegPos.Append( UNKNOWN );
2217 myBegPos( thePartIndex ) = thePosition;
2220 //================================================================================
2222 * \brief Returns whitespace symbols at the line beginning
2223 * \retval TCollection_AsciiString - result
2225 //================================================================================
2227 TCollection_AsciiString _pyCommand::GetIndentation()
2230 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2231 GetWord( myString, end, true );
2233 end = GetBegPos( RESULT_IND );
2234 return myString.SubString( 1, end - 1 );
2237 //================================================================================
2239 * \brief Return substring of python command looking like ResultValue = Obj.Meth()
2240 * \retval const TCollection_AsciiString & - ResultValue substring
2242 //================================================================================
2244 const TCollection_AsciiString & _pyCommand::GetResultValue()
2246 if ( GetBegPos( RESULT_IND ) == UNKNOWN )
2248 int begPos = myString.Location( "=", 1, Length() );
2250 myRes = GetWord( myString, begPos, false );
2253 SetBegPos( RESULT_IND, begPos );
2258 //================================================================================
2260 * \brief Return number of python command result value ResultValue = Obj.Meth()
2263 //================================================================================
2265 const int _pyCommand::GetNbResultValues()
2269 int endPos = myString.Location( "=", 1, Length() );
2270 TCollection_AsciiString str = "";
2271 while ( begPos < endPos) {
2272 str = GetWord( myString, begPos, true );
2273 begPos = begPos+ str.Length();
2280 //================================================================================
2282 * \brief Return substring of python command looking like
2283 * ResultValue1 , ResultValue1,... = Obj.Meth() with res index
2284 * \retval const TCollection_AsciiString & - ResultValue with res index substring
2286 //================================================================================
2287 const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
2291 int endPos = myString.Location( "=", 1, Length() );
2292 while ( begPos < endPos) {
2293 myRes = GetWord( myString, begPos, true );
2294 begPos = begPos + myRes.Length();
2297 myRes.RemoveAll('[');myRes.RemoveAll(']');
2303 return theEmptyString;
2306 //================================================================================
2308 * \brief Return substring of python command looking like ResVal = Object.Meth()
2309 * \retval const TCollection_AsciiString & - Object substring
2311 //================================================================================
2313 const TCollection_AsciiString & _pyCommand::GetObject()
2315 if ( GetBegPos( OBJECT_IND ) == UNKNOWN )
2318 int begPos = GetBegPos( RESULT_IND ) + myRes.Length();
2320 begPos = myString.Location( "=", 1, Length() ) + 1;
2321 // is '=' in the string argument (for example, name) or not
2322 int nb1 = 0; // number of ' character at the left of =
2323 int nb2 = 0; // number of " character at the left of =
2324 for ( int i = 1; i < begPos-1; i++ ) {
2325 if ( myString.Value( i )=='\'' )
2327 else if ( myString.Value( i )=='"' )
2330 // if number of ' or " is not divisible by 2,
2331 // then get an object at the start of the command
2332 if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
2335 myObj = GetWord( myString, begPos, true );
2336 // check if object is complex,
2337 // so far consider case like "smesh.smesh.Method()"
2338 if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
2339 //if ( bracketPos==0 ) bracketPos = Length();
2340 int dotPos = begPos+myObj.Length();
2341 while ( dotPos+1 < bracketPos ) {
2342 if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
2347 if ( dotPos > begPos+myObj.Length() )
2348 myObj = myString.SubString( begPos, dotPos-1 );
2351 SetBegPos( OBJECT_IND, begPos );
2357 //================================================================================
2359 * \brief Return substring of python command looking like ResVal = Obj.Method()
2360 * \retval const TCollection_AsciiString & - Method substring
2362 //================================================================================
2364 const TCollection_AsciiString & _pyCommand::GetMethod()
2366 if ( GetBegPos( METHOD_IND ) == UNKNOWN )
2369 int begPos = GetBegPos( OBJECT_IND ) + myObj.Length();
2370 bool forward = true;
2372 begPos = myString.Location( "(", 1, Length() ) - 1;
2376 myMeth = GetWord( myString, begPos, forward );
2377 SetBegPos( METHOD_IND, begPos );
2383 //================================================================================
2385 * \brief Return substring of python command looking like ResVal = Obj.Meth(Arg1,...)
2386 * \retval const TCollection_AsciiString & - Arg<index> substring
2388 //================================================================================
2390 const TCollection_AsciiString & _pyCommand::GetArg( int index )
2392 if ( GetBegPos( ARG1_IND ) == UNKNOWN )
2396 int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
2398 pos = myString.Location( "(", 1, Length() );
2402 // we are at or before '(', skip it if present
2404 while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
2405 if ( myString.Value( pos ) != '(' )
2409 SetBegPos( ARG1_IND, 0 ); // even no '('
2410 return theEmptyString;
2414 list< TCollection_AsciiString > separatorStack( 1, ",)");
2415 bool ignoreNesting = false;
2417 while ( pos <= Length() )
2419 const char chr = myString.Value( pos );
2421 if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
2423 if ( separatorStack.size() == 1 ) // ',' dividing args or a terminal ')' found
2425 while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
2427 if ( pos-1 >= prevPos ) {
2428 TCollection_AsciiString arg = myString.SubString( prevPos, pos-1 );
2429 arg.RightAdjust(); // remove spaces
2431 SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
2432 myArgs.Append( arg );
2438 else // end of nesting args found
2440 separatorStack.pop_back();
2441 ignoreNesting = false;
2444 else if ( !ignoreNesting )
2447 case '(' : separatorStack.push_back(")"); break;
2448 case '[' : separatorStack.push_back("]"); break;
2449 case '\'': separatorStack.push_back("'"); ignoreNesting=true; break;
2450 case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
2457 if ( myArgs.Length() < index )
2458 return theEmptyString;
2459 return myArgs( index );
2462 //================================================================================
2464 * \brief Check if char is a word part
2465 * \param c - The character to check
2466 * \retval bool - The check result
2468 //================================================================================
2470 static inline bool isWord(const char c, const bool dotIsWord)
2473 !isspace(c) && c != ',' && c != '=' && c != ')' && c != '(' && ( dotIsWord || c != '.');
2476 //================================================================================
2478 * \brief Looks for a word in the string and returns word's beginning
2479 * \param theString - The input string
2480 * \param theStartPos - The position to start the search, returning word's beginning
2481 * \param theForward - The search direction
2482 * \retval TCollection_AsciiString - The found word
2484 //================================================================================
2486 TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & theString,
2488 const bool theForward,
2489 const bool dotIsWord )
2491 int beg = theStartPos, end = theStartPos;
2492 theStartPos = EMPTY;
2493 if ( beg < 1 || beg > theString.Length() )
2494 return theEmptyString;
2496 if ( theForward ) { // search forward
2498 while ( beg <= theString.Length() && !isWord( theString.Value( beg ), dotIsWord))
2500 if ( beg > theString.Length() )
2501 return theEmptyString; // no word found
2504 char begChar = theString.Value( beg );
2505 if ( begChar == '"' || begChar == '\'' || begChar == '[') {
2506 char endChar = ( begChar == '[' ) ? ']' : begChar;
2507 // end is at the corresponding quoting mark or bracket
2508 while ( end < theString.Length() &&
2509 ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\'))
2513 while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
2518 else { // search backward
2520 while ( end > 0 && !isWord( theString.Value( end ), dotIsWord))
2523 return theEmptyString; // no word found
2525 char endChar = theString.Value( end );
2526 if ( endChar == '"' || endChar == '\'' ) {
2527 // beg is at the corresponding quoting mark
2529 ( theString.Value( beg ) != endChar || theString.Value( beg-1 ) == '\\'))
2533 while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
2539 //cout << theString << " ---- " << beg << " - " << end << endl;
2540 return theString.SubString( beg, end );
2543 //================================================================================
2545 * \brief Look for position where not space char is
2546 * \param theString - The string
2547 * \param thePos - The position to search from and which returns result
2548 * \retval bool - false if there are only space after thePos in theString
2552 //================================================================================
2554 bool _pyCommand::SkipSpaces( const TCollection_AsciiString & theString, int & thePos )
2556 if ( thePos < 1 || thePos > theString.Length() )
2559 while ( thePos <= theString.Length() && isspace( theString.Value( thePos )))
2562 return thePos <= theString.Length();
2565 //================================================================================
2567 * \brief Modify a part of the command
2568 * \param thePartIndex - The index of the part
2569 * \param thePart - The new part string
2570 * \param theOldPart - The old part
2572 //================================================================================
2574 void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePart,
2575 TCollection_AsciiString& theOldPart)
2577 int pos = GetBegPos( thePartIndex );
2578 if ( pos <= Length() && theOldPart != thePart)
2580 TCollection_AsciiString seperator;
2582 pos = GetBegPos( thePartIndex + 1 );
2583 if ( pos < 1 ) return;
2584 switch ( thePartIndex ) {
2585 case RESULT_IND: seperator = " = "; break;
2586 case OBJECT_IND: seperator = "."; break;
2587 case METHOD_IND: seperator = "()"; break;
2591 myString.Remove( pos, theOldPart.Length() );
2592 if ( !seperator.IsEmpty() )
2593 myString.Insert( pos , seperator );
2594 myString.Insert( pos, thePart );
2595 // update starting positions of the following parts
2596 int posDelta = thePart.Length() + seperator.Length() - theOldPart.Length();
2597 for ( int i = thePartIndex + 1; i <= myBegPos.Length(); ++i ) {
2598 if ( myBegPos( i ) > 0 )
2599 myBegPos( i ) += posDelta;
2601 theOldPart = thePart;
2605 //================================================================================
2607 * \brief Set agrument
2608 * \param index - The argument index, it counts from 1
2609 * \param theArg - The argument string
2611 //================================================================================
2613 void _pyCommand::SetArg( int index, const TCollection_AsciiString& theArg)
2616 int argInd = ARG1_IND + index - 1;
2617 int pos = GetBegPos( argInd );
2618 if ( pos < 1 ) // no index-th arg exist, append inexistent args
2620 // find a closing parenthesis
2621 if ( GetNbArgs() != 0 && index <= GetNbArgs() ) {
2622 int lastArgInd = GetNbArgs();
2623 pos = GetBegPos( ARG1_IND + lastArgInd - 1 ) + GetArg( lastArgInd ).Length();
2624 while ( pos > 0 && pos <= Length() && myString.Value( pos ) != ')' )
2629 while ( pos > 0 && myString.Value( pos ) != ')' )
2632 if ( pos < 1 || myString.Value( pos ) != ')' ) { // no parentheses at all
2636 while ( myArgs.Length() < index ) {
2637 if ( myArgs.Length() )
2638 myString.Insert( pos++, "," );
2639 myArgs.Append("None");
2640 myString.Insert( pos, myArgs.Last() );
2641 SetBegPos( ARG1_IND + myArgs.Length() - 1, pos );
2642 pos += myArgs.Last().Length();
2645 SetPart( argInd, theArg, myArgs( index ));
2648 //================================================================================
2650 * \brief Empty arg list
2652 //================================================================================
2654 void _pyCommand::RemoveArgs()
2656 if ( int pos = myString.Location( '(', 1, Length() ))
2657 myString.Trunc( pos );
2660 if ( myBegPos.Length() >= ARG1_IND )
2661 myBegPos.Remove( ARG1_IND, myBegPos.Length() );
2664 //================================================================================
2666 * \brief Set dependent commands after this one
2668 //================================================================================
2670 bool _pyCommand::SetDependentCmdsAfter() const
2672 bool orderChanged = false;
2673 list< Handle(_pyCommand)>::const_reverse_iterator cmd = myDependentCmds.rbegin();
2674 for ( ; cmd != myDependentCmds.rend(); ++cmd ) {
2675 if ( (*cmd)->GetOrderNb() < GetOrderNb() ) {
2676 orderChanged = true;
2677 theGen->SetCommandAfter( *cmd, this );
2678 (*cmd)->SetDependentCmdsAfter();
2681 return orderChanged;
2683 //================================================================================
2685 * \brief Insert accessor method after theObjectID
2686 * \param theObjectID - id of the accessed object
2687 * \param theAcsMethod - name of the method giving access to the object
2688 * \retval bool - false if theObjectID is not found in the command string
2690 //================================================================================
2692 bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod )
2694 if ( !theAcsMethod )
2696 // start object search from the object, i.e. ignore result
2698 int beg = GetBegPos( OBJECT_IND );
2699 if ( beg < 1 || beg > Length() )
2702 while (( beg = myString.Location( theObjectID, beg, Length() )))
2704 // check that theObjectID is not just a part of a longer ID
2705 int afterEnd = beg + theObjectID.Length();
2706 Standard_Character c = myString.Value( afterEnd );
2707 if ( !isalnum( c ) && c != ':' ) {
2708 // check if accessor method already present
2710 myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
2712 int oldLen = Length();
2713 myString.Insert( afterEnd, (char*) theAcsMethod );
2714 myString.Insert( afterEnd, "." );
2715 // update starting positions of the parts following the modified one
2716 int posDelta = Length() - oldLen;
2717 for ( int i = 1; i <= myBegPos.Length(); ++i ) {
2718 if ( myBegPos( i ) > afterEnd )
2719 myBegPos( i ) += posDelta;
2724 beg = afterEnd; // is a part - next search
2729 //================================================================================
2731 * \brief Return method name giving access to an interaface object wrapped by python class
2732 * \retval const char* - method name
2734 //================================================================================
2736 const char* _pyObject::AccessorMethod() const
2740 //================================================================================
2742 * \brief Return ID of a father
2744 //================================================================================
2746 _pyID _pyObject::FatherID(const _pyID & childID)
2748 int colPos = childID.SearchFromEnd(':');
2750 return childID.SubString( 1, colPos-1 );
2754 //================================================================================
2756 * \brief SelfEraser erases creation command if no more it's commands invoked
2758 //================================================================================
2760 void _pySelfEraser::Flush()
2762 if ( GetNbCalls() == 0 )
2763 GetCreationCmd()->Clear();
2766 //================================================================================
2768 * \brief count invoked commands
2770 //================================================================================
2772 void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
2774 _pyObject::Process(theCommand); // count calls of Process()
2775 GetCreationCmd()->AddDependantCmd( theCommand );
2778 //================================================================================
2780 * \brief Clear creation command if no commands invoked
2782 //================================================================================
2784 void _pySubMesh::Flush()
2786 if ( GetNbCalls() == 0 ) // move to the end of all commands
2787 theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
2788 else if ( !myCreator.IsNull() )
2789 // move to be just after creator
2790 myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
2793 //================================================================================
2795 * \brief To convert creation of a group by filter
2797 //================================================================================
2799 void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
2801 // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
2802 // group = mesh.CreateEmptyGroup( elemType, groupName )
2803 // aFilter.SetMesh(mesh)
2804 // nbAdd = group.AddFrom( aFilter )
2805 if ( theCommand->GetMethod() == "AddFrom" )
2807 _pyID idSource = theCommand->GetArg(1);
2808 // check if idSource is a filter
2809 Handle(_pyObject) filter = theGen->FindObject( idSource );
2810 if ( filter.IsNull() || !filter->IsKind(STANDARD_TYPE(_pyFilter)))
2812 // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
2813 list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin();
2814 while ( *cmdIt != theCommand ) ++cmdIt;
2815 while ( (*cmdIt)->GetOrderNb() != 1 )
2817 const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
2818 if ((setMeshCmd->GetObject() == idSource ||
2819 setMeshCmd->GetObject() == Handle(_pyFilter)::DownCast(filter)->GetNewID() )
2821 setMeshCmd->GetMethod() == "SetMesh")
2823 setMeshCmd->Clear();
2827 // replace 3 commands by one
2828 theCommand->Clear();
2829 const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
2830 TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
2831 makeGroupCmd->SetMethod( "MakeGroupByFilter" );
2832 makeGroupCmd->SetArg( 1, name );
2833 makeGroupCmd->SetArg( 2, idSource );
2834 // set new name of a filter
2835 filter->Process( makeGroupCmd );
2837 else if ( theCommand->GetMethod() == "SetFilter" )
2839 // set new name of a filter
2840 _pyID filterID = theCommand->GetArg(1);
2841 Handle(_pyObject) filter = theGen->FindObject( filterID );
2842 if ( !filter.IsNull() )
2843 filter->Process( theCommand );
2847 //================================================================================
2849 * \brief Constructor of _pyFilter
2851 //================================================================================
2853 _pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
2854 :_pyObject(theCreationCmd), myNewID( newID )
2858 //================================================================================
2860 * \brief To convert creation of a filter by criteria and
2861 * to replace an old name by a new one
2863 //================================================================================
2865 void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
2867 if ( theCommand->GetObject() == GetID() )
2868 _pyObject::Process(theCommand); // count commands
2870 if ( !myNewID.IsEmpty() )
2872 if ( theCommand->GetObject() == GetID() )
2873 theCommand->SetObject( myNewID );
2874 else if ( theCommand->GetResultValue() == GetID() )
2875 theCommand->SetResultValue( myNewID );
2877 for ( int i = 1, nb = theCommand->GetNbArgs(); i <= nb; ++i )
2878 if ( theCommand->GetArg( i ) == GetID() )
2880 theCommand->SetArg( i, myNewID );
2885 // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
2886 // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
2887 // aFilter0x2aaab0487080.SetCriteria(aCriteria)
2888 if ( GetNbCalls() == 0 && // none method was called before SetCriteria()
2889 theCommand->GetMethod() == "SetCriteria")
2891 // aFilter.SetCriteria(aCriteria) ->
2892 // aFilter = smesh.GetFilterFromCriteria(criteria)
2893 if ( myNewID.IsEmpty() )
2894 theCommand->SetResultValue( GetID() );
2896 theCommand->SetResultValue( myNewID );
2897 theCommand->SetObject( SMESH_2smeshpy::GenName() );
2898 theCommand->SetMethod( "GetFilterFromCriteria" );
2900 // Clear aFilterManager.CreateFilter()
2901 GetCreationCmd()->Clear();
2903 else if ( theCommand->GetMethod() == "SetMesh")
2905 theGen->AddMeshAccessorMethod( theCommand );
2909 //================================================================================
2911 * \brief Set new filter name to the creation command
2913 //================================================================================
2915 void _pyFilter::Flush()
2917 if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
2918 GetCreationCmd()->SetResultValue( myNewID );