Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/smesh.git] / src / SMESHClient / SMESH_Client.cxx
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 //  SMESH SMESHClient : tool to update client mesh structure by mesh from server
23 //  File   : SMESH_Client.cxx
24 //  Author : Pavel TELKOV
25 //  Module : SMESH
26 //
27 #include "SMESH_Client.hxx"
28 #include "SMESH_Mesh.hxx"
29
30 #include "SALOME_NamingService.hxx"
31 #include "SALOME_LifeCycleCORBA.hxx"
32
33 #include <SALOMEconfig.h>
34 #include CORBA_SERVER_HEADER(SALOME_Component)
35 #include CORBA_SERVER_HEADER(SALOME_Exception)
36
37 #include "Basics_Utils.hxx"
38 #include "utilities.h"
39
40 #ifdef WNT
41 #include <process.h>
42 #else
43 #include <unistd.h>
44 #endif
45
46 #include <stdexcept>
47
48 #ifndef EXCEPTION
49 #define EXCEPTION(TYPE, MSG) {\
50   std::ostringstream aStream;\
51   aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
52   throw TYPE(aStream.str());\
53 }
54 #endif
55
56 #ifdef _DEBUG_
57 static int MYDEBUG = 0;
58 #else
59 static int MYDEBUG = 0;
60 #endif
61
62 namespace
63 {
64
65   //=======================================================================
66   //function : FindNode
67   //=======================================================================
68   inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
69     if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
70     EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
71   }
72
73
74   //=======================================================================
75   //function : FindElement
76   //=======================================================================
77   inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
78     if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
79     EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
80   }
81
82
83   //=======================================================================
84   //function : AddNodesWithID
85   //=======================================================================
86   inline void AddNodesWithID(SMDS_Mesh* theMesh, 
87                              SMESH::log_array_var& theSeq,
88                              CORBA::Long theId)
89   {
90     const SMESH::double_array& aCoords = theSeq[theId].coords;
91     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
92     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
93     if(3*aNbElems != aCoords.length())
94       EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
95     for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
96       SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
97                                                         aCoords[aCoordId+1],
98                                                         aCoords[aCoordId+2],
99                                                         anIndexes[anElemId]);
100       if(!anElem)
101         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
102     }
103   }
104
105
106   //=======================================================================
107   //function : AddEdgesWithID
108   //=======================================================================
109   inline void AddEdgesWithID(SMDS_Mesh* theMesh, 
110                              SMESH::log_array_var& theSeq,
111                              CORBA::Long theId)
112   {
113     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
114     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
115     if(3*aNbElems != anIndexes.length())
116       EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
117     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
118       SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
119                                                         anIndexes[anIndexId+2],
120                                                         anIndexes[anIndexId]);
121       if(!anElem)
122         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
123     }
124   }
125
126
127   //=======================================================================
128   //function : AddTriasWithID
129   //=======================================================================
130   inline void AddTriasWithID(SMDS_Mesh* theMesh, 
131                              SMESH::log_array_var& theSeq,
132                              CORBA::Long theId)
133   {
134     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
135     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
136     if(4*aNbElems != anIndexes.length())
137       EXCEPTION(runtime_error,"AddTriasWithID - 4*aNbElems != anIndexes.length()");
138     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
139       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
140                                                         anIndexes[anIndexId+2],
141                                                         anIndexes[anIndexId+3],
142                                                         anIndexes[anIndexId]);
143       if(!anElem)
144         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
145     }
146   }
147
148
149   //=======================================================================
150   //function : AddQuadsWithID
151   //=======================================================================
152   inline void AddQuadsWithID(SMDS_Mesh* theMesh, 
153                              SMESH::log_array_var theSeq,
154                              CORBA::Long theId)
155   {
156     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
157     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
158     if(5*aNbElems != anIndexes.length())
159       EXCEPTION(runtime_error,"AddQuadsWithID - 4*aNbElems != anIndexes.length()");
160     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
161       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
162                                                         anIndexes[anIndexId+2],
163                                                         anIndexes[anIndexId+3],
164                                                         anIndexes[anIndexId+4],
165                                                         anIndexes[anIndexId]);
166       if(!anElem)
167         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
168     }
169   }
170
171
172   //=======================================================================
173   //function : AddPolygonsWithID
174   //=======================================================================
175   inline void AddPolygonsWithID(SMDS_Mesh* theMesh, 
176                                 SMESH::log_array_var& theSeq,
177                                 CORBA::Long theId)
178   {
179     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
180     CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
181
182     for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
183       int aFaceId = anIndexes[anIndexId++];
184
185       int aNbNodes = anIndexes[anIndexId++];
186       std::vector<int> nodes_ids (aNbNodes);
187       for (int i = 0; i < aNbNodes; i++) {
188         nodes_ids[i] = anIndexes[anIndexId++];
189       }
190
191       SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId);
192       if (!anElem)
193         EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = "
194                   << anElemId);
195     }
196   }
197
198
199   //=======================================================================
200   //function : AddTetrasWithID
201   //=======================================================================
202   inline void AddTetrasWithID(SMDS_Mesh* theMesh, 
203                               SMESH::log_array_var& theSeq,
204                               CORBA::Long theId)
205   {
206     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
207     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
208     if(5*aNbElems != anIndexes.length())
209       EXCEPTION(runtime_error,"AddTetrasWithID - 5*aNbElems != anIndexes.length()");
210     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
211       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
212                                                           anIndexes[anIndexId+2],
213                                                           anIndexes[anIndexId+3],
214                                                           anIndexes[anIndexId+4],
215                                                           anIndexes[anIndexId]);
216       if(!anElem)
217         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
218     }
219   }
220
221
222   //=======================================================================
223   //function : AddPiramidsWithID
224   //=======================================================================
225   inline void AddPiramidsWithID(SMDS_Mesh* theMesh, 
226                                 SMESH::log_array_var& theSeq,
227                                 CORBA::Long theId)
228   {
229     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
230     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
231     if(6*aNbElems != anIndexes.length())
232       EXCEPTION(runtime_error,"AddPiramidsWithID - 6*aNbElems != anIndexes.length()");
233     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
234       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
235                                                           anIndexes[anIndexId+2],
236                                                           anIndexes[anIndexId+3],
237                                                           anIndexes[anIndexId+4],
238                                                           anIndexes[anIndexId+5],
239                                                           anIndexes[anIndexId]);
240       if(!anElem)
241         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
242     }
243   }
244
245
246   //=======================================================================
247   //function : AddPrismsWithID
248   //=======================================================================
249   inline void AddPrismsWithID(SMDS_Mesh* theMesh, 
250                               SMESH::log_array_var& theSeq,
251                               CORBA::Long theId)
252   {
253     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
254     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
255     if(7*aNbElems != anIndexes.length())
256       EXCEPTION(runtime_error,"AddPrismsWithID - 7*aNbElems != anIndexes.length()");
257     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
258       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
259                                                           anIndexes[anIndexId+2],
260                                                           anIndexes[anIndexId+3],
261                                                           anIndexes[anIndexId+4],
262                                                           anIndexes[anIndexId+5],
263                                                           anIndexes[anIndexId+6],
264                                                           anIndexes[anIndexId]);
265       if(!anElem)
266         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
267     }
268   }
269
270
271   //=======================================================================
272   //function : AddHexasWithID
273   //=======================================================================
274   inline void AddHexasWithID(SMDS_Mesh* theMesh, 
275                              SMESH::log_array_var& theSeq,
276                              CORBA::Long theId)
277   {
278     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
279     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
280     if(9*aNbElems != anIndexes.length())
281       EXCEPTION(runtime_error,"AddHexasWithID - 9*aNbElems != anIndexes.length()");
282     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
283       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
284                                                           anIndexes[anIndexId+2],
285                                                           anIndexes[anIndexId+3],
286                                                           anIndexes[anIndexId+4],
287                                                           anIndexes[anIndexId+5],
288                                                           anIndexes[anIndexId+6],
289                                                           anIndexes[anIndexId+7],
290                                                           anIndexes[anIndexId+8],
291                                                           anIndexes[anIndexId]);
292       if(!anElem)
293         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
294     }
295   }
296
297
298   //=======================================================================
299   //function : AddPolyhedronsWithID
300   //=======================================================================
301   inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh, 
302                                     SMESH::log_array_var& theSeq,
303                                     CORBA::Long theId)
304   {
305     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
306     CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
307
308     for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
309       int aFaceId = anIndexes[anIndexId++];
310
311       int aNbNodes = anIndexes[anIndexId++];
312       std::vector<int> nodes_ids (aNbNodes);
313       for (int i = 0; i < aNbNodes; i++) {
314         nodes_ids[i] = anIndexes[anIndexId++];
315       }
316
317       int aNbFaces = anIndexes[anIndexId++];
318       std::vector<int> quantities (aNbFaces);
319       for (int i = 0; i < aNbFaces; i++) {
320         quantities[i] = anIndexes[anIndexId++];
321       }
322
323       SMDS_MeshElement* anElem =
324         theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId);
325       if (!anElem)
326         EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
327                   << anElemId);
328     }
329   }
330
331
332   //=======================================================================
333   //function : AddQuadEdgesWithID
334   //=======================================================================
335   inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh, 
336                                  SMESH::log_array_var& theSeq,
337                                  CORBA::Long theId)
338   {
339     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
340     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
341     if(4*aNbElems != anIndexes.length())
342       EXCEPTION(runtime_error,"AddQuadEdgeWithID - 4*aNbElems != aCoords.length()");
343     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
344       SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
345                                                         anIndexes[anIndexId+2],
346                                                         anIndexes[anIndexId+3],
347                                                         anIndexes[anIndexId]);
348       if(!anElem)
349         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
350     }
351   }
352
353
354   //=======================================================================
355   //function : AddQuadTriasWithID
356   //=======================================================================
357   inline void AddQuadTriasWithID(SMDS_Mesh* theMesh, 
358                                  SMESH::log_array_var& theSeq,
359                                  CORBA::Long theId)
360   {
361     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
362     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
363     if(7*aNbElems != anIndexes.length())
364       EXCEPTION(runtime_error,"AddQuadTriasWithID - 7*aNbElems != anIndexes.length()");
365     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
366       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
367                                                         anIndexes[anIndexId+2],
368                                                         anIndexes[anIndexId+3],
369                                                         anIndexes[anIndexId+4],
370                                                         anIndexes[anIndexId+5],
371                                                         anIndexes[anIndexId+6],
372                                                         anIndexes[anIndexId]);
373       if(!anElem)
374         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
375     }
376   }
377
378
379   //=======================================================================
380   //function : AddQuadQuadsWithID
381   //=======================================================================
382   inline void AddQuadQuadsWithID(SMDS_Mesh* theMesh, 
383                                  SMESH::log_array_var theSeq,
384                                  CORBA::Long theId)
385   {
386     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
387     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
388     if(9*aNbElems != anIndexes.length())
389       EXCEPTION(runtime_error,"AddQuadQuadsWithID - 9*aNbElems != anIndexes.length()");
390     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
391       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
392                                                         anIndexes[anIndexId+2],
393                                                         anIndexes[anIndexId+3],
394                                                         anIndexes[anIndexId+4],
395                                                         anIndexes[anIndexId+5],
396                                                         anIndexes[anIndexId+6],
397                                                         anIndexes[anIndexId+7],
398                                                         anIndexes[anIndexId+8],
399                                                         anIndexes[anIndexId]);
400       if(!anElem)
401         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
402     }
403   }
404
405
406   //=======================================================================
407   //function : AddQuadTetrasWithID
408   //=======================================================================
409   inline void AddQuadTetrasWithID(SMDS_Mesh* theMesh, 
410                                   SMESH::log_array_var& theSeq,
411                                   CORBA::Long theId)
412   {
413     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
414     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
415     if(11*aNbElems != anIndexes.length())
416       EXCEPTION(runtime_error,"AddQuadTetrasWithID - 11*aNbElems != anIndexes.length()");
417     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=11){
418       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
419                                                           anIndexes[anIndexId+2],
420                                                           anIndexes[anIndexId+3],
421                                                           anIndexes[anIndexId+4],
422                                                           anIndexes[anIndexId+5],
423                                                           anIndexes[anIndexId+6],
424                                                           anIndexes[anIndexId+7],
425                                                           anIndexes[anIndexId+8],
426                                                           anIndexes[anIndexId+9],
427                                                           anIndexes[anIndexId+10],
428                                                           anIndexes[anIndexId]);
429       if(!anElem)
430         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
431     }
432   }
433
434
435   //=======================================================================
436   //function : AddQuadPiramidsWithID
437   //=======================================================================
438   inline void AddQuadPiramidsWithID(SMDS_Mesh* theMesh, 
439                                     SMESH::log_array_var& theSeq,
440                                     CORBA::Long theId)
441   {
442     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
443     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
444     if(14*aNbElems != anIndexes.length())
445       EXCEPTION(runtime_error,"AddQuadPiramidsWithID - 14*aNbElems != anIndexes.length()");
446     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=14){
447       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
448                                                           anIndexes[anIndexId+2],
449                                                           anIndexes[anIndexId+3],
450                                                           anIndexes[anIndexId+4],
451                                                           anIndexes[anIndexId+5],
452                                                           anIndexes[anIndexId+6],
453                                                           anIndexes[anIndexId+7],
454                                                           anIndexes[anIndexId+8],
455                                                           anIndexes[anIndexId+9],
456                                                           anIndexes[anIndexId+10],
457                                                           anIndexes[anIndexId+11],
458                                                           anIndexes[anIndexId+12],
459                                                           anIndexes[anIndexId+13],
460                                                           anIndexes[anIndexId]);
461       if(!anElem)
462         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
463     }
464   }
465
466
467   //=======================================================================
468   //function : AddQuadPentasWithID
469   //=======================================================================
470   inline void AddQuadPentasWithID(SMDS_Mesh* theMesh, 
471                                   SMESH::log_array_var& theSeq,
472                                   CORBA::Long theId)
473   {
474     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
475     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
476     if(16*aNbElems != anIndexes.length())
477       EXCEPTION(runtime_error,"AddQuadPentasWithID - 16*aNbElems != anIndexes.length()");
478     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=16){
479       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
480                                                           anIndexes[anIndexId+2],
481                                                           anIndexes[anIndexId+3],
482                                                           anIndexes[anIndexId+4],
483                                                           anIndexes[anIndexId+5],
484                                                           anIndexes[anIndexId+6],
485                                                           anIndexes[anIndexId+7],
486                                                           anIndexes[anIndexId+8],
487                                                           anIndexes[anIndexId+9],
488                                                           anIndexes[anIndexId+10],
489                                                           anIndexes[anIndexId+11],
490                                                           anIndexes[anIndexId+12],
491                                                           anIndexes[anIndexId+13],
492                                                           anIndexes[anIndexId+14],
493                                                           anIndexes[anIndexId+15],
494                                                           anIndexes[anIndexId]);
495       if(!anElem)
496         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
497     }
498   }
499
500
501   //=======================================================================
502   //function : AddQuadHexasWithID
503   //=======================================================================
504   inline void AddQuadHexasWithID(SMDS_Mesh* theMesh, 
505                                  SMESH::log_array_var& theSeq,
506                                  CORBA::Long theId)
507   {
508     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
509     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
510     if(21*aNbElems != anIndexes.length())
511       EXCEPTION(runtime_error,"AddQuadHexasWithID - 21*aNbElems != anIndexes.length()");
512     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=21){
513       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
514                                                           anIndexes[anIndexId+2],
515                                                           anIndexes[anIndexId+3],
516                                                           anIndexes[anIndexId+4],
517                                                           anIndexes[anIndexId+5],
518                                                           anIndexes[anIndexId+6],
519                                                           anIndexes[anIndexId+7],
520                                                           anIndexes[anIndexId+8],
521                                                           anIndexes[anIndexId+9],
522                                                           anIndexes[anIndexId+10],
523                                                           anIndexes[anIndexId+11],
524                                                           anIndexes[anIndexId+12],
525                                                           anIndexes[anIndexId+13],
526                                                           anIndexes[anIndexId+14],
527                                                           anIndexes[anIndexId+15],
528                                                           anIndexes[anIndexId+16],
529                                                           anIndexes[anIndexId+17],
530                                                           anIndexes[anIndexId+18],
531                                                           anIndexes[anIndexId+19],
532                                                           anIndexes[anIndexId+20],
533                                                           anIndexes[anIndexId]);
534       if(!anElem)
535         EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
536     }
537   }
538
539
540   //=======================================================================
541   //function : ChangePolyhedronNodes
542   //=======================================================================
543   inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh, 
544                                      SMESH::log_array_var& theSeq,
545                                      CORBA::Long theId)
546   {
547     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
548     CORBA::Long iind = 0, aNbElems = theSeq[theId].number;
549
550     for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++)
551     {
552       // find element
553       const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]);
554       // nb nodes
555       int nbNodes = anIndexes[iind++];
556       // nodes
557       std::vector<const SMDS_MeshNode*> aNodes (nbNodes);
558       for (int iNode = 0; iNode < nbNodes; iNode++) {
559         aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]);
560       }
561       // nb faces
562       int nbFaces = anIndexes[iind++];
563       // quantities
564       std::vector<int> quantities (nbFaces);
565       for (int iFace = 0; iFace < nbFaces; iFace++) {
566         quantities[iFace] = anIndexes[iind++];
567       }
568       // change
569       theMesh->ChangePolyhedronNodes(elem, aNodes, quantities);
570     }
571   }
572 }
573
574 //=======================================================================
575 SMESH::SMESH_Gen_var 
576 SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB,
577                           CORBA::Boolean& theIsEmbeddedMode)
578 {
579   static SMESH::SMESH_Gen_var aMeshGen;
580
581   if(CORBA::is_nil(aMeshGen.in())){    
582 #ifdef WNT
583     long aClientPID = (long)_getpid();
584 #else
585     long aClientPID =  (long)getpid();
586 #endif
587
588     SALOME_NamingService aNamingService(theORB);
589     SALOME_LifeCycleCORBA aLifeCycleCORBA(&aNamingService);
590     Engines::Component_var aComponent = aLifeCycleCORBA.FindOrLoad_Component("FactoryServer","SMESH");
591     aMeshGen = SMESH::SMESH_Gen::_narrow(aComponent);
592     
593     std::string aClientHostName = Kernel_Utils::GetHostname();
594     Engines::Container_var aServerContainer = aMeshGen->GetContainerRef();
595     CORBA::String_var aServerHostName = aServerContainer->getHostName();
596     CORBA::Long aServerPID = aServerContainer->getPID();
597     aMeshGen->SetEmbeddedMode((aClientPID == aServerPID) && (aClientHostName == aServerHostName.in()));
598   }
599   theIsEmbeddedMode = aMeshGen->IsEmbeddedMode();
600
601   return aMeshGen;
602 }
603
604
605 //=======================================================================
606 // function : Create()
607 // purpose  : 
608 //=======================================================================
609 SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
610                            SMESH::SMESH_Mesh_ptr theMesh):
611   myMeshServer(SMESH::SMESH_Mesh::_duplicate(theMesh)),
612   mySMESHDSMesh(NULL),
613   mySMDSMesh(NULL)
614 {
615   myMeshServer->Register();
616
617   CORBA::Boolean anIsEmbeddedMode;
618   GetSMESHGen(theORB,anIsEmbeddedMode);
619   if(anIsEmbeddedMode){
620     if ( MYDEBUG )
621       MESSAGE("Info: The same process, update mesh by pointer ");
622     // just set client mesh pointer to server mesh pointer
623     //SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
624     CORBA::LongLong pointeur = theMesh->GetMeshPtr();
625     if( MYDEBUG )
626       MESSAGE("SMESH_Client::SMESH_Client pointeur "<<pointeur);
627     SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
628     if ( MYDEBUG )
629       MESSAGE("SMESH_Client::SMESH_Client aMesh "<<aMesh);
630     if(aMesh->GetMeshDS()->IsEmbeddedMode()){
631       mySMESHDSMesh = aMesh->GetMeshDS();
632       mySMDSMesh = mySMESHDSMesh;
633     }
634   }
635   if(!mySMDSMesh)
636     mySMDSMesh = new SMDS_Mesh();
637 }
638
639
640 //=================================================================================
641 // function : ~SMESH_Client
642 // purpose  : Destructor
643 //=================================================================================
644 SMESH_Client::~SMESH_Client()
645 {
646   myMeshServer->Destroy();
647   if(!mySMESHDSMesh)
648     delete mySMDSMesh;
649 }
650
651
652 //=================================================================================
653 SMDS_Mesh* 
654 SMESH_Client::GetMesh() const 
655 {
656   return mySMDSMesh; 
657 }
658
659
660 //=================================================================================
661 SMDS_Mesh*
662 SMESH_Client::operator->() const
663 {
664   return GetMesh();
665 }
666
667
668 //=================================================================================
669 SMESH::SMESH_Mesh_ptr
670 SMESH_Client::GetMeshServer()
671 {
672   return myMeshServer.in(); 
673 }
674
675
676 //=================================================================================
677 // function : SMESH_Client
678 // purpose  : Update mesh
679 //=================================================================================
680 bool
681 SMESH_Client::Update(bool theIsClear)
682 {
683   bool anIsModified = true;
684   if(mySMESHDSMesh){
685     SMESHDS_Script* aScript = mySMESHDSMesh->GetScript();
686     anIsModified = aScript->IsModified();
687     aScript->SetModified(false);
688   }else{
689     SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
690     CORBA::Long aLength = aSeq->length();
691     anIsModified = aLength > 0;
692     if( MYDEBUG )
693       MESSAGE( "Update: length of the script is "<<aLength );
694   
695     if(!anIsModified)
696       return false;
697
698     // update client mesh structure by logged changes commands
699     try
700     {
701       for ( CORBA::Long anId = 0; anId < aLength; anId++)
702       {
703         const SMESH::double_array& aCoords = aSeq[anId].coords;
704         const SMESH::long_array& anIndexes = aSeq[anId].indexes;
705         CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
706         CORBA::Long aCommand = aSeq[anId].commandType;
707
708         switch(aCommand)
709         {
710         case SMESH::ADD_NODE       : AddNodesWithID      ( mySMDSMesh, aSeq, anId ); break;
711         case SMESH::ADD_EDGE       : AddEdgesWithID      ( mySMDSMesh, aSeq, anId ); break;
712         case SMESH::ADD_TRIANGLE   : AddTriasWithID      ( mySMDSMesh, aSeq, anId ); break;
713         case SMESH::ADD_QUADRANGLE : AddQuadsWithID      ( mySMDSMesh, aSeq, anId ); break;
714         case SMESH::ADD_POLYGON    : AddPolygonsWithID   ( mySMDSMesh, aSeq, anId ); break;
715         case SMESH::ADD_TETRAHEDRON: AddTetrasWithID     ( mySMDSMesh, aSeq, anId ); break;
716         case SMESH::ADD_PYRAMID    : AddPiramidsWithID   ( mySMDSMesh, aSeq, anId ); break;
717         case SMESH::ADD_PRISM      : AddPrismsWithID     ( mySMDSMesh, aSeq, anId ); break;
718         case SMESH::ADD_HEXAHEDRON : AddHexasWithID      ( mySMDSMesh, aSeq, anId ); break;
719         case SMESH::ADD_POLYHEDRON : AddPolyhedronsWithID( mySMDSMesh, aSeq, anId ); break;
720
721         case SMESH::ADD_QUADEDGE       : AddQuadEdgesWithID   ( mySMDSMesh, aSeq, anId ); break;
722         case SMESH::ADD_QUADTRIANGLE   : AddQuadTriasWithID   ( mySMDSMesh, aSeq, anId ); break;
723         case SMESH::ADD_QUADQUADRANGLE : AddQuadQuadsWithID   ( mySMDSMesh, aSeq, anId ); break;
724         case SMESH::ADD_QUADTETRAHEDRON: AddQuadTetrasWithID  ( mySMDSMesh, aSeq, anId ); break;
725         case SMESH::ADD_QUADPYRAMID    : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break;
726         case SMESH::ADD_QUADPENTAHEDRON: AddQuadPentasWithID  ( mySMDSMesh, aSeq, anId ); break;
727         case SMESH::ADD_QUADHEXAHEDRON : AddQuadHexasWithID   ( mySMDSMesh, aSeq, anId ); break;
728
729         case SMESH::CLEAR_MESH:
730           mySMDSMesh->Clear();
731           break;
732
733         case SMESH::REMOVE_NODE:
734           for( ; anElemId < aNbElems; anElemId++ )
735             mySMDSMesh->RemoveNode( FindNode( mySMDSMesh, anIndexes[anElemId] ) );
736         break;
737         
738         case SMESH::REMOVE_ELEMENT:
739           for( ; anElemId < aNbElems; anElemId++ )
740             mySMDSMesh->RemoveElement( FindElement( mySMDSMesh, anIndexes[anElemId] ) );
741         break;
742
743         case SMESH::MOVE_NODE:
744           for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
745           {
746             SMDS_MeshNode* node =
747               const_cast<SMDS_MeshNode*>( FindNode( mySMDSMesh, anIndexes[anElemId] ));
748             node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
749           }
750         break;
751
752         case SMESH::CHANGE_ELEMENT_NODES:
753           for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
754           {
755             // find element
756             const SMDS_MeshElement* elem = FindElement( mySMDSMesh, anIndexes[i++] );
757             // nb nodes
758             int nbNodes = anIndexes[i++];
759             // nodes
760             //ASSERT( nbNodes < 9 );
761             vector<const SMDS_MeshNode*> aNodes( nbNodes );
762             for ( int iNode = 0; iNode < nbNodes; iNode++ )
763               aNodes[ iNode ] = FindNode( mySMDSMesh, anIndexes[i++] );
764             // change
765             mySMDSMesh->ChangeElementNodes( elem, &aNodes[0], nbNodes );
766           }
767           break;
768
769         case SMESH::CHANGE_POLYHEDRON_NODES:
770           ChangePolyhedronNodes(mySMDSMesh, aSeq, anId);
771           break;
772         case SMESH::RENUMBER:
773           for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
774           {
775             mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
776           }
777           break;
778           
779         default:;
780         }
781       }
782     }
783     catch ( SALOME::SALOME_Exception& exc )
784     {
785       INFOS("Following exception was cought:\n\t"<<exc.details.text);
786     }
787     catch( const std::exception& exc)
788     {
789       INFOS("Following exception was cought:\n\t"<<exc.what());
790     }
791     catch(...)
792     {
793       INFOS("Unknown exception was cought !!!");
794     }
795
796     if ( MYDEBUG && mySMDSMesh )
797     {
798       MESSAGE("Update - mySMDSMesh->NbNodes() = "<<mySMDSMesh->NbNodes());
799       MESSAGE("Update - mySMDSMesh->NbEdges() = "<<mySMDSMesh->NbEdges());
800       MESSAGE("Update - mySMDSMesh->NbFaces() = "<<mySMDSMesh->NbFaces());
801       MESSAGE("Update - mySMDSMesh->NbVolumes() = "<<mySMDSMesh->NbVolumes());
802     }
803   } // end of update mesh by log script
804   
805   return anIsModified;
806 }