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