Salome HOME
cosmetic changes
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.hxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File      : SMESH_smesh.hxx
24 // Created   : Fri Nov 18 12:05:18 2005
25 // Author    : Edward AGAPOV (eap)
26 //
27 #ifndef SMESH_smesh_HeaderFile
28 #define SMESH_smesh_HeaderFile
29
30 #include <Standard_DefineHandle.hxx>
31 #include <Standard_Type.hxx>
32 #include <Standard_Transient.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <TColStd_SequenceOfAsciiString.hxx>
35 #include <TColStd_SequenceOfInteger.hxx>
36
37 #include <list>
38 #include <map>
39
40 // ===========================================================================================
41 /*!
42  * This file was created in order to respond to requirement of bug PAL10494:
43  * SMESH python dump uses idl interface.
44  *
45  * The creation reason is that smesh.py commands defining hypotheses encapsulate
46  * several SMESH engine method calls. As well, the dependencies between smesh.py
47  * classes differ from ones between corresponding SMESH IDL interfaces.
48  * 
49  * Everything here is for internal usage by SMESH_2smeshpy::ConvertScript()
50  * declared in SMESH_PythonDump.hxx
51  *
52  * See comments to _pyHypothesis class to know how to assure convertion of a new
53  * type of hypothesis
54  */
55 // ===========================================================================================
56
57 class Resource_DataMapOfAsciiStringAsciiString;
58
59 // ===========================================================================================
60 // =====================
61 //    INTERNAL STUFF
62 // =====================
63 // ===========================================================================================
64
65 class _pyCommand;
66 class _pyObject;
67 class _pyGen;
68 class _pyMesh;
69 class _pySubMesh;
70 class _pyHypothesis;
71 class _pyAlgorithm;
72
73 DEFINE_STANDARD_HANDLE (_pyCommand   ,Standard_Transient);
74 DEFINE_STANDARD_HANDLE (_pyObject    ,Standard_Transient);
75 DEFINE_STANDARD_HANDLE (_pyGen       ,_pyObject);
76 DEFINE_STANDARD_HANDLE (_pyMesh      ,_pyObject);
77 DEFINE_STANDARD_HANDLE (_pySubMesh   ,_pyObject);
78 DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject);
79 DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject);
80 DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
81
82 typedef TCollection_AsciiString _pyID;
83
84 // ===========================================================
85 /*!
86  * \brief Class operating on a command string looking like
87  *        ResultValue = Object.Method( Arg1, Arg2,...)
88  */
89 // ===========================================================
90
91 class _pyCommand: public Standard_Transient
92 {
93   int                             myOrderNb;            //!< position within the script
94   TCollection_AsciiString         myString;             //!< command text
95   TCollection_AsciiString         myRes, myObj, myMeth; //!< found parts of command
96   TColStd_SequenceOfAsciiString   myArgs;               //!< found arguments
97   TColStd_SequenceOfInteger       myBegPos;             //!< where myRes, myObj, ... begin
98   std::list< Handle(_pyCommand) > myDependentCmds; //!< commands that sould follow me in the script
99
100   enum { UNKNOWN=-1, EMPTY=0, RESULT_IND, OBJECT_IND, METHOD_IND, ARG1_IND };
101   int GetBegPos( int thePartIndex );
102   void SetBegPos( int thePartIndex, int thePosition );
103   void SetPart( int thePartIndex, const TCollection_AsciiString& theNewPart,
104                 TCollection_AsciiString& theOldPart);
105   void FindAllArgs() { GetArg(1); }
106
107 public:
108   _pyCommand() {};
109   _pyCommand( const TCollection_AsciiString& theString, int theNb )
110     : myString( theString ), myOrderNb( theNb ) {};
111   TCollection_AsciiString & GetString() { return myString; }
112   int GetOrderNb() const { return myOrderNb; }
113   void SetOrderNb( int theNb ) { myOrderNb = theNb; }
114   int Length() { return myString.Length(); }
115   void Clear() { myString.Clear(); myBegPos.Clear(); myArgs.Clear(); }
116   bool IsEmpty() const { return myString.IsEmpty(); }
117   TCollection_AsciiString GetIndentation();
118   const TCollection_AsciiString & GetResultValue();
119   const int GetNbResultValues();
120   const TCollection_AsciiString & GetResultValue(int res);
121   const TCollection_AsciiString & GetObject();
122   const TCollection_AsciiString & GetMethod();
123   const TCollection_AsciiString & GetArg( int index );
124   int GetNbArgs() { FindAllArgs(); return myArgs.Length(); }
125   //Handle(TColStd_HSequenceOfAsciiString) GetArgs();
126   void SetResultValue( const TCollection_AsciiString& theResult )
127   { GetResultValue(); SetPart( RESULT_IND, theResult, myRes ); }
128   void SetObject(const TCollection_AsciiString& theObject)
129   { GetObject(); SetPart( OBJECT_IND, theObject, myObj ); }
130   void SetMethod(const TCollection_AsciiString& theMethod)
131   { GetMethod(); SetPart( METHOD_IND, theMethod, myMeth ); }
132   void SetArg( int index, const TCollection_AsciiString& theArg);
133   void RemoveArgs();
134   static bool SkipSpaces( const TCollection_AsciiString & theSring, int & thePos );
135   static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring,
136                                           int & theStartPos, const bool theForward,
137                                           const bool dotIsWord = false);
138   void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false)
139   { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); }
140   bool SetDependentCmdsAfter() const;
141
142   bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
143
144   DEFINE_STANDARD_RTTI (_pyCommand)
145 };
146
147 // -------------------------------------------------------------------------------------
148 /*!
149  * \brief Root of all objects. It counts calls of Process()
150  */
151 // -------------------------------------------------------------------------------------
152
153 class _pyObject: public Standard_Transient
154 {
155   Handle(_pyCommand) myCreationCmd;
156   int                myNbCalls;
157   bool               myIsRemoved, myIsProtected;
158   std::list< Handle(_pyCommand) > myProcessedCmds;
159 public:
160   _pyObject(const Handle(_pyCommand)& theCreationCmd);
161   const _pyID& GetID() { return myCreationCmd->GetResultValue(); }
162   static _pyID FatherID(const _pyID & childID);
163   const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
164   int GetNbCalls() const { return myNbCalls; }
165   bool IsRemovedFromStudy() const { return myIsRemoved; }
166   void  SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
167   int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
168   void AddProcessedCmd( const Handle(_pyCommand) & cmd )
169   { if ( !cmd.IsNull() ) myProcessedCmds.push_back( cmd ); }
170   virtual void Process(const Handle(_pyCommand) & theCommand) { myNbCalls++; }
171   virtual void Flush() = 0;
172   virtual const char* AccessorMethod() const;
173
174   DEFINE_STANDARD_RTTI (_pyObject)
175 };
176
177 // -------------------------------------------------------------------------------------
178 /*!
179  * \brief Class corresponding to SMESH_Gen. It holds info on existing
180  *        meshes and hypotheses
181  */
182 // -------------------------------------------------------------------------------------
183 class _pyGen: public _pyObject
184 {
185 public:
186   _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
187          Resource_DataMapOfAsciiStringAsciiString& theObjectNames);
188   Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
189   void Process( const Handle(_pyCommand)& theCommand );
190   void Flush();
191   Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
192   Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
193                                   const Handle(_pyHypothesis)& theHypothesis);
194   Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID );
195   void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 );
196   void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd );
197   void SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd );
198   Handle(_pyCommand)& GetLastCommand();
199   std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; }
200   void SetAccessorMethod(const _pyID& theID, const char* theMethod );
201   bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const;
202   bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const;
203   const char* AccessorMethod() const;
204   _pyID GenerateNewID( const _pyID& theID );
205   void AddObject( Handle(_pyObject)& theObj );
206   Handle(_pyObject) FindObject( const _pyID& theObjID ) const;
207   bool IsDead(const _pyID& theObjID) const;
208
209 private:
210   void setNeighbourCommand( Handle(_pyCommand)& theCmd,
211                             Handle(_pyCommand)& theOtherCmd,
212                             const bool theIsAfter );
213   
214 private:
215   std::map< _pyID, Handle(_pyMesh) >       myMeshes;
216   std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors;
217   std::map< _pyID, Handle(_pyObject) >     myObjects;
218   std::list< Handle(_pyHypothesis) >       myHypos;
219   std::list< Handle(_pyCommand) >          myCommands;
220   int                                      myNbCommands;
221   Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod;
222   Resource_DataMapOfAsciiStringAsciiString& myObjectNames;
223   Handle(_pyCommand)                       myLastCommand;
224   int                                      myNbFilters;
225
226   DEFINE_STANDARD_RTTI (_pyGen)
227 };
228
229 // -------------------------------------------------------------------------------------
230 /*!
231  * \brief Contains commands concerning mesh substructures
232  */
233 // -------------------------------------------------------------------------------------
234 #define _pyMesh_ACCESS_METHOD "GetMesh()"
235 class _pyMesh: public _pyObject
236 {
237   std::list< Handle(_pyHypothesis) > myHypos;
238   std::list< Handle(_pyCommand) >    myAddHypCmds;
239   std::list< Handle(_pySubMesh) >    mySubmeshes;
240   bool                               myHasEditor;
241 public:
242   _pyMesh(const Handle(_pyCommand) creationCmd);
243   _pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString & id);
244   const _pyID& GetGeom() { return GetCreationCmd()->GetArg(1); }
245   void Process( const Handle(_pyCommand)& theCommand);
246   void Flush();
247   const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; }
248 private:
249   static bool NeedMeshAccess( const Handle(_pyCommand)& theCommand );
250   static void AddMeshAccess( const Handle(_pyCommand)& theCommand )
251   { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); }
252
253   DEFINE_STANDARD_RTTI (_pyMesh)
254 };
255 #undef _pyMesh_ACCESS_METHOD 
256
257 // -------------------------------------------------------------------------------------
258 /*!
259  * \brief MeshEditor convert its commands to ones of mesh
260  */
261 // -------------------------------------------------------------------------------------
262 class _pyMeshEditor: public _pyObject
263 {
264   _pyID myMesh;
265   TCollection_AsciiString myCreationCmdStr;
266 public:
267   _pyMeshEditor(const Handle(_pyCommand)& theCreationCmd);
268   void Process( const Handle(_pyCommand)& theCommand);
269   virtual void Flush() {}
270
271   DEFINE_STANDARD_RTTI (_pyMesh)
272 };
273
274 // -------------------------------------------------------------------------------------
275 /*!
276  * \brief Root class for hypothesis
277  *
278  * HOWTO assure convertion of a new type of hypothesis
279  * In _pyHypothesis::NewHypothesis():
280  * 1. add a case for the name of the new hypothesis
281  * 2. use SetConvMethodAndType() to set
282  *    . for algo: algorithm name and method of Mesh creating the algo
283  *    . for hypo: name of the algorithm and method creating the hypothesis
284  * 3. append to myArgMethods interface methods setting param values in the
285  *    order they are used when creation method is called. If arguments of
286  *    the creation method can't be easily got from calls of hypothesis methods, you are
287  *    to derive a specific class from _pyHypothesis that would redefine Process(),
288  *    see _pyComplexParamHypo for example
289  */
290 // -------------------------------------------------------------------------------------
291 class _pyHypothesis: public _pyObject
292 {
293 protected:
294   bool    myIsAlgo, myIsWrapped;
295   _pyID   myGeom,   myMesh;
296   // a hypothesis can be used and created by different algos by different methods
297   std::map<TCollection_AsciiString, TCollection_AsciiString > myType2CreationMethod;
298   TColStd_SequenceOfAsciiString myArgs;           // creation arguments
299   TColStd_SequenceOfAsciiString myArgMethods;     // hypo methods setting myArgs
300   TColStd_SequenceOfInteger     myNbArgsByMethod; // nb args set by each method
301   std::list<Handle(_pyCommand)> myArgCommands;
302   std::list<Handle(_pyCommand)> myUnknownCommands;
303 public:
304   _pyHypothesis(const Handle(_pyCommand)& theCreationCmd);
305   void SetConvMethodAndType(const char* creationMethod, const char* type)
306   { myType2CreationMethod[ (char*)type ] = (char*)creationMethod; }
307   void AddArgMethod(const char* method, const int nbArgs = 1)
308   { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); }
309   const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
310   const std::list<Handle(_pyCommand)>& GetArgCommands() const { return myArgCommands; }
311   void ClearAllCommands();
312   virtual bool IsAlgo() const { return myIsAlgo; }
313   bool IsValid() const { return !myType2CreationMethod.empty(); }
314   bool IsWrapped() const { return myIsWrapped; }
315   const _pyID & GetGeom() const { return myGeom; }
316   void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; }
317   const _pyID & GetMesh() const { return myMesh; }
318   const TCollection_AsciiString& GetAlgoType() const
319   { return myType2CreationMethod.begin()->first; }
320   const TCollection_AsciiString& GetAlgoCreationMethod() const
321   { return myType2CreationMethod.begin()->second; }
322   bool CanBeCreatedBy(const TCollection_AsciiString& algoType ) const
323   { return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); }
324   const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const
325   { return myType2CreationMethod.find( algoType )->second; }
326   virtual bool IsWrappable(const _pyID& theMesh) const;
327   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
328                                   const _pyID&              theMesh);
329   static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd);
330   void Process( const Handle(_pyCommand)& theCommand);
331   void Flush();
332   virtual void Assign( const Handle(_pyHypothesis)& theOther,
333                        const _pyID&                 theMesh );
334
335   DEFINE_STANDARD_RTTI (_pyHypothesis)
336 };
337
338 // -------------------------------------------------------------------------------------
339 /*!
340  * \brief Class representing smesh.Mesh_Algorithm
341  */
342 // -------------------------------------------------------------------------------------
343 class _pyAlgorithm: public _pyHypothesis
344 {
345 public:
346   _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
347   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
348                                   const _pyID&              theMesh);
349   const char* AccessorMethod() const { return "GetAlgorithm()"; }
350   virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; }
351
352   DEFINE_STANDARD_RTTI (_pyAlgorithm)
353 };
354
355 // -------------------------------------------------------------------------------------
356 /*!
357  * \brief Class for hypotheses having several parameters modified by one method
358  */
359 // -------------------------------------------------------------------------------------
360 class _pyComplexParamHypo: public _pyHypothesis
361 {
362 public:
363   _pyComplexParamHypo(const Handle(_pyCommand)& theCreationCmd): _pyHypothesis(theCreationCmd) {}
364   void Process( const Handle(_pyCommand)& theCommand);
365   void Flush();
366
367   DEFINE_STANDARD_RTTI (_pyComplexParamHypo)
368 };
369 DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis);
370
371 // -------------------------------------------------------------------------------------
372 /*!
373  * \brief Class for LayerDistribution hypothesis conversion
374  */
375 // -------------------------------------------------------------------------------------
376 class _pyLayerDistributionHypo: public _pyHypothesis
377 {
378   Handle(_pyHypothesis) my1dHyp;
379   TCollection_AsciiString myAlgoMethod;
380 public:
381   _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd, const char* algoMethod):
382     _pyHypothesis(theCreationCmd), myAlgoMethod((char*)algoMethod) {}
383   void Process( const Handle(_pyCommand)& theCommand);
384   void Flush();
385   bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
386                           const _pyID&              theMesh);
387
388   DEFINE_STANDARD_RTTI (_pyLayerDistributionHypo)
389 };
390 DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
391
392 // -------------------------------------------------------------------------------------
393 /*!
394  * \brief Class representing NumberOfSegments hypothesis
395  */
396 // -------------------------------------------------------------------------------------
397 class _pyNumberOfSegmentsHyp: public _pyHypothesis
398 {
399 public:
400   _pyNumberOfSegmentsHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
401   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
402                                   const _pyID&              theMesh);
403   void Flush();
404
405   DEFINE_STANDARD_RTTI (_pyNumberOfSegmentsHyp)
406 };
407 DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis);
408
409 // -------------------------------------------------------------------------------------
410 /*!
411  * \brief Class representing SegmentLengthAroundVertex hypothesis
412  */
413 // -------------------------------------------------------------------------------------
414 class _pySegmentLengthAroundVertexHyp: public _pyHypothesis
415 {
416 public:
417   _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
418   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
419                                   const _pyID&              theMesh);
420   DEFINE_STANDARD_RTTI (_pySegmentLengthAroundVertexHyp)
421 };
422 DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
423
424 // -------------------------------------------------------------------------------------
425 /*!
426  * \brief SelfEraser erases creation command if no more it's commands invoked
427  */
428 // -------------------------------------------------------------------------------------
429 class _pySelfEraser: public _pyObject
430 {
431 public:
432   _pySelfEraser(const Handle(_pyCommand)& theCreationCmd):_pyObject(theCreationCmd) {}
433   virtual void Flush();
434
435   DEFINE_STANDARD_RTTI (_pySelfEraser)
436 };
437 DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject);
438
439 // -------------------------------------------------------------------------------------
440 /*!
441  * \brief SubMesh creation can be moved to the end of engine commands
442  */
443 // -------------------------------------------------------------------------------------
444 class _pySubMesh:  public _pyObject
445 {
446 public:
447   _pySubMesh(const Handle(_pyCommand)& theCreationCmd):_pyObject(theCreationCmd) {}
448   void Process( const Handle(_pyCommand)& theCommand);
449   virtual void Flush();
450   void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; }
451
452   DEFINE_STANDARD_RTTI (_pySubMesh)
453 private:
454   Handle(_pyObject) myCreator;
455 };
456 // -------------------------------------------------------------------------------------
457 /*!
458  * \brief To convert creation of a group by filter
459  */
460 // -------------------------------------------------------------------------------------
461 class _pyGroup:  public _pyObject
462 {
463 public:
464   _pyGroup(const Handle(_pyCommand)& theCreationCmd):_pyObject(theCreationCmd) {}
465   void Process( const Handle(_pyCommand)& theCommand);
466   virtual void Flush() {}
467
468   DEFINE_STANDARD_RTTI (_pyGroup)
469 };
470 DEFINE_STANDARD_HANDLE (_pyGroup, _pyObject);
471
472 // -------------------------------------------------------------------------------------
473 /*!
474  * \brief A filter sets a human readable name to self
475  */
476 // -------------------------------------------------------------------------------------
477 class _pyFilter:  public _pyObject
478 {
479   _pyID myNewID;
480 public:
481   _pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID="");
482   void Process( const Handle(_pyCommand)& theCommand);
483   virtual void Flush();
484   const _pyID& GetNewID() const { return myNewID; }
485
486   DEFINE_STANDARD_RTTI (_pyFilter)
487 };
488 DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject);
489
490 #endif