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