Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "SMESHDS_SubMesh.hxx"
00030 #include "SMESHDS_Mesh.hxx"
00031
00032 #include "utilities.h"
00033 #include "SMDS_SetIterator.hxx"
00034 #include <iostream>
00035 #include <cassert>
00036
00037 using namespace std;
00038
00039
00040
00044
00045
00046 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
00047 {
00048 myParent = parent;
00049 myElements.clear();
00050 myNodes.clear();
00051 myIndex = index;
00052 myUnusedIdNodes = 0;
00053 myUnusedIdElements = 0;
00054 }
00055
00056
00060
00061
00062 SMESHDS_SubMesh::~SMESHDS_SubMesh()
00063 {
00064 }
00065
00066
00067
00068
00069
00070 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
00071 {
00072 if (!IsComplexSubmesh())
00073 {
00074
00075 int oldShapeId = ME->getshapeId();
00076 if ( oldShapeId > 0 )
00077 {
00078 if (oldShapeId != myIndex)
00079 {
00080 MESSAGE("add element in subshape already belonging to another subshape "
00081 << ME->GetID() << " " << oldShapeId << " " << myIndex);
00082 throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape"));
00083 }
00084 else
00085 {
00086 int idInSubShape = ME->getIdInShape();
00087 if (idInSubShape >= 0)
00088 {
00089 MESSAGE("add element in subshape already belonging to that subshape "
00090 << ME->GetID() << " " << oldShapeId << " " << idInSubShape);
00091
00092 if (idInSubShape >= myElements.size())
00093 {
00094 MESSAGE("out of bounds " << idInSubShape << " " << myElements.size());
00095 throw SALOME_Exception(LOCALIZED("out of bounds"));
00096 }
00097 if (ME != myElements[idInSubShape])
00098 {
00099 MESSAGE("not the same element");
00100 throw SALOME_Exception(LOCALIZED("not the same element"));
00101 }
00102 MESSAGE("already done, OK, nothing to do");
00103 return;
00104 }
00105 }
00106 }
00107
00108 SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
00109 elem->setShapeId(myIndex);
00110 elem->setIdInShape(myElements.size());
00111 myElements.push_back(ME);
00112 }
00113 }
00114
00115
00116
00117
00118
00119 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
00120 {
00121 if (!ME)
00122 {
00123 MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
00124 return false;
00125 }
00126
00127 if (!IsComplexSubmesh())
00128 {
00129 if ( ME->getshapeId() != myIndex )
00130 return false;
00131 int idInSubShape = ME->getIdInShape();
00132
00133 SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
00134 elem->setShapeId(0);
00135 elem->setIdInShape(-1);
00136 if ((idInSubShape >= 0) && (idInSubShape < myElements.size()))
00137 {
00138 myElements[idInSubShape] = 0;
00139 myUnusedIdElements++;
00140 return true;
00141 }
00142 return false;
00143
00144 }
00145 MESSAGE("Try to remove an element from a complex submesh ");
00146 return false;
00147 }
00148
00149
00150
00151
00152
00153 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
00154 {
00155 if ( !IsComplexSubmesh() )
00156 {
00157 int idInSubShape = N->getIdInShape();
00158 int shapeId = N->getshapeId();
00159 if ((shapeId > 0) && (idInSubShape >= 0))
00160 {
00161 MESSAGE("========== AddNode already belonging to other subShape " << N->GetID());
00162
00163
00164 }
00165 SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
00166 node->setShapeId(myIndex);
00167 node->setIdInShape(myNodes.size());
00168 myNodes.push_back(N);
00169
00170 }
00171
00172 }
00173
00174
00175
00176
00177
00178
00179 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
00180 {
00181 if (!IsComplexSubmesh())
00182 {
00183
00184
00185 if ( N->getshapeId() != myIndex )
00186 return false;
00187 int idInSubShape = N->getIdInShape();
00188
00189
00190 SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
00191 node->setShapeId(0);
00192 node->setIdInShape(-1);
00193 if ((idInSubShape >= 0) && (idInSubShape < myNodes.size()))
00194 {
00195 myNodes[idInSubShape] = 0;
00196 myUnusedIdNodes++;
00197 return true;
00198 }
00199 return false;
00200
00201 }
00202 MESSAGE("Try to remove a node from a complex submesh");
00203 return false;
00204 }
00205
00206
00207
00208
00209
00210 int SMESHDS_SubMesh::NbElements() const
00211 {
00212
00213 if ( !IsComplexSubmesh() )
00214 return myElements.size() - myUnusedIdElements;
00215
00216 int nbElems = 0;
00217 set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
00218 for ( ; it != mySubMeshes.end(); it++ )
00219 nbElems += (*it)->NbElements();
00220
00221 return nbElems;
00222 }
00223
00224
00225
00226
00227
00228
00229 int SMESHDS_SubMesh::NbNodes() const
00230 {
00231
00232 if ( !IsComplexSubmesh() )
00233 return myNodes.size() - myUnusedIdNodes;
00234
00235 int nbElems = 0;
00236 set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
00237 for ( ; it != mySubMeshes.end(); it++ )
00238 nbElems += (*it)->NbNodes();
00239
00240 return nbElems;
00241 }
00242
00250 template <class ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
00251 {
00252 protected:
00253 typename TSET::const_iterator _it, _end;
00254 TSET _table;
00255 public:
00256 MySetIterator(const TSET& table)
00257 {
00258 _table = table;
00259 _it = _table.begin();
00260 _end = _table.end();
00261 while ((_it != _end) && (*_it == 0))
00262 _it++;
00263 }
00264
00265 virtual bool more()
00266 {
00267 while ((_it != _end) && (*_it == 0))
00268 _it++;
00269 return (_it != _end);
00270 }
00271
00272 virtual ELEM next()
00273 {
00274 ELEM e = *_it;
00275 _it++;
00276 return e;
00277 }
00278 };
00279
00280
00281
00282
00283
00284 template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
00285 {
00286 public:
00287 MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
00288 : mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false)
00289 {}
00290 bool more()
00291 {
00292 while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd)
00293 {
00294 myElemIt = getElements(*mySubIt);
00295 mySubIt++;
00296 }
00297 myMore = myElemIt.get() && myElemIt->more();
00298 return myMore;
00299 }
00300 VALUE next()
00301 {
00302 VALUE elem = 0;
00303 if ( myMore )
00304 elem = myElemIt->next();
00305 return elem;
00306 }
00307 protected:
00308 virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
00309 getElements(const SMESHDS_SubMesh*) const = 0;
00310
00311 private:
00312 bool myMore;
00313 set<const SMESHDS_SubMesh*>::const_iterator mySubIt, mySubEnd;
00314 boost::shared_ptr< SMDS_Iterator<VALUE> > myElemIt;
00315 };
00316
00317
00318
00319
00320
00321 class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
00322 {
00323 public:
00324 MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
00325 :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
00326 SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
00327 { return theSubMesh->GetElements(); }
00328 };
00329
00330
00331
00332
00333
00334 class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
00335 {
00336 public:
00337 MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
00338 :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
00339 SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
00340 { return theSubMesh->GetNodes(); }
00341 };
00342
00343
00344
00345
00346
00347
00348 SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
00349 {
00350 if ( IsComplexSubmesh() )
00351 return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
00352 return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> >(myElements));
00353 }
00354
00355
00356
00357
00358
00359
00360 SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
00361 {
00362 if ( IsComplexSubmesh() )
00363 return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
00364
00365 return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> >(myNodes));
00366 }
00367
00368
00369
00370
00371
00372
00373 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
00374 {
00375
00376
00377 if (!ME)
00378 return false;
00379
00380 if (IsComplexSubmesh())
00381 {
00382 set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
00383 for (; aSubIt != mySubMeshes.end(); aSubIt++)
00384 if ((*aSubIt)->Contains(ME))
00385 return true;
00386 return false;
00387 }
00388
00389 if (ME->GetType() == SMDSAbs_Node)
00390 {
00391 int idInShape = ME->getIdInShape();
00392 if ((idInShape >= 0) && (idInShape < myNodes.size()))
00393 if (myNodes[idInShape] == ME)
00394 return true;
00395 }
00396 else
00397 {
00398 int idInShape = ME->getIdInShape();
00399 if ((idInShape >= 0) && (idInShape < myElements.size()))
00400 if (myElements[idInShape] == ME)
00401 return true;
00402 }
00403 return false;
00404 }
00405
00406
00407
00408
00409
00410
00411 void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
00412 {
00413 ASSERT( theSubMesh );
00414 mySubMeshes.insert( theSubMesh );
00415 }
00416
00417
00418
00419
00420
00421
00422 bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
00423 {
00424 return mySubMeshes.erase( theSubMesh );
00425 }
00426
00427
00428
00429
00430
00431
00432 void SMESHDS_SubMesh::RemoveAllSubmeshes()
00433 {
00434 mySubMeshes.clear();
00435 }
00436
00437
00438
00439
00440
00441
00442 bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
00443 {
00444 return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
00445 }
00446
00447
00448
00449
00450
00451
00452 SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const
00453 {
00454 typedef set<const SMESHDS_SubMesh*>::const_iterator TIterator;
00455 return SMESHDS_SubMeshIteratorPtr
00456 ( new SMDS_SetIterator< const SMESHDS_SubMesh*, TIterator >( mySubMeshes.begin(),
00457 mySubMeshes.end()));
00458 }
00459
00460
00461
00462
00463
00464
00465 void SMESHDS_SubMesh::Clear()
00466 {
00467 myElements.clear();
00468 myNodes.clear();
00469 myUnusedIdNodes = 0;
00470 myUnusedIdElements = 0;
00471 SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
00472 while ( sub->more() ) {
00473 if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
00474 sm->Clear();
00475 }
00476 }
00477
00478 int SMESHDS_SubMesh::getSize()
00479 {
00480 int c = NbNodes();
00481 int d = NbElements();
00482
00483
00484 return c+d;
00485 }
00486
00487 void SMESHDS_SubMesh::compactList()
00488 {
00489
00490
00491
00492
00493
00494
00495 std::vector<const SMDS_MeshElement*> newElems;
00496 newElems.clear();
00497 for (int i = 0; i < myElements.size(); i++)
00498 if (myElements[i])
00499 {
00500 SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i];
00501 elem->setIdInShape(newElems.size());
00502 newElems.push_back(elem);
00503
00504
00505 }
00506
00507
00508 myElements.swap(newElems);
00509 myUnusedIdElements = 0;
00510
00511
00512
00513 std::vector<const SMDS_MeshNode*> newNodes;
00514 newNodes.clear();
00515 for (int i = 0; i < myNodes.size(); i++)
00516 if (myNodes[i])
00517 {
00518 SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i];
00519 node->setIdInShape(newNodes.size());
00520 newNodes.push_back(node);
00521
00522
00523 }
00524
00525
00526 myNodes.swap(newNodes);
00527 myUnusedIdNodes = 0;
00528
00529
00530
00531 }