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