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