1 // SMESH SMESHClient : tool to update client mesh structure by mesh from server
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESH_Client.cxx
25 // Author : Pavel TELKOV
28 #include "SMESH_Client.hxx"
29 #include "SMESH_Mesh.hxx"
31 #include "SALOME_NamingService.hxx"
32 #include "SALOME_LifeCycleCORBA.hxx"
34 #include <SALOMEconfig.h>
35 #include CORBA_SERVER_HEADER(SALOME_Component)
36 #include CORBA_SERVER_HEADER(SALOME_Exception)
39 #include "utilities.h"
50 #define EXCEPTION(TYPE, MSG) {\
51 std::ostringstream aStream;\
52 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
53 throw TYPE(aStream.str());\
58 static int MYDEBUG = 0;
60 static int MYDEBUG = 0;
66 inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
67 if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
68 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
72 inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
73 if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
74 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
78 inline void AddNodesWithID(SMDS_Mesh* theMesh,
79 SMESH::log_array_var& theSeq,
82 const SMESH::double_array& aCoords = theSeq[theId].coords;
83 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
84 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
85 if(3*aNbElems != aCoords.length())
86 EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
87 for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
88 SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
93 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
98 inline void AddEdgesWithID(SMDS_Mesh* theMesh,
99 SMESH::log_array_var& theSeq,
102 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
103 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
104 if(3*aNbElems != anIndexes.length())
105 EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
106 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
107 SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
108 anIndexes[anIndexId+2],
109 anIndexes[anIndexId]);
111 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
116 inline void AddTriasWithID(SMDS_Mesh* theMesh,
117 SMESH::log_array_var& theSeq,
120 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
121 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
122 if(4*aNbElems != anIndexes.length())
123 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
124 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
125 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
126 anIndexes[anIndexId+2],
127 anIndexes[anIndexId+3],
128 anIndexes[anIndexId]);
130 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
135 inline void AddQuadsWithID(SMDS_Mesh* theMesh,
136 SMESH::log_array_var theSeq,
139 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
140 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
141 if(5*aNbElems != anIndexes.length())
142 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
143 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
144 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
145 anIndexes[anIndexId+2],
146 anIndexes[anIndexId+3],
147 anIndexes[anIndexId+4],
148 anIndexes[anIndexId]);
150 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
155 inline void AddPolygonsWithID(SMDS_Mesh* theMesh,
156 SMESH::log_array_var& theSeq,
159 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
160 CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
162 for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
163 int aFaceId = anIndexes[anIndexId++];
165 int aNbNodes = anIndexes[anIndexId++];
166 std::vector<int> nodes_ids (aNbNodes);
167 for (int i = 0; i < aNbNodes; i++) {
168 nodes_ids[i] = anIndexes[anIndexId++];
171 SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId);
173 EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = "
179 inline void AddTetrasWithID(SMDS_Mesh* theMesh,
180 SMESH::log_array_var& theSeq,
183 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
184 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
185 if(5*aNbElems != anIndexes.length())
186 EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
187 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
188 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
189 anIndexes[anIndexId+2],
190 anIndexes[anIndexId+3],
191 anIndexes[anIndexId+4],
192 anIndexes[anIndexId]);
194 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
199 inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
200 SMESH::log_array_var& theSeq,
203 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
204 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
205 if(6*aNbElems != anIndexes.length())
206 EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
207 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
208 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
209 anIndexes[anIndexId+2],
210 anIndexes[anIndexId+3],
211 anIndexes[anIndexId+4],
212 anIndexes[anIndexId+5],
213 anIndexes[anIndexId]);
215 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
220 inline void AddPrismsWithID(SMDS_Mesh* theMesh,
221 SMESH::log_array_var& theSeq,
224 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
225 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
226 if(7*aNbElems != anIndexes.length())
227 EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
228 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
229 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
230 anIndexes[anIndexId+2],
231 anIndexes[anIndexId+3],
232 anIndexes[anIndexId+4],
233 anIndexes[anIndexId+5],
234 anIndexes[anIndexId+6],
235 anIndexes[anIndexId]);
237 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
242 inline void AddHexasWithID(SMDS_Mesh* theMesh,
243 SMESH::log_array_var& theSeq,
246 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
247 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
248 if(9*aNbElems != anIndexes.length())
249 EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
250 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
251 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
252 anIndexes[anIndexId+2],
253 anIndexes[anIndexId+3],
254 anIndexes[anIndexId+4],
255 anIndexes[anIndexId+5],
256 anIndexes[anIndexId+6],
257 anIndexes[anIndexId+7],
258 anIndexes[anIndexId+8],
259 anIndexes[anIndexId]);
261 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
266 inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh,
267 SMESH::log_array_var& theSeq,
270 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
271 CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
273 for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
274 int aFaceId = anIndexes[anIndexId++];
276 int aNbNodes = anIndexes[anIndexId++];
277 std::vector<int> nodes_ids (aNbNodes);
278 for (int i = 0; i < aNbNodes; i++) {
279 nodes_ids[i] = anIndexes[anIndexId++];
282 int aNbFaces = anIndexes[anIndexId++];
283 std::vector<int> quantities (aNbFaces);
284 for (int i = 0; i < aNbFaces; i++) {
285 quantities[i] = anIndexes[anIndexId++];
288 SMDS_MeshElement* anElem =
289 theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId);
291 EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
297 inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh,
298 SMESH::log_array_var& theSeq,
301 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
302 CORBA::Long iind = 0, aNbElems = theSeq[theId].number;
304 for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++)
307 const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]);
309 int nbNodes = anIndexes[iind++];
311 std::vector<const SMDS_MeshNode*> aNodes (nbNodes);
312 for (int iNode = 0; iNode < nbNodes; iNode++) {
313 aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]);
316 int nbFaces = anIndexes[iind++];
318 std::vector<int> quantities (nbFaces);
319 for (int iFace = 0; iFace < nbFaces; iFace++) {
320 quantities[iFace] = anIndexes[iind++];
323 theMesh->ChangePolyhedronNodes(elem, aNodes, quantities);
328 //=======================================================================
330 SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB,
331 CORBA::Boolean& theIsEmbeddedMode)
333 static SMESH::SMESH_Gen_var aMeshGen;
335 if(CORBA::is_nil(aMeshGen.in())){
337 long aClientPID = (long)_getpid();
339 long aClientPID = (long)getpid();
342 SALOME_NamingService aNamingService(theORB);
343 SALOME_LifeCycleCORBA aLifeCycleCORBA(&aNamingService);
344 Engines::Component_var aComponent = aLifeCycleCORBA.FindOrLoad_Component("FactoryServer","SMESH");
345 aMeshGen = SMESH::SMESH_Gen::_narrow(aComponent);
347 std::string aClientHostName = GetHostname();
348 Engines::Container_var aServerContainer = aMeshGen->GetContainerRef();
349 CORBA::String_var aServerHostName = aServerContainer->getHostName();
350 CORBA::Long aServerPID = aServerContainer->getPID();
351 aMeshGen->SetEmbeddedMode((aClientPID == aServerPID) && (aClientHostName == aServerHostName.in()));
353 theIsEmbeddedMode = aMeshGen->IsEmbeddedMode();
359 //=======================================================================
360 // function : Create()
362 //=======================================================================
363 SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
364 SMESH::SMESH_Mesh_ptr theMesh):
365 myMeshServer(SMESH::SMESH_Mesh::_duplicate(theMesh)),
369 myMeshServer->Register();
371 CORBA::Boolean anIsEmbeddedMode;
372 GetSMESHGen(theORB,anIsEmbeddedMode);
373 if(anIsEmbeddedMode){
375 MESSAGE("Info: The same process, update mesh by pointer ");
376 // just set client mesh pointer to server mesh pointer
377 SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
378 if(aMesh->GetMeshDS()->IsEmbeddedMode()){
379 mySMESHDSMesh = aMesh->GetMeshDS();
380 mySMDSMesh = mySMESHDSMesh;
384 mySMDSMesh = new SMDS_Mesh();
388 //=================================================================================
389 // function : ~SMESH_Client
390 // purpose : Destructor
391 //=================================================================================
392 SMESH_Client::~SMESH_Client()
394 myMeshServer->Destroy();
400 //=================================================================================
402 SMESH_Client::GetMesh() const
408 //=================================================================================
410 SMESH_Client::operator->() const
416 //=================================================================================
417 SMESH::SMESH_Mesh_ptr
418 SMESH_Client::GetMeshServer()
420 return myMeshServer.in();
424 //=================================================================================
425 // function : SMESH_Client
426 // purpose : Update mesh
427 //=================================================================================
429 SMESH_Client::Update(bool theIsClear)
431 bool anIsModified = true;
433 SMESHDS_Script* aScript = mySMESHDSMesh->GetScript();
434 anIsModified = aScript->IsModified();
435 aScript->SetModified(false);
437 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
438 CORBA::Long aLength = aSeq->length();
439 anIsModified = aLength > 0;
441 MESSAGE( "Update: length of the script is "<<aLength );
446 // update client mesh structure by logged changes commands
449 for ( CORBA::Long anId = 0; anId < aLength; anId++)
451 const SMESH::double_array& aCoords = aSeq[anId].coords;
452 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
453 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
454 CORBA::Long aCommand = aSeq[anId].commandType;
458 case SMESH::ADD_NODE : AddNodesWithID ( mySMDSMesh, aSeq, anId ); break;
459 case SMESH::ADD_EDGE : AddEdgesWithID ( mySMDSMesh, aSeq, anId ); break;
460 case SMESH::ADD_TRIANGLE : AddTriasWithID ( mySMDSMesh, aSeq, anId ); break;
461 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( mySMDSMesh, aSeq, anId ); break;
462 case SMESH::ADD_POLYGON : AddPolygonsWithID ( mySMDSMesh, aSeq, anId ); break;
463 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( mySMDSMesh, aSeq, anId ); break;
464 case SMESH::ADD_PYRAMID : AddPiramidsWithID ( mySMDSMesh, aSeq, anId ); break;
465 case SMESH::ADD_PRISM : AddPrismsWithID ( mySMDSMesh, aSeq, anId ); break;
466 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( mySMDSMesh, aSeq, anId ); break;
467 case SMESH::ADD_POLYHEDRON : AddPolyhedronsWithID( mySMDSMesh, aSeq, anId ); break;
469 case SMESH::REMOVE_NODE:
470 for( ; anElemId < aNbElems; anElemId++ )
471 mySMDSMesh->RemoveNode( FindNode( mySMDSMesh, anIndexes[anElemId] ) );
474 case SMESH::REMOVE_ELEMENT:
475 for( ; anElemId < aNbElems; anElemId++ )
476 mySMDSMesh->RemoveElement( FindElement( mySMDSMesh, anIndexes[anElemId] ) );
479 case SMESH::MOVE_NODE:
480 for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
482 SMDS_MeshNode* node =
483 const_cast<SMDS_MeshNode*>( FindNode( mySMDSMesh, anIndexes[anElemId] ));
484 node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
488 case SMESH::CHANGE_ELEMENT_NODES:
489 for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
492 const SMDS_MeshElement* elem = FindElement( mySMDSMesh, anIndexes[i++] );
494 int nbNodes = anIndexes[i++];
496 //ASSERT( nbNodes < 9 );
497 const SMDS_MeshNode* aNodes[ nbNodes ];
498 for ( int iNode = 0; iNode < nbNodes; iNode++ )
499 aNodes[ iNode ] = FindNode( mySMDSMesh, anIndexes[i++] );
501 mySMDSMesh->ChangeElementNodes( elem, aNodes, nbNodes );
505 case SMESH::CHANGE_POLYHEDRON_NODES:
506 ChangePolyhedronNodes(mySMDSMesh, aSeq, anId);
508 case SMESH::RENUMBER:
509 for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
511 mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
519 catch ( SALOME::SALOME_Exception& exc )
521 INFOS("Following exception was cought:\n\t"<<exc.details.text);
523 catch( const std::exception& exc)
525 INFOS("Following exception was cought:\n\t"<<exc.what());
529 INFOS("Unknown exception was cought !!!");
532 if ( MYDEBUG && mySMDSMesh )
534 MESSAGE("Update - mySMDSMesh->NbNodes() = "<<mySMDSMesh->NbNodes());
535 MESSAGE("Update - mySMDSMesh->NbEdges() = "<<mySMDSMesh->NbEdges());
536 MESSAGE("Update - mySMDSMesh->NbFaces() = "<<mySMDSMesh->NbFaces());
537 MESSAGE("Update - mySMDSMesh->NbVolumes() = "<<mySMDSMesh->NbVolumes());
539 } // end of update mesh by log script