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_Tria3OfNodes.hxx"
28 #include "SMDS_HexahedronOfNodes.hxx"
29 #include "SMDS_FaceOfEdges.hxx"
34 ///////////////////////////////////////////////////////////////////////////////
35 /// Create a new mesh object
36 ///////////////////////////////////////////////////////////////////////////////
37 SMDS_Mesh::SMDS_Mesh()
38 :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
39 myElementIDFactory(new SMDS_MeshElementIDFactory()),
40 myHasConstructionEdges(false), myHasConstructionFaces(false),
41 myHasInverseElements(true)
45 ///////////////////////////////////////////////////////////////////////////////
46 /// Create a new child mesh
47 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
48 /// (2003-09-08) of SMESH
49 ///////////////////////////////////////////////////////////////////////////////
50 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
51 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
52 myElementIDFactory(parent->myElementIDFactory),
53 myHasConstructionEdges(false), myHasConstructionFaces(false),
54 myHasInverseElements(true)
58 ///////////////////////////////////////////////////////////////////////////////
59 ///Create a submesh and add it to the current mesh
60 ///////////////////////////////////////////////////////////////////////////////
62 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
64 SMDS_Mesh *submesh = new SMDS_Mesh(this);
65 myChildren.insert(myChildren.end(), submesh);
69 ///////////////////////////////////////////////////////////////////////////////
70 ///create a MeshNode and add it to the current Mesh
71 ///An ID is automatically assigned to the node.
72 ///@return : The created node
73 ///////////////////////////////////////////////////////////////////////////////
75 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
77 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
80 ///////////////////////////////////////////////////////////////////////////////
81 ///create a MeshNode and add it to the current Mesh
82 ///@param ID : The ID of the MeshNode to create
83 ///@return : The created node or NULL if a node with this ID already exists
84 ///////////////////////////////////////////////////////////////////////////////
85 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
87 // find the MeshNode corresponding to ID
88 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
90 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
92 myNodeIDFactory->BindID(ID,node);
98 ///////////////////////////////////////////////////////////////////////////////
99 /// create a MeshEdge and add it to the current Mesh
100 /// @return : The created MeshEdge
101 ///////////////////////////////////////////////////////////////////////////////
103 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
105 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
106 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
107 if(!node1 || !node2) return NULL;
108 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
111 ///////////////////////////////////////////////////////////////////////////////
112 /// create a MeshEdge and add it to the current Mesh
113 /// @return : The created MeshEdge
114 ///////////////////////////////////////////////////////////////////////////////
116 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
117 const SMDS_MeshNode * node2)
119 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
122 ///////////////////////////////////////////////////////////////////////////////
123 /// Create a new edge and at it to the mesh
124 /// @param idnode1 ID of the first node
125 /// @param idnode2 ID of the second node
126 /// @param ID ID of the edge to create
127 /// @return The created edge or NULL if an element with this ID already exists or
128 /// if input nodes are not found.
129 ///////////////////////////////////////////////////////////////////////////////
131 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
132 const SMDS_MeshNode * n2,
135 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
136 if(myElementIDFactory->BindID(ID, edge)) {
137 SMDS_MeshNode *node1,*node2;
138 node1=const_cast<SMDS_MeshNode*>(n1);
139 node2=const_cast<SMDS_MeshNode*>(n2);
140 node1->AddInverseElement(edge);
141 node2->AddInverseElement(edge);
142 myEdges.insert(edge);
151 ///////////////////////////////////////////////////////////////////////////////
152 /// Add a triangle defined by its nodes. An ID is automatically affected to the
154 ///////////////////////////////////////////////////////////////////////////////
156 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
157 const SMDS_MeshNode * n2,
158 const SMDS_MeshNode * n3)
160 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
163 ///////////////////////////////////////////////////////////////////////////////
164 /// Add a triangle defined by its nodes IDs
165 ///////////////////////////////////////////////////////////////////////////////
167 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
169 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
170 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
171 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
172 if(!node1 || !node2 || !node3) return NULL;
173 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
176 ///////////////////////////////////////////////////////////////////////////////
177 /// Add a triangle defined by its nodes
178 ///////////////////////////////////////////////////////////////////////////////
180 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
181 const SMDS_MeshNode * n2,
182 const SMDS_MeshNode * n3,
185 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
187 if (!registerElement(ID, face)) {
188 RemoveElement(face, false);
194 ///////////////////////////////////////////////////////////////////////////////
195 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
197 ///////////////////////////////////////////////////////////////////////////////
199 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
200 const SMDS_MeshNode * n2,
201 const SMDS_MeshNode * n3,
202 const SMDS_MeshNode * n4)
204 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
207 ///////////////////////////////////////////////////////////////////////////////
208 /// Add a quadrangle defined by its nodes IDs
209 ///////////////////////////////////////////////////////////////////////////////
211 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
217 SMDS_MeshNode *node1, *node2, *node3, *node4;
218 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
219 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
220 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
221 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
222 if(!node1 || !node2 || !node3 || !node4) return NULL;
223 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
226 ///////////////////////////////////////////////////////////////////////////////
227 /// Add a quadrangle defined by its nodes
228 ///////////////////////////////////////////////////////////////////////////////
230 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
231 const SMDS_MeshNode * n2,
232 const SMDS_MeshNode * n3,
233 const SMDS_MeshNode * n4,
236 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
238 if (!registerElement(ID, face)) {
239 RemoveElement(face, false);
245 ///////////////////////////////////////////////////////////////////////////////
246 /// Add a triangle defined by its edges. An ID is automatically assigned to the
248 ///////////////////////////////////////////////////////////////////////////////
250 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
251 const SMDS_MeshEdge * e2,
252 const SMDS_MeshEdge * e3)
254 if (!hasConstructionEdges())
256 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
259 ///////////////////////////////////////////////////////////////////////////////
260 /// Add a triangle defined by its edges
261 ///////////////////////////////////////////////////////////////////////////////
263 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
264 const SMDS_MeshEdge * e2,
265 const SMDS_MeshEdge * e3,
268 if (!hasConstructionEdges())
270 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
271 myFaces.insert(face);
273 if (!registerElement(ID, face)) {
274 RemoveElement(face, false);
280 ///////////////////////////////////////////////////////////////////////////////
281 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
283 ///////////////////////////////////////////////////////////////////////////////
285 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
286 const SMDS_MeshEdge * e2,
287 const SMDS_MeshEdge * e3,
288 const SMDS_MeshEdge * e4)
290 if (!hasConstructionEdges())
292 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
295 ///////////////////////////////////////////////////////////////////////////////
296 /// Add a quadrangle defined by its edges
297 ///////////////////////////////////////////////////////////////////////////////
299 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
300 const SMDS_MeshEdge * e2,
301 const SMDS_MeshEdge * e3,
302 const SMDS_MeshEdge * e4,
305 if (!hasConstructionEdges())
307 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
308 myFaces.insert(face);
310 if (!registerElement(ID, face))
312 RemoveElement(face, false);
318 ///////////////////////////////////////////////////////////////////////////////
319 ///Create a new tetrahedron and add it to the mesh.
320 ///@return The created tetrahedron
321 ///////////////////////////////////////////////////////////////////////////////
323 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
324 const SMDS_MeshNode * n2,
325 const SMDS_MeshNode * n3,
326 const SMDS_MeshNode * n4)
328 int ID = myElementIDFactory->GetFreeID();
329 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
330 if(v==NULL) myElementIDFactory->ReleaseID(ID);
334 ///////////////////////////////////////////////////////////////////////////////
335 ///Create a new tetrahedron and add it to the mesh.
336 ///@param ID The ID of the new volume
337 ///@return The created tetrahedron or NULL if an element with this ID already exists
338 ///or if input nodes are not found.
339 ///////////////////////////////////////////////////////////////////////////////
341 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
347 SMDS_MeshNode *node1, *node2, *node3, *node4;
348 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
349 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
350 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
351 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
352 if(!node1 || !node2 || !node3 || !node4) return NULL;
353 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
356 ///////////////////////////////////////////////////////////////////////////////
357 ///Create a new tetrahedron and add it to the mesh.
358 ///@param ID The ID of the new volume
359 ///@return The created tetrahedron
360 ///////////////////////////////////////////////////////////////////////////////
362 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
363 const SMDS_MeshNode * n2,
364 const SMDS_MeshNode * n3,
365 const SMDS_MeshNode * n4,
368 SMDS_MeshVolume* volume;
369 if(hasConstructionFaces()) {
370 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
371 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
372 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
373 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
374 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
375 myVolumes.insert(volume);
377 else if(hasConstructionEdges()) {
378 MESSAGE("Error : Not implemented");
382 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
383 myVolumes.insert(volume);
386 if (!registerElement(ID, volume)) {
387 RemoveElement(volume, false);
393 ///////////////////////////////////////////////////////////////////////////////
394 ///Create a new pyramid and add it to the mesh.
395 ///Nodes 1,2,3 and 4 define the base of the pyramid
396 ///@return The created pyramid
397 ///////////////////////////////////////////////////////////////////////////////
399 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
400 const SMDS_MeshNode * n2,
401 const SMDS_MeshNode * n3,
402 const SMDS_MeshNode * n4,
403 const SMDS_MeshNode * n5)
405 int ID = myElementIDFactory->GetFreeID();
406 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
407 if(v==NULL) myElementIDFactory->ReleaseID(ID);
411 ///////////////////////////////////////////////////////////////////////////////
412 ///Create a new pyramid and add it to the mesh.
413 ///Nodes 1,2,3 and 4 define the base of the pyramid
414 ///@param ID The ID of the new volume
415 ///@return The created pyramid or NULL if an element with this ID already exists
416 ///or if input nodes are not found.
417 ///////////////////////////////////////////////////////////////////////////////
419 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
426 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
427 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
428 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
429 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
430 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
431 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
432 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
433 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
436 ///////////////////////////////////////////////////////////////////////////////
437 ///Create a new pyramid and add it to the mesh.
438 ///Nodes 1,2,3 and 4 define the base of the pyramid
439 ///@param ID The ID of the new volume
440 ///@return The created pyramid
441 ///////////////////////////////////////////////////////////////////////////////
443 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
444 const SMDS_MeshNode * n2,
445 const SMDS_MeshNode * n3,
446 const SMDS_MeshNode * n4,
447 const SMDS_MeshNode * n5,
450 SMDS_MeshVolume* volume;
451 if(hasConstructionFaces()) {
452 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
453 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
454 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
455 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
456 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
457 myVolumes.insert(volume);
459 else if(hasConstructionEdges()) {
460 MESSAGE("Error : Not implemented");
464 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
465 myVolumes.insert(volume);
468 if (!registerElement(ID, volume)) {
469 RemoveElement(volume, false);
475 ///////////////////////////////////////////////////////////////////////////////
476 ///Create a new prism and add it to the mesh.
477 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
478 ///@return The created prism
479 ///////////////////////////////////////////////////////////////////////////////
481 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
482 const SMDS_MeshNode * n2,
483 const SMDS_MeshNode * n3,
484 const SMDS_MeshNode * n4,
485 const SMDS_MeshNode * n5,
486 const SMDS_MeshNode * n6)
488 int ID = myElementIDFactory->GetFreeID();
489 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
490 if(v==NULL) myElementIDFactory->ReleaseID(ID);
494 ///////////////////////////////////////////////////////////////////////////////
495 ///Create a new prism and add it to the mesh.
496 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
497 ///@param ID The ID of the new volume
498 ///@return The created prism or NULL if an element with this ID already exists
499 ///or if input nodes are not found.
500 ///////////////////////////////////////////////////////////////////////////////
502 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
510 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
511 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
512 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
513 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
514 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
515 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
516 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
517 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
518 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
521 ///////////////////////////////////////////////////////////////////////////////
522 ///Create a new prism and add it to the mesh.
523 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
524 ///@param ID The ID of the new volume
525 ///@return The created prism
526 ///////////////////////////////////////////////////////////////////////////////
528 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
529 const SMDS_MeshNode * n2,
530 const SMDS_MeshNode * n3,
531 const SMDS_MeshNode * n4,
532 const SMDS_MeshNode * n5,
533 const SMDS_MeshNode * n6,
536 SMDS_MeshVolume* volume;
537 if(hasConstructionFaces()) {
538 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
539 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
540 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
541 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
542 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
543 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
544 myVolumes.insert(volume);
546 else if(hasConstructionEdges()) {
547 MESSAGE("Error : Not implemented");
551 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
552 myVolumes.insert(volume);
555 if (!registerElement(ID, volume)) {
556 RemoveElement(volume, false);
562 ///////////////////////////////////////////////////////////////////////////////
563 ///Create a new hexahedron and add it to the mesh.
564 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
565 ///@return The created hexahedron
566 ///////////////////////////////////////////////////////////////////////////////
568 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
569 const SMDS_MeshNode * n2,
570 const SMDS_MeshNode * n3,
571 const SMDS_MeshNode * n4,
572 const SMDS_MeshNode * n5,
573 const SMDS_MeshNode * n6,
574 const SMDS_MeshNode * n7,
575 const SMDS_MeshNode * n8)
577 int ID = myElementIDFactory->GetFreeID();
578 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
579 if(v==NULL) myElementIDFactory->ReleaseID(ID);
583 ///////////////////////////////////////////////////////////////////////////////
584 ///Create a new hexahedron and add it to the mesh.
585 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
586 ///@param ID The ID of the new volume
587 ///@return The created hexahedron or NULL if an element with this ID already
588 ///exists or if input nodes are not found.
589 ///////////////////////////////////////////////////////////////////////////////
591 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
601 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
602 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
603 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
604 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
605 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
606 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
607 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
608 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
609 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
610 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
612 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
616 ///////////////////////////////////////////////////////////////////////////////
617 ///Create a new hexahedron and add it to the mesh.
618 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
619 ///@param ID The ID of the new volume
620 ///@return The created prism or NULL if an element with this ID already exists
621 ///or if input nodes are not found.
622 ///////////////////////////////////////////////////////////////////////////////
624 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
625 const SMDS_MeshNode * n2,
626 const SMDS_MeshNode * n3,
627 const SMDS_MeshNode * n4,
628 const SMDS_MeshNode * n5,
629 const SMDS_MeshNode * n6,
630 const SMDS_MeshNode * n7,
631 const SMDS_MeshNode * n8,
634 SMDS_MeshVolume* volume;
635 if(hasConstructionFaces()) {
636 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
637 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
638 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
639 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
640 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
641 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
642 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
643 myVolumes.insert(volume);
645 else if(hasConstructionEdges()) {
646 MESSAGE("Error : Not implemented");
650 volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
651 myVolumes.insert(volume);
654 if (!registerElement(ID, volume)) {
655 RemoveElement(volume, false);
661 ///////////////////////////////////////////////////////////////////////////////
662 ///Create a new tetrahedron defined by its faces and add it to the mesh.
663 ///@return The created tetrahedron
664 ///////////////////////////////////////////////////////////////////////////////
666 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
667 const SMDS_MeshFace * f2,
668 const SMDS_MeshFace * f3,
669 const SMDS_MeshFace * f4)
671 if (!hasConstructionFaces())
673 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
676 ///////////////////////////////////////////////////////////////////////////////
677 ///Create a new tetrahedron defined by its faces and add it to the mesh.
678 ///@param ID The ID of the new volume
679 ///@return The created tetrahedron
680 ///////////////////////////////////////////////////////////////////////////////
682 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
683 const SMDS_MeshFace * f2,
684 const SMDS_MeshFace * f3,
685 const SMDS_MeshFace * f4,
688 if (!hasConstructionFaces())
690 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
691 myVolumes.insert(volume);
693 if (!registerElement(ID, volume)) {
694 RemoveElement(volume, false);
700 ///////////////////////////////////////////////////////////////////////////////
701 ///Create a new pyramid defined by its faces and add it to the mesh.
702 ///@return The created pyramid
703 ///////////////////////////////////////////////////////////////////////////////
705 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
706 const SMDS_MeshFace * f2,
707 const SMDS_MeshFace * f3,
708 const SMDS_MeshFace * f4,
709 const SMDS_MeshFace * f5)
711 if (!hasConstructionFaces())
713 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
716 ///////////////////////////////////////////////////////////////////////////////
717 ///Create a new pyramid defined by its faces and add it to the mesh.
718 ///@param ID The ID of the new volume
719 ///@return The created pyramid
720 ///////////////////////////////////////////////////////////////////////////////
722 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
723 const SMDS_MeshFace * f2,
724 const SMDS_MeshFace * f3,
725 const SMDS_MeshFace * f4,
726 const SMDS_MeshFace * f5,
729 if (!hasConstructionFaces())
731 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
732 myVolumes.insert(volume);
734 if (!registerElement(ID, volume)) {
735 RemoveElement(volume, false);
741 ///////////////////////////////////////////////////////////////////////////////
742 ///Create a new prism defined by its faces and add it to the mesh.
743 ///@return The created prism
744 ///////////////////////////////////////////////////////////////////////////////
746 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
747 const SMDS_MeshFace * f2,
748 const SMDS_MeshFace * f3,
749 const SMDS_MeshFace * f4,
750 const SMDS_MeshFace * f5,
751 const SMDS_MeshFace * f6)
753 if (!hasConstructionFaces())
755 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
758 ///////////////////////////////////////////////////////////////////////////////
759 ///Create a new prism defined by its faces and add it to the mesh.
760 ///@param ID The ID of the new volume
761 ///@return The created prism
762 ///////////////////////////////////////////////////////////////////////////////
764 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
765 const SMDS_MeshFace * f2,
766 const SMDS_MeshFace * f3,
767 const SMDS_MeshFace * f4,
768 const SMDS_MeshFace * f5,
769 const SMDS_MeshFace * f6,
772 if (!hasConstructionFaces())
774 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
775 myVolumes.insert(volume);
777 if (!registerElement(ID, volume)) {
778 RemoveElement(volume, false);
784 ///////////////////////////////////////////////////////////////////////////////
785 /// Registers element with the given ID, maintains inverse connections
786 ///////////////////////////////////////////////////////////////////////////////
787 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
789 if (myElementIDFactory->BindID(ID, element)) {
790 SMDS_ElemIteratorPtr it = element->nodesIterator();
792 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
793 (const_cast<SMDS_MeshElement*>(it->next()));
794 node->AddInverseElement(element);
801 ///////////////////////////////////////////////////////////////////////////////
802 /// Return the node whose ID is 'ID'.
803 ///////////////////////////////////////////////////////////////////////////////
804 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
806 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
809 ///////////////////////////////////////////////////////////////////////////////
810 ///Create a triangle and add it to the current mesh. This methode do not bind a
811 ///ID to the create triangle.
812 ///////////////////////////////////////////////////////////////////////////////
813 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
814 const SMDS_MeshNode * node2,
815 const SMDS_MeshNode * node3)
817 if(hasConstructionEdges())
819 SMDS_MeshEdge *edge1, *edge2, *edge3;
820 edge1=FindEdgeOrCreate(node1,node2);
821 edge2=FindEdgeOrCreate(node2,node3);
822 edge3=FindEdgeOrCreate(node3,node1);
824 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
825 myFaces.insert(face);
830 SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3);
831 myFaces.insert(face);
836 ///////////////////////////////////////////////////////////////////////////////
837 ///Create a quadrangle and add it to the current mesh. This methode do not bind
838 ///a ID to the create triangle.
839 ///////////////////////////////////////////////////////////////////////////////
840 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
841 const SMDS_MeshNode * node2,
842 const SMDS_MeshNode * node3,
843 const SMDS_MeshNode * node4)
845 if(hasConstructionEdges())
847 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
848 edge1=FindEdgeOrCreate(node1,node2);
849 edge2=FindEdgeOrCreate(node2,node3);
850 edge3=FindEdgeOrCreate(node3,node4);
851 edge4=FindEdgeOrCreate(node4,node1);
853 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
854 myFaces.insert(face);
859 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
860 myFaces.insert(face);
865 ///////////////////////////////////////////////////////////////////////////////
866 /// Remove a node and all the elements which own this node
867 ///////////////////////////////////////////////////////////////////////////////
869 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
871 RemoveElement(node, true);
874 ///////////////////////////////////////////////////////////////////////////////
875 /// Remove an edge and all the elements which own this edge
876 ///////////////////////////////////////////////////////////////////////////////
878 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
880 RemoveElement(edge,true);
883 ///////////////////////////////////////////////////////////////////////////////
884 /// Remove an face and all the elements which own this face
885 ///////////////////////////////////////////////////////////////////////////////
887 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
889 RemoveElement(face, true);
892 ///////////////////////////////////////////////////////////////////////////////
894 ///////////////////////////////////////////////////////////////////////////////
896 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
898 RemoveElement(volume, true);
901 //=======================================================================
902 //function : RemoveFromParent
904 //=======================================================================
906 bool SMDS_Mesh::RemoveFromParent()
908 if (myParent==NULL) return false;
909 else return (myParent->RemoveSubMesh(this));
912 //=======================================================================
913 //function : RemoveSubMesh
915 //=======================================================================
917 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
921 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
922 for (; itmsh!=myChildren.end() && !found; itmsh++)
924 SMDS_Mesh * submesh = *itmsh;
925 if (submesh == aMesh)
928 myChildren.erase(itmsh);
936 //=======================================================================
937 //function : FindEdge
939 //=======================================================================
941 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
943 const SMDS_MeshNode * node1=FindNode(idnode1);
944 const SMDS_MeshNode * node2=FindNode(idnode2);
945 if((node1==NULL)||(node2==NULL)) return NULL;
946 return FindEdge(node1,node2);
949 //#include "Profiler.h"
950 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
951 const SMDS_MeshNode * node2) const
953 const SMDS_MeshEdge * toReturn=NULL;
956 SMDS_ElemIteratorPtr it1=node1->edgesIterator();
961 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
963 SMDS_ElemIteratorPtr it2=e->nodesIterator();
966 if(it2->next()->GetID()==node2->GetID())
978 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
979 const SMDS_MeshNode * node2)
981 SMDS_MeshEdge * toReturn=NULL;
982 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
985 toReturn=new SMDS_MeshEdge(node1,node2);
986 myEdges.insert(toReturn);
991 //=======================================================================
992 //function : FindFace
994 //=======================================================================
996 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
999 const SMDS_MeshNode * node1=FindNode(idnode1);
1000 const SMDS_MeshNode * node2=FindNode(idnode2);
1001 const SMDS_MeshNode * node3=FindNode(idnode3);
1002 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
1003 return FindFace(node1, node2, node3);
1006 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1007 const SMDS_MeshNode *node1,
1008 const SMDS_MeshNode *node2,
1009 const SMDS_MeshNode *node3) const
1011 const SMDS_MeshFace * face;
1012 const SMDS_MeshElement * node;
1013 bool node2found, node3found;
1015 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1018 face=static_cast<const SMDS_MeshFace*>(it1->next());
1019 if(face->NbNodes()!=3) continue;
1020 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1026 if(node->GetID()==node2->GetID()) node2found=true;
1027 if(node->GetID()==node3->GetID()) node3found=true;
1029 if(node2found&&node3found)
1035 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1036 const SMDS_MeshNode *node1,
1037 const SMDS_MeshNode *node2,
1038 const SMDS_MeshNode *node3)
1040 SMDS_MeshFace * toReturn=NULL;
1041 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1044 toReturn=createTriangle(node1,node2,node3);
1049 //=======================================================================
1050 //function : FindFace
1052 //=======================================================================
1054 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
1057 const SMDS_MeshNode * node1=FindNode(idnode1);
1058 const SMDS_MeshNode * node2=FindNode(idnode2);
1059 const SMDS_MeshNode * node3=FindNode(idnode3);
1060 const SMDS_MeshNode * node4=FindNode(idnode4);
1061 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
1062 return FindFace(node1, node2, node3, node4);
1065 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1066 const SMDS_MeshNode *node1,
1067 const SMDS_MeshNode *node2,
1068 const SMDS_MeshNode *node3,
1069 const SMDS_MeshNode *node4) const
1071 const SMDS_MeshFace * face;
1072 const SMDS_MeshElement * node;
1073 bool node2found, node3found, node4found;
1074 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1077 face=static_cast<const SMDS_MeshFace *>(it1->next());
1078 if(face->NbNodes()!=4) continue;
1079 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1086 if(node->GetID()==node2->GetID()) node2found=true;
1087 if(node->GetID()==node3->GetID()) node3found=true;
1088 if(node->GetID()==node4->GetID()) node4found=true;
1090 if(node2found&&node3found&&node4found)
1096 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1097 const SMDS_MeshNode *node1,
1098 const SMDS_MeshNode *node2,
1099 const SMDS_MeshNode *node3,
1100 const SMDS_MeshNode *node4)
1102 SMDS_MeshFace * toReturn=NULL;
1103 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1106 toReturn=createQuadrangle(node1,node2,node3,node4);
1111 //=======================================================================
1112 //function : FindElement
1114 //=======================================================================
1116 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1118 return myElementIDFactory->MeshElement(IDelem);
1121 //=======================================================================
1122 //function : DumpNodes
1124 //=======================================================================
1126 void SMDS_Mesh::DumpNodes() const
1128 MESSAGE("dump nodes of mesh : ");
1129 SMDS_NodeIteratorPtr itnode=nodesIterator();
1130 while(itnode->more()) MESSAGE(itnode->next());
1133 //=======================================================================
1134 //function : DumpEdges
1136 //=======================================================================
1138 void SMDS_Mesh::DumpEdges() const
1140 MESSAGE("dump edges of mesh : ");
1141 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1142 while(itedge->more()) MESSAGE(itedge->next());
1145 //=======================================================================
1146 //function : DumpFaces
1148 //=======================================================================
1150 void SMDS_Mesh::DumpFaces() const
1152 MESSAGE("dump faces of mesh : ");
1153 SMDS_FaceIteratorPtr itface=facesIterator();
1154 while(itface->more()) MESSAGE(itface->next());
1157 //=======================================================================
1158 //function : DumpVolumes
1160 //=======================================================================
1162 void SMDS_Mesh::DumpVolumes() const
1164 MESSAGE("dump volumes of mesh : ");
1165 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1166 while(itvol->more()) MESSAGE(itvol->next());
1169 //=======================================================================
1170 //function : DebugStats
1172 //=======================================================================
1174 void SMDS_Mesh::DebugStats() const
1176 MESSAGE("Debug stats of mesh : ");
1178 MESSAGE("===== NODES ====="<<NbNodes());
1179 MESSAGE("===== EDGES ====="<<NbEdges());
1180 MESSAGE("===== FACES ====="<<NbFaces());
1181 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1183 MESSAGE("End Debug stats of mesh ");
1187 SMDS_NodeIteratorPtr itnode=nodesIterator();
1188 int sizeofnodes = 0;
1189 int sizeoffaces = 0;
1191 while(itnode->more())
1193 const SMDS_MeshNode *node = itnode->next();
1195 sizeofnodes += sizeof(*node);
1197 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1200 const SMDS_MeshElement *me = it->next();
1201 sizeofnodes += sizeof(me);
1206 SMDS_FaceIteratorPtr itface=facesIterator();
1207 while(itface->more())
1209 const SMDS_MeshElement *face = itface->next();
1210 sizeoffaces += sizeof(*face);
1213 MESSAGE("total size of node elements = " << sizeofnodes);;
1214 MESSAGE("total size of face elements = " << sizeoffaces);;
1219 ///////////////////////////////////////////////////////////////////////////////
1220 /// Return the number of nodes
1221 ///////////////////////////////////////////////////////////////////////////////
1222 int SMDS_Mesh::NbNodes() const
1224 return myNodes.size();
1227 ///////////////////////////////////////////////////////////////////////////////
1228 /// Return the number of edges (including construction edges)
1229 ///////////////////////////////////////////////////////////////////////////////
1230 int SMDS_Mesh::NbEdges() const
1232 return myEdges.size();
1235 ///////////////////////////////////////////////////////////////////////////////
1236 /// Return the number of faces (including construction faces)
1237 ///////////////////////////////////////////////////////////////////////////////
1238 int SMDS_Mesh::NbFaces() const
1240 return myFaces.size();
1243 ///////////////////////////////////////////////////////////////////////////////
1244 /// Return the number of volumes
1245 ///////////////////////////////////////////////////////////////////////////////
1246 int SMDS_Mesh::NbVolumes() const
1248 return myVolumes.size();
1251 ///////////////////////////////////////////////////////////////////////////////
1252 /// Return the number of child mesh of this mesh.
1253 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1254 /// (2003-09-08) of SMESH
1255 ///////////////////////////////////////////////////////////////////////////////
1256 int SMDS_Mesh::NbSubMesh() const
1258 return myChildren.size();
1261 ///////////////////////////////////////////////////////////////////////////////
1262 /// Destroy the mesh and all its elements
1263 /// All pointer on elements owned by this mesh become illegals.
1264 ///////////////////////////////////////////////////////////////////////////////
1265 SMDS_Mesh::~SMDS_Mesh()
1269 delete myNodeIDFactory;
1270 delete myElementIDFactory;
1273 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1274 while(itc!=myChildren.end())
1280 SMDS_NodeIteratorPtr itn=nodesIterator();
1286 set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1287 while(ite!=myEdges.end())
1293 set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1294 while(itf!=myFaces.end())
1300 set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1301 while(itv!=myVolumes.end())
1308 ///////////////////////////////////////////////////////////////////////////////
1309 /// Return true if this mesh create faces with edges.
1310 /// A false returned value mean that faces are created with nodes. A concequence
1311 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1312 ///////////////////////////////////////////////////////////////////////////////
1313 bool SMDS_Mesh::hasConstructionEdges()
1315 return myHasConstructionEdges;
1318 ///////////////////////////////////////////////////////////////////////////////
1319 /// Return true if this mesh create volumes with faces
1320 /// A false returned value mean that volumes are created with nodes or edges.
1321 /// (see hasConstructionEdges)
1322 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1324 ///////////////////////////////////////////////////////////////////////////////
1325 bool SMDS_Mesh::hasConstructionFaces()
1327 return myHasConstructionFaces;
1330 ///////////////////////////////////////////////////////////////////////////////
1331 /// Return true if nodes are linked to the finit elements, they are belonging to.
1332 /// Currently, It always return true.
1333 ///////////////////////////////////////////////////////////////////////////////
1334 bool SMDS_Mesh::hasInverseElements()
1336 return myHasInverseElements;
1339 ///////////////////////////////////////////////////////////////////////////////
1340 /// Make this mesh creating construction edges (see hasConstructionEdges)
1341 /// @param b true to have construction edges, else false.
1342 ///////////////////////////////////////////////////////////////////////////////
1343 void SMDS_Mesh::setConstructionEdges(bool b)
1345 myHasConstructionEdges=b;
1348 ///////////////////////////////////////////////////////////////////////////////
1349 /// Make this mesh creating construction faces (see hasConstructionFaces)
1350 /// @param b true to have construction faces, else false.
1351 ///////////////////////////////////////////////////////////////////////////////
1352 void SMDS_Mesh::setConstructionFaces(bool b)
1354 myHasConstructionFaces=b;
1357 ///////////////////////////////////////////////////////////////////////////////
1358 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1359 /// @param b true to link nodes to elements, else false.
1360 ///////////////////////////////////////////////////////////////////////////////
1361 void SMDS_Mesh::setInverseElements(bool b)
1363 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1364 myHasInverseElements=b;
1367 ///////////////////////////////////////////////////////////////////////////////
1368 /// Return an iterator on nodes of the current mesh. Once used this iterator
1369 /// must be free by the caller
1370 ///////////////////////////////////////////////////////////////////////////////
1371 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1373 typedef SMDS_Mesh::SetOfNodes SetOfNodes;
1374 const SetOfNodes& mySet;
1375 SetOfNodes::iterator myIterator;
1377 SMDS_Mesh_MyNodeIterator(const SetOfNodes& s):mySet(s)
1379 myIterator=mySet.begin();
1384 return myIterator!=mySet.end();
1387 const SMDS_MeshNode* next()
1389 const SMDS_MeshNode* current=*myIterator;
1395 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1397 return SMDS_NodeIteratorPtr(new SMDS_Mesh_MyNodeIterator(myNodes));
1400 ///////////////////////////////////////////////////////////////////////////////
1401 ///Return an iterator on volumes of the current mesh. Once used this iterator
1402 ///must be free by the caller
1403 ///////////////////////////////////////////////////////////////////////////////
1404 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1406 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1407 const SetOfEdges& mySet;
1408 const SMDS_MeshEdge * myEdge;
1409 SetOfEdges::iterator myIterator;
1411 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s)
1413 myIterator=mySet.begin();
1418 while((myIterator!=mySet.end()))
1420 if((*myIterator)->GetID()!=-1)
1427 const SMDS_MeshEdge* next()
1429 const SMDS_MeshEdge* current=*myIterator;
1435 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1437 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1440 ///////////////////////////////////////////////////////////////////////////////
1441 ///Return an iterator on faces of the current mesh. Once used this iterator
1442 ///must be free by the caller
1443 ///////////////////////////////////////////////////////////////////////////////
1444 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1446 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1447 const SetOfFaces& mySet;
1448 SetOfFaces::iterator myIterator;
1450 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s)
1452 myIterator=mySet.begin();
1457 while((myIterator!=mySet.end()))
1459 if((*myIterator)->GetID()!=-1)
1466 const SMDS_MeshFace* next()
1468 const SMDS_MeshFace* current=*myIterator;
1474 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1476 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
1479 ///////////////////////////////////////////////////////////////////////////////
1480 ///Return an iterator on volumes of the current mesh. Once used this iterator
1481 ///must be free by the caller
1482 ///////////////////////////////////////////////////////////////////////////////
1483 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
1485 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
1486 const SetOfVolumes& mySet;
1487 SetOfVolumes::iterator myIterator;
1489 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s)
1491 myIterator=mySet.begin();
1496 return myIterator!=mySet.end();
1499 const SMDS_MeshVolume* next()
1501 const SMDS_MeshVolume* current=*myIterator;
1507 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1509 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
1512 ///////////////////////////////////////////////////////////////////////////////
1513 /// Do intersection of sets (more than 2)
1514 ///////////////////////////////////////////////////////////////////////////////
1515 static set<const SMDS_MeshElement*> * intersectionOfSets(
1516 set<const SMDS_MeshElement*> vs[], int numberOfSets)
1518 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1519 set<const SMDS_MeshElement*>* rsetB;
1521 for(int i=0; i<numberOfSets-1; i++)
1523 rsetB=new set<const SMDS_MeshElement*>();
1525 rsetA->begin(), rsetA->end(),
1526 vs[i+1].begin(), vs[i+1].end(),
1527 inserter(*rsetB, rsetB->begin()));
1534 ///////////////////////////////////////////////////////////////////////////////
1535 /// Return the list of finit elements owning the given element
1536 ///////////////////////////////////////////////////////////////////////////////
1537 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1539 int numberOfSets=element->NbNodes();
1540 set<const SMDS_MeshElement*> initSet[numberOfSets];
1542 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1545 while(itNodes->more())
1547 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1548 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1550 //initSet[i]=set<const SMDS_MeshElement*>();
1552 initSet[i].insert(itFe->next());
1557 return intersectionOfSets(initSet, numberOfSets);
1560 ///////////////////////////////////////////////////////////////////////////////
1561 /// Return the list of nodes used only by the given elements
1562 ///////////////////////////////////////////////////////////////////////////////
1563 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1564 set<const SMDS_MeshElement*>& elements)
1566 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1567 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1569 while(itElements!=elements.end())
1571 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
1574 while(itNodes->more())
1576 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1577 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1578 set<const SMDS_MeshElement*> s;
1580 s.insert(itFe->next());
1581 if(s==elements) toReturn->insert(n);
1587 ///////////////////////////////////////////////////////////////////////////////
1588 ///Find the children of an element that are made of given nodes
1589 ///@param setOfChildren The set in which matching children will be inserted
1590 ///@param element The element were to search matching children
1591 ///@param nodes The nodes that the children must have to be selected
1592 ///////////////////////////////////////////////////////////////////////////////
1593 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
1594 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1597 switch(element->GetType())
1600 MESSAGE("Internal Error: This should not append");
1604 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1607 const SMDS_MeshElement * e=itn->next();
1608 if(nodes.find(e)!=nodes.end())
1610 setOfChildren.insert(element);
1617 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1620 const SMDS_MeshElement * e=itn->next();
1621 if(nodes.find(e)!=nodes.end())
1623 setOfChildren.insert(element);
1627 if(hasConstructionEdges())
1629 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1631 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1634 case SMDSAbs_Volume:
1636 if(hasConstructionFaces())
1638 SMDS_ElemIteratorPtr ite=element->facesIterator();
1640 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1642 else if(hasConstructionEdges())
1644 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1646 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1652 ///////////////////////////////////////////////////////////////////////////////
1653 ///@param elem The element to delete
1654 ///@param removenodes if true remaining nodes will be removed
1655 ///////////////////////////////////////////////////////////////////////////////
1656 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1657 const bool removenodes)
1659 list<const SMDS_MeshElement *> removedElems;
1660 list<const SMDS_MeshElement *> removedNodes;
1661 RemoveElement( elem, removedElems, removedNodes, removenodes );
1664 ///////////////////////////////////////////////////////////////////////////////
1665 ///@param elem The element to delete
1666 ///@param removedElems contains all removed elements
1667 ///@param removedNodes contains all removed nodes
1668 ///@param removenodes if true remaining nodes will be removed
1669 ///////////////////////////////////////////////////////////////////////////////
1670 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1671 list<const SMDS_MeshElement *>& removedElems,
1672 list<const SMDS_MeshElement *>& removedNodes,
1673 const bool removenodes)
1675 // get finite elements built on elem
1676 set<const SMDS_MeshElement*> * s1;
1677 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
1678 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
1680 s1 = new set<const SMDS_MeshElement*>();
1684 s1 = getFinitElements(elem);
1686 // get exclusive nodes (which would become free afterwards)
1687 set<const SMDS_MeshElement*> * s2;
1688 if (s1->empty() && elem->GetType() == SMDSAbs_Node)
1690 s2 = new set<const SMDS_MeshElement*>();
1694 s2 = getExclusiveNodes(*s1);
1696 // form the set of finite and construction elements to remove
1697 set<const SMDS_MeshElement*> s3;
1698 set<const SMDS_MeshElement*>::iterator it=s1->begin();
1699 while(it!=s1->end())
1701 addChildrenWithNodes(s3, *it ,*s2);
1705 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1707 // remove finite and construction elements
1711 // Remove element from <InverseElements> of its nodes
1712 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
1715 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1716 (const_cast<SMDS_MeshElement *>(itn->next()));
1717 n->RemoveInverseElement( (*it) );
1720 switch((*it)->GetType())
1723 MESSAGE("Internal Error: This should not happen");
1726 myEdges.erase(static_cast<SMDS_MeshEdge*>
1727 (const_cast<SMDS_MeshElement*>(*it)));
1730 myFaces.erase(static_cast<SMDS_MeshFace*>
1731 (const_cast<SMDS_MeshElement*>(*it)));
1733 case SMDSAbs_Volume:
1734 myVolumes.erase(static_cast<SMDS_MeshVolume*>
1735 (const_cast<SMDS_MeshElement*>(*it)));
1738 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
1739 removedElems.push_back( (*it) );
1740 myElementIDFactory->ReleaseID((*it)->GetID());
1745 // remove exclusive (free) nodes
1749 while(it!=s2->end())
1751 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
1752 myNodes.erase(static_cast<SMDS_MeshNode*>
1753 (const_cast<SMDS_MeshElement*>(*it)));
1754 myNodeIDFactory->ReleaseID((*it)->GetID());
1755 removedNodes.push_back( (*it) );
1766 * Checks if the element is present in mesh.
1767 * Useful to determine dead pointers.
1769 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1771 // we should not imply on validity of *elem, so iterate on containers
1772 // of all types in the hope of finding <elem> somewhere there
1773 SMDS_NodeIteratorPtr itn = nodesIterator();
1775 if (elem == itn->next())
1777 SMDS_EdgeIteratorPtr ite = edgesIterator();
1779 if (elem == ite->next())
1781 SMDS_FaceIteratorPtr itf = facesIterator();
1783 if (elem == itf->next())
1785 SMDS_VolumeIteratorPtr itv = volumesIterator();
1787 if (elem == itv->next())