1 // SMESH SMDS : implementaion of Salome mesh data structure
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 #include "utilities.h"
23 #include "SMDS_Mesh.hxx"
24 #include "SMDS_VolumeOfNodes.hxx"
25 #include "SMDS_VolumeOfFaces.hxx"
26 #include "SMDS_FaceOfNodes.hxx"
27 #include "SMDS_FaceOfEdges.hxx"
32 ///////////////////////////////////////////////////////////////////////////////
33 /// Create a new mesh object
34 ///////////////////////////////////////////////////////////////////////////////
35 SMDS_Mesh::SMDS_Mesh()
36 :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
37 myElementIDFactory(new SMDS_MeshElementIDFactory()),
38 myHasConstructionEdges(false), myHasConstructionFaces(false),
39 myHasInverseElements(true)
43 ///////////////////////////////////////////////////////////////////////////////
44 /// Create a new child mesh
45 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
46 /// (2003-09-08) of SMESH
47 ///////////////////////////////////////////////////////////////////////////////
48 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
49 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
50 myElementIDFactory(parent->myElementIDFactory),
51 myHasConstructionEdges(false), myHasConstructionFaces(false),
52 myHasInverseElements(true)
56 ///////////////////////////////////////////////////////////////////////////////
57 ///Create a submesh and add it to the current mesh
58 ///////////////////////////////////////////////////////////////////////////////
60 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
62 SMDS_Mesh *submesh = new SMDS_Mesh(this);
63 myChildren.insert(myChildren.end(), submesh);
67 ///////////////////////////////////////////////////////////////////////////////
68 ///create a MeshNode and add it to the current Mesh
69 ///An ID is automatically assigned to the node.
70 ///@return : The created node
71 ///////////////////////////////////////////////////////////////////////////////
73 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
75 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
78 ///////////////////////////////////////////////////////////////////////////////
79 ///create a MeshNode and add it to the current Mesh
80 ///@param ID : The ID of the MeshNode to create
81 ///@return : The created node or NULL if a node with this ID already exists
82 ///////////////////////////////////////////////////////////////////////////////
83 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
85 // find the MeshNode corresponding to ID
86 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
88 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
90 myNodeIDFactory->BindID(ID,node);
96 ///////////////////////////////////////////////////////////////////////////////
97 /// create a MeshEdge and add it to the current Mesh
98 /// @return : The created MeshEdge
99 ///////////////////////////////////////////////////////////////////////////////
101 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
103 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
104 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
105 if(!node1 || !node2) return NULL;
106 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
109 ///////////////////////////////////////////////////////////////////////////////
110 /// create a MeshEdge and add it to the current Mesh
111 /// @return : The created MeshEdge
112 ///////////////////////////////////////////////////////////////////////////////
114 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
115 const SMDS_MeshNode * node2)
117 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
120 ///////////////////////////////////////////////////////////////////////////////
121 /// Create a new edge and at it to the mesh
122 /// @param idnode1 ID of the first node
123 /// @param idnode2 ID of the second node
124 /// @param ID ID of the edge to create
125 /// @return The created edge or NULL if an element with this ID already exists or
126 /// if input nodes are not found.
127 ///////////////////////////////////////////////////////////////////////////////
129 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
130 const SMDS_MeshNode * n2,
133 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
134 if(myElementIDFactory->BindID(ID, edge)) {
135 SMDS_MeshNode *node1,*node2;
136 node1=const_cast<SMDS_MeshNode*>(n1);
137 node2=const_cast<SMDS_MeshNode*>(n2);
138 node1->AddInverseElement(edge);
139 node2->AddInverseElement(edge);
140 myEdges.insert(edge);
149 ///////////////////////////////////////////////////////////////////////////////
150 /// Add a triangle defined by its nodes. An ID is automatically affected to the
152 ///////////////////////////////////////////////////////////////////////////////
154 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
155 const SMDS_MeshNode * n2,
156 const SMDS_MeshNode * n3)
158 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
161 ///////////////////////////////////////////////////////////////////////////////
162 /// Add a triangle defined by its nodes IDs
163 ///////////////////////////////////////////////////////////////////////////////
165 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
167 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
168 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
169 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
170 if(!node1 || !node2 || !node3) return NULL;
171 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
174 ///////////////////////////////////////////////////////////////////////////////
175 /// Add a triangle defined by its nodes
176 ///////////////////////////////////////////////////////////////////////////////
178 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
179 const SMDS_MeshNode * n2,
180 const SMDS_MeshNode * n3,
183 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
185 if (!registerElement(ID, face)) {
186 RemoveElement(face, false);
192 ///////////////////////////////////////////////////////////////////////////////
193 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
195 ///////////////////////////////////////////////////////////////////////////////
197 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
198 const SMDS_MeshNode * n2,
199 const SMDS_MeshNode * n3,
200 const SMDS_MeshNode * n4)
202 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
205 ///////////////////////////////////////////////////////////////////////////////
206 /// Add a quadrangle defined by its nodes IDs
207 ///////////////////////////////////////////////////////////////////////////////
209 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
215 SMDS_MeshNode *node1, *node2, *node3, *node4;
216 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
217 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
218 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
219 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
220 if(!node1 || !node2 || !node3 || !node4) return NULL;
221 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
224 ///////////////////////////////////////////////////////////////////////////////
225 /// Add a quadrangle defined by its nodes
226 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
229 const SMDS_MeshNode * n2,
230 const SMDS_MeshNode * n3,
231 const SMDS_MeshNode * n4,
234 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
236 if (!registerElement(ID, face)) {
237 RemoveElement(face, false);
243 ///////////////////////////////////////////////////////////////////////////////
244 /// Add a triangle defined by its edges. An ID is automatically assigned to the
246 ///////////////////////////////////////////////////////////////////////////////
248 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
249 const SMDS_MeshEdge * e2,
250 const SMDS_MeshEdge * e3)
252 if (!hasConstructionEdges())
254 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
257 ///////////////////////////////////////////////////////////////////////////////
258 /// Add a triangle defined by its edges
259 ///////////////////////////////////////////////////////////////////////////////
261 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
262 const SMDS_MeshEdge * e2,
263 const SMDS_MeshEdge * e3,
266 if (!hasConstructionEdges())
268 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
269 myFaces.insert(face);
271 if (!registerElement(ID, face)) {
272 RemoveElement(face, false);
278 ///////////////////////////////////////////////////////////////////////////////
279 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
281 ///////////////////////////////////////////////////////////////////////////////
283 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
284 const SMDS_MeshEdge * e2,
285 const SMDS_MeshEdge * e3,
286 const SMDS_MeshEdge * e4)
288 if (!hasConstructionEdges())
290 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
293 ///////////////////////////////////////////////////////////////////////////////
294 /// Add a quadrangle defined by its edges
295 ///////////////////////////////////////////////////////////////////////////////
297 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
298 const SMDS_MeshEdge * e2,
299 const SMDS_MeshEdge * e3,
300 const SMDS_MeshEdge * e4,
303 if (!hasConstructionEdges())
305 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
306 myFaces.insert(face);
308 if (!registerElement(ID, face))
310 RemoveElement(face, false);
316 ///////////////////////////////////////////////////////////////////////////////
317 ///Create a new tetrahedron and add it to the mesh.
318 ///@return The created tetrahedron
319 ///////////////////////////////////////////////////////////////////////////////
321 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
322 const SMDS_MeshNode * n2,
323 const SMDS_MeshNode * n3,
324 const SMDS_MeshNode * n4)
326 int ID = myElementIDFactory->GetFreeID();
327 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
328 if(v==NULL) myElementIDFactory->ReleaseID(ID);
332 ///////////////////////////////////////////////////////////////////////////////
333 ///Create a new tetrahedron and add it to the mesh.
334 ///@param ID The ID of the new volume
335 ///@return The created tetrahedron or NULL if an element with this ID already exists
336 ///or if input nodes are not found.
337 ///////////////////////////////////////////////////////////////////////////////
339 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
345 SMDS_MeshNode *node1, *node2, *node3, *node4;
346 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
347 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
348 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
349 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
350 if(!node1 || !node2 || !node3 || !node4) return NULL;
351 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
354 ///////////////////////////////////////////////////////////////////////////////
355 ///Create a new tetrahedron and add it to the mesh.
356 ///@param ID The ID of the new volume
357 ///@return The created tetrahedron
358 ///////////////////////////////////////////////////////////////////////////////
360 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
361 const SMDS_MeshNode * n2,
362 const SMDS_MeshNode * n3,
363 const SMDS_MeshNode * n4,
366 SMDS_MeshVolume* volume;
367 if(hasConstructionFaces()) {
368 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
369 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
370 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
371 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
372 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
373 myVolumes.insert(volume);
375 else if(hasConstructionEdges()) {
376 MESSAGE("Error : Not implemented");
380 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
381 myVolumes.insert(volume);
384 if (!registerElement(ID, volume)) {
385 RemoveElement(volume, false);
391 ///////////////////////////////////////////////////////////////////////////////
392 ///Create a new pyramid and add it to the mesh.
393 ///Nodes 1,2,3 and 4 define the base of the pyramid
394 ///@return The created pyramid
395 ///////////////////////////////////////////////////////////////////////////////
397 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
398 const SMDS_MeshNode * n2,
399 const SMDS_MeshNode * n3,
400 const SMDS_MeshNode * n4,
401 const SMDS_MeshNode * n5)
403 int ID = myElementIDFactory->GetFreeID();
404 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
405 if(v==NULL) myElementIDFactory->ReleaseID(ID);
409 ///////////////////////////////////////////////////////////////////////////////
410 ///Create a new pyramid and add it to the mesh.
411 ///Nodes 1,2,3 and 4 define the base of the pyramid
412 ///@param ID The ID of the new volume
413 ///@return The created pyramid or NULL if an element with this ID already exists
414 ///or if input nodes are not found.
415 ///////////////////////////////////////////////////////////////////////////////
417 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
424 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
425 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
426 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
427 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
428 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
429 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
430 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
431 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
434 ///////////////////////////////////////////////////////////////////////////////
435 ///Create a new pyramid and add it to the mesh.
436 ///Nodes 1,2,3 and 4 define the base of the pyramid
437 ///@param ID The ID of the new volume
438 ///@return The created pyramid
439 ///////////////////////////////////////////////////////////////////////////////
441 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
442 const SMDS_MeshNode * n2,
443 const SMDS_MeshNode * n3,
444 const SMDS_MeshNode * n4,
445 const SMDS_MeshNode * n5,
448 SMDS_MeshVolume* volume;
449 if(hasConstructionFaces()) {
450 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
451 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
452 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
453 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
454 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
455 myVolumes.insert(volume);
457 else if(hasConstructionEdges()) {
458 MESSAGE("Error : Not implemented");
462 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
463 myVolumes.insert(volume);
466 if (!registerElement(ID, volume)) {
467 RemoveElement(volume, false);
473 ///////////////////////////////////////////////////////////////////////////////
474 ///Create a new prism and add it to the mesh.
475 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
476 ///@return The created prism
477 ///////////////////////////////////////////////////////////////////////////////
479 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
480 const SMDS_MeshNode * n2,
481 const SMDS_MeshNode * n3,
482 const SMDS_MeshNode * n4,
483 const SMDS_MeshNode * n5,
484 const SMDS_MeshNode * n6)
486 int ID = myElementIDFactory->GetFreeID();
487 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
488 if(v==NULL) myElementIDFactory->ReleaseID(ID);
492 ///////////////////////////////////////////////////////////////////////////////
493 ///Create a new prism and add it to the mesh.
494 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
495 ///@param ID The ID of the new volume
496 ///@return The created prism or NULL if an element with this ID already exists
497 ///or if input nodes are not found.
498 ///////////////////////////////////////////////////////////////////////////////
500 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
508 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
509 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
510 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
511 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
512 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
513 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
514 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
515 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
516 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
519 ///////////////////////////////////////////////////////////////////////////////
520 ///Create a new prism and add it to the mesh.
521 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
522 ///@param ID The ID of the new volume
523 ///@return The created prism
524 ///////////////////////////////////////////////////////////////////////////////
526 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
527 const SMDS_MeshNode * n2,
528 const SMDS_MeshNode * n3,
529 const SMDS_MeshNode * n4,
530 const SMDS_MeshNode * n5,
531 const SMDS_MeshNode * n6,
534 SMDS_MeshVolume* volume;
535 if(hasConstructionFaces()) {
536 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
537 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
538 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
539 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
540 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
541 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
542 myVolumes.insert(volume);
544 else if(hasConstructionEdges()) {
545 MESSAGE("Error : Not implemented");
549 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
550 myVolumes.insert(volume);
553 if (!registerElement(ID, volume)) {
554 RemoveElement(volume, false);
560 ///////////////////////////////////////////////////////////////////////////////
561 ///Create a new hexahedron and add it to the mesh.
562 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
563 ///@return The created hexahedron
564 ///////////////////////////////////////////////////////////////////////////////
566 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
567 const SMDS_MeshNode * n2,
568 const SMDS_MeshNode * n3,
569 const SMDS_MeshNode * n4,
570 const SMDS_MeshNode * n5,
571 const SMDS_MeshNode * n6,
572 const SMDS_MeshNode * n7,
573 const SMDS_MeshNode * n8)
575 int ID = myElementIDFactory->GetFreeID();
576 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
577 if(v==NULL) myElementIDFactory->ReleaseID(ID);
581 ///////////////////////////////////////////////////////////////////////////////
582 ///Create a new hexahedron and add it to the mesh.
583 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
584 ///@param ID The ID of the new volume
585 ///@return The created hexahedron or NULL if an element with this ID already
586 ///exists or if input nodes are not found.
587 ///////////////////////////////////////////////////////////////////////////////
589 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
599 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
600 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
601 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
602 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
603 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
604 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
605 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
606 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
607 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
608 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
610 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
614 ///////////////////////////////////////////////////////////////////////////////
615 ///Create a new hexahedron and add it to the mesh.
616 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
617 ///@param ID The ID of the new volume
618 ///@return The created prism or NULL if an element with this ID already exists
619 ///or if input nodes are not found.
620 ///////////////////////////////////////////////////////////////////////////////
622 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
623 const SMDS_MeshNode * n2,
624 const SMDS_MeshNode * n3,
625 const SMDS_MeshNode * n4,
626 const SMDS_MeshNode * n5,
627 const SMDS_MeshNode * n6,
628 const SMDS_MeshNode * n7,
629 const SMDS_MeshNode * n8,
632 SMDS_MeshVolume* volume;
633 if(hasConstructionFaces()) {
634 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
635 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
636 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
637 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
638 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
639 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
640 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
641 myVolumes.insert(volume);
643 else if(hasConstructionEdges()) {
644 MESSAGE("Error : Not implemented");
648 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
649 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
650 myVolumes.insert(volume);
653 if (!registerElement(ID, volume)) {
654 RemoveElement(volume, false);
660 ///////////////////////////////////////////////////////////////////////////////
661 ///Create a new tetrahedron defined by its faces and add it to the mesh.
662 ///@return The created tetrahedron
663 ///////////////////////////////////////////////////////////////////////////////
665 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
666 const SMDS_MeshFace * f2,
667 const SMDS_MeshFace * f3,
668 const SMDS_MeshFace * f4)
670 if (!hasConstructionFaces())
672 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
675 ///////////////////////////////////////////////////////////////////////////////
676 ///Create a new tetrahedron defined by its faces and add it to the mesh.
677 ///@param ID The ID of the new volume
678 ///@return The created tetrahedron
679 ///////////////////////////////////////////////////////////////////////////////
681 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
682 const SMDS_MeshFace * f2,
683 const SMDS_MeshFace * f3,
684 const SMDS_MeshFace * f4,
687 if (!hasConstructionFaces())
689 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
690 myVolumes.insert(volume);
692 if (!registerElement(ID, volume)) {
693 RemoveElement(volume, false);
699 ///////////////////////////////////////////////////////////////////////////////
700 ///Create a new pyramid defined by its faces and add it to the mesh.
701 ///@return The created pyramid
702 ///////////////////////////////////////////////////////////////////////////////
704 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
705 const SMDS_MeshFace * f2,
706 const SMDS_MeshFace * f3,
707 const SMDS_MeshFace * f4,
708 const SMDS_MeshFace * f5)
710 if (!hasConstructionFaces())
712 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
715 ///////////////////////////////////////////////////////////////////////////////
716 ///Create a new pyramid defined by its faces and add it to the mesh.
717 ///@param ID The ID of the new volume
718 ///@return The created pyramid
719 ///////////////////////////////////////////////////////////////////////////////
721 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
722 const SMDS_MeshFace * f2,
723 const SMDS_MeshFace * f3,
724 const SMDS_MeshFace * f4,
725 const SMDS_MeshFace * f5,
728 if (!hasConstructionFaces())
730 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
731 myVolumes.insert(volume);
733 if (!registerElement(ID, volume)) {
734 RemoveElement(volume, false);
740 ///////////////////////////////////////////////////////////////////////////////
741 ///Create a new prism defined by its faces and add it to the mesh.
742 ///@return The created prism
743 ///////////////////////////////////////////////////////////////////////////////
745 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
746 const SMDS_MeshFace * f2,
747 const SMDS_MeshFace * f3,
748 const SMDS_MeshFace * f4,
749 const SMDS_MeshFace * f5,
750 const SMDS_MeshFace * f6)
752 if (!hasConstructionFaces())
754 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
757 ///////////////////////////////////////////////////////////////////////////////
758 ///Create a new prism defined by its faces and add it to the mesh.
759 ///@param ID The ID of the new volume
760 ///@return The created prism
761 ///////////////////////////////////////////////////////////////////////////////
763 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
764 const SMDS_MeshFace * f2,
765 const SMDS_MeshFace * f3,
766 const SMDS_MeshFace * f4,
767 const SMDS_MeshFace * f5,
768 const SMDS_MeshFace * f6,
771 if (!hasConstructionFaces())
773 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
774 myVolumes.insert(volume);
776 if (!registerElement(ID, volume)) {
777 RemoveElement(volume, false);
783 ///////////////////////////////////////////////////////////////////////////////
784 /// Registers element with the given ID, maintains inverse connections
785 ///////////////////////////////////////////////////////////////////////////////
786 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
788 if (myElementIDFactory->BindID(ID, element)) {
789 SMDS_ElemIteratorPtr it = element->nodesIterator();
791 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
792 (const_cast<SMDS_MeshElement*>(it->next()));
793 node->AddInverseElement(element);
800 ///////////////////////////////////////////////////////////////////////////////
801 /// Return the node whose ID is 'ID'.
802 ///////////////////////////////////////////////////////////////////////////////
803 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
805 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
808 ///////////////////////////////////////////////////////////////////////////////
809 ///Create a triangle and add it to the current mesh. This methode do not bind a
810 ///ID to the create triangle.
811 ///////////////////////////////////////////////////////////////////////////////
812 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
813 const SMDS_MeshNode * node2,
814 const SMDS_MeshNode * node3)
816 if(hasConstructionEdges())
818 SMDS_MeshEdge *edge1, *edge2, *edge3;
819 edge1=FindEdgeOrCreate(node1,node2);
820 edge2=FindEdgeOrCreate(node2,node3);
821 edge3=FindEdgeOrCreate(node3,node1);
823 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
824 myFaces.insert(face);
829 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
830 myFaces.insert(face);
835 ///////////////////////////////////////////////////////////////////////////////
836 ///Create a quadrangle and add it to the current mesh. This methode do not bind
837 ///a ID to the create triangle.
838 ///////////////////////////////////////////////////////////////////////////////
839 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
840 const SMDS_MeshNode * node2,
841 const SMDS_MeshNode * node3,
842 const SMDS_MeshNode * node4)
844 if(hasConstructionEdges())
846 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
847 edge1=FindEdgeOrCreate(node1,node2);
848 edge2=FindEdgeOrCreate(node2,node3);
849 edge3=FindEdgeOrCreate(node3,node4);
850 edge4=FindEdgeOrCreate(node4,node1);
852 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
853 myFaces.insert(face);
858 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
859 myFaces.insert(face);
864 ///////////////////////////////////////////////////////////////////////////////
865 /// Remove a node and all the elements which own this node
866 ///////////////////////////////////////////////////////////////////////////////
868 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
870 RemoveElement(node, true);
873 ///////////////////////////////////////////////////////////////////////////////
874 /// Remove an edge and all the elements which own this edge
875 ///////////////////////////////////////////////////////////////////////////////
877 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
879 RemoveElement(edge,true);
882 ///////////////////////////////////////////////////////////////////////////////
883 /// Remove an face and all the elements which own this face
884 ///////////////////////////////////////////////////////////////////////////////
886 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
888 RemoveElement(face, true);
891 ///////////////////////////////////////////////////////////////////////////////
893 ///////////////////////////////////////////////////////////////////////////////
895 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
897 RemoveElement(volume, true);
900 //=======================================================================
901 //function : RemoveFromParent
903 //=======================================================================
905 bool SMDS_Mesh::RemoveFromParent()
907 if (myParent==NULL) return false;
908 else return (myParent->RemoveSubMesh(this));
911 //=======================================================================
912 //function : RemoveSubMesh
914 //=======================================================================
916 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
920 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
921 for (; itmsh!=myChildren.end() && !found; itmsh++)
923 SMDS_Mesh * submesh = *itmsh;
924 if (submesh == aMesh)
927 myChildren.erase(itmsh);
934 //=======================================================================
935 //function : ChangeElementNodes
937 //=======================================================================
939 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
940 const SMDS_MeshNode * nodes[],
943 // keep current nodes of elem
944 set<const SMDS_MeshElement*> oldNodes;
945 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
947 oldNodes.insert( itn->next() );
951 switch ( elem->GetType() )
954 if ( nbnodes == 2 ) {
955 const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
957 Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
962 const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
964 Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
967 case SMDSAbs_Volume: {
968 const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
970 Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
974 MESSAGE ( "WRONG ELEM TYPE");
977 if ( Ok ) { // update InverseElements
979 // AddInverseElement to new nodes
980 for ( int i = 0; i < nbnodes; i++ )
981 if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
983 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
985 // remove from oldNodes a node that remains in elem
986 oldNodes.erase( nodes[i] );
989 // RemoveInverseElement from the nodes removed from elem
990 set<const SMDS_MeshElement*>::iterator it;
991 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
993 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
994 (const_cast<SMDS_MeshElement *>( *it ));
995 n->RemoveInverseElement( elem );
999 //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1004 //=======================================================================
1005 //function : FindEdge
1007 //=======================================================================
1009 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1011 const SMDS_MeshNode * node1=FindNode(idnode1);
1012 const SMDS_MeshNode * node2=FindNode(idnode2);
1013 if((node1==NULL)||(node2==NULL)) return NULL;
1014 return FindEdge(node1,node2);
1017 //#include "Profiler.h"
1018 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1019 const SMDS_MeshNode * node2)
1021 const SMDS_MeshEdge * toReturn=NULL;
1024 SMDS_ElemIteratorPtr it1=node1->edgesIterator();
1029 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
1031 SMDS_ElemIteratorPtr it2=e->nodesIterator();
1034 if(it2->next()->GetID()==node2->GetID())
1046 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1047 const SMDS_MeshNode * node2)
1049 SMDS_MeshEdge * toReturn=NULL;
1050 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1053 toReturn=new SMDS_MeshEdge(node1,node2);
1054 myEdges.insert(toReturn);
1059 //=======================================================================
1060 //function : FindFace
1062 //=======================================================================
1064 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1067 const SMDS_MeshNode * node1=FindNode(idnode1);
1068 const SMDS_MeshNode * node2=FindNode(idnode2);
1069 const SMDS_MeshNode * node3=FindNode(idnode3);
1070 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
1071 return FindFace(node1, node2, node3);
1074 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1075 const SMDS_MeshNode *node1,
1076 const SMDS_MeshNode *node2,
1077 const SMDS_MeshNode *node3)
1079 const SMDS_MeshFace * face;
1080 const SMDS_MeshElement * node;
1081 bool node2found, node3found;
1083 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1086 face=static_cast<const SMDS_MeshFace*>(it1->next());
1087 if(face->NbNodes()!=3) continue;
1088 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1094 if(node->GetID()==node2->GetID()) node2found=true;
1095 if(node->GetID()==node3->GetID()) node3found=true;
1097 if(node2found&&node3found)
1103 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1104 const SMDS_MeshNode *node1,
1105 const SMDS_MeshNode *node2,
1106 const SMDS_MeshNode *node3)
1108 SMDS_MeshFace * toReturn=NULL;
1109 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1112 toReturn=createTriangle(node1,node2,node3);
1117 //=======================================================================
1118 //function : FindFace
1120 //=======================================================================
1122 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
1125 const SMDS_MeshNode * node1=FindNode(idnode1);
1126 const SMDS_MeshNode * node2=FindNode(idnode2);
1127 const SMDS_MeshNode * node3=FindNode(idnode3);
1128 const SMDS_MeshNode * node4=FindNode(idnode4);
1129 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
1130 return FindFace(node1, node2, node3, node4);
1133 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1134 const SMDS_MeshNode *node1,
1135 const SMDS_MeshNode *node2,
1136 const SMDS_MeshNode *node3,
1137 const SMDS_MeshNode *node4)
1139 const SMDS_MeshFace * face;
1140 const SMDS_MeshElement * node;
1141 bool node2found, node3found, node4found;
1142 SMDS_ElemIteratorPtr it1=node1->facesIterator();
1145 face=static_cast<const SMDS_MeshFace *>(it1->next());
1146 if(face->NbNodes()!=4) continue;
1147 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1154 if(node->GetID()==node2->GetID()) node2found=true;
1155 if(node->GetID()==node3->GetID()) node3found=true;
1156 if(node->GetID()==node4->GetID()) node4found=true;
1158 if(node2found&&node3found&&node4found)
1164 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1165 const SMDS_MeshNode *node1,
1166 const SMDS_MeshNode *node2,
1167 const SMDS_MeshNode *node3,
1168 const SMDS_MeshNode *node4)
1170 SMDS_MeshFace * toReturn=NULL;
1171 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1174 toReturn=createQuadrangle(node1,node2,node3,node4);
1179 //=======================================================================
1180 //function : FindElement
1182 //=======================================================================
1184 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1186 return myElementIDFactory->MeshElement(IDelem);
1189 //=======================================================================
1190 //function : DumpNodes
1192 //=======================================================================
1194 void SMDS_Mesh::DumpNodes() const
1196 MESSAGE("dump nodes of mesh : ");
1197 SMDS_NodeIteratorPtr itnode=nodesIterator();
1198 while(itnode->more()) MESSAGE(itnode->next());
1201 //=======================================================================
1202 //function : DumpEdges
1204 //=======================================================================
1206 void SMDS_Mesh::DumpEdges() const
1208 MESSAGE("dump edges of mesh : ");
1209 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1210 while(itedge->more()) MESSAGE(itedge->next());
1213 //=======================================================================
1214 //function : DumpFaces
1216 //=======================================================================
1218 void SMDS_Mesh::DumpFaces() const
1220 MESSAGE("dump faces of mesh : ");
1221 SMDS_FaceIteratorPtr itface=facesIterator();
1222 while(itface->more()) MESSAGE(itface->next());
1225 //=======================================================================
1226 //function : DumpVolumes
1228 //=======================================================================
1230 void SMDS_Mesh::DumpVolumes() const
1232 MESSAGE("dump volumes of mesh : ");
1233 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1234 while(itvol->more()) MESSAGE(itvol->next());
1237 //=======================================================================
1238 //function : DebugStats
1240 //=======================================================================
1242 void SMDS_Mesh::DebugStats() const
1244 MESSAGE("Debug stats of mesh : ");
1246 MESSAGE("===== NODES ====="<<NbNodes());
1247 MESSAGE("===== EDGES ====="<<NbEdges());
1248 MESSAGE("===== FACES ====="<<NbFaces());
1249 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1251 MESSAGE("End Debug stats of mesh ");
1255 SMDS_NodeIteratorPtr itnode=nodesIterator();
1256 int sizeofnodes = 0;
1257 int sizeoffaces = 0;
1259 while(itnode->more())
1261 const SMDS_MeshNode *node = itnode->next();
1263 sizeofnodes += sizeof(*node);
1265 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1268 const SMDS_MeshElement *me = it->next();
1269 sizeofnodes += sizeof(me);
1274 SMDS_FaceIteratorPtr itface=facesIterator();
1275 while(itface->more())
1277 const SMDS_MeshElement *face = itface->next();
1278 sizeoffaces += sizeof(*face);
1281 MESSAGE("total size of node elements = " << sizeofnodes);;
1282 MESSAGE("total size of face elements = " << sizeoffaces);;
1287 ///////////////////////////////////////////////////////////////////////////////
1288 /// Return the number of nodes
1289 ///////////////////////////////////////////////////////////////////////////////
1290 int SMDS_Mesh::NbNodes() const
1292 return myNodes.size();
1295 ///////////////////////////////////////////////////////////////////////////////
1296 /// Return the number of edges (including construction edges)
1297 ///////////////////////////////////////////////////////////////////////////////
1298 int SMDS_Mesh::NbEdges() const
1300 return myEdges.size();
1303 ///////////////////////////////////////////////////////////////////////////////
1304 /// Return the number of faces (including construction faces)
1305 ///////////////////////////////////////////////////////////////////////////////
1306 int SMDS_Mesh::NbFaces() const
1308 return myFaces.size();
1311 ///////////////////////////////////////////////////////////////////////////////
1312 /// Return the number of volumes
1313 ///////////////////////////////////////////////////////////////////////////////
1314 int SMDS_Mesh::NbVolumes() const
1316 return myVolumes.size();
1319 ///////////////////////////////////////////////////////////////////////////////
1320 /// Return the number of child mesh of this mesh.
1321 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1322 /// (2003-09-08) of SMESH
1323 ///////////////////////////////////////////////////////////////////////////////
1324 int SMDS_Mesh::NbSubMesh() const
1326 return myChildren.size();
1329 ///////////////////////////////////////////////////////////////////////////////
1330 /// Destroy the mesh and all its elements
1331 /// All pointer on elements owned by this mesh become illegals.
1332 ///////////////////////////////////////////////////////////////////////////////
1333 SMDS_Mesh::~SMDS_Mesh()
1337 delete myNodeIDFactory;
1338 delete myElementIDFactory;
1341 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1342 while(itc!=myChildren.end())
1348 SMDS_NodeIteratorPtr itn=nodesIterator();
1354 set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1355 while(ite!=myEdges.end())
1361 set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1362 while(itf!=myFaces.end())
1368 set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1369 while(itv!=myVolumes.end())
1376 ///////////////////////////////////////////////////////////////////////////////
1377 /// Return true if this mesh create faces with edges.
1378 /// A false returned value mean that faces are created with nodes. A concequence
1379 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1380 ///////////////////////////////////////////////////////////////////////////////
1381 bool SMDS_Mesh::hasConstructionEdges()
1383 return myHasConstructionEdges;
1386 ///////////////////////////////////////////////////////////////////////////////
1387 /// Return true if this mesh create volumes with faces
1388 /// A false returned value mean that volumes are created with nodes or edges.
1389 /// (see hasConstructionEdges)
1390 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1392 ///////////////////////////////////////////////////////////////////////////////
1393 bool SMDS_Mesh::hasConstructionFaces()
1395 return myHasConstructionFaces;
1398 ///////////////////////////////////////////////////////////////////////////////
1399 /// Return true if nodes are linked to the finit elements, they are belonging to.
1400 /// Currently, It always return true.
1401 ///////////////////////////////////////////////////////////////////////////////
1402 bool SMDS_Mesh::hasInverseElements()
1404 return myHasInverseElements;
1407 ///////////////////////////////////////////////////////////////////////////////
1408 /// Make this mesh creating construction edges (see hasConstructionEdges)
1409 /// @param b true to have construction edges, else false.
1410 ///////////////////////////////////////////////////////////////////////////////
1411 void SMDS_Mesh::setConstructionEdges(bool b)
1413 myHasConstructionEdges=b;
1416 ///////////////////////////////////////////////////////////////////////////////
1417 /// Make this mesh creating construction faces (see hasConstructionFaces)
1418 /// @param b true to have construction faces, else false.
1419 ///////////////////////////////////////////////////////////////////////////////
1420 void SMDS_Mesh::setConstructionFaces(bool b)
1422 myHasConstructionFaces=b;
1425 ///////////////////////////////////////////////////////////////////////////////
1426 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1427 /// @param b true to link nodes to elements, else false.
1428 ///////////////////////////////////////////////////////////////////////////////
1429 void SMDS_Mesh::setInverseElements(bool b)
1431 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1432 myHasInverseElements=b;
1435 ///////////////////////////////////////////////////////////////////////////////
1436 /// Return an iterator on nodes of the current mesh
1437 ///////////////////////////////////////////////////////////////////////////////
1438 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1440 const SMDS_IdElementMap& myIdElemMap;
1441 SMDS_IdElementMap::const_iterator myIterator;
1443 SMDS_Mesh_MyNodeIterator(const SMDS_IdElementMap& s):myIdElemMap(s)
1445 myIterator=myIdElemMap.begin();
1450 return myIterator!=myIdElemMap.end();
1453 const SMDS_MeshNode* next()
1455 const SMDS_MeshElement* current=(*myIterator).second;
1457 return static_cast<const SMDS_MeshNode*>( current );
1461 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1463 return SMDS_NodeIteratorPtr
1464 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->GetIdElementMap()));
1466 ///////////////////////////////////////////////////////////////////////////////
1467 /// Return an iterator on nodes of the current mesh
1468 ///////////////////////////////////////////////////////////////////////////////
1469 class SMDS_Mesh_MyElemIterator:public SMDS_ElemIterator
1471 const SMDS_IdElementMap& myIdElemMap;
1472 SMDS_IdElementMap::const_iterator myIterator;
1474 SMDS_Mesh_MyElemIterator(const SMDS_IdElementMap& s):myIdElemMap(s)
1476 myIterator=myIdElemMap.begin();
1481 return myIterator!=myIdElemMap.end();
1484 const SMDS_MeshElement* next()
1486 const SMDS_MeshElement* current=(*myIterator).second;
1492 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1494 return SMDS_ElemIteratorPtr
1495 (new SMDS_Mesh_MyElemIterator(myElementIDFactory->GetIdElementMap()));
1498 ///////////////////////////////////////////////////////////////////////////////
1499 ///Return an iterator on volumes of the current mesh.
1500 ///////////////////////////////////////////////////////////////////////////////
1501 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1503 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1504 const SetOfEdges& mySet;
1505 const SMDS_MeshEdge * myEdge;
1506 SetOfEdges::iterator myIterator;
1508 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s)
1510 myIterator=mySet.begin();
1515 while((myIterator!=mySet.end()))
1517 if((*myIterator)->GetID()!=-1)
1524 const SMDS_MeshEdge* next()
1526 const SMDS_MeshEdge* current=*myIterator;
1532 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1534 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1537 ///////////////////////////////////////////////////////////////////////////////
1538 ///Return an iterator on faces of the current mesh. Once used this iterator
1539 ///must be free by the caller
1540 ///////////////////////////////////////////////////////////////////////////////
1541 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1543 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1544 const SetOfFaces& mySet;
1545 SetOfFaces::iterator myIterator;
1547 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s)
1549 myIterator=mySet.begin();
1554 while((myIterator!=mySet.end()))
1556 if((*myIterator)->GetID()!=-1)
1563 const SMDS_MeshFace* next()
1565 const SMDS_MeshFace* current=*myIterator;
1571 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1573 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
1576 ///////////////////////////////////////////////////////////////////////////////
1577 ///Return an iterator on volumes of the current mesh. Once used this iterator
1578 ///must be free by the caller
1579 ///////////////////////////////////////////////////////////////////////////////
1580 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
1582 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
1583 const SetOfVolumes& mySet;
1584 SetOfVolumes::iterator myIterator;
1586 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s)
1588 myIterator=mySet.begin();
1593 return myIterator!=mySet.end();
1596 const SMDS_MeshVolume* next()
1598 const SMDS_MeshVolume* current=*myIterator;
1604 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1606 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
1609 ///////////////////////////////////////////////////////////////////////////////
1610 /// Do intersection of sets (more than 2)
1611 ///////////////////////////////////////////////////////////////////////////////
1612 static set<const SMDS_MeshElement*> * intersectionOfSets(
1613 set<const SMDS_MeshElement*> vs[], int numberOfSets)
1615 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1616 set<const SMDS_MeshElement*>* rsetB;
1618 for(int i=0; i<numberOfSets-1; i++)
1620 rsetB=new set<const SMDS_MeshElement*>();
1622 rsetA->begin(), rsetA->end(),
1623 vs[i+1].begin(), vs[i+1].end(),
1624 inserter(*rsetB, rsetB->begin()));
1631 ///////////////////////////////////////////////////////////////////////////////
1632 /// Return the list of finit elements owning the given element
1633 ///////////////////////////////////////////////////////////////////////////////
1634 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1636 int numberOfSets=element->NbNodes();
1637 set<const SMDS_MeshElement*> initSet[numberOfSets];
1639 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1642 while(itNodes->more())
1644 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1645 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1647 //initSet[i]=set<const SMDS_MeshElement*>();
1649 initSet[i].insert(itFe->next());
1654 return intersectionOfSets(initSet, numberOfSets);
1657 ///////////////////////////////////////////////////////////////////////////////
1658 /// Return the list of nodes used only by the given elements
1659 ///////////////////////////////////////////////////////////////////////////////
1660 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1661 set<const SMDS_MeshElement*>& elements)
1663 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1664 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1666 while(itElements!=elements.end())
1668 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
1671 while(itNodes->more())
1673 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1674 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1675 set<const SMDS_MeshElement*> s;
1677 s.insert(itFe->next());
1678 if(s==elements) toReturn->insert(n);
1684 ///////////////////////////////////////////////////////////////////////////////
1685 ///Find the children of an element that are made of given nodes
1686 ///@param setOfChildren The set in which matching children will be inserted
1687 ///@param element The element were to search matching children
1688 ///@param nodes The nodes that the children must have to be selected
1689 ///////////////////////////////////////////////////////////////////////////////
1690 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
1691 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1694 switch(element->GetType())
1697 MESSAGE("Internal Error: This should not append");
1701 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1704 const SMDS_MeshElement * e=itn->next();
1705 if(nodes.find(e)!=nodes.end())
1707 setOfChildren.insert(element);
1714 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1717 const SMDS_MeshElement * e=itn->next();
1718 if(nodes.find(e)!=nodes.end())
1720 setOfChildren.insert(element);
1724 if(hasConstructionEdges())
1726 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1728 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1731 case SMDSAbs_Volume:
1733 if(hasConstructionFaces())
1735 SMDS_ElemIteratorPtr ite=element->facesIterator();
1737 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1739 else if(hasConstructionEdges())
1741 SMDS_ElemIteratorPtr ite=element->edgesIterator();
1743 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1749 ///////////////////////////////////////////////////////////////////////////////
1750 ///@param elem The element to delete
1751 ///@param removenodes if true remaining nodes will be removed
1752 ///////////////////////////////////////////////////////////////////////////////
1753 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1754 const bool removenodes)
1756 list<const SMDS_MeshElement *> removedElems;
1757 list<const SMDS_MeshElement *> removedNodes;
1758 RemoveElement( elem, removedElems, removedNodes, removenodes );
1761 ///////////////////////////////////////////////////////////////////////////////
1762 ///@param elem The element to delete
1763 ///@param removedElems contains all removed elements
1764 ///@param removedNodes contains all removed nodes
1765 ///@param removenodes if true remaining nodes will be removed
1766 ///////////////////////////////////////////////////////////////////////////////
1767 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1768 list<const SMDS_MeshElement *>& removedElems,
1769 list<const SMDS_MeshElement *>& removedNodes,
1772 // get finite elements built on elem
1773 set<const SMDS_MeshElement*> * s1;
1774 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
1775 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
1777 s1 = new set<const SMDS_MeshElement*>();
1781 s1 = getFinitElements(elem);
1783 // get exclusive nodes (which would become free afterwards)
1784 set<const SMDS_MeshElement*> * s2;
1785 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1787 // do not remove nodes except elem
1788 s2 = new set<const SMDS_MeshElement*>();
1793 s2 = getExclusiveNodes(*s1);
1795 // form the set of finite and construction elements to remove
1796 set<const SMDS_MeshElement*> s3;
1797 set<const SMDS_MeshElement*>::iterator it=s1->begin();
1798 while(it!=s1->end())
1800 addChildrenWithNodes(s3, *it ,*s2);
1804 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1806 // remove finite and construction elements
1810 // Remove element from <InverseElements> of its nodes
1811 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
1814 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1815 (const_cast<SMDS_MeshElement *>(itn->next()));
1816 n->RemoveInverseElement( (*it) );
1819 switch((*it)->GetType())
1822 MESSAGE("Internal Error: This should not happen");
1825 myEdges.erase(static_cast<SMDS_MeshEdge*>
1826 (const_cast<SMDS_MeshElement*>(*it)));
1829 myFaces.erase(static_cast<SMDS_MeshFace*>
1830 (const_cast<SMDS_MeshElement*>(*it)));
1832 case SMDSAbs_Volume:
1833 myVolumes.erase(static_cast<SMDS_MeshVolume*>
1834 (const_cast<SMDS_MeshElement*>(*it)));
1837 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
1838 removedElems.push_back( (*it) );
1839 myElementIDFactory->ReleaseID((*it)->GetID());
1844 // remove exclusive (free) nodes
1848 while(it!=s2->end())
1850 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
1851 myNodes.erase(static_cast<SMDS_MeshNode*>
1852 (const_cast<SMDS_MeshElement*>(*it)));
1853 myNodeIDFactory->ReleaseID((*it)->GetID());
1854 removedNodes.push_back( (*it) );
1865 * Checks if the element is present in mesh.
1866 * Useful to determine dead pointers.
1868 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1870 // we should not imply on validity of *elem, so iterate on containers
1871 // of all types in the hope of finding <elem> somewhere there
1872 SMDS_NodeIteratorPtr itn = nodesIterator();
1874 if (elem == itn->next())
1876 SMDS_EdgeIteratorPtr ite = edgesIterator();
1878 if (elem == ite->next())
1880 SMDS_FaceIteratorPtr itf = facesIterator();
1882 if (elem == itf->next())
1884 SMDS_VolumeIteratorPtr itv = volumesIterator();
1886 if (elem == itv->next())
1891 //=======================================================================
1892 //function : MaxNodeID
1894 //=======================================================================
1896 int SMDS_Mesh::MaxNodeID() const
1898 return myNodeIDFactory->GetMaxID();
1901 //=======================================================================
1902 //function : MinNodeID
1904 //=======================================================================
1906 int SMDS_Mesh::MinNodeID() const
1908 return myNodeIDFactory->GetMinID();
1911 //=======================================================================
1912 //function : MaxElementID
1914 //=======================================================================
1916 int SMDS_Mesh::MaxElementID() const
1918 return myElementIDFactory->GetMaxID();
1921 //=======================================================================
1922 //function : MinElementID
1924 //=======================================================================
1926 int SMDS_Mesh::MinElementID() const
1928 return myElementIDFactory->GetMinID();
1931 //=======================================================================
1932 //function : Renumber
1933 //purpose : Renumber all nodes or elements.
1934 //=======================================================================
1936 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
1941 SMDS_MeshElementIDFactory * idFactory =
1942 isNodes ? myNodeIDFactory : myElementIDFactory;
1944 // get existing elements in the order of ID increasing and release their ids
1945 list< SMDS_MeshElement * > elemList;
1946 const SMDS_IdElementMap& idElemMap = idFactory->GetIdElementMap();
1947 SMDS_IdElementMap::const_iterator idElemIt = idElemMap.begin();
1948 while ( idElemIt != idElemMap.end() ) {
1949 SMDS_MeshElement* elem = (*idElemIt).second;
1950 int id = (*idElemIt).first;
1952 elemList.push_back( elem );
1953 idFactory->ReleaseID( id );
1957 list< SMDS_MeshElement * >::iterator elemIt = elemList.begin();
1958 for ( ; elemIt != elemList.end(); elemIt++ )
1960 idFactory->BindID( ID, *elemIt );