Salome HOME
Join modifications from V3_2_0_maintainance (V3_2_6pre4 - T32x_16Aug2007_16h00m)
[modules/smesh.git] / src / SMESH_I / SMESH_2smeshpy.hxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
8 //
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File      : SMESH_smesh.hxx
21 // Created   : Fri Nov 18 12:05:18 2005
22 // Author    : Edward AGAPOV (eap)
23
24 #ifndef SMESH_smesh_HeaderFile
25 #define SMESH_smesh_HeaderFile
26
27 #include <Standard_DefineHandle.hxx>
28 #include <Standard_Type.hxx>
29 #include <Standard_Transient.hxx>
30 #include <TCollection_AsciiString.hxx>
31 #include <TColStd_SequenceOfAsciiString.hxx>
32 #include <TColStd_SequenceOfInteger.hxx>
33
34 #include <list>
35 #include <map>
36
37 // ===========================================================================================
38 /*!
39  * This file was created in order to respond to requirement of bug PAL10494:
40  * SMESH python dump uses idl interface.
41  *
42  * The creation reason is that smesh.py commands defining hypotheses encapsulate
43  * several SMESH engine method calls. As well, the dependencies between smesh.py
44  * classes differ from ones between corresponding SMESH IDL interfaces.
45  * 
46  * Everything here is for internal usage by SMESH_2smeshpy::ConvertScript()
47  * declared in SMESH_PythonDump.hxx
48  *
49  * See comments to _pyHypothesis class to know how to assure convertion of a new
50  * type of hypothesis
51  */
52 // ===========================================================================================
53
54 class Resource_DataMapOfAsciiStringAsciiString;
55
56 // ===========================================================================================
57 // =====================
58 //    INTERNAL STUFF
59 // =====================
60 // ===========================================================================================
61
62 class _pyCommand;
63 class _pyObject;
64 class _pyGen;
65 class _pyMesh;
66 class _pyHypothesis;
67 class _pyAlgorithm;
68
69 DEFINE_STANDARD_HANDLE (_pyCommand   ,Standard_Transient);
70 DEFINE_STANDARD_HANDLE (_pyObject    ,Standard_Transient);
71 DEFINE_STANDARD_HANDLE (_pyGen       ,_pyObject);
72 DEFINE_STANDARD_HANDLE (_pyMesh      ,_pyObject);
73 DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject);
74 DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject);
75 DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
76
77 typedef TCollection_AsciiString _pyID;
78
79 // ===========================================================
80 /*!
81  * \brief Class operating on a command string looking like
82  *        ResultValue = Object.Method( Arg1, Arg2,...)
83  */
84 // ===========================================================
85
86 class _pyCommand: public Standard_Transient
87 {
88   int                             myOrderNb;            //!< position within the script
89   TCollection_AsciiString         myString;             //!< command text
90   TCollection_AsciiString         myRes, myObj, myMeth; //!< found parts of command
91   TColStd_SequenceOfAsciiString   myArgs;               //!< found arguments
92   TColStd_SequenceOfInteger       myBegPos;             //!< where myRes, myObj, ... begin
93   std::list< Handle(_pyCommand) > myDependentCmds; //!< commands that sould follow me in the script
94
95   enum { UNKNOWN=-1, EMPTY=0, RESULT_IND, OBJECT_IND, METHOD_IND, ARG1_IND };
96   int GetBegPos( int thePartIndex );
97   void SetBegPos( int thePartIndex, int thePosition );
98   void SetPart( int thePartIndex, const TCollection_AsciiString& theNewPart,
99                 TCollection_AsciiString& theOldPart);
100   void FindAllArgs() { GetArg(1); }
101
102 public:
103   _pyCommand() {};
104   _pyCommand( const TCollection_AsciiString& theString, int theNb )
105     : myString( theString ), myOrderNb( theNb ) {};
106   TCollection_AsciiString & GetString() { return myString; }
107   int GetOrderNb() const { return myOrderNb; }
108   void SetOrderNb( int theNb ) { myOrderNb = theNb; }
109   int Length() { return myString.Length(); }
110   void Clear() { myString.Clear(); myBegPos.Clear(); }
111   bool IsEmpty() const { return myString.IsEmpty(); }
112   TCollection_AsciiString GetIndentation();
113   const TCollection_AsciiString & GetResultValue();
114   const TCollection_AsciiString & GetObject();
115   const TCollection_AsciiString & GetMethod();
116   const TCollection_AsciiString & GetArg( int index );
117   int GetNbArgs() { FindAllArgs(); return myArgs.Length(); }
118   //Handle(TColStd_HSequenceOfAsciiString) GetArgs();
119   void SetResultValue( const TCollection_AsciiString& theResult )
120   { GetResultValue(); SetPart( RESULT_IND, theResult, myRes ); }
121   void SetObject(const TCollection_AsciiString& theObject)
122   { GetObject(); SetPart( OBJECT_IND, theObject, myObj ); }
123   void SetMethod(const TCollection_AsciiString& theMethod)
124   { GetMethod(); SetPart( METHOD_IND, theMethod, myMeth ); }
125   void SetArg( int index, const TCollection_AsciiString& theArg);
126   void RemoveArgs();
127   static bool SkipSpaces( const TCollection_AsciiString & theSring, int & thePos );
128   static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring,
129                                           int & theStartPos, const bool theForward,
130                                           const bool dotIsWord = false);
131   void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false)
132   { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); }
133   bool SetDependentCmdsAfter() const;
134
135   bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
136
137   DEFINE_STANDARD_RTTI (_pyCommand)
138 };
139
140 // -------------------------------------------------------------------------------------
141 /*!
142  * \brief Root of all objects
143  */
144 // -------------------------------------------------------------------------------------
145
146 class _pyObject: public Standard_Transient
147 {
148   Handle(_pyCommand)              myCreationCmd;
149 public:
150   _pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {}
151   const _pyID& GetID() { return myCreationCmd->GetResultValue(); }
152   static _pyID FatherID(const _pyID & childID);
153   const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
154   void  SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
155   int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
156   virtual void Process(const Handle(_pyCommand) & theCommand) = 0;
157   virtual void Flush() = 0;
158   virtual const char* AccessorMethod() const;
159
160   DEFINE_STANDARD_RTTI (_pyObject)
161 };
162
163 // -------------------------------------------------------------------------------------
164 /*!
165  * \brief Class corresponding to SMESH_Gen. It holds info on existing
166  *        meshes and hypotheses
167  */
168 // -------------------------------------------------------------------------------------
169 class _pyGen: public _pyObject
170 {
171 public:
172   _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod);
173   //~_pyGen();
174   Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
175   void Process( const Handle(_pyCommand)& theCommand );
176   void Flush();
177   Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
178   Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
179                                   const Handle(_pyHypothesis)& theHypothesis);
180   void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 );
181   void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd );
182   std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; }
183   void SetAccessorMethod(const _pyID& theID, const char* theMethod );
184   bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const;
185   bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const;
186   const char* AccessorMethod() const;
187 private:
188   std::map< _pyID, Handle(_pyMesh) >       myMeshes;
189   std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors;
190   std::list< Handle(_pyHypothesis) >       myHypos;
191   std::list< Handle(_pyCommand) >          myCommands;
192   int                                      myNbCommands;
193   bool                                     myHasPattern;
194   Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod;
195
196   DEFINE_STANDARD_RTTI (_pyGen)
197 };
198
199 // -------------------------------------------------------------------------------------
200 /*!
201  * \brief Contains commands concerning mesh substructures
202  */
203 // -------------------------------------------------------------------------------------
204 #define _pyMesh_ACCESS_METHOD "GetMesh()"
205 class _pyMesh: public _pyObject
206 {
207   std::list< Handle(_pyHypothesis) > myHypos;
208   std::list< Handle(_pyCommand) > myAddHypCmds;
209   std::list< Handle(_pyCommand) > mySubmeshes;
210   bool                            myHasEditor;
211 public:
212   _pyMesh(const Handle(_pyCommand) theCreationCmd);
213   const _pyID& GetGeom() { return GetCreationCmd()->GetArg(1); }
214   void Process( const Handle(_pyCommand)& theCommand);
215   void Flush();
216   const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; }
217 private:
218   static bool NeedMeshAccess( const Handle(_pyCommand)& theCommand );
219   static void AddMeshAccess( const Handle(_pyCommand)& theCommand )
220   { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); }
221
222   DEFINE_STANDARD_RTTI (_pyMesh)
223 };
224 #undef _pyMesh_ACCESS_METHOD 
225
226 // -------------------------------------------------------------------------------------
227 /*!
228  * \brief MeshEditor convert its commands to ones of mesh
229  */
230 // -------------------------------------------------------------------------------------
231 class _pyMeshEditor: public _pyObject
232 {
233   _pyID myMesh;
234   TCollection_AsciiString myCreationCmdStr;
235 public:
236   _pyMeshEditor(const Handle(_pyCommand)& theCreationCmd);
237   void Process( const Handle(_pyCommand)& theCommand);
238   virtual void Flush() {}
239
240   DEFINE_STANDARD_RTTI (_pyMesh)
241 };
242
243 // -------------------------------------------------------------------------------------
244 /*!
245  * \brief Root class for hypothesis
246  *
247  * HOWTO assure convertion of a new type of hypothesis
248  * In _pyHypothesis::NewHypothesis():
249  * 1. add a case for the name of the new hypothesis
250  * 2. use SetConvMethodAndType() to set
251  *    . for algo: algorithm name and method of Mesh creating the algo
252  *    . for hypo: name of the algorithm and method creating the hypothesis
253  * 3. append to myArgMethods interface methods setting param values in the
254  *    order they are used when creation method is called. If arguments of
255  *    the creation method can't be easily got from calls of hypothesis methods, you are
256  *    to derive a specific class from _pyHypothesis that would redefine Process(),
257  *    see _pyComplexParamHypo for example
258  */
259 // -------------------------------------------------------------------------------------
260 class _pyHypothesis: public _pyObject
261 {
262 protected:
263   bool    myIsAlgo, myIsWrapped;
264   _pyID   myGeom,   myMesh;
265   // a hypothesis can be used and created by different algos by different methods
266   std::map<TCollection_AsciiString, TCollection_AsciiString > myType2CreationMethod;
267   //TCollection_AsciiString       myCreationMethod, myType;
268   TColStd_SequenceOfAsciiString myArgs;           // creation arguments
269   TColStd_SequenceOfAsciiString myArgMethods;     // hypo methods setting myArgs
270   TColStd_SequenceOfInteger     myNbArgsByMethod; // nb args set by each method
271   std::list<Handle(_pyCommand)>  myArgCommands;
272   std::list<Handle(_pyCommand)>  myUnknownCommands;
273 public:
274   _pyHypothesis(const Handle(_pyCommand)& theCreationCmd);
275   void SetConvMethodAndType(const char* creationMethod, const char* type)
276   { myType2CreationMethod[ (char*)type ] = (char*)creationMethod; }
277   void AddArgMethod(const char* method, const int nbArgs = 1)
278   { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); }
279   const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
280   const std::list<Handle(_pyCommand)>& GetArgCommands() const { return myArgCommands; }
281   void ClearAllCommands();
282   virtual bool IsAlgo() const { return myIsAlgo; }
283   bool IsValid() const { return !myType2CreationMethod.empty(); }
284   bool IsWrapped() const { return myIsWrapped; }
285   const _pyID & GetGeom() const { return myGeom; }
286   void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; }
287   const _pyID & GetMesh() const { return myMesh; }
288   const TCollection_AsciiString& GetAlgoType() const
289   { return myType2CreationMethod.begin()->first; }
290   const TCollection_AsciiString& GetAlgoCreationMethod() const
291   { return myType2CreationMethod.begin()->second; }
292   bool CanBeCreatedBy(const TCollection_AsciiString& algoType ) const
293   { return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); }
294   const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const
295   { return myType2CreationMethod.find( algoType )->second; }
296   bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; }
297   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
298                                   const _pyID&              theMesh);
299   static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd);
300   void Process( const Handle(_pyCommand)& theCommand);
301   void Flush();
302
303   DEFINE_STANDARD_RTTI (_pyHypothesis)
304 };
305
306 // -------------------------------------------------------------------------------------
307 /*!
308  * \brief Class representing smesh.Mesh_Algorithm
309  */
310 // -------------------------------------------------------------------------------------
311 class _pyAlgorithm: public _pyHypothesis
312 {
313 public:
314   _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
315   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
316                                   const _pyID&              theMesh);
317   const char* AccessorMethod() const { return "GetAlgorithm()"; }
318
319   DEFINE_STANDARD_RTTI (_pyAlgorithm)
320 };
321
322 // -------------------------------------------------------------------------------------
323 /*!
324  * \brief Class for hypotheses having several parameters modified by one method
325  */
326 // -------------------------------------------------------------------------------------
327 class _pyComplexParamHypo: public _pyHypothesis
328 {
329 public:
330   _pyComplexParamHypo(const Handle(_pyCommand)& theCreationCmd): _pyHypothesis(theCreationCmd) {}
331   void Process( const Handle(_pyCommand)& theCommand);
332
333   DEFINE_STANDARD_RTTI (_pyComplexParamHypo)
334 };
335 DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis);
336
337 // -------------------------------------------------------------------------------------
338 /*!
339  * \brief Class for LayerDistribution hypothesis conversion
340  */
341 // -------------------------------------------------------------------------------------
342 class _pyLayerDistributionHypo: public _pyHypothesis
343 {
344   Handle(_pyHypothesis) my1dHyp;
345 public:
346   _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd):
347     _pyHypothesis(theCreationCmd) {}
348   void Process( const Handle(_pyCommand)& theCommand);
349   void Flush();
350   bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
351                           const _pyID&              theMesh);
352
353   DEFINE_STANDARD_RTTI (_pyLayerDistributionHypo)
354 };
355 DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
356
357 // -------------------------------------------------------------------------------------
358 /*!
359  * \brief Class representing NumberOfSegments hypothesis
360  */
361 // -------------------------------------------------------------------------------------
362 class _pyNumberOfSegmentsHyp: public _pyHypothesis
363 {
364 public:
365   _pyNumberOfSegmentsHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
366   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
367                                   const _pyID&              theMesh);
368   void Flush();
369
370   DEFINE_STANDARD_RTTI (_pyNumberOfSegmentsHyp)
371 };
372 DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis);
373
374 // -------------------------------------------------------------------------------------
375 /*!
376  * \brief Class representing SegmentLengthAroundVertex hypothesis
377  */
378 // -------------------------------------------------------------------------------------
379 class _pySegmentLengthAroundVertexHyp: public _pyHypothesis
380 {
381 public:
382   _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
383   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
384                                   const _pyID&              theMesh);
385   DEFINE_STANDARD_RTTI (_pySegmentLengthAroundVertexHyp)
386 };
387 DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
388
389 #endif