1 // SMESH SMDS : implementaion of Salome mesh data structure
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
22 #include "utilities.h"
23 #include "SMDS_Mesh.hxx"
24 #include "SMDS_VolumeOfNodes.hxx"
25 #include "SMDS_VolumeOfFaces.hxx"
26 #include "SMDS_FaceOfNodes.hxx"
27 #include "SMDS_FaceOfEdges.hxx"
29 ///////////////////////////////////////////////////////////////////////////////
30 /// Create a new mesh object
31 ///////////////////////////////////////////////////////////////////////////////
32 SMDS_Mesh::SMDS_Mesh()
33 :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
34 myElementIDFactory(new SMDS_MeshElementIDFactory()),
35 myHasConstructionEdges(false), myHasConstructionFaces(false),
36 myHasInverseElements(true)
40 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
43 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
44 myElementIDFactory(parent->myElementIDFactory),
45 myHasConstructionEdges(false), myHasConstructionFaces(false),
46 myHasInverseElements(true)
50 ///////////////////////////////////////////////////////////////////////////////
51 ///Create a submesh and add it to the current mesh
52 ///////////////////////////////////////////////////////////////////////////////
54 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
56 SMDS_Mesh *submesh = new SMDS_Mesh(this);
57 myChildren.insert(myChildren.end(), submesh);
61 ///////////////////////////////////////////////////////////////////////////////
62 ///create a MeshNode and add it to the current Mesh
63 ///@return : The created node
64 ///////////////////////////////////////////////////////////////////////////////
66 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
68 return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
71 ///////////////////////////////////////////////////////////////////////////////
72 ///create a MeshNode and add it to the current Mesh
73 ///@param ID : The ID of the MeshNode to create
74 ///@return : The created node or NULL if a node with this ID already exists
75 ///////////////////////////////////////////////////////////////////////////////
76 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
78 // find the MeshNode corresponding to ID
79 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
83 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
85 myNodeIDFactory->BindID(ID,node);
92 ///////////////////////////////////////////////////////////////////////////////
93 ///create a MeshEdge and add it to the current Mesh
94 ///@return : The created MeshEdge
95 ///////////////////////////////////////////////////////////////////////////////
97 SMDS_MeshEdge* SMDS_Mesh::AddEdge(int idnode1, int idnode2)
99 return AddEdgeWithID(idnode1, idnode2, myElementIDFactory->GetFreeID());
102 ///////////////////////////////////////////////////////////////////////////////
103 ///Create a new edge and at it to the mesh
104 ///@param idnode1 ID of the first node
105 ///@param idnode2 ID of the second node
106 ///@param ID ID of the edge to create
107 ///@return The created edge or NULL if an edge with this ID already exists or
108 ///if input nodes are not found.
109 ///////////////////////////////////////////////////////////////////////////////
111 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
113 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
114 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
115 if((node1==NULL)||(node2==NULL)) return NULL;
116 SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1, node2);
117 if(myElementIDFactory->BindID(ID, edge))
119 node1->AddInverseElement(edge);
120 node2->AddInverseElement(edge);
121 myEdges.insert(edge);
131 ///////////////////////////////////////////////////////////////////////////////
132 /// Add a triangle defined by its nodes IDs
133 ///////////////////////////////////////////////////////////////////////////////
135 SMDS_MeshFace* SMDS_Mesh::AddFace(int idnode1, int idnode2, int idnode3)
137 return AddFaceWithID(idnode1,idnode2,idnode3,
138 myElementIDFactory->GetFreeID());
141 ///////////////////////////////////////////////////////////////////////////////
142 /// Add a quandrangle defined by its nodes IDs
143 ///////////////////////////////////////////////////////////////////////////////
145 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
147 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
148 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
149 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
151 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
152 SMDS_MeshFace * face=createTriangle(node1,node2,node3);
154 if(myElementIDFactory->BindID(ID, face))
156 node1->AddInverseElement(face);
157 node2->AddInverseElement(face);
158 node3->AddInverseElement(face);
168 //=======================================================================
171 //=======================================================================
173 SMDS_MeshFace* SMDS_Mesh::AddFace(int idnode1,
174 int idnode2, int idnode3, int idnode4)
176 int ID=myElementIDFactory->GetFreeID();
177 SMDS_MeshFace* f= AddFaceWithID(idnode1, idnode2, idnode3, idnode4, ID);
178 if(f==NULL) myElementIDFactory->ReleaseID(ID);
181 //=======================================================================
184 //=======================================================================
186 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
187 int idnode2, int idnode3, int idnode4, int ID)
189 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
190 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
191 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
192 SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
194 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
195 SMDS_MeshFace * face=createQuadrangle(node1,node2,node3,node4);
197 if(myElementIDFactory->BindID(ID, face))
199 node1->AddInverseElement(face);
200 node2->AddInverseElement(face);
201 node3->AddInverseElement(face);
202 node4->AddInverseElement(face);
212 //=======================================================================
213 //function : AddVolume
214 //purpose : Tetrahedra
215 //=======================================================================
217 SMDS_MeshVolume * SMDS_Mesh::AddVolume(int idnode1, int idnode2, int idnode3,
220 int ID = myElementIDFactory->GetFreeID();
222 AddVolumeWithID(idnode1, idnode2, idnode3, idnode4, ID);
223 if(v==NULL) myElementIDFactory->ReleaseID(ID);
227 ///////////////////////////////////////////////////////////////////////////////
228 ///Create a new tetrahedron and add it to the mesh.
229 ///@return The created tetrahedron or NULL if an edge with this ID already exists
230 ///or if input nodes are not found.
231 ///////////////////////////////////////////////////////////////////////////////
233 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
234 int idnode3, int idnode4, int ID)
236 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
237 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
238 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
239 SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
241 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
243 SMDS_MeshVolume* volume;
244 if(hasConstructionFaces())
246 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
247 SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
248 SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
249 SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
250 SMDS_MeshVolume* volume=
251 new SMDS_VolumeOfFaces(f1,f2,f3,f4);
252 myVolumes.insert(volume);
254 else if(hasConstructionEdges())
263 if(myElementIDFactory->BindID(ID, volume))
265 node1->AddInverseElement(volume);
266 node2->AddInverseElement(volume);
267 node3->AddInverseElement(volume);
268 node4->AddInverseElement(volume);
273 RemoveVolume(volume);
278 ///////////////////////////////////////////////////////////////////////////////
279 /// Add a pyramid to the mesh. node 1,2,3 and 4 define the base of the pyramid
280 ///////////////////////////////////////////////////////////////////////////////
281 SMDS_MeshVolume * SMDS_Mesh::AddVolume(int idnode1,
282 int idnode2, int idnode3, int idnode4, int idnode5)
284 int ID = myElementIDFactory->GetFreeID();
286 AddVolumeWithID(idnode1, idnode2, idnode3, idnode4, idnode5, ID);
287 if(v==NULL) myElementIDFactory->ReleaseID(ID);
290 ///////////////////////////////////////////////////////////////////////////////
291 /// Add a pyramid to the mesh. node 1,2,3 and 4 define the base of the pyramid
292 ///////////////////////////////////////////////////////////////////////////////
293 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
294 int idnode3, int idnode4, int idnode5, int ID)
296 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
297 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
298 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
299 SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
300 SMDS_MeshNode * node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
302 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)||(node5==NULL))
305 SMDS_MeshVolume* volume;
306 if(hasConstructionFaces())
308 SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
309 SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
310 SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
311 SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
312 SMDS_MeshFace * f5=createTriangle(node4,node1,node4);
313 SMDS_MeshVolume* volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
314 myVolumes.insert(volume);
316 else if(hasConstructionEdges())
325 if(myElementIDFactory->BindID(ID, volume))
327 node1->AddInverseElement(volume);
328 node2->AddInverseElement(volume);
329 node3->AddInverseElement(volume);
330 node4->AddInverseElement(volume);
331 node5->AddInverseElement(volume);
336 RemoveVolume(volume);
341 ///////////////////////////////////////////////////////////////////////////////
342 /// Add a prism. Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
343 ///////////////////////////////////////////////////////////////////////////////
344 SMDS_MeshVolume* SMDS_Mesh::AddVolume(int idnode1, int idnode2, int idnode3,
345 int idnode4, int idnode5, int idnode6)
347 int ID = myElementIDFactory->GetFreeID();
349 AddVolumeWithID(idnode1, idnode2, idnode3, idnode4, idnode5, idnode6,
351 if(v==NULL) myElementIDFactory->ReleaseID(ID);
354 //=======================================================================
355 //function : AddVolume
357 //=======================================================================
359 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, int idnode3,
360 int idnode4, int idnode5, int idnode6, int ID)
362 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
363 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
364 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
365 SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
366 SMDS_MeshNode * node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
367 SMDS_MeshNode * node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
369 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)||(node5==NULL)||
370 (node6==NULL)) return NULL;
372 SMDS_MeshVolume* volume;
373 if(hasConstructionFaces())
376 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
377 SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
378 SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
379 SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
380 SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
382 SMDS_MeshVolume* volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
383 myVolumes.insert(volume);
385 else if(hasConstructionEdges())
394 if(myElementIDFactory->BindID(ID, volume))
396 node1->AddInverseElement(volume);
397 node2->AddInverseElement(volume);
398 node3->AddInverseElement(volume);
399 node4->AddInverseElement(volume);
400 node5->AddInverseElement(volume);
401 node6->AddInverseElement(volume);
406 RemoveVolume(volume);
411 //=======================================================================
412 //function : AddVolume
413 //purpose : Hexahedra
414 //=======================================================================
416 SMDS_MeshVolume* SMDS_Mesh::AddVolume(int idnode1, int idnode2, int idnode3,
417 int idnode4, int idnode5, int idnode6, int idnode7, int idnode8)
419 int ID = myElementIDFactory->GetFreeID();
421 AddVolumeWithID(idnode1, idnode2, idnode3, idnode4, idnode5, idnode6,
422 idnode7, idnode8, ID);
423 if(v==NULL) myElementIDFactory->ReleaseID(ID);
426 ///////////////////////////////////////////////////////////////////////////////
427 /// Add an hexahedron to the mesh. node 1,2,3,4 and 5,6,7,8 are quadrangle and
428 /// 5,1 and 7,3 are an edges.
429 ///////////////////////////////////////////////////////////////////////////////
430 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2, int idnode3,
431 int idnode4, int idnode5, int idnode6, int idnode7, int idnode8, int ID)
433 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
434 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
435 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
436 SMDS_MeshNode * node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
437 SMDS_MeshNode * node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
438 SMDS_MeshNode * node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
439 SMDS_MeshNode * node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
440 SMDS_MeshNode * node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
442 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)||(node5==NULL)||
443 (node6==NULL)||(node7==NULL)||(node8==NULL)) return NULL;
445 SMDS_MeshVolume* volume;
446 if(hasConstructionFaces())
448 SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
449 SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
450 SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
451 SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
452 SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
453 SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
454 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
455 myVolumes.insert(volume);
457 else if(hasConstructionEdges())
459 MESSAGE("Error : Not Implemented");
463 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6,node7,node8);
464 myVolumes.insert(volume);
467 if(myElementIDFactory->BindID(ID, volume))
469 //MESSAGE("SMDS_Mesh::AddVolumeWithID: update inverse elements");
470 node1->AddInverseElement(volume);
471 node2->AddInverseElement(volume);
472 node3->AddInverseElement(volume);
473 node4->AddInverseElement(volume);
474 node5->AddInverseElement(volume);
475 node6->AddInverseElement(volume);
476 node7->AddInverseElement(volume);
477 node8->AddInverseElement(volume);
482 RemoveVolume(volume);
487 //=======================================================================
488 //function : FindNode
490 //=======================================================================
492 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
494 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
497 ///////////////////////////////////////////////////////////////////////////////
498 ///Create a triangle and add it to the current mesh. This methode do not bind a
499 ///ID to the create triangle.
500 ///////////////////////////////////////////////////////////////////////////////
501 SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
502 SMDS_MeshNode * node2, SMDS_MeshNode * node3)
504 if(hasConstructionEdges())
506 SMDS_MeshEdge *edge1, *edge2, *edge3;
507 edge1=FindEdgeOrCreate(node1,node2);
508 edge2=FindEdgeOrCreate(node2,node3);
509 edge3=FindEdgeOrCreate(node3,node1);
511 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
512 myFaces.insert(face);
517 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
518 myFaces.insert(face);
523 ///////////////////////////////////////////////////////////////////////////////
524 ///Create a quadrangle and add it to the current mesh. This methode do not bind
525 ///a ID to the create triangle.
526 ///////////////////////////////////////////////////////////////////////////////
527 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
528 SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
530 if(hasConstructionEdges())
532 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
533 edge1=FindEdgeOrCreate(node1,node2);
534 edge2=FindEdgeOrCreate(node2,node3);
535 edge3=FindEdgeOrCreate(node3,node4);
536 edge4=FindEdgeOrCreate(node4,node1);
538 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
539 myFaces.insert(face);
544 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
545 myFaces.insert(face);
550 //=======================================================================
551 //function : RemoveNode
553 //=======================================================================
555 void SMDS_Mesh::RemoveNode(int IDnode)
557 RemoveNode(FindNode(IDnode));
560 //=======================================================================
561 //function : RemoveNode
563 //=======================================================================
565 bool SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
567 SMDS_Iterator<const SMDS_MeshElement *> * it=
568 node->GetInverseElementIterator();
569 while(it->more()) RemoveElement(it->next(),true);
570 myNodeIDFactory->ReleaseID(node->GetID());
571 myNodes.erase(const_cast<SMDS_MeshNode*>(node));
574 //=======================================================================
575 //function : RemoveEdge
577 //=======================================================================
579 void SMDS_Mesh::RemoveEdge(int idnode1, int idnode2)
581 RemoveEdge(FindEdge(idnode1, idnode2));
584 //=======================================================================
585 //function : RemoveEdge
587 //=======================================================================
589 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
591 /** @todo to be fix */
592 myEdges.erase(const_cast<SMDS_MeshEdge*>(edge));
593 //removeElementDependencies(edge);
597 //=======================================================================
598 //function : RemoveFace
600 //=======================================================================
602 void SMDS_Mesh::RemoveFace(int idnode1, int idnode2, int idnode3)
604 RemoveFace(FindFace(idnode1, idnode2, idnode3));
607 //=======================================================================
608 //function : RemoveFace
610 //=======================================================================
612 void SMDS_Mesh::RemoveFace(int idnode1, int idnode2, int idnode3, int idnode4)
614 RemoveFace(FindFace(idnode1, idnode2, idnode3, idnode4));
617 //=======================================================================
618 //function : RemoveFace
620 //=======================================================================
622 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
624 /** @todo to be fix */
625 myFaces.erase(const_cast<SMDS_MeshFace*>(face));
626 //removeElementDependencies(face);
630 //=======================================================================
631 //function : RemoveVolume
633 //=======================================================================
635 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
637 /** @todo to be fix */
638 myVolumes.erase(const_cast<SMDS_MeshVolume*>(volume));
639 //removeElementDependencies(volume);
642 ///////////////////////////////////////////////////////////////////////////////
643 /// Remove no longer used sub element of an element. Unbind the element ID
644 ///////////////////////////////////////////////////////////////////////////////
645 void SMDS_Mesh::removeElementDependencies(SMDS_MeshElement * element)
647 /** @todo to be fix */
648 myElementIDFactory->ReleaseID(element->GetID());
649 SMDS_Iterator<const SMDS_MeshElement*> * it=element->nodesIterator();
652 SMDS_MeshNode * node=static_cast<SMDS_MeshNode*>(
653 const_cast<SMDS_MeshElement*>(it->next()));
654 node->RemoveInverseElement(element);
655 if(node->emptyInverseElements()) RemoveNode(node);
658 //=======================================================================
659 //function : RemoveElement
661 //=======================================================================
663 void SMDS_Mesh::RemoveElement(int IDelem, const bool removenodes)
665 RemoveElement(myElementIDFactory->MeshElement(IDelem), removenodes);
668 //=======================================================================
669 //function : RemoveElement
671 //=======================================================================
673 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
674 const bool removenodes)
676 /** @todo to be fix */
677 switch(elem->GetType())
680 RemoveNode((const SMDS_MeshNode*)elem);
683 RemoveEdge((const SMDS_MeshEdge*)elem);
686 RemoveFace((const SMDS_MeshFace*)elem);
689 RemoveVolume((const SMDS_MeshVolume*)elem);
692 MESSAGE("remove function : unknown type");
696 SMDS_Iterator<const SMDS_MeshNode*> * it=elem->nodesIterator();
699 const SMDS_MeshNode * node=it->next();
704 //=======================================================================
705 //function : RemoveFromParent
707 //=======================================================================
709 bool SMDS_Mesh::RemoveFromParent()
711 if (myParent==NULL) return false;
712 else return (myParent->RemoveSubMesh(this));
715 //=======================================================================
716 //function : RemoveSubMesh
718 //=======================================================================
720 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
724 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
725 for (; itmsh!=myChildren.end() && !found; itmsh++)
727 SMDS_Mesh * submesh = *itmsh;
728 if (submesh == aMesh)
731 myChildren.erase(itmsh);
739 //=======================================================================
740 //function : FindEdge
742 //=======================================================================
744 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
746 const SMDS_MeshNode * node1=FindNode(idnode1);
747 const SMDS_MeshNode * node2=FindNode(idnode2);
748 if((node1==NULL)||(node2==NULL)) return NULL;
749 return FindEdge(node1,node2);
752 ///////////////////////////////////////////////////////////////////////////////
754 ///////////////////////////////////////////////////////////////////////////////
755 //#include "Profiler.h"
756 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
757 const SMDS_MeshNode * node2) const
759 const SMDS_MeshEdge * toReturn=NULL;
762 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->edgesIterator();
767 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
769 SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
772 if(it2->next()->GetID()==node2->GetID())
786 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
787 const SMDS_MeshNode * node2)
789 SMDS_MeshEdge * toReturn=NULL;
790 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
793 toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
794 const_cast<SMDS_MeshNode*>(node2));
795 myEdges.insert(toReturn);
800 //=======================================================================
801 //function : FindFace
803 //=======================================================================
805 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
808 const SMDS_MeshNode * node1=FindNode(idnode1);
809 const SMDS_MeshNode * node2=FindNode(idnode2);
810 const SMDS_MeshNode * node3=FindNode(idnode3);
811 const SMDS_MeshFace * face;
812 const SMDS_MeshElement * node;
813 bool node2found, node3found;
814 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
816 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
819 face=static_cast<const SMDS_MeshFace*>(it1->next());
820 if(face->NbNodes()!=3) continue;
821 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
827 if(node->GetID()==idnode2) node2found=true;
828 if(node->GetID()==idnode3) node3found=true;
831 if(node2found&&node3found)
841 //=======================================================================
842 //function : FindFace
844 //=======================================================================
846 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
849 const SMDS_MeshNode * node1=FindNode(idnode1);
850 const SMDS_MeshNode * node2=FindNode(idnode2);
851 const SMDS_MeshNode * node3=FindNode(idnode3);
852 const SMDS_MeshNode * node4=FindNode(idnode4);
853 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
854 return FindFace(node1, node2, node3, node4);
857 const SMDS_MeshFace* SMDS_Mesh::FindFace(
858 const SMDS_MeshNode *node1,
859 const SMDS_MeshNode *node2,
860 const SMDS_MeshNode *node3,
861 const SMDS_MeshNode *node4) const
863 const SMDS_MeshFace * face;
864 const SMDS_MeshElement * node;
865 bool node2found, node3found, node4found;
866 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
869 face=static_cast<const SMDS_MeshFace *>(it1->next());
870 if(face->NbNodes()!=4) continue;
871 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
878 if(node->GetID()==node2->GetID()) node2found=true;
879 if(node->GetID()==node3->GetID()) node3found=true;
880 if(node->GetID()==node4->GetID()) node4found=true;
883 if(node2found&&node3found&&node4found)
893 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
894 const SMDS_MeshNode *node1,
895 const SMDS_MeshNode *node2,
896 const SMDS_MeshNode *node3,
897 const SMDS_MeshNode *node4)
899 SMDS_MeshFace * toReturn=NULL;
900 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
903 toReturn=createQuadrangle(
904 const_cast<SMDS_MeshNode *>(node1),
905 const_cast<SMDS_MeshNode *>(node2),
906 const_cast<SMDS_MeshNode *>(node3),
907 const_cast<SMDS_MeshNode *>(node4)
913 //=======================================================================
914 //function : FindElement
916 //=======================================================================
918 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
920 return myElementIDFactory->MeshElement(IDelem);
923 //=======================================================================
924 //function : DumpNodes
926 //=======================================================================
928 void SMDS_Mesh::DumpNodes() const
930 MESSAGE("dump nodes of mesh : ");
931 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
932 while(itnode->more()) MESSAGE(itnode->next());
936 //=======================================================================
937 //function : DumpEdges
939 //=======================================================================
941 void SMDS_Mesh::DumpEdges() const
943 MESSAGE("dump edges of mesh : ");
944 SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
945 while(itedge->more()) MESSAGE(itedge->next());
949 //=======================================================================
950 //function : DumpFaces
952 //=======================================================================
954 void SMDS_Mesh::DumpFaces() const
956 MESSAGE("dump faces of mesh : ");
957 SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
958 while(itface->more()) MESSAGE(itface->next());
962 //=======================================================================
963 //function : DumpVolumes
965 //=======================================================================
967 void SMDS_Mesh::DumpVolumes() const
969 MESSAGE("dump volumes of mesh : ");
970 SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
971 while(itvol->more()) MESSAGE(itvol->next());
975 //=======================================================================
976 //function : DebugStats
978 //=======================================================================
980 void SMDS_Mesh::DebugStats() const
982 MESSAGE("Debug stats of mesh : ");
984 MESSAGE("===== NODES ====="<<NbNodes());
985 MESSAGE("===== EDGES ====="<<NbEdges());
986 MESSAGE("===== FACES ====="<<NbFaces());
987 MESSAGE("===== VOLUMES ====="<<NbVolumes());
989 MESSAGE("End Debug stats of mesh ");
993 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
997 while(itnode->more())
999 const SMDS_MeshNode *node = itnode->next();
1001 sizeofnodes += sizeof(*node);
1003 SMDS_Iterator<const SMDS_MeshElement *> * it=
1004 node->GetInverseElementIterator();
1007 const SMDS_MeshElement *me = it->next();
1008 sizeofnodes += sizeof(me);
1014 SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
1016 while(itface->more())
1018 const SMDS_MeshElement *face = itface->next();
1019 sizeoffaces += sizeof(*face);
1022 MESSAGE("total size of node elements = " << sizeofnodes);;
1023 MESSAGE("total size of face elements = " << sizeoffaces);;
1029 int SMDS_Mesh::NbNodes() const
1034 int SMDS_Mesh::NbEdges() const
1036 return myEdges.size();
1039 int SMDS_Mesh::NbFaces() const
1041 return myFaces.size();
1044 int SMDS_Mesh::NbVolumes() const
1046 return myVolumes.size();
1049 int SMDS_Mesh::NbSubMesh() const
1051 return myChildren.size();
1054 SMDS_Mesh::~SMDS_Mesh()
1058 delete myNodeIDFactory;
1059 delete myElementIDFactory;
1062 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1063 while(itc!=myChildren.end())
1069 SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1076 set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1077 while(ite!=myEdges.end())
1083 set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1084 while(itf!=myFaces.end())
1090 set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1091 while(itv!=myVolumes.end())
1099 bool SMDS_Mesh::hasConstructionEdges()
1101 return myHasConstructionEdges;
1104 bool SMDS_Mesh::hasConstructionFaces()
1106 return myHasConstructionFaces;
1109 bool SMDS_Mesh::hasInverseElements()
1111 return myHasInverseElements;
1114 void SMDS_Mesh::setConstructionEdges(bool b)
1116 myHasConstructionEdges=b;
1119 void SMDS_Mesh::setConstructionFaces(bool b)
1121 myHasConstructionFaces=b;
1124 void SMDS_Mesh::setInverseElements(bool b)
1126 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1127 myHasInverseElements=b;
1130 ///////////////////////////////////////////////////////////////////////////////
1131 ///Return an iterator on nodes of the current mesh. Once used this iterator
1132 ///must be free by the caller
1133 ///////////////////////////////////////////////////////////////////////////////
1134 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1136 class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1138 const SetOfNodes& mySet;
1139 SetOfNodes::iterator myIterator;
1141 MyIterator(const SetOfNodes& s):mySet(s)
1143 myIterator=mySet.begin();
1148 myIterator!=mySet.end();
1151 const SMDS_MeshNode* next()
1153 const SMDS_MeshNode* current=*myIterator;
1158 return new MyIterator(myNodes);
1161 ///////////////////////////////////////////////////////////////////////////////
1162 ///Return an iterator on volumes of the current mesh. Once used this iterator
1163 ///must be free by the caller
1164 ///////////////////////////////////////////////////////////////////////////////
1165 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1167 class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1169 const SetOfEdges& mySet;
1170 const SMDS_MeshEdge * myEdge;
1171 SetOfEdges::iterator myIterator;
1173 MyIterator(const SetOfEdges& s):mySet(s)
1175 myIterator=mySet.begin();
1180 while((myIterator!=mySet.end()))
1182 if((*myIterator)->GetID()!=-1)
1189 const SMDS_MeshEdge* next()
1191 const SMDS_MeshEdge* current=*myIterator;
1196 return new MyIterator(myEdges);
1199 ///////////////////////////////////////////////////////////////////////////////
1200 ///Return an iterator on faces of the current mesh. Once used this iterator
1201 ///must be free by the caller
1202 ///////////////////////////////////////////////////////////////////////////////
1203 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1205 class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1207 const SetOfFaces& mySet;
1208 set<SMDS_MeshFace*>::iterator myIterator;
1210 MyIterator(const SetOfFaces& s):mySet(s)
1212 myIterator=mySet.begin();
1217 while((myIterator!=mySet.end()))
1219 if((*myIterator)->GetID()!=-1)
1226 const SMDS_MeshFace* next()
1228 const SMDS_MeshFace* current=*myIterator;
1233 return new MyIterator(myFaces);
1236 ///////////////////////////////////////////////////////////////////////////////
1237 ///Return an iterator on volumes of the current mesh. Once used this iterator
1238 ///must be free by the caller
1239 ///////////////////////////////////////////////////////////////////////////////
1240 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1242 class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1244 const SetOfVolumes& mySet;
1245 SetOfVolumes::iterator myIterator;
1247 MyIterator(const SetOfVolumes& s):mySet(s)
1249 myIterator=mySet.begin();
1254 myIterator!=mySet.end();
1257 const SMDS_MeshVolume* next()
1259 const SMDS_MeshVolume* current=*myIterator;
1264 return new MyIterator(myVolumes);