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