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
23 #pragma warning(disable:4786)
26 #include "utilities.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeOfNodes.hxx"
29 #include "SMDS_VolumeOfFaces.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_FaceOfEdges.hxx"
37 ///////////////////////////////////////////////////////////////////////////////
38 /// Create a new mesh object
39 ///////////////////////////////////////////////////////////////////////////////
40 SMDS_Mesh::SMDS_Mesh()
42 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
43 myElementIDFactory(new SMDS_MeshElementIDFactory()),
44 myHasConstructionEdges(false), myHasConstructionFaces(false),
45 myHasInverseElements(true)
49 ///////////////////////////////////////////////////////////////////////////////
50 /// Create a new child mesh
51 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
52 /// (2003-09-08) of SMESH
53 ///////////////////////////////////////////////////////////////////////////////
54 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
55 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
56 myElementIDFactory(parent->myElementIDFactory),
57 myHasConstructionEdges(false), myHasConstructionFaces(false),
58 myHasInverseElements(true)
62 ///////////////////////////////////////////////////////////////////////////////
63 ///Create a submesh and add it to the current mesh
64 ///////////////////////////////////////////////////////////////////////////////
66 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
68 SMDS_Mesh *submesh = new SMDS_Mesh(this);
69 myChildren.insert(myChildren.end(), submesh);
73 ///////////////////////////////////////////////////////////////////////////////
74 ///create a MeshNode and add it to the current Mesh
75 ///An ID is automatically assigned to the node.
76 ///@return : The created node
77 ///////////////////////////////////////////////////////////////////////////////
79 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
81 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
84 ///////////////////////////////////////////////////////////////////////////////
85 ///create a MeshNode and add it to the current Mesh
86 ///@param ID : The ID of the MeshNode to create
87 ///@return : The created node or NULL if a node with this ID already exists
88 ///////////////////////////////////////////////////////////////////////////////
89 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
91 // find the MeshNode corresponding to ID
92 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
94 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
96 myNodeIDFactory->BindID(ID,node);
102 ///////////////////////////////////////////////////////////////////////////////
103 /// create a MeshEdge and add it to the current Mesh
104 /// @return : The created MeshEdge
105 ///////////////////////////////////////////////////////////////////////////////
107 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
109 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
110 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
111 if(!node1 || !node2) return NULL;
112 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
115 ///////////////////////////////////////////////////////////////////////////////
116 /// create a MeshEdge and add it to the current Mesh
117 /// @return : The created MeshEdge
118 ///////////////////////////////////////////////////////////////////////////////
120 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
121 const SMDS_MeshNode * node2)
123 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
126 ///////////////////////////////////////////////////////////////////////////////
127 /// Create a new edge and at it to the mesh
128 /// @param idnode1 ID of the first node
129 /// @param idnode2 ID of the second node
130 /// @param ID ID of the edge to create
131 /// @return The created edge or NULL if an element with this ID already exists or
132 /// if input nodes are not found.
133 ///////////////////////////////////////////////////////////////////////////////
135 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
136 const SMDS_MeshNode * n2,
139 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
140 if(myElementIDFactory->BindID(ID, edge)) {
141 SMDS_MeshNode *node1,*node2;
142 node1=const_cast<SMDS_MeshNode*>(n1);
143 node2=const_cast<SMDS_MeshNode*>(n2);
144 node1->AddInverseElement(edge);
145 node2->AddInverseElement(edge);
155 ///////////////////////////////////////////////////////////////////////////////
156 /// Add a triangle defined by its nodes. An ID is automatically affected to the
158 ///////////////////////////////////////////////////////////////////////////////
160 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
161 const SMDS_MeshNode * n2,
162 const SMDS_MeshNode * n3)
164 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
167 ///////////////////////////////////////////////////////////////////////////////
168 /// Add a triangle defined by its nodes IDs
169 ///////////////////////////////////////////////////////////////////////////////
171 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
173 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
174 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
175 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
176 if(!node1 || !node2 || !node3) return NULL;
177 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
180 ///////////////////////////////////////////////////////////////////////////////
181 /// Add a triangle defined by its nodes
182 ///////////////////////////////////////////////////////////////////////////////
184 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
185 const SMDS_MeshNode * n2,
186 const SMDS_MeshNode * n3,
189 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
191 if (!registerElement(ID, face)) {
192 RemoveElement(face, false);
198 ///////////////////////////////////////////////////////////////////////////////
199 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
201 ///////////////////////////////////////////////////////////////////////////////
203 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
204 const SMDS_MeshNode * n2,
205 const SMDS_MeshNode * n3,
206 const SMDS_MeshNode * n4)
208 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
211 ///////////////////////////////////////////////////////////////////////////////
212 /// Add a quadrangle defined by its nodes IDs
213 ///////////////////////////////////////////////////////////////////////////////
215 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
221 SMDS_MeshNode *node1, *node2, *node3, *node4;
222 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
223 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
224 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
225 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
226 if(!node1 || !node2 || !node3 || !node4) return NULL;
227 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
230 ///////////////////////////////////////////////////////////////////////////////
231 /// Add a quadrangle defined by its nodes
232 ///////////////////////////////////////////////////////////////////////////////
234 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
235 const SMDS_MeshNode * n2,
236 const SMDS_MeshNode * n3,
237 const SMDS_MeshNode * n4,
240 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
242 if (!registerElement(ID, face)) {
243 RemoveElement(face, false);
249 ///////////////////////////////////////////////////////////////////////////////
250 /// Add a triangle defined by its edges. An ID is automatically assigned to the
252 ///////////////////////////////////////////////////////////////////////////////
254 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
255 const SMDS_MeshEdge * e2,
256 const SMDS_MeshEdge * e3)
258 if (!hasConstructionEdges())
260 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Add a triangle defined by its edges
265 ///////////////////////////////////////////////////////////////////////////////
267 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
268 const SMDS_MeshEdge * e2,
269 const SMDS_MeshEdge * e3,
272 if (!hasConstructionEdges())
274 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
277 if (!registerElement(ID, face)) {
278 RemoveElement(face, false);
284 ///////////////////////////////////////////////////////////////////////////////
285 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
287 ///////////////////////////////////////////////////////////////////////////////
289 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
290 const SMDS_MeshEdge * e2,
291 const SMDS_MeshEdge * e3,
292 const SMDS_MeshEdge * e4)
294 if (!hasConstructionEdges())
296 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
299 ///////////////////////////////////////////////////////////////////////////////
300 /// Add a quadrangle defined by its edges
301 ///////////////////////////////////////////////////////////////////////////////
303 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
304 const SMDS_MeshEdge * e2,
305 const SMDS_MeshEdge * e3,
306 const SMDS_MeshEdge * e4,
309 if (!hasConstructionEdges())
311 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
314 if (!registerElement(ID, face))
316 RemoveElement(face, false);
322 ///////////////////////////////////////////////////////////////////////////////
323 ///Create a new tetrahedron and add it to the mesh.
324 ///@return The created tetrahedron
325 ///////////////////////////////////////////////////////////////////////////////
327 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
328 const SMDS_MeshNode * n2,
329 const SMDS_MeshNode * n3,
330 const SMDS_MeshNode * n4)
332 int ID = myElementIDFactory->GetFreeID();
333 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
334 if(v==NULL) myElementIDFactory->ReleaseID(ID);
338 ///////////////////////////////////////////////////////////////////////////////
339 ///Create a new tetrahedron and add it to the mesh.
340 ///@param ID The ID of the new volume
341 ///@return The created tetrahedron or NULL if an element with this ID already exists
342 ///or if input nodes are not found.
343 ///////////////////////////////////////////////////////////////////////////////
345 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
351 SMDS_MeshNode *node1, *node2, *node3, *node4;
352 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
353 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
354 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
355 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
356 if(!node1 || !node2 || !node3 || !node4) return NULL;
357 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
360 ///////////////////////////////////////////////////////////////////////////////
361 ///Create a new tetrahedron and add it to the mesh.
362 ///@param ID The ID of the new volume
363 ///@return The created tetrahedron
364 ///////////////////////////////////////////////////////////////////////////////
366 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
367 const SMDS_MeshNode * n2,
368 const SMDS_MeshNode * n3,
369 const SMDS_MeshNode * n4,
372 SMDS_MeshVolume* volume;
373 if(hasConstructionFaces()) {
374 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
375 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
376 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
377 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
378 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
379 myVolumes.Add(volume);
381 else if(hasConstructionEdges()) {
382 MESSAGE("Error : Not implemented");
386 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
387 myVolumes.Add(volume);
390 if (!registerElement(ID, volume)) {
391 RemoveElement(volume, false);
397 ///////////////////////////////////////////////////////////////////////////////
398 ///Create a new pyramid and add it to the mesh.
399 ///Nodes 1,2,3 and 4 define the base of the pyramid
400 ///@return The created pyramid
401 ///////////////////////////////////////////////////////////////////////////////
403 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
404 const SMDS_MeshNode * n2,
405 const SMDS_MeshNode * n3,
406 const SMDS_MeshNode * n4,
407 const SMDS_MeshNode * n5)
409 int ID = myElementIDFactory->GetFreeID();
410 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
411 if(v==NULL) myElementIDFactory->ReleaseID(ID);
415 ///////////////////////////////////////////////////////////////////////////////
416 ///Create a new pyramid and add it to the mesh.
417 ///Nodes 1,2,3 and 4 define the base of the pyramid
418 ///@param ID The ID of the new volume
419 ///@return The created pyramid or NULL if an element with this ID already exists
420 ///or if input nodes are not found.
421 ///////////////////////////////////////////////////////////////////////////////
423 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
430 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
431 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
432 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
433 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
434 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
435 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
436 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
437 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
440 ///////////////////////////////////////////////////////////////////////////////
441 ///Create a new pyramid and add it to the mesh.
442 ///Nodes 1,2,3 and 4 define the base of the pyramid
443 ///@param ID The ID of the new volume
444 ///@return The created pyramid
445 ///////////////////////////////////////////////////////////////////////////////
447 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
448 const SMDS_MeshNode * n2,
449 const SMDS_MeshNode * n3,
450 const SMDS_MeshNode * n4,
451 const SMDS_MeshNode * n5,
454 SMDS_MeshVolume* volume;
455 if(hasConstructionFaces()) {
456 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
457 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
458 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
459 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
460 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
461 myVolumes.Add(volume);
463 else if(hasConstructionEdges()) {
464 MESSAGE("Error : Not implemented");
468 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
469 myVolumes.Add(volume);
472 if (!registerElement(ID, volume)) {
473 RemoveElement(volume, false);
479 ///////////////////////////////////////////////////////////////////////////////
480 ///Create a new prism and add it to the mesh.
481 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
482 ///@return The created prism
483 ///////////////////////////////////////////////////////////////////////////////
485 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
486 const SMDS_MeshNode * n2,
487 const SMDS_MeshNode * n3,
488 const SMDS_MeshNode * n4,
489 const SMDS_MeshNode * n5,
490 const SMDS_MeshNode * n6)
492 int ID = myElementIDFactory->GetFreeID();
493 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
494 if(v==NULL) myElementIDFactory->ReleaseID(ID);
498 ///////////////////////////////////////////////////////////////////////////////
499 ///Create a new prism and add it to the mesh.
500 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
501 ///@param ID The ID of the new volume
502 ///@return The created prism or NULL if an element with this ID already exists
503 ///or if input nodes are not found.
504 ///////////////////////////////////////////////////////////////////////////////
506 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
514 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
515 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
516 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
517 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
518 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
519 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
520 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
521 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
522 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
525 ///////////////////////////////////////////////////////////////////////////////
526 ///Create a new prism and add it to the mesh.
527 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
528 ///@param ID The ID of the new volume
529 ///@return The created prism
530 ///////////////////////////////////////////////////////////////////////////////
532 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
533 const SMDS_MeshNode * n2,
534 const SMDS_MeshNode * n3,
535 const SMDS_MeshNode * n4,
536 const SMDS_MeshNode * n5,
537 const SMDS_MeshNode * n6,
540 SMDS_MeshVolume* volume;
541 if(hasConstructionFaces()) {
542 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
543 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
544 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
545 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
546 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
547 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
548 myVolumes.Add(volume);
550 else if(hasConstructionEdges()) {
551 MESSAGE("Error : Not implemented");
555 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
556 myVolumes.Add(volume);
559 if (!registerElement(ID, volume)) {
560 RemoveElement(volume, false);
566 ///////////////////////////////////////////////////////////////////////////////
567 ///Create a new hexahedron and add it to the mesh.
568 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
569 ///@return The created hexahedron
570 ///////////////////////////////////////////////////////////////////////////////
572 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
573 const SMDS_MeshNode * n2,
574 const SMDS_MeshNode * n3,
575 const SMDS_MeshNode * n4,
576 const SMDS_MeshNode * n5,
577 const SMDS_MeshNode * n6,
578 const SMDS_MeshNode * n7,
579 const SMDS_MeshNode * n8)
581 int ID = myElementIDFactory->GetFreeID();
582 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
583 if(v==NULL) myElementIDFactory->ReleaseID(ID);
587 ///////////////////////////////////////////////////////////////////////////////
588 ///Create a new hexahedron and add it to the mesh.
589 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
590 ///@param ID The ID of the new volume
591 ///@return The created hexahedron or NULL if an element with this ID already
592 ///exists or if input nodes are not found.
593 ///////////////////////////////////////////////////////////////////////////////
595 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
605 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
606 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
607 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
608 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
609 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
610 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
611 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
612 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
613 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
614 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
616 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
620 ///////////////////////////////////////////////////////////////////////////////
621 ///Create a new hexahedron and add it to the mesh.
622 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
623 ///@param ID The ID of the new volume
624 ///@return The created prism or NULL if an element with this ID already exists
625 ///or if input nodes are not found.
626 ///////////////////////////////////////////////////////////////////////////////
628 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
629 const SMDS_MeshNode * n2,
630 const SMDS_MeshNode * n3,
631 const SMDS_MeshNode * n4,
632 const SMDS_MeshNode * n5,
633 const SMDS_MeshNode * n6,
634 const SMDS_MeshNode * n7,
635 const SMDS_MeshNode * n8,
638 SMDS_MeshVolume* volume;
639 if(hasConstructionFaces()) {
640 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
641 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
642 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
643 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
644 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
645 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
646 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
647 myVolumes.Add(volume);
649 else if(hasConstructionEdges()) {
650 MESSAGE("Error : Not implemented");
654 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
655 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
656 myVolumes.Add(volume);
659 if (!registerElement(ID, volume)) {
660 RemoveElement(volume, false);
666 ///////////////////////////////////////////////////////////////////////////////
667 ///Create a new tetrahedron defined by its faces and add it to the mesh.
668 ///@return The created tetrahedron
669 ///////////////////////////////////////////////////////////////////////////////
671 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
672 const SMDS_MeshFace * f2,
673 const SMDS_MeshFace * f3,
674 const SMDS_MeshFace * f4)
676 if (!hasConstructionFaces())
678 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
681 ///////////////////////////////////////////////////////////////////////////////
682 ///Create a new tetrahedron defined by its faces and add it to the mesh.
683 ///@param ID The ID of the new volume
684 ///@return The created tetrahedron
685 ///////////////////////////////////////////////////////////////////////////////
687 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
688 const SMDS_MeshFace * f2,
689 const SMDS_MeshFace * f3,
690 const SMDS_MeshFace * f4,
693 if (!hasConstructionFaces())
695 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
696 myVolumes.Add(volume);
698 if (!registerElement(ID, volume)) {
699 RemoveElement(volume, false);
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new pyramid defined by its faces and add it to the mesh.
707 ///@return The created pyramid
708 ///////////////////////////////////////////////////////////////////////////////
710 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
711 const SMDS_MeshFace * f2,
712 const SMDS_MeshFace * f3,
713 const SMDS_MeshFace * f4,
714 const SMDS_MeshFace * f5)
716 if (!hasConstructionFaces())
718 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
721 ///////////////////////////////////////////////////////////////////////////////
722 ///Create a new pyramid defined by its faces and add it to the mesh.
723 ///@param ID The ID of the new volume
724 ///@return The created pyramid
725 ///////////////////////////////////////////////////////////////////////////////
727 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
728 const SMDS_MeshFace * f2,
729 const SMDS_MeshFace * f3,
730 const SMDS_MeshFace * f4,
731 const SMDS_MeshFace * f5,
734 if (!hasConstructionFaces())
736 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
737 myVolumes.Add(volume);
739 if (!registerElement(ID, volume)) {
740 RemoveElement(volume, false);
746 ///////////////////////////////////////////////////////////////////////////////
747 ///Create a new prism defined by its faces and add it to the mesh.
748 ///@return The created prism
749 ///////////////////////////////////////////////////////////////////////////////
751 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
752 const SMDS_MeshFace * f2,
753 const SMDS_MeshFace * f3,
754 const SMDS_MeshFace * f4,
755 const SMDS_MeshFace * f5,
756 const SMDS_MeshFace * f6)
758 if (!hasConstructionFaces())
760 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
763 ///////////////////////////////////////////////////////////////////////////////
764 ///Create a new prism defined by its faces and add it to the mesh.
765 ///@param ID The ID of the new volume
766 ///@return The created prism
767 ///////////////////////////////////////////////////////////////////////////////
769 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
770 const SMDS_MeshFace * f2,
771 const SMDS_MeshFace * f3,
772 const SMDS_MeshFace * f4,
773 const SMDS_MeshFace * f5,
774 const SMDS_MeshFace * f6,
777 if (!hasConstructionFaces())
779 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
780 myVolumes.Add(volume);
782 if (!registerElement(ID, volume)) {
783 RemoveElement(volume, false);
789 ///////////////////////////////////////////////////////////////////////////////
790 /// Registers element with the given ID, maintains inverse connections
791 ///////////////////////////////////////////////////////////////////////////////
792 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
794 if (myElementIDFactory->BindID(ID, element)) {
795 SMDS_ElemIteratorPtr it = element->nodesIterator();
797 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
798 (const_cast<SMDS_MeshElement*>(it->next()));
799 node->AddInverseElement(element);
806 ///////////////////////////////////////////////////////////////////////////////
807 /// Return the node whose ID is 'ID'.
808 ///////////////////////////////////////////////////////////////////////////////
809 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
811 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
814 ///////////////////////////////////////////////////////////////////////////////
815 ///Create a triangle and add it to the current mesh. This methode do not bind a
816 ///ID to the create triangle.
817 ///////////////////////////////////////////////////////////////////////////////
818 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
819 const SMDS_MeshNode * node2,
820 const SMDS_MeshNode * node3)
822 if(hasConstructionEdges())
824 SMDS_MeshEdge *edge1, *edge2, *edge3;
825 edge1=FindEdgeOrCreate(node1,node2);
826 edge2=FindEdgeOrCreate(node2,node3);
827 edge3=FindEdgeOrCreate(node3,node1);
829 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
835 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
841 ///////////////////////////////////////////////////////////////////////////////
842 ///Create a quadrangle and add it to the current mesh. This methode do not bind
843 ///a ID to the create triangle.
844 ///////////////////////////////////////////////////////////////////////////////
845 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
846 const SMDS_MeshNode * node2,
847 const SMDS_MeshNode * node3,
848 const SMDS_MeshNode * node4)
850 if(hasConstructionEdges())
852 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
853 edge1=FindEdgeOrCreate(node1,node2);
854 edge2=FindEdgeOrCreate(node2,node3);
855 edge3=FindEdgeOrCreate(node3,node4);
856 edge4=FindEdgeOrCreate(node4,node1);
858 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
864 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
870 ///////////////////////////////////////////////////////////////////////////////
871 /// Remove a node and all the elements which own this node
872 ///////////////////////////////////////////////////////////////////////////////
874 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
876 RemoveElement(node, true);
879 ///////////////////////////////////////////////////////////////////////////////
880 /// Remove an edge and all the elements which own this edge
881 ///////////////////////////////////////////////////////////////////////////////
883 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
885 RemoveElement(edge,true);
888 ///////////////////////////////////////////////////////////////////////////////
889 /// Remove an face and all the elements which own this face
890 ///////////////////////////////////////////////////////////////////////////////
892 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
894 RemoveElement(face, true);
897 ///////////////////////////////////////////////////////////////////////////////
899 ///////////////////////////////////////////////////////////////////////////////
901 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
903 RemoveElement(volume, true);
906 //=======================================================================
907 //function : RemoveFromParent
909 //=======================================================================
911 bool SMDS_Mesh::RemoveFromParent()
913 if (myParent==NULL) return false;
914 else return (myParent->RemoveSubMesh(this));
917 //=======================================================================
918 //function : RemoveSubMesh
920 //=======================================================================
922 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
926 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
927 for (; itmsh!=myChildren.end() && !found; itmsh++)
929 SMDS_Mesh * submesh = *itmsh;
930 if (submesh == aMesh)
933 myChildren.erase(itmsh);
940 //=======================================================================
941 //function : ChangeElementNodes
943 //=======================================================================
945 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
946 const SMDS_MeshNode * nodes[],
949 // keep current nodes of elem
950 set<const SMDS_MeshElement*> oldNodes;
951 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
953 oldNodes.insert( itn->next() );
957 switch ( elem->GetType() )
960 if ( nbnodes == 2 ) {
961 const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
963 Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
968 const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
970 Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
973 case SMDSAbs_Volume: {
974 const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
976 Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
980 MESSAGE ( "WRONG ELEM TYPE");
983 if ( Ok ) { // update InverseElements
985 // AddInverseElement to new nodes
986 for ( int i = 0; i < nbnodes; i++ )
987 if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
989 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
991 // remove from oldNodes a node that remains in elem
992 oldNodes.erase( nodes[i] );
995 // RemoveInverseElement from the nodes removed from elem
996 set<const SMDS_MeshElement*>::iterator it;
997 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
999 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1000 (const_cast<SMDS_MeshElement *>( *it ));
1001 n->RemoveInverseElement( elem );
1005 //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1010 //=======================================================================
1011 //function : FindEdge
1013 //=======================================================================
1015 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1017 const SMDS_MeshNode * node1=FindNode(idnode1);
1018 const SMDS_MeshNode * node2=FindNode(idnode2);
1019 if((node1==NULL)||(node2==NULL)) return NULL;
1020 return FindEdge(node1,node2);
1023 //#include "Profiler.h"
1024 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1025 const SMDS_MeshNode * node2)
1027 const SMDS_MeshEdge * toReturn=NULL;
1030 SMDS_ElemIteratorPtr it1=node1->edgesIterator();
1035 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
1037 SMDS_ElemIteratorPtr it2=e->nodesIterator();
1040 if(it2->next()->GetID()==node2->GetID())
1052 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1053 const SMDS_MeshNode * node2)
1055 SMDS_MeshEdge * toReturn=NULL;
1056 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1059 toReturn=new SMDS_MeshEdge(node1,node2);
1060 myEdges.Add(toReturn);
1065 //=======================================================================
1066 //function : FindFace
1068 //=======================================================================
1070 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1073 const SMDS_MeshNode * node1=FindNode(idnode1);
1074 const SMDS_MeshNode * node2=FindNode(idnode2);
1075 const SMDS_MeshNode * node3=FindNode(idnode3);
1076 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
1077 return FindFace(node1, node2, node3);
1080 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1081 const SMDS_MeshNode *node1,
1082 const SMDS_MeshNode *node2,
1083 const SMDS_MeshNode *node3)
1085 const SMDS_MeshFace * face;
1086 const SMDS_MeshElement * node;
1087 bool node2found, node3found;
1089 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1092 face=static_cast<const SMDS_MeshFace*>(it1->next());
1093 if(face->NbNodes()!=3) continue;
1094 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1100 if(node->GetID()==node2->GetID()) node2found=true;
1101 if(node->GetID()==node3->GetID()) node3found=true;
1103 if(node2found&&node3found)
1109 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1110 const SMDS_MeshNode *node1,
1111 const SMDS_MeshNode *node2,
1112 const SMDS_MeshNode *node3)
1114 SMDS_MeshFace * toReturn=NULL;
1115 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1118 toReturn=createTriangle(node1,node2,node3);
1123 //=======================================================================
1124 //function : FindFace
1126 //=======================================================================
1128 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
1131 const SMDS_MeshNode * node1=FindNode(idnode1);
1132 const SMDS_MeshNode * node2=FindNode(idnode2);
1133 const SMDS_MeshNode * node3=FindNode(idnode3);
1134 const SMDS_MeshNode * node4=FindNode(idnode4);
1135 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
1136 return FindFace(node1, node2, node3, node4);
1139 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1140 const SMDS_MeshNode *node1,
1141 const SMDS_MeshNode *node2,
1142 const SMDS_MeshNode *node3,
1143 const SMDS_MeshNode *node4)
1145 const SMDS_MeshFace * face;
1146 const SMDS_MeshElement * node;
1147 bool node2found, node3found, node4found;
1148 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1151 face=static_cast<const SMDS_MeshFace *>(it1->next());
1152 if(face->NbNodes()!=4) continue;
1153 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1160 if(node->GetID()==node2->GetID()) node2found=true;
1161 if(node->GetID()==node3->GetID()) node3found=true;
1162 if(node->GetID()==node4->GetID()) node4found=true;
1164 if(node2found&&node3found&&node4found)
1170 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1171 const SMDS_MeshNode *node1,
1172 const SMDS_MeshNode *node2,
1173 const SMDS_MeshNode *node3,
1174 const SMDS_MeshNode *node4)
1176 SMDS_MeshFace * toReturn=NULL;
1177 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1180 toReturn=createQuadrangle(node1,node2,node3,node4);
1185 //=======================================================================
1186 //function : FindElement
1188 //=======================================================================
1190 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1192 return myElementIDFactory->MeshElement(IDelem);
1195 //=======================================================================
1196 //function : DumpNodes
1198 //=======================================================================
1200 void SMDS_Mesh::DumpNodes() const
1202 MESSAGE("dump nodes of mesh : ");
1203 SMDS_NodeIteratorPtr itnode=nodesIterator();
1204 while(itnode->more()) MESSAGE(itnode->next());
1207 //=======================================================================
1208 //function : DumpEdges
1210 //=======================================================================
1212 void SMDS_Mesh::DumpEdges() const
1214 MESSAGE("dump edges of mesh : ");
1215 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1216 while(itedge->more()) MESSAGE(itedge->next());
1219 //=======================================================================
1220 //function : DumpFaces
1222 //=======================================================================
1224 void SMDS_Mesh::DumpFaces() const
1226 MESSAGE("dump faces of mesh : ");
1227 SMDS_FaceIteratorPtr itface=facesIterator();
1228 while(itface->more()) MESSAGE(itface->next());
1231 //=======================================================================
1232 //function : DumpVolumes
1234 //=======================================================================
1236 void SMDS_Mesh::DumpVolumes() const
1238 MESSAGE("dump volumes of mesh : ");
1239 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1240 while(itvol->more()) MESSAGE(itvol->next());
1243 //=======================================================================
1244 //function : DebugStats
1246 //=======================================================================
1248 void SMDS_Mesh::DebugStats() const
1250 MESSAGE("Debug stats of mesh : ");
1252 MESSAGE("===== NODES ====="<<NbNodes());
1253 MESSAGE("===== EDGES ====="<<NbEdges());
1254 MESSAGE("===== FACES ====="<<NbFaces());
1255 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1257 MESSAGE("End Debug stats of mesh ");
1261 SMDS_NodeIteratorPtr itnode=nodesIterator();
1262 int sizeofnodes = 0;
1263 int sizeoffaces = 0;
1265 while(itnode->more())
1267 const SMDS_MeshNode *node = itnode->next();
1269 sizeofnodes += sizeof(*node);
1271 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1274 const SMDS_MeshElement *me = it->next();
1275 sizeofnodes += sizeof(me);
1280 SMDS_FaceIteratorPtr itface=facesIterator();
1281 while(itface->more())
1283 const SMDS_MeshElement *face = itface->next();
1284 sizeoffaces += sizeof(*face);
1287 MESSAGE("total size of node elements = " << sizeofnodes);;
1288 MESSAGE("total size of face elements = " << sizeoffaces);;
1293 ///////////////////////////////////////////////////////////////////////////////
1294 /// Return the number of nodes
1295 ///////////////////////////////////////////////////////////////////////////////
1296 int SMDS_Mesh::NbNodes() const
1298 return myNodes.Size();
1301 ///////////////////////////////////////////////////////////////////////////////
1302 /// Return the number of edges (including construction edges)
1303 ///////////////////////////////////////////////////////////////////////////////
1304 int SMDS_Mesh::NbEdges() const
1306 return myEdges.Size();
1309 ///////////////////////////////////////////////////////////////////////////////
1310 /// Return the number of faces (including construction faces)
1311 ///////////////////////////////////////////////////////////////////////////////
1312 int SMDS_Mesh::NbFaces() const
1314 return myFaces.Size();
1317 ///////////////////////////////////////////////////////////////////////////////
1318 /// Return the number of volumes
1319 ///////////////////////////////////////////////////////////////////////////////
1320 int SMDS_Mesh::NbVolumes() const
1322 return myVolumes.Size();
1325 ///////////////////////////////////////////////////////////////////////////////
1326 /// Return the number of child mesh of this mesh.
1327 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1328 /// (2003-09-08) of SMESH
1329 ///////////////////////////////////////////////////////////////////////////////
1330 int SMDS_Mesh::NbSubMesh() const
1332 return myChildren.size();
1335 ///////////////////////////////////////////////////////////////////////////////
1336 /// Destroy the mesh and all its elements
1337 /// All pointer on elements owned by this mesh become illegals.
1338 ///////////////////////////////////////////////////////////////////////////////
1339 SMDS_Mesh::~SMDS_Mesh()
1341 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1342 while(itc!=myChildren.end())
1348 SetOfNodes::Iterator itn(myNodes);
1349 for (; itn.More(); itn.Next())
1352 SetOfEdges::Iterator ite(myEdges);
1353 for (; ite.More(); ite.Next())
1355 SMDS_MeshElement* elem = ite.Value();
1357 myElementIDFactory->ReleaseID(elem->GetID());
1361 SetOfFaces::Iterator itf(myFaces);
1362 for (; itf.More(); itf.Next())
1364 SMDS_MeshElement* elem = itf.Value();
1366 myElementIDFactory->ReleaseID(elem->GetID());
1370 SetOfVolumes::Iterator itv(myVolumes);
1371 for (; itv.More(); itv.Next())
1373 SMDS_MeshElement* elem = itv.Value();
1375 myElementIDFactory->ReleaseID(elem->GetID());
1381 delete myNodeIDFactory;
1382 delete myElementIDFactory;
1386 ///////////////////////////////////////////////////////////////////////////////
1387 /// Return true if this mesh create faces with edges.
1388 /// A false returned value mean that faces are created with nodes. A concequence
1389 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1390 ///////////////////////////////////////////////////////////////////////////////
1391 bool SMDS_Mesh::hasConstructionEdges()
1393 return myHasConstructionEdges;
1396 ///////////////////////////////////////////////////////////////////////////////
1397 /// Return true if this mesh create volumes with faces
1398 /// A false returned value mean that volumes are created with nodes or edges.
1399 /// (see hasConstructionEdges)
1400 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1402 ///////////////////////////////////////////////////////////////////////////////
1403 bool SMDS_Mesh::hasConstructionFaces()
1405 return myHasConstructionFaces;
1408 ///////////////////////////////////////////////////////////////////////////////
1409 /// Return true if nodes are linked to the finit elements, they are belonging to.
1410 /// Currently, It always return true.
1411 ///////////////////////////////////////////////////////////////////////////////
1412 bool SMDS_Mesh::hasInverseElements()
1414 return myHasInverseElements;
1417 ///////////////////////////////////////////////////////////////////////////////
1418 /// Make this mesh creating construction edges (see hasConstructionEdges)
1419 /// @param b true to have construction edges, else false.
1420 ///////////////////////////////////////////////////////////////////////////////
1421 void SMDS_Mesh::setConstructionEdges(bool b)
1423 myHasConstructionEdges=b;
1426 ///////////////////////////////////////////////////////////////////////////////
1427 /// Make this mesh creating construction faces (see hasConstructionFaces)
1428 /// @param b true to have construction faces, else false.
1429 ///////////////////////////////////////////////////////////////////////////////
1430 void SMDS_Mesh::setConstructionFaces(bool b)
1432 myHasConstructionFaces=b;
1435 ///////////////////////////////////////////////////////////////////////////////
1436 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1437 /// @param b true to link nodes to elements, else false.
1438 ///////////////////////////////////////////////////////////////////////////////
1439 void SMDS_Mesh::setInverseElements(bool b)
1441 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1442 myHasInverseElements=b;
1445 ///////////////////////////////////////////////////////////////////////////////
1446 /// Return an iterator on nodes of the current mesh factory
1447 ///////////////////////////////////////////////////////////////////////////////
1448 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1450 SMDS_ElemIteratorPtr myIterator;
1452 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1457 return myIterator->more();
1460 const SMDS_MeshNode* next()
1462 return static_cast<const SMDS_MeshNode*>(myIterator->next());
1466 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1468 return SMDS_NodeIteratorPtr
1469 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1472 ///////////////////////////////////////////////////////////////////////////////
1473 /// Return an iterator on elements of the current mesh factory
1474 ///////////////////////////////////////////////////////////////////////////////
1475 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1477 return myElementIDFactory->elementsIterator();
1480 ///////////////////////////////////////////////////////////////////////////////
1481 ///Return an iterator on edges of the current mesh.
1482 ///////////////////////////////////////////////////////////////////////////////
1483 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1485 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1486 SetOfEdges::Iterator myIterator;
1488 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1493 while(myIterator.More())
1495 if(myIterator.Value()->GetID()!=-1)
1502 const SMDS_MeshEdge* next()
1504 const SMDS_MeshEdge* current = myIterator.Value();
1510 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1512 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1515 ///////////////////////////////////////////////////////////////////////////////
1516 ///Return an iterator on faces of the current mesh.
1517 ///////////////////////////////////////////////////////////////////////////////
1518 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1520 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1521 SetOfFaces::Iterator myIterator;
1523 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
1528 while(myIterator.More())
1530 if(myIterator.Value()->GetID()!=-1)
1537 const SMDS_MeshFace* next()
1539 const SMDS_MeshFace* current = myIterator.Value();
1545 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1547 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
1550 ///////////////////////////////////////////////////////////////////////////////
1551 ///Return an iterator on volumes of the current mesh.
1552 ///////////////////////////////////////////////////////////////////////////////
1553 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
1555 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
1556 SetOfVolumes::Iterator myIterator;
1558 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
1563 return myIterator.More() != Standard_False;
1566 const SMDS_MeshVolume* next()
1568 const SMDS_MeshVolume* current = myIterator.Value();
1574 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1576 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
1579 ///////////////////////////////////////////////////////////////////////////////
1580 /// Do intersection of sets (more than 2)
1581 ///////////////////////////////////////////////////////////////////////////////
1582 static set<const SMDS_MeshElement*> * intersectionOfSets(
1583 set<const SMDS_MeshElement*> vs[], int numberOfSets)
1585 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1586 set<const SMDS_MeshElement*>* rsetB;
1588 for(int i=0; i<numberOfSets-1; i++)
1590 rsetB=new set<const SMDS_MeshElement*>();
1592 rsetA->begin(), rsetA->end(),
1593 vs[i+1].begin(), vs[i+1].end(),
1594 inserter(*rsetB, rsetB->begin()));
1601 ///////////////////////////////////////////////////////////////////////////////
1602 /// Return the list of finit elements owning the given element
1603 ///////////////////////////////////////////////////////////////////////////////
1604 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1606 int numberOfSets=element->NbNodes();
1607 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
1609 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1612 while(itNodes->more())
1614 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1615 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1617 //initSet[i]=set<const SMDS_MeshElement*>();
1619 initSet[i].insert(itFe->next());
1623 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
1628 ///////////////////////////////////////////////////////////////////////////////
1629 /// Return the list of nodes used only by the given elements
1630 ///////////////////////////////////////////////////////////////////////////////
1631 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1632 set<const SMDS_MeshElement*>& elements)
1634 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1635 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1637 while(itElements!=elements.end())
1639 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
1642 while(itNodes->more())
1644 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1645 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1646 set<const SMDS_MeshElement*> s;
1648 s.insert(itFe->next());
1649 if(s==elements) toReturn->insert(n);
1655 ///////////////////////////////////////////////////////////////////////////////
1656 ///Find the children of an element that are made of given nodes
1657 ///@param setOfChildren The set in which matching children will be inserted
1658 ///@param element The element were to search matching children
1659 ///@param nodes The nodes that the children must have to be selected
1660 ///////////////////////////////////////////////////////////////////////////////
1661 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
1662 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1665 switch(element->GetType())
1668 MESSAGE("Internal Error: This should not append");
1672 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1675 const SMDS_MeshElement * e=itn->next();
1676 if(nodes.find(e)!=nodes.end())
1678 setOfChildren.insert(element);
1685 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1688 const SMDS_MeshElement * e=itn->next();
1689 if(nodes.find(e)!=nodes.end())
1691 setOfChildren.insert(element);
1695 if(hasConstructionEdges())
1697 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1699 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1702 case SMDSAbs_Volume:
1704 if(hasConstructionFaces())
1706 SMDS_ElemIteratorPtr ite=element->facesIterator();
1708 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1710 else if(hasConstructionEdges())
1712 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1714 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1720 ///////////////////////////////////////////////////////////////////////////////
1721 ///@param elem The element to delete
1722 ///@param removenodes if true remaining nodes will be removed
1723 ///////////////////////////////////////////////////////////////////////////////
1724 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1725 const bool removenodes)
1727 list<const SMDS_MeshElement *> removedElems;
1728 list<const SMDS_MeshElement *> removedNodes;
1729 RemoveElement( elem, removedElems, removedNodes, removenodes );
1732 ///////////////////////////////////////////////////////////////////////////////
1733 ///@param elem The element to delete
1734 ///@param removedElems contains all removed elements
1735 ///@param removedNodes contains all removed nodes
1736 ///@param removenodes if true remaining nodes will be removed
1737 ///////////////////////////////////////////////////////////////////////////////
1738 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1739 list<const SMDS_MeshElement *>& removedElems,
1740 list<const SMDS_MeshElement *>& removedNodes,
1743 // get finite elements built on elem
1744 set<const SMDS_MeshElement*> * s1;
1745 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
1746 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
1748 s1 = new set<const SMDS_MeshElement*>();
1752 s1 = getFinitElements(elem);
1754 // get exclusive nodes (which would become free afterwards)
1755 set<const SMDS_MeshElement*> * s2;
1756 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1758 // do not remove nodes except elem
1759 s2 = new set<const SMDS_MeshElement*>();
1764 s2 = getExclusiveNodes(*s1);
1766 // form the set of finite and construction elements to remove
1767 set<const SMDS_MeshElement*> s3;
1768 set<const SMDS_MeshElement*>::iterator it=s1->begin();
1769 while(it!=s1->end())
1771 addChildrenWithNodes(s3, *it ,*s2);
1775 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1777 // remove finite and construction elements
1781 // Remove element from <InverseElements> of its nodes
1782 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
1785 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1786 (const_cast<SMDS_MeshElement *>(itn->next()));
1787 n->RemoveInverseElement( (*it) );
1790 switch((*it)->GetType())
1793 MESSAGE("Internal Error: This should not happen");
1796 myEdges.Remove(static_cast<SMDS_MeshEdge*>
1797 (const_cast<SMDS_MeshElement*>(*it)));
1800 myFaces.Remove(static_cast<SMDS_MeshFace*>
1801 (const_cast<SMDS_MeshElement*>(*it)));
1803 case SMDSAbs_Volume:
1804 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
1805 (const_cast<SMDS_MeshElement*>(*it)));
1808 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
1809 removedElems.push_back( (*it) );
1810 myElementIDFactory->ReleaseID((*it)->GetID());
1815 // remove exclusive (free) nodes
1819 while(it!=s2->end())
1821 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
1822 myNodes.Remove(static_cast<SMDS_MeshNode*>
1823 (const_cast<SMDS_MeshElement*>(*it)));
1824 myNodeIDFactory->ReleaseID((*it)->GetID());
1825 removedNodes.push_back( (*it) );
1836 * Checks if the element is present in mesh.
1837 * Useful to determine dead pointers.
1839 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1841 // we should not imply on validity of *elem, so iterate on containers
1842 // of all types in the hope of finding <elem> somewhere there
1843 SMDS_NodeIteratorPtr itn = nodesIterator();
1845 if (elem == itn->next())
1847 SMDS_EdgeIteratorPtr ite = edgesIterator();
1849 if (elem == ite->next())
1851 SMDS_FaceIteratorPtr itf = facesIterator();
1853 if (elem == itf->next())
1855 SMDS_VolumeIteratorPtr itv = volumesIterator();
1857 if (elem == itv->next())
1862 //=======================================================================
1863 //function : MaxNodeID
1865 //=======================================================================
1867 int SMDS_Mesh::MaxNodeID() const
1869 return myNodeIDFactory->GetMaxID();
1872 //=======================================================================
1873 //function : MinNodeID
1875 //=======================================================================
1877 int SMDS_Mesh::MinNodeID() const
1879 return myNodeIDFactory->GetMinID();
1882 //=======================================================================
1883 //function : MaxElementID
1885 //=======================================================================
1887 int SMDS_Mesh::MaxElementID() const
1889 return myElementIDFactory->GetMaxID();
1892 //=======================================================================
1893 //function : MinElementID
1895 //=======================================================================
1897 int SMDS_Mesh::MinElementID() const
1899 return myElementIDFactory->GetMinID();
1902 //=======================================================================
1903 //function : Renumber
1904 //purpose : Renumber all nodes or elements.
1905 //=======================================================================
1907 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
1912 SMDS_MeshElementIDFactory * idFactory =
1913 isNodes ? myNodeIDFactory : myElementIDFactory;
1915 // get existing elements in the order of ID increasing
1916 map<int,SMDS_MeshElement*> elemMap;
1917 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
1918 while ( idElemIt->more() ) {
1919 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
1920 int id = elem->GetID();
1921 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
1923 // release their ids
1924 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
1925 for ( ; elemIt != elemMap.end(); elemIt++ )
1927 int id = (*elemIt).first;
1928 idFactory->ReleaseID( id );
1932 elemIt = elemMap.begin();
1933 for ( ; elemIt != elemMap.end(); elemIt++ )
1935 idFactory->BindID( ID, (*elemIt).second );