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.salome-platform.org/ or email : webmaster.salome@opencascade.com
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"
32 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
33 #include "SMDS_PolygonalFaceOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
43 #include <sys/sysinfo.h>
46 //================================================================================
48 * \brief Raise an exception if free memory (ram+swap) too low
49 * \param doNotRaise - if true, suppres exception, just return bool
50 * \retval bool - true if there is enough memory
52 //================================================================================
54 bool SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
58 int err = sysinfo( &si );
62 int freeMbyte = ( si.freeram + si.freeswap ) * si.mem_unit / 1024 / 1024;
67 throw std::bad_alloc();
73 ///////////////////////////////////////////////////////////////////////////////
74 /// Create a new mesh object
75 ///////////////////////////////////////////////////////////////////////////////
76 SMDS_Mesh::SMDS_Mesh()
78 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
79 myElementIDFactory(new SMDS_MeshElementIDFactory()),
80 myHasConstructionEdges(false), myHasConstructionFaces(false),
81 myHasInverseElements(true)
85 ///////////////////////////////////////////////////////////////////////////////
86 /// Create a new child mesh
87 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
88 /// (2003-09-08) of SMESH
89 ///////////////////////////////////////////////////////////////////////////////
90 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
91 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
92 myElementIDFactory(parent->myElementIDFactory),
93 myHasConstructionEdges(false), myHasConstructionFaces(false),
94 myHasInverseElements(true)
98 ///////////////////////////////////////////////////////////////////////////////
99 ///Create a submesh and add it to the current mesh
100 ///////////////////////////////////////////////////////////////////////////////
102 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
104 SMDS_Mesh *submesh = new SMDS_Mesh(this);
105 myChildren.insert(myChildren.end(), submesh);
109 ///////////////////////////////////////////////////////////////////////////////
110 ///create a MeshNode and add it to the current Mesh
111 ///An ID is automatically assigned to the node.
112 ///@return : The created node
113 ///////////////////////////////////////////////////////////////////////////////
115 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
117 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
120 ///////////////////////////////////////////////////////////////////////////////
121 ///create a MeshNode and add it to the current Mesh
122 ///@param ID : The ID of the MeshNode to create
123 ///@return : The created node or NULL if a node with this ID already exists
124 ///////////////////////////////////////////////////////////////////////////////
125 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
127 // find the MeshNode corresponding to ID
128 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
131 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
133 myNodeIDFactory->BindID(ID,node);
139 ///////////////////////////////////////////////////////////////////////////////
140 /// create a MeshEdge and add it to the current Mesh
141 /// @return : The created MeshEdge
142 ///////////////////////////////////////////////////////////////////////////////
144 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
146 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
147 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
148 if(!node1 || !node2) return NULL;
149 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
152 ///////////////////////////////////////////////////////////////////////////////
153 /// create a MeshEdge and add it to the current Mesh
154 /// @return : The created MeshEdge
155 ///////////////////////////////////////////////////////////////////////////////
157 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
158 const SMDS_MeshNode * node2)
160 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
163 ///////////////////////////////////////////////////////////////////////////////
164 /// Create a new edge and at it to the mesh
165 /// @param idnode1 ID of the first node
166 /// @param idnode2 ID of the second node
167 /// @param ID ID of the edge to create
168 /// @return The created edge or NULL if an element with this ID already exists or
169 /// if input nodes are not found.
170 ///////////////////////////////////////////////////////////////////////////////
172 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
173 const SMDS_MeshNode * n2,
176 if ( !n1 || !n2 ) return 0;
179 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
180 if(myElementIDFactory->BindID(ID, edge)) {
181 SMDS_MeshNode *node1,*node2;
182 node1=const_cast<SMDS_MeshNode*>(n1);
183 node2=const_cast<SMDS_MeshNode*>(n2);
184 node1->AddInverseElement(edge);
185 node2->AddInverseElement(edge);
195 ///////////////////////////////////////////////////////////////////////////////
196 /// Add a triangle defined by its nodes. An ID is automatically affected to the
198 ///////////////////////////////////////////////////////////////////////////////
200 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
201 const SMDS_MeshNode * n2,
202 const SMDS_MeshNode * n3)
204 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
207 ///////////////////////////////////////////////////////////////////////////////
208 /// Add a triangle defined by its nodes IDs
209 ///////////////////////////////////////////////////////////////////////////////
211 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
213 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
214 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
215 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
216 if(!node1 || !node2 || !node3) return NULL;
217 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
220 ///////////////////////////////////////////////////////////////////////////////
221 /// Add a triangle defined by its nodes
222 ///////////////////////////////////////////////////////////////////////////////
224 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
225 const SMDS_MeshNode * n2,
226 const SMDS_MeshNode * n3,
229 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
231 if (face && !registerElement(ID, face)) {
232 RemoveElement(face, false);
238 ///////////////////////////////////////////////////////////////////////////////
239 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
241 ///////////////////////////////////////////////////////////////////////////////
243 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
244 const SMDS_MeshNode * n2,
245 const SMDS_MeshNode * n3,
246 const SMDS_MeshNode * n4)
248 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
251 ///////////////////////////////////////////////////////////////////////////////
252 /// Add a quadrangle defined by its nodes IDs
253 ///////////////////////////////////////////////////////////////////////////////
255 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
261 SMDS_MeshNode *node1, *node2, *node3, *node4;
262 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
263 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
264 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
265 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
266 if(!node1 || !node2 || !node3 || !node4) return NULL;
267 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
270 ///////////////////////////////////////////////////////////////////////////////
271 /// Add a quadrangle defined by its nodes
272 ///////////////////////////////////////////////////////////////////////////////
274 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
275 const SMDS_MeshNode * n2,
276 const SMDS_MeshNode * n3,
277 const SMDS_MeshNode * n4,
280 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
282 if (face && !registerElement(ID, face)) {
283 RemoveElement(face, false);
289 ///////////////////////////////////////////////////////////////////////////////
290 /// Add a triangle defined by its edges. An ID is automatically assigned to the
292 ///////////////////////////////////////////////////////////////////////////////
294 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
295 const SMDS_MeshEdge * e2,
296 const SMDS_MeshEdge * e3)
298 if (!hasConstructionEdges())
300 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
303 ///////////////////////////////////////////////////////////////////////////////
304 /// Add a triangle defined by its edges
305 ///////////////////////////////////////////////////////////////////////////////
307 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
308 const SMDS_MeshEdge * e2,
309 const SMDS_MeshEdge * e3,
312 if (!hasConstructionEdges())
314 if ( !e1 || !e2 || !e3 ) return 0;
317 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
320 if (!registerElement(ID, face)) {
321 RemoveElement(face, false);
327 ///////////////////////////////////////////////////////////////////////////////
328 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
330 ///////////////////////////////////////////////////////////////////////////////
332 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
333 const SMDS_MeshEdge * e2,
334 const SMDS_MeshEdge * e3,
335 const SMDS_MeshEdge * e4)
337 if (!hasConstructionEdges())
339 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
342 ///////////////////////////////////////////////////////////////////////////////
343 /// Add a quadrangle defined by its edges
344 ///////////////////////////////////////////////////////////////////////////////
346 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
347 const SMDS_MeshEdge * e2,
348 const SMDS_MeshEdge * e3,
349 const SMDS_MeshEdge * e4,
352 if (!hasConstructionEdges())
354 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
356 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
359 if (!registerElement(ID, face))
361 RemoveElement(face, false);
367 ///////////////////////////////////////////////////////////////////////////////
368 ///Create a new tetrahedron and add it to the mesh.
369 ///@return The created tetrahedron
370 ///////////////////////////////////////////////////////////////////////////////
372 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
373 const SMDS_MeshNode * n2,
374 const SMDS_MeshNode * n3,
375 const SMDS_MeshNode * n4)
377 int ID = myElementIDFactory->GetFreeID();
378 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
379 if(v==NULL) myElementIDFactory->ReleaseID(ID);
383 ///////////////////////////////////////////////////////////////////////////////
384 ///Create a new tetrahedron and add it to the mesh.
385 ///@param ID The ID of the new volume
386 ///@return The created tetrahedron or NULL if an element with this ID already exists
387 ///or if input nodes are not found.
388 ///////////////////////////////////////////////////////////////////////////////
390 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
396 SMDS_MeshNode *node1, *node2, *node3, *node4;
397 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
398 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
399 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
400 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
401 if(!node1 || !node2 || !node3 || !node4) return NULL;
402 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
405 ///////////////////////////////////////////////////////////////////////////////
406 ///Create a new tetrahedron and add it to the mesh.
407 ///@param ID The ID of the new volume
408 ///@return The created tetrahedron
409 ///////////////////////////////////////////////////////////////////////////////
411 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
412 const SMDS_MeshNode * n2,
413 const SMDS_MeshNode * n3,
414 const SMDS_MeshNode * n4,
417 SMDS_MeshVolume* volume = 0;
418 if ( !n1 || !n2 || !n3 || !n4) return volume;
420 if(hasConstructionFaces()) {
421 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
422 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
423 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
424 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
425 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
426 myVolumes.Add(volume);
428 else if(hasConstructionEdges()) {
429 MESSAGE("Error : Not implemented");
433 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
434 myVolumes.Add(volume);
437 if (!registerElement(ID, volume)) {
438 RemoveElement(volume, false);
444 ///////////////////////////////////////////////////////////////////////////////
445 ///Create a new pyramid and add it to the mesh.
446 ///Nodes 1,2,3 and 4 define the base of the pyramid
447 ///@return The created pyramid
448 ///////////////////////////////////////////////////////////////////////////////
450 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
451 const SMDS_MeshNode * n2,
452 const SMDS_MeshNode * n3,
453 const SMDS_MeshNode * n4,
454 const SMDS_MeshNode * n5)
456 int ID = myElementIDFactory->GetFreeID();
457 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
458 if(v==NULL) myElementIDFactory->ReleaseID(ID);
462 ///////////////////////////////////////////////////////////////////////////////
463 ///Create a new pyramid and add it to the mesh.
464 ///Nodes 1,2,3 and 4 define the base of the pyramid
465 ///@param ID The ID of the new volume
466 ///@return The created pyramid or NULL if an element with this ID already exists
467 ///or if input nodes are not found.
468 ///////////////////////////////////////////////////////////////////////////////
470 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
477 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
478 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
479 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
480 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
481 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
482 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
483 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
484 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
487 ///////////////////////////////////////////////////////////////////////////////
488 ///Create a new pyramid and add it to the mesh.
489 ///Nodes 1,2,3 and 4 define the base of the pyramid
490 ///@param ID The ID of the new volume
491 ///@return The created pyramid
492 ///////////////////////////////////////////////////////////////////////////////
494 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
495 const SMDS_MeshNode * n2,
496 const SMDS_MeshNode * n3,
497 const SMDS_MeshNode * n4,
498 const SMDS_MeshNode * n5,
501 SMDS_MeshVolume* volume = 0;
502 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
504 if(hasConstructionFaces()) {
505 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
506 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
507 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
508 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
509 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
510 myVolumes.Add(volume);
512 else if(hasConstructionEdges()) {
513 MESSAGE("Error : Not implemented");
517 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
518 myVolumes.Add(volume);
521 if (!registerElement(ID, volume)) {
522 RemoveElement(volume, false);
528 ///////////////////////////////////////////////////////////////////////////////
529 ///Create a new prism and add it to the mesh.
530 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
531 ///@return The created prism
532 ///////////////////////////////////////////////////////////////////////////////
534 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
535 const SMDS_MeshNode * n2,
536 const SMDS_MeshNode * n3,
537 const SMDS_MeshNode * n4,
538 const SMDS_MeshNode * n5,
539 const SMDS_MeshNode * n6)
541 int ID = myElementIDFactory->GetFreeID();
542 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
543 if(v==NULL) myElementIDFactory->ReleaseID(ID);
547 ///////////////////////////////////////////////////////////////////////////////
548 ///Create a new prism and add it to the mesh.
549 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
550 ///@param ID The ID of the new volume
551 ///@return The created prism or NULL if an element with this ID already exists
552 ///or if input nodes are not found.
553 ///////////////////////////////////////////////////////////////////////////////
555 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
563 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
564 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
565 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
566 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
567 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
568 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
569 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
570 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
571 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
574 ///////////////////////////////////////////////////////////////////////////////
575 ///Create a new prism and add it to the mesh.
576 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
577 ///@param ID The ID of the new volume
578 ///@return The created prism
579 ///////////////////////////////////////////////////////////////////////////////
581 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
582 const SMDS_MeshNode * n2,
583 const SMDS_MeshNode * n3,
584 const SMDS_MeshNode * n4,
585 const SMDS_MeshNode * n5,
586 const SMDS_MeshNode * n6,
589 SMDS_MeshVolume* volume = 0;
590 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
592 if(hasConstructionFaces()) {
593 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
594 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
595 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
596 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
597 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
598 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
599 myVolumes.Add(volume);
601 else if(hasConstructionEdges()) {
602 MESSAGE("Error : Not implemented");
606 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
607 myVolumes.Add(volume);
610 if (!registerElement(ID, volume)) {
611 RemoveElement(volume, false);
617 ///////////////////////////////////////////////////////////////////////////////
618 ///Create a new hexahedron and add it to the mesh.
619 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
620 ///@return The created hexahedron
621 ///////////////////////////////////////////////////////////////////////////////
623 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
624 const SMDS_MeshNode * n2,
625 const SMDS_MeshNode * n3,
626 const SMDS_MeshNode * n4,
627 const SMDS_MeshNode * n5,
628 const SMDS_MeshNode * n6,
629 const SMDS_MeshNode * n7,
630 const SMDS_MeshNode * n8)
632 int ID = myElementIDFactory->GetFreeID();
633 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
634 if(v==NULL) myElementIDFactory->ReleaseID(ID);
638 ///////////////////////////////////////////////////////////////////////////////
639 ///Create a new hexahedron and add it to the mesh.
640 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
641 ///@param ID The ID of the new volume
642 ///@return The created hexahedron or NULL if an element with this ID already
643 ///exists or if input nodes are not found.
644 ///////////////////////////////////////////////////////////////////////////////
646 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
656 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
657 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
658 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
659 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
660 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
661 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
662 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
663 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
664 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
665 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
667 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
671 ///////////////////////////////////////////////////////////////////////////////
672 ///Create a new hexahedron and add it to the mesh.
673 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
674 ///@param ID The ID of the new volume
675 ///@return The created prism or NULL if an element with this ID already exists
676 ///or if input nodes are not found.
677 ///////////////////////////////////////////////////////////////////////////////
679 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
680 const SMDS_MeshNode * n2,
681 const SMDS_MeshNode * n3,
682 const SMDS_MeshNode * n4,
683 const SMDS_MeshNode * n5,
684 const SMDS_MeshNode * n6,
685 const SMDS_MeshNode * n7,
686 const SMDS_MeshNode * n8,
689 SMDS_MeshVolume* volume = 0;
690 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
692 if(hasConstructionFaces()) {
693 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
694 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
695 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
696 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
697 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
698 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
699 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
700 myVolumes.Add(volume);
702 else if(hasConstructionEdges()) {
703 MESSAGE("Error : Not implemented");
707 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
708 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
709 myVolumes.Add(volume);
712 if (!registerElement(ID, volume)) {
713 RemoveElement(volume, false);
719 ///////////////////////////////////////////////////////////////////////////////
720 ///Create a new tetrahedron defined by its faces and add it to the mesh.
721 ///@return The created tetrahedron
722 ///////////////////////////////////////////////////////////////////////////////
724 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
725 const SMDS_MeshFace * f2,
726 const SMDS_MeshFace * f3,
727 const SMDS_MeshFace * f4)
729 if (!hasConstructionFaces())
731 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
734 ///////////////////////////////////////////////////////////////////////////////
735 ///Create a new tetrahedron defined by its faces and add it to the mesh.
736 ///@param ID The ID of the new volume
737 ///@return The created tetrahedron
738 ///////////////////////////////////////////////////////////////////////////////
740 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
741 const SMDS_MeshFace * f2,
742 const SMDS_MeshFace * f3,
743 const SMDS_MeshFace * f4,
746 if (!hasConstructionFaces())
748 if ( !f1 || !f2 || !f3 || !f4) return 0;
750 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
751 myVolumes.Add(volume);
753 if (!registerElement(ID, volume)) {
754 RemoveElement(volume, false);
760 ///////////////////////////////////////////////////////////////////////////////
761 ///Create a new pyramid defined by its faces and add it to the mesh.
762 ///@return The created pyramid
763 ///////////////////////////////////////////////////////////////////////////////
765 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
766 const SMDS_MeshFace * f2,
767 const SMDS_MeshFace * f3,
768 const SMDS_MeshFace * f4,
769 const SMDS_MeshFace * f5)
771 if (!hasConstructionFaces())
773 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
776 ///////////////////////////////////////////////////////////////////////////////
777 ///Create a new pyramid defined by its faces and add it to the mesh.
778 ///@param ID The ID of the new volume
779 ///@return The created pyramid
780 ///////////////////////////////////////////////////////////////////////////////
782 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
783 const SMDS_MeshFace * f2,
784 const SMDS_MeshFace * f3,
785 const SMDS_MeshFace * f4,
786 const SMDS_MeshFace * f5,
789 if (!hasConstructionFaces())
791 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
793 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
794 myVolumes.Add(volume);
796 if (!registerElement(ID, volume)) {
797 RemoveElement(volume, false);
803 ///////////////////////////////////////////////////////////////////////////////
804 ///Create a new prism defined by its faces and add it to the mesh.
805 ///@return The created prism
806 ///////////////////////////////////////////////////////////////////////////////
808 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
809 const SMDS_MeshFace * f2,
810 const SMDS_MeshFace * f3,
811 const SMDS_MeshFace * f4,
812 const SMDS_MeshFace * f5,
813 const SMDS_MeshFace * f6)
815 if (!hasConstructionFaces())
817 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
820 ///////////////////////////////////////////////////////////////////////////////
821 ///Create a new prism defined by its faces and add it to the mesh.
822 ///@param ID The ID of the new volume
823 ///@return The created prism
824 ///////////////////////////////////////////////////////////////////////////////
826 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
827 const SMDS_MeshFace * f2,
828 const SMDS_MeshFace * f3,
829 const SMDS_MeshFace * f4,
830 const SMDS_MeshFace * f5,
831 const SMDS_MeshFace * f6,
834 if (!hasConstructionFaces())
836 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
838 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
839 myVolumes.Add(volume);
841 if (!registerElement(ID, volume)) {
842 RemoveElement(volume, false);
848 ///////////////////////////////////////////////////////////////////////////////
849 /// Add a polygon defined by its nodes IDs
850 ///////////////////////////////////////////////////////////////////////////////
852 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
855 int nbNodes = nodes_ids.size();
856 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
857 for (int i = 0; i < nbNodes; i++) {
858 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
859 if (!nodes[i]) return NULL;
861 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
864 ///////////////////////////////////////////////////////////////////////////////
865 /// Add a polygon defined by its nodes
866 ///////////////////////////////////////////////////////////////////////////////
868 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
869 (std::vector<const SMDS_MeshNode*> nodes,
872 SMDS_MeshFace * face;
875 if (hasConstructionEdges())
877 MESSAGE("Error : Not implemented");
882 for ( int i = 0; i < nodes.size(); ++i )
883 if ( !nodes[ i ] ) return 0;
884 face = new SMDS_PolygonalFaceOfNodes(nodes);
888 if (!registerElement(ID, face)) {
889 RemoveElement(face, false);
895 ///////////////////////////////////////////////////////////////////////////////
896 /// Add a polygon defined by its nodes.
897 /// An ID is automatically affected to the created face.
898 ///////////////////////////////////////////////////////////////////////////////
900 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
902 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
905 ///////////////////////////////////////////////////////////////////////////////
906 /// Create a new polyhedral volume and add it to the mesh.
907 /// @param ID The ID of the new volume
908 /// @return The created volume or NULL if an element with this ID already exists
909 /// or if input nodes are not found.
910 ///////////////////////////////////////////////////////////////////////////////
912 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
913 (std::vector<int> nodes_ids,
914 std::vector<int> quantities,
917 int nbNodes = nodes_ids.size();
918 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
919 for (int i = 0; i < nbNodes; i++) {
920 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
921 if (!nodes[i]) return NULL;
923 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
926 ///////////////////////////////////////////////////////////////////////////////
927 /// Create a new polyhedral volume and add it to the mesh.
928 /// @param ID The ID of the new volume
929 /// @return The created volume
930 ///////////////////////////////////////////////////////////////////////////////
932 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
933 (std::vector<const SMDS_MeshNode*> nodes,
934 std::vector<int> quantities,
937 SMDS_MeshVolume* volume;
939 if (hasConstructionFaces()) {
940 MESSAGE("Error : Not implemented");
942 } else if (hasConstructionEdges()) {
943 MESSAGE("Error : Not implemented");
946 for ( int i = 0; i < nodes.size(); ++i )
947 if ( !nodes[ i ] ) return 0;
948 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
949 myVolumes.Add(volume);
952 if (!registerElement(ID, volume)) {
953 RemoveElement(volume, false);
959 ///////////////////////////////////////////////////////////////////////////////
960 /// Create a new polyhedral volume and add it to the mesh.
961 /// @return The created volume
962 ///////////////////////////////////////////////////////////////////////////////
964 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
965 (std::vector<const SMDS_MeshNode*> nodes,
966 std::vector<int> quantities)
968 int ID = myElementIDFactory->GetFreeID();
969 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
970 if (v == NULL) myElementIDFactory->ReleaseID(ID);
974 ///////////////////////////////////////////////////////////////////////////////
975 /// Registers element with the given ID, maintains inverse connections
976 ///////////////////////////////////////////////////////////////////////////////
977 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
979 if (myElementIDFactory->BindID(ID, element)) {
980 SMDS_ElemIteratorPtr it = element->nodesIterator();
982 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
983 (const_cast<SMDS_MeshElement*>(it->next()));
984 node->AddInverseElement(element);
991 ///////////////////////////////////////////////////////////////////////////////
992 /// Return the node whose ID is 'ID'.
993 ///////////////////////////////////////////////////////////////////////////////
994 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
996 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
999 ///////////////////////////////////////////////////////////////////////////////
1000 ///Create a triangle and add it to the current mesh. This methode do not bind a
1001 ///ID to the create triangle.
1002 ///////////////////////////////////////////////////////////////////////////////
1003 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1004 const SMDS_MeshNode * node2,
1005 const SMDS_MeshNode * node3)
1007 if ( !node1 || !node2 || !node3) return 0;
1009 if(hasConstructionEdges())
1011 SMDS_MeshEdge *edge1, *edge2, *edge3;
1012 edge1=FindEdgeOrCreate(node1,node2);
1013 edge2=FindEdgeOrCreate(node2,node3);
1014 edge3=FindEdgeOrCreate(node3,node1);
1016 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1022 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1028 ///////////////////////////////////////////////////////////////////////////////
1029 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1030 ///a ID to the create triangle.
1031 ///////////////////////////////////////////////////////////////////////////////
1032 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1033 const SMDS_MeshNode * node2,
1034 const SMDS_MeshNode * node3,
1035 const SMDS_MeshNode * node4)
1037 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1039 if(hasConstructionEdges())
1041 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1042 edge1=FindEdgeOrCreate(node1,node2);
1043 edge2=FindEdgeOrCreate(node2,node3);
1044 edge3=FindEdgeOrCreate(node3,node4);
1045 edge4=FindEdgeOrCreate(node4,node1);
1047 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1053 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1059 ///////////////////////////////////////////////////////////////////////////////
1060 /// Remove a node and all the elements which own this node
1061 ///////////////////////////////////////////////////////////////////////////////
1063 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1065 RemoveElement(node, true);
1068 ///////////////////////////////////////////////////////////////////////////////
1069 /// Remove an edge and all the elements which own this edge
1070 ///////////////////////////////////////////////////////////////////////////////
1072 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1074 RemoveElement(edge,true);
1077 ///////////////////////////////////////////////////////////////////////////////
1078 /// Remove an face and all the elements which own this face
1079 ///////////////////////////////////////////////////////////////////////////////
1081 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1083 RemoveElement(face, true);
1086 ///////////////////////////////////////////////////////////////////////////////
1088 ///////////////////////////////////////////////////////////////////////////////
1090 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1092 RemoveElement(volume, true);
1095 //=======================================================================
1096 //function : RemoveFromParent
1098 //=======================================================================
1100 bool SMDS_Mesh::RemoveFromParent()
1102 if (myParent==NULL) return false;
1103 else return (myParent->RemoveSubMesh(this));
1106 //=======================================================================
1107 //function : RemoveSubMesh
1109 //=======================================================================
1111 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1115 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1116 for (; itmsh!=myChildren.end() && !found; itmsh++)
1118 SMDS_Mesh * submesh = *itmsh;
1119 if (submesh == aMesh)
1122 myChildren.erase(itmsh);
1129 //=======================================================================
1130 //function : ChangeElementNodes
1132 //=======================================================================
1134 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
1135 const SMDS_MeshNode * nodes[],
1138 // keep current nodes of elem
1139 set<const SMDS_MeshElement*> oldNodes;
1140 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1142 oldNodes.insert( itn->next() );
1146 switch ( elem->GetType() )
1148 case SMDSAbs_Edge: {
1149 if ( nbnodes == 2 ) {
1150 const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
1152 Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
1154 else if ( nbnodes == 3 ) {
1155 const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
1157 Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1161 case SMDSAbs_Face: {
1162 const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
1164 Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
1167 const SMDS_QuadraticFaceOfNodes* QF =
1168 dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
1170 Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
1174 const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1176 Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1183 //case SMDSAbs_PolygonalFace: {
1184 // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1186 // Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1190 case SMDSAbs_Volume: {
1191 const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
1193 Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
1196 const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
1198 Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
1204 MESSAGE ( "WRONG ELEM TYPE");
1207 if ( Ok ) { // update InverseElements
1209 // AddInverseElement to new nodes
1210 for ( int i = 0; i < nbnodes; i++ )
1211 if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
1213 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1215 // remove from oldNodes a node that remains in elem
1216 oldNodes.erase( nodes[i] );
1219 // RemoveInverseElement from the nodes removed from elem
1220 set<const SMDS_MeshElement*>::iterator it;
1221 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1223 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1224 (const_cast<SMDS_MeshElement *>( *it ));
1225 n->RemoveInverseElement( elem );
1229 //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1234 //=======================================================================
1235 //function : ChangePolyhedronNodes
1236 //purpose : to change nodes of polyhedral volume
1237 //=======================================================================
1238 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1239 std::vector<const SMDS_MeshNode*> nodes,
1240 std::vector<int> quantities)
1242 if (elem->GetType() != SMDSAbs_Volume) {
1243 MESSAGE("WRONG ELEM TYPE");
1247 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1252 // keep current nodes of elem
1253 set<const SMDS_MeshElement*> oldNodes;
1254 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1255 while (itn->more()) {
1256 oldNodes.insert(itn->next());
1260 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1265 // update InverseElements
1267 // AddInverseElement to new nodes
1268 int nbnodes = nodes.size();
1269 for (int i = 0; i < nbnodes; i++) {
1270 if (oldNodes.find(nodes[i]) == oldNodes.end()) {
1272 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1274 // remove from oldNodes a node that remains in elem
1275 oldNodes.erase(nodes[i]);
1279 // RemoveInverseElement from the nodes removed from elem
1280 set<const SMDS_MeshElement*>::iterator it;
1281 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1282 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1283 (const_cast<SMDS_MeshElement *>( *it ));
1284 n->RemoveInverseElement(elem);
1291 //=======================================================================
1292 //function : FindEdge
1294 //=======================================================================
1296 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1298 const SMDS_MeshNode * node1=FindNode(idnode1);
1299 const SMDS_MeshNode * node2=FindNode(idnode2);
1300 if((node1==NULL)||(node2==NULL)) return NULL;
1301 return FindEdge(node1,node2);
1304 //#include "Profiler.h"
1305 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1306 const SMDS_MeshNode * node2)
1308 if ( !node1 ) return 0;
1309 const SMDS_MeshEdge * toReturn=NULL;
1312 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1315 while(it1->more()) {
1316 const SMDS_MeshElement * e = it1->next();
1317 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1318 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1327 //=======================================================================
1328 //function : FindEdgeOrCreate
1330 //=======================================================================
1332 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1333 const SMDS_MeshNode * node2)
1335 if ( !node1 || !node2) return 0;
1336 SMDS_MeshEdge * toReturn=NULL;
1337 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1338 if(toReturn==NULL) {
1340 toReturn=new SMDS_MeshEdge(node1,node2);
1341 myEdges.Add(toReturn);
1347 //=======================================================================
1348 //function : FindEdge
1350 //=======================================================================
1352 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1355 const SMDS_MeshNode * node1=FindNode(idnode1);
1356 const SMDS_MeshNode * node2=FindNode(idnode2);
1357 const SMDS_MeshNode * node3=FindNode(idnode3);
1358 return FindEdge(node1,node2,node3);
1361 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1362 const SMDS_MeshNode * node2,
1363 const SMDS_MeshNode * node3)
1365 if ( !node1 ) return 0;
1366 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1367 while(it1->more()) {
1368 const SMDS_MeshElement * e = it1->next();
1369 if ( e->NbNodes() == 3 ) {
1370 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1371 while(it2->more()) {
1372 const SMDS_MeshElement* n = it2->next();
1382 return static_cast<const SMDS_MeshEdge *> (e);
1389 //=======================================================================
1390 //function : FindFace
1392 //=======================================================================
1394 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1397 const SMDS_MeshNode * node1=FindNode(idnode1);
1398 const SMDS_MeshNode * node2=FindNode(idnode2);
1399 const SMDS_MeshNode * node3=FindNode(idnode3);
1400 return FindFace(node1, node2, node3);
1403 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1404 const SMDS_MeshNode *node2,
1405 const SMDS_MeshNode *node3)
1407 if ( !node1 ) return 0;
1408 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1409 while(it1->more()) {
1410 const SMDS_MeshElement * e = it1->next();
1411 if ( e->NbNodes() == 3 ) {
1412 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1413 while(it2->more()) {
1414 const SMDS_MeshElement* n = it2->next();
1424 return static_cast<const SMDS_MeshFace *> (e);
1430 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1431 const SMDS_MeshNode *node2,
1432 const SMDS_MeshNode *node3)
1434 SMDS_MeshFace * toReturn=NULL;
1435 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1436 if(toReturn==NULL) {
1437 toReturn = createTriangle(node1,node2,node3);
1443 //=======================================================================
1444 //function : FindFace
1446 //=======================================================================
1448 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1449 int idnode3, int idnode4) const
1451 const SMDS_MeshNode * node1=FindNode(idnode1);
1452 const SMDS_MeshNode * node2=FindNode(idnode2);
1453 const SMDS_MeshNode * node3=FindNode(idnode3);
1454 const SMDS_MeshNode * node4=FindNode(idnode4);
1455 return FindFace(node1, node2, node3, node4);
1458 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1459 const SMDS_MeshNode *node2,
1460 const SMDS_MeshNode *node3,
1461 const SMDS_MeshNode *node4)
1463 if ( !node1 ) return 0;
1464 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1465 while(it1->more()) {
1466 const SMDS_MeshElement * e = it1->next();
1467 if ( e->NbNodes() == 4 ) {
1468 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1469 while(it2->more()) {
1470 const SMDS_MeshElement* n = it2->next();
1481 return static_cast<const SMDS_MeshFace *> (e);
1487 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1488 const SMDS_MeshNode *node2,
1489 const SMDS_MeshNode *node3,
1490 const SMDS_MeshNode *node4)
1492 SMDS_MeshFace * toReturn=NULL;
1493 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1494 if(toReturn==NULL) {
1495 toReturn=createQuadrangle(node1,node2,node3,node4);
1501 //=======================================================================
1502 //function : FindFace
1503 //purpose :quadratic triangle
1504 //=======================================================================
1506 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1507 int idnode3, int idnode4,
1508 int idnode5, int idnode6) const
1510 const SMDS_MeshNode * node1 = FindNode(idnode1);
1511 const SMDS_MeshNode * node2 = FindNode(idnode2);
1512 const SMDS_MeshNode * node3 = FindNode(idnode3);
1513 const SMDS_MeshNode * node4 = FindNode(idnode4);
1514 const SMDS_MeshNode * node5 = FindNode(idnode5);
1515 const SMDS_MeshNode * node6 = FindNode(idnode6);
1516 return FindFace(node1, node2, node3, node4, node5, node6);
1519 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1520 const SMDS_MeshNode *node2,
1521 const SMDS_MeshNode *node3,
1522 const SMDS_MeshNode *node4,
1523 const SMDS_MeshNode *node5,
1524 const SMDS_MeshNode *node6)
1526 if ( !node1 ) return 0;
1527 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1528 while(it1->more()) {
1529 const SMDS_MeshElement * e = it1->next();
1530 if ( e->NbNodes() == 6 ) {
1531 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1532 while(it2->more()) {
1533 const SMDS_MeshElement* n = it2->next();
1546 return static_cast<const SMDS_MeshFace *> (e);
1553 //=======================================================================
1554 //function : FindFace
1555 //purpose : quadratic quadrangle
1556 //=======================================================================
1558 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1559 int idnode3, int idnode4,
1560 int idnode5, int idnode6,
1561 int idnode7, int idnode8) const
1563 const SMDS_MeshNode * node1 = FindNode(idnode1);
1564 const SMDS_MeshNode * node2 = FindNode(idnode2);
1565 const SMDS_MeshNode * node3 = FindNode(idnode3);
1566 const SMDS_MeshNode * node4 = FindNode(idnode4);
1567 const SMDS_MeshNode * node5 = FindNode(idnode5);
1568 const SMDS_MeshNode * node6 = FindNode(idnode6);
1569 const SMDS_MeshNode * node7 = FindNode(idnode7);
1570 const SMDS_MeshNode * node8 = FindNode(idnode8);
1571 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1574 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1575 const SMDS_MeshNode *node2,
1576 const SMDS_MeshNode *node3,
1577 const SMDS_MeshNode *node4,
1578 const SMDS_MeshNode *node5,
1579 const SMDS_MeshNode *node6,
1580 const SMDS_MeshNode *node7,
1581 const SMDS_MeshNode *node8)
1583 if ( !node1 ) return 0;
1584 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1585 while(it1->more()) {
1586 const SMDS_MeshElement * e = it1->next();
1587 if ( e->NbNodes() == 8 ) {
1588 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1589 while(it2->more()) {
1590 const SMDS_MeshElement* n = it2->next();
1605 return static_cast<const SMDS_MeshFace *> (e);
1612 //=======================================================================
1613 //function : FindElement
1615 //=======================================================================
1617 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1619 return myElementIDFactory->MeshElement(IDelem);
1622 //=======================================================================
1623 //function : FindFace
1624 //purpose : find polygon
1625 //=======================================================================
1627 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1629 int nbnodes = nodes_ids.size();
1630 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1631 for (int inode = 0; inode < nbnodes; inode++) {
1632 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1633 if (node == NULL) return NULL;
1635 return FindFace(poly_nodes);
1638 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1640 if ( nodes.size() > 2 && nodes[0] ) {
1641 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1642 while (itF->more()) {
1643 const SMDS_MeshElement* f = itF->next();
1644 if ( f->NbNodes() == nodes.size() ) {
1645 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1646 while(it2->more()) {
1647 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1653 return static_cast<const SMDS_MeshFace *> (f);
1660 //=======================================================================
1661 //function : DumpNodes
1663 //=======================================================================
1665 void SMDS_Mesh::DumpNodes() const
1667 MESSAGE("dump nodes of mesh : ");
1668 SMDS_NodeIteratorPtr itnode=nodesIterator();
1669 while(itnode->more()) MESSAGE(itnode->next());
1672 //=======================================================================
1673 //function : DumpEdges
1675 //=======================================================================
1677 void SMDS_Mesh::DumpEdges() const
1679 MESSAGE("dump edges of mesh : ");
1680 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1681 while(itedge->more()) MESSAGE(itedge->next());
1684 //=======================================================================
1685 //function : DumpFaces
1687 //=======================================================================
1689 void SMDS_Mesh::DumpFaces() const
1691 MESSAGE("dump faces of mesh : ");
1692 SMDS_FaceIteratorPtr itface=facesIterator();
1693 while(itface->more()) MESSAGE(itface->next());
1696 //=======================================================================
1697 //function : DumpVolumes
1699 //=======================================================================
1701 void SMDS_Mesh::DumpVolumes() const
1703 MESSAGE("dump volumes of mesh : ");
1704 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1705 while(itvol->more()) MESSAGE(itvol->next());
1708 //=======================================================================
1709 //function : DebugStats
1711 //=======================================================================
1713 void SMDS_Mesh::DebugStats() const
1715 MESSAGE("Debug stats of mesh : ");
1717 MESSAGE("===== NODES ====="<<NbNodes());
1718 MESSAGE("===== EDGES ====="<<NbEdges());
1719 MESSAGE("===== FACES ====="<<NbFaces());
1720 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1722 MESSAGE("End Debug stats of mesh ");
1726 SMDS_NodeIteratorPtr itnode=nodesIterator();
1727 int sizeofnodes = 0;
1728 int sizeoffaces = 0;
1730 while(itnode->more())
1732 const SMDS_MeshNode *node = itnode->next();
1734 sizeofnodes += sizeof(*node);
1736 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1739 const SMDS_MeshElement *me = it->next();
1740 sizeofnodes += sizeof(me);
1745 SMDS_FaceIteratorPtr itface=facesIterator();
1746 while(itface->more())
1748 const SMDS_MeshElement *face = itface->next();
1749 sizeoffaces += sizeof(*face);
1752 MESSAGE("total size of node elements = " << sizeofnodes);;
1753 MESSAGE("total size of face elements = " << sizeoffaces);;
1758 ///////////////////////////////////////////////////////////////////////////////
1759 /// Return the number of nodes
1760 ///////////////////////////////////////////////////////////////////////////////
1761 int SMDS_Mesh::NbNodes() const
1763 return myNodes.Size();
1766 ///////////////////////////////////////////////////////////////////////////////
1767 /// Return the number of edges (including construction edges)
1768 ///////////////////////////////////////////////////////////////////////////////
1769 int SMDS_Mesh::NbEdges() const
1771 return myEdges.Size();
1774 ///////////////////////////////////////////////////////////////////////////////
1775 /// Return the number of faces (including construction faces)
1776 ///////////////////////////////////////////////////////////////////////////////
1777 int SMDS_Mesh::NbFaces() const
1779 return myFaces.Size();
1782 ///////////////////////////////////////////////////////////////////////////////
1783 /// Return the number of volumes
1784 ///////////////////////////////////////////////////////////////////////////////
1785 int SMDS_Mesh::NbVolumes() const
1787 return myVolumes.Size();
1790 ///////////////////////////////////////////////////////////////////////////////
1791 /// Return the number of child mesh of this mesh.
1792 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1793 /// (2003-09-08) of SMESH
1794 ///////////////////////////////////////////////////////////////////////////////
1795 int SMDS_Mesh::NbSubMesh() const
1797 return myChildren.size();
1800 ///////////////////////////////////////////////////////////////////////////////
1801 /// Destroy the mesh and all its elements
1802 /// All pointer on elements owned by this mesh become illegals.
1803 ///////////////////////////////////////////////////////////////////////////////
1804 SMDS_Mesh::~SMDS_Mesh()
1806 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1807 while(itc!=myChildren.end())
1813 SetOfNodes::Iterator itn(myNodes);
1814 for (; itn.More(); itn.Next())
1817 SetOfEdges::Iterator ite(myEdges);
1818 for (; ite.More(); ite.Next())
1820 SMDS_MeshElement* elem = ite.Value();
1822 myElementIDFactory->ReleaseID(elem->GetID());
1826 SetOfFaces::Iterator itf(myFaces);
1827 for (; itf.More(); itf.Next())
1829 SMDS_MeshElement* elem = itf.Value();
1831 myElementIDFactory->ReleaseID(elem->GetID());
1835 SetOfVolumes::Iterator itv(myVolumes);
1836 for (; itv.More(); itv.Next())
1838 SMDS_MeshElement* elem = itv.Value();
1840 myElementIDFactory->ReleaseID(elem->GetID());
1846 delete myNodeIDFactory;
1847 delete myElementIDFactory;
1851 ///////////////////////////////////////////////////////////////////////////////
1852 /// Return true if this mesh create faces with edges.
1853 /// A false returned value mean that faces are created with nodes. A concequence
1854 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1855 ///////////////////////////////////////////////////////////////////////////////
1856 bool SMDS_Mesh::hasConstructionEdges()
1858 return myHasConstructionEdges;
1861 ///////////////////////////////////////////////////////////////////////////////
1862 /// Return true if this mesh create volumes with faces
1863 /// A false returned value mean that volumes are created with nodes or edges.
1864 /// (see hasConstructionEdges)
1865 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1867 ///////////////////////////////////////////////////////////////////////////////
1868 bool SMDS_Mesh::hasConstructionFaces()
1870 return myHasConstructionFaces;
1873 ///////////////////////////////////////////////////////////////////////////////
1874 /// Return true if nodes are linked to the finit elements, they are belonging to.
1875 /// Currently, It always return true.
1876 ///////////////////////////////////////////////////////////////////////////////
1877 bool SMDS_Mesh::hasInverseElements()
1879 return myHasInverseElements;
1882 ///////////////////////////////////////////////////////////////////////////////
1883 /// Make this mesh creating construction edges (see hasConstructionEdges)
1884 /// @param b true to have construction edges, else false.
1885 ///////////////////////////////////////////////////////////////////////////////
1886 void SMDS_Mesh::setConstructionEdges(bool b)
1888 myHasConstructionEdges=b;
1891 ///////////////////////////////////////////////////////////////////////////////
1892 /// Make this mesh creating construction faces (see hasConstructionFaces)
1893 /// @param b true to have construction faces, else false.
1894 ///////////////////////////////////////////////////////////////////////////////
1895 void SMDS_Mesh::setConstructionFaces(bool b)
1897 myHasConstructionFaces=b;
1900 ///////////////////////////////////////////////////////////////////////////////
1901 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1902 /// @param b true to link nodes to elements, else false.
1903 ///////////////////////////////////////////////////////////////////////////////
1904 void SMDS_Mesh::setInverseElements(bool b)
1906 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1907 myHasInverseElements=b;
1910 ///////////////////////////////////////////////////////////////////////////////
1911 /// Return an iterator on nodes of the current mesh factory
1912 ///////////////////////////////////////////////////////////////////////////////
1913 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1915 SMDS_ElemIteratorPtr myIterator;
1917 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1922 return myIterator->more();
1925 const SMDS_MeshNode* next()
1927 return static_cast<const SMDS_MeshNode*>(myIterator->next());
1931 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1933 return SMDS_NodeIteratorPtr
1934 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1937 ///////////////////////////////////////////////////////////////////////////////
1938 /// Return an iterator on elements of the current mesh factory
1939 ///////////////////////////////////////////////////////////////////////////////
1940 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1942 return myElementIDFactory->elementsIterator();
1945 ///////////////////////////////////////////////////////////////////////////////
1946 ///Return an iterator on edges of the current mesh.
1947 ///////////////////////////////////////////////////////////////////////////////
1948 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1950 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1951 SetOfEdges::Iterator myIterator;
1953 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1958 while(myIterator.More())
1960 if(myIterator.Value()->GetID()!=-1)
1967 const SMDS_MeshEdge* next()
1969 const SMDS_MeshEdge* current = myIterator.Value();
1975 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1977 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1980 ///////////////////////////////////////////////////////////////////////////////
1981 ///Return an iterator on faces of the current mesh.
1982 ///////////////////////////////////////////////////////////////////////////////
1983 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1985 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1986 SetOfFaces::Iterator myIterator;
1988 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
1993 while(myIterator.More())
1995 if(myIterator.Value()->GetID()!=-1)
2002 const SMDS_MeshFace* next()
2004 const SMDS_MeshFace* current = myIterator.Value();
2010 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2012 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2015 ///////////////////////////////////////////////////////////////////////////////
2016 ///Return an iterator on volumes of the current mesh.
2017 ///////////////////////////////////////////////////////////////////////////////
2018 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2020 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2021 SetOfVolumes::Iterator myIterator;
2023 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2028 return myIterator.More() != Standard_False;
2031 const SMDS_MeshVolume* next()
2033 const SMDS_MeshVolume* current = myIterator.Value();
2039 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2041 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2044 ///////////////////////////////////////////////////////////////////////////////
2045 /// Do intersection of sets (more than 2)
2046 ///////////////////////////////////////////////////////////////////////////////
2047 static set<const SMDS_MeshElement*> * intersectionOfSets(
2048 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2050 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2051 set<const SMDS_MeshElement*>* rsetB;
2053 for(int i=0; i<numberOfSets-1; i++)
2055 rsetB=new set<const SMDS_MeshElement*>();
2057 rsetA->begin(), rsetA->end(),
2058 vs[i+1].begin(), vs[i+1].end(),
2059 inserter(*rsetB, rsetB->begin()));
2066 ///////////////////////////////////////////////////////////////////////////////
2067 /// Return the list of finit elements owning the given element
2068 ///////////////////////////////////////////////////////////////////////////////
2069 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2071 int numberOfSets=element->NbNodes();
2072 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2074 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2077 while(itNodes->more())
2079 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2080 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2082 //initSet[i]=set<const SMDS_MeshElement*>();
2084 initSet[i].insert(itFe->next());
2088 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2093 ///////////////////////////////////////////////////////////////////////////////
2094 /// Return the list of nodes used only by the given elements
2095 ///////////////////////////////////////////////////////////////////////////////
2096 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2097 set<const SMDS_MeshElement*>& elements)
2099 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2100 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2102 while(itElements!=elements.end())
2104 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2107 while(itNodes->more())
2109 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2110 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2111 set<const SMDS_MeshElement*> s;
2113 s.insert(itFe->next());
2114 if(s==elements) toReturn->insert(n);
2120 ///////////////////////////////////////////////////////////////////////////////
2121 ///Find the children of an element that are made of given nodes
2122 ///@param setOfChildren The set in which matching children will be inserted
2123 ///@param element The element were to search matching children
2124 ///@param nodes The nodes that the children must have to be selected
2125 ///////////////////////////////////////////////////////////////////////////////
2126 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2127 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2130 switch(element->GetType())
2133 MESSAGE("Internal Error: This should not append");
2137 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2140 const SMDS_MeshElement * e=itn->next();
2141 if(nodes.find(e)!=nodes.end())
2143 setOfChildren.insert(element);
2150 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2153 const SMDS_MeshElement * e=itn->next();
2154 if(nodes.find(e)!=nodes.end())
2156 setOfChildren.insert(element);
2160 if(hasConstructionEdges())
2162 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2164 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2167 case SMDSAbs_Volume:
2169 if(hasConstructionFaces())
2171 SMDS_ElemIteratorPtr ite=element->facesIterator();
2173 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2175 else if(hasConstructionEdges())
2177 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2179 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2185 ///////////////////////////////////////////////////////////////////////////////
2186 ///@param elem The element to delete
2187 ///@param removenodes if true remaining nodes will be removed
2188 ///////////////////////////////////////////////////////////////////////////////
2189 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2190 const bool removenodes)
2192 list<const SMDS_MeshElement *> removedElems;
2193 list<const SMDS_MeshElement *> removedNodes;
2194 RemoveElement( elem, removedElems, removedNodes, removenodes );
2197 ///////////////////////////////////////////////////////////////////////////////
2198 ///@param elem The element to delete
2199 ///@param removedElems contains all removed elements
2200 ///@param removedNodes contains all removed nodes
2201 ///@param removenodes if true remaining nodes will be removed
2202 ///////////////////////////////////////////////////////////////////////////////
2203 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2204 list<const SMDS_MeshElement *>& removedElems,
2205 list<const SMDS_MeshElement *>& removedNodes,
2208 // get finite elements built on elem
2209 set<const SMDS_MeshElement*> * s1;
2210 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2211 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2212 elem->GetType() == SMDSAbs_Volume)
2214 s1 = new set<const SMDS_MeshElement*>();
2218 s1 = getFinitElements(elem);
2220 // get exclusive nodes (which would become free afterwards)
2221 set<const SMDS_MeshElement*> * s2;
2222 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2224 // do not remove nodes except elem
2225 s2 = new set<const SMDS_MeshElement*>();
2230 s2 = getExclusiveNodes(*s1);
2232 // form the set of finite and construction elements to remove
2233 set<const SMDS_MeshElement*> s3;
2234 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2235 while(it!=s1->end())
2237 addChildrenWithNodes(s3, *it ,*s2);
2241 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2243 // remove finite and construction elements
2247 // Remove element from <InverseElements> of its nodes
2248 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2251 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2252 (const_cast<SMDS_MeshElement *>(itn->next()));
2253 n->RemoveInverseElement( (*it) );
2256 switch((*it)->GetType())
2259 MESSAGE("Internal Error: This should not happen");
2262 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2263 (const_cast<SMDS_MeshElement*>(*it)));
2266 myFaces.Remove(static_cast<SMDS_MeshFace*>
2267 (const_cast<SMDS_MeshElement*>(*it)));
2269 case SMDSAbs_Volume:
2270 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2271 (const_cast<SMDS_MeshElement*>(*it)));
2274 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2275 removedElems.push_back( (*it) );
2276 myElementIDFactory->ReleaseID((*it)->GetID());
2281 // remove exclusive (free) nodes
2285 while(it!=s2->end())
2287 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2288 myNodes.Remove(static_cast<SMDS_MeshNode*>
2289 (const_cast<SMDS_MeshElement*>(*it)));
2290 myNodeIDFactory->ReleaseID((*it)->GetID());
2291 removedNodes.push_back( (*it) );
2302 ///////////////////////////////////////////////////////////////////////////////
2303 ///@param elem The element to delete
2304 ///////////////////////////////////////////////////////////////////////////////
2305 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2307 SMDSAbs_ElementType aType = elem->GetType();
2308 if (aType == SMDSAbs_Node) {
2309 // only free node can be removed by this method
2310 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2311 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2312 if (!itFe->more()) { // free node
2313 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2314 myNodeIDFactory->ReleaseID(elem->GetID());
2318 if (hasConstructionEdges() || hasConstructionFaces())
2319 // this methods is only for meshes without descendants
2322 // Remove element from <InverseElements> of its nodes
2323 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2324 while (itn->more()) {
2325 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2326 (const_cast<SMDS_MeshElement *>(itn->next()));
2327 n->RemoveInverseElement(elem);
2330 // in meshes without descendants elements are always free
2333 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2334 (const_cast<SMDS_MeshElement*>(elem)));
2337 myFaces.Remove(static_cast<SMDS_MeshFace*>
2338 (const_cast<SMDS_MeshElement*>(elem)));
2340 case SMDSAbs_Volume:
2341 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2342 (const_cast<SMDS_MeshElement*>(elem)));
2347 myElementIDFactory->ReleaseID(elem->GetID());
2353 * Checks if the element is present in mesh.
2354 * Useful to determine dead pointers.
2356 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2358 // we should not imply on validity of *elem, so iterate on containers
2359 // of all types in the hope of finding <elem> somewhere there
2360 SMDS_NodeIteratorPtr itn = nodesIterator();
2362 if (elem == itn->next())
2364 SMDS_EdgeIteratorPtr ite = edgesIterator();
2366 if (elem == ite->next())
2368 SMDS_FaceIteratorPtr itf = facesIterator();
2370 if (elem == itf->next())
2372 SMDS_VolumeIteratorPtr itv = volumesIterator();
2374 if (elem == itv->next())
2379 //=======================================================================
2380 //function : MaxNodeID
2382 //=======================================================================
2384 int SMDS_Mesh::MaxNodeID() const
2386 return myNodeIDFactory->GetMaxID();
2389 //=======================================================================
2390 //function : MinNodeID
2392 //=======================================================================
2394 int SMDS_Mesh::MinNodeID() const
2396 return myNodeIDFactory->GetMinID();
2399 //=======================================================================
2400 //function : MaxElementID
2402 //=======================================================================
2404 int SMDS_Mesh::MaxElementID() const
2406 return myElementIDFactory->GetMaxID();
2409 //=======================================================================
2410 //function : MinElementID
2412 //=======================================================================
2414 int SMDS_Mesh::MinElementID() const
2416 return myElementIDFactory->GetMinID();
2419 //=======================================================================
2420 //function : Renumber
2421 //purpose : Renumber all nodes or elements.
2422 //=======================================================================
2424 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2429 SMDS_MeshElementIDFactory * idFactory =
2430 isNodes ? myNodeIDFactory : myElementIDFactory;
2432 // get existing elements in the order of ID increasing
2433 map<int,SMDS_MeshElement*> elemMap;
2434 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2435 while ( idElemIt->more() ) {
2436 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2437 int id = elem->GetID();
2438 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2440 // release their ids
2441 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2442 for ( ; elemIt != elemMap.end(); elemIt++ )
2444 int id = (*elemIt).first;
2445 idFactory->ReleaseID( id );
2449 elemIt = elemMap.begin();
2450 for ( ; elemIt != elemMap.end(); elemIt++ )
2452 idFactory->BindID( ID, (*elemIt).second );
2457 //=======================================================================
2458 //function : GetElementType
2459 //purpose : Return type of element or node with id
2460 //=======================================================================
2462 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2464 SMDS_MeshElement* elem = 0;
2466 elem = myElementIDFactory->MeshElement( id );
2468 elem = myNodeIDFactory->MeshElement( id );
2472 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2476 return elem->GetType();
2481 //********************************************************************
2482 //********************************************************************
2483 //******** *********
2484 //***** Methods for addition of quadratic elements ******
2485 //******** *********
2486 //********************************************************************
2487 //********************************************************************
2489 //=======================================================================
2490 //function : AddEdgeWithID
2492 //=======================================================================
2493 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2495 return SMDS_Mesh::AddEdgeWithID
2496 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2497 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2498 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2502 //=======================================================================
2503 //function : AddEdge
2505 //=======================================================================
2506 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2507 const SMDS_MeshNode* n2,
2508 const SMDS_MeshNode* n12)
2510 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2513 //=======================================================================
2514 //function : AddEdgeWithID
2516 //=======================================================================
2517 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2518 const SMDS_MeshNode * n2,
2519 const SMDS_MeshNode * n12,
2522 if ( !n1 || !n2 || !n12 ) return 0;
2523 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2524 if(myElementIDFactory->BindID(ID, edge)) {
2525 SMDS_MeshNode *node1,*node2, *node12;
2526 node1 = const_cast<SMDS_MeshNode*>(n1);
2527 node2 = const_cast<SMDS_MeshNode*>(n2);
2528 node12 = const_cast<SMDS_MeshNode*>(n12);
2529 node1->AddInverseElement(edge);
2530 node2->AddInverseElement(edge);
2531 node12->AddInverseElement(edge);
2542 //=======================================================================
2543 //function : AddFace
2545 //=======================================================================
2546 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2547 const SMDS_MeshNode * n2,
2548 const SMDS_MeshNode * n3,
2549 const SMDS_MeshNode * n12,
2550 const SMDS_MeshNode * n23,
2551 const SMDS_MeshNode * n31)
2553 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2554 myElementIDFactory->GetFreeID());
2557 //=======================================================================
2558 //function : AddFaceWithID
2560 //=======================================================================
2561 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2562 int n12,int n23,int n31, int ID)
2564 return SMDS_Mesh::AddFaceWithID
2565 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2566 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2567 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2568 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2569 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2570 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2574 //=======================================================================
2575 //function : AddFaceWithID
2577 //=======================================================================
2578 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2579 const SMDS_MeshNode * n2,
2580 const SMDS_MeshNode * n3,
2581 const SMDS_MeshNode * n12,
2582 const SMDS_MeshNode * n23,
2583 const SMDS_MeshNode * n31,
2586 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2587 if(hasConstructionEdges()) {
2588 // creation quadratic edges - not implemented
2591 SMDS_QuadraticFaceOfNodes* face =
2592 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2595 if (!registerElement(ID, face)) {
2596 RemoveElement(face, false);
2603 //=======================================================================
2604 //function : AddFace
2606 //=======================================================================
2607 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2608 const SMDS_MeshNode * n2,
2609 const SMDS_MeshNode * n3,
2610 const SMDS_MeshNode * n4,
2611 const SMDS_MeshNode * n12,
2612 const SMDS_MeshNode * n23,
2613 const SMDS_MeshNode * n34,
2614 const SMDS_MeshNode * n41)
2616 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2617 myElementIDFactory->GetFreeID());
2620 //=======================================================================
2621 //function : AddFaceWithID
2623 //=======================================================================
2624 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2625 int n12,int n23,int n34,int n41, int ID)
2627 return SMDS_Mesh::AddFaceWithID
2628 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2629 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2630 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2631 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2632 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2633 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2634 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2635 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2639 //=======================================================================
2640 //function : AddFaceWithID
2642 //=======================================================================
2643 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2644 const SMDS_MeshNode * n2,
2645 const SMDS_MeshNode * n3,
2646 const SMDS_MeshNode * n4,
2647 const SMDS_MeshNode * n12,
2648 const SMDS_MeshNode * n23,
2649 const SMDS_MeshNode * n34,
2650 const SMDS_MeshNode * n41,
2653 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2654 if(hasConstructionEdges()) {
2655 // creation quadratic edges - not implemented
2657 SMDS_QuadraticFaceOfNodes* face =
2658 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2661 if (!registerElement(ID, face)) {
2662 RemoveElement(face, false);
2669 //=======================================================================
2670 //function : AddVolume
2672 //=======================================================================
2673 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2674 const SMDS_MeshNode * n2,
2675 const SMDS_MeshNode * n3,
2676 const SMDS_MeshNode * n4,
2677 const SMDS_MeshNode * n12,
2678 const SMDS_MeshNode * n23,
2679 const SMDS_MeshNode * n31,
2680 const SMDS_MeshNode * n14,
2681 const SMDS_MeshNode * n24,
2682 const SMDS_MeshNode * n34)
2684 int ID = myElementIDFactory->GetFreeID();
2685 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2686 n31, n14, n24, n34, ID);
2687 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2691 //=======================================================================
2692 //function : AddVolumeWithID
2694 //=======================================================================
2695 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2696 int n12,int n23,int n31,
2697 int n14,int n24,int n34, int ID)
2699 return SMDS_Mesh::AddVolumeWithID
2700 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2701 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2702 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2703 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2704 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2705 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2706 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2707 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2708 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2709 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2713 //=======================================================================
2714 //function : AddVolumeWithID
2715 //purpose : 2d order tetrahedron of 10 nodes
2716 //=======================================================================
2717 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2718 const SMDS_MeshNode * n2,
2719 const SMDS_MeshNode * n3,
2720 const SMDS_MeshNode * n4,
2721 const SMDS_MeshNode * n12,
2722 const SMDS_MeshNode * n23,
2723 const SMDS_MeshNode * n31,
2724 const SMDS_MeshNode * n14,
2725 const SMDS_MeshNode * n24,
2726 const SMDS_MeshNode * n34,
2729 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2731 if(hasConstructionFaces()) {
2732 // creation quadratic faces - not implemented
2735 SMDS_QuadraticVolumeOfNodes * volume =
2736 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2737 myVolumes.Add(volume);
2739 if (!registerElement(ID, volume)) {
2740 RemoveElement(volume, false);
2747 //=======================================================================
2748 //function : AddVolume
2750 //=======================================================================
2751 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2752 const SMDS_MeshNode * n2,
2753 const SMDS_MeshNode * n3,
2754 const SMDS_MeshNode * n4,
2755 const SMDS_MeshNode * n5,
2756 const SMDS_MeshNode * n12,
2757 const SMDS_MeshNode * n23,
2758 const SMDS_MeshNode * n34,
2759 const SMDS_MeshNode * n41,
2760 const SMDS_MeshNode * n15,
2761 const SMDS_MeshNode * n25,
2762 const SMDS_MeshNode * n35,
2763 const SMDS_MeshNode * n45)
2765 int ID = myElementIDFactory->GetFreeID();
2766 SMDS_MeshVolume * v =
2767 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2768 n15, n25, n35, n45, ID);
2769 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2773 //=======================================================================
2774 //function : AddVolumeWithID
2776 //=======================================================================
2777 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2778 int n12,int n23,int n34,int n41,
2779 int n15,int n25,int n35,int n45, int ID)
2781 return SMDS_Mesh::AddVolumeWithID
2782 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2783 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2784 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2785 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2786 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2787 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2788 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2789 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2790 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2791 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2792 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2793 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2794 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2798 //=======================================================================
2799 //function : AddVolumeWithID
2800 //purpose : 2d order pyramid of 13 nodes
2801 //=======================================================================
2802 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2803 const SMDS_MeshNode * n2,
2804 const SMDS_MeshNode * n3,
2805 const SMDS_MeshNode * n4,
2806 const SMDS_MeshNode * n5,
2807 const SMDS_MeshNode * n12,
2808 const SMDS_MeshNode * n23,
2809 const SMDS_MeshNode * n34,
2810 const SMDS_MeshNode * n41,
2811 const SMDS_MeshNode * n15,
2812 const SMDS_MeshNode * n25,
2813 const SMDS_MeshNode * n35,
2814 const SMDS_MeshNode * n45,
2817 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2818 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2820 if(hasConstructionFaces()) {
2821 // creation quadratic faces - not implemented
2824 SMDS_QuadraticVolumeOfNodes * volume =
2825 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2826 n34,n41,n15,n25,n35,n45);
2827 myVolumes.Add(volume);
2829 if (!registerElement(ID, volume)) {
2830 RemoveElement(volume, false);
2837 //=======================================================================
2838 //function : AddVolume
2840 //=======================================================================
2841 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2842 const SMDS_MeshNode * n2,
2843 const SMDS_MeshNode * n3,
2844 const SMDS_MeshNode * n4,
2845 const SMDS_MeshNode * n5,
2846 const SMDS_MeshNode * n6,
2847 const SMDS_MeshNode * n12,
2848 const SMDS_MeshNode * n23,
2849 const SMDS_MeshNode * n31,
2850 const SMDS_MeshNode * n45,
2851 const SMDS_MeshNode * n56,
2852 const SMDS_MeshNode * n64,
2853 const SMDS_MeshNode * n14,
2854 const SMDS_MeshNode * n25,
2855 const SMDS_MeshNode * n36)
2857 int ID = myElementIDFactory->GetFreeID();
2858 SMDS_MeshVolume * v =
2859 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2860 n45, n56, n64, n14, n25, n36, ID);
2861 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2865 //=======================================================================
2866 //function : AddVolumeWithID
2868 //=======================================================================
2869 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2870 int n4, int n5, int n6,
2871 int n12,int n23,int n31,
2872 int n45,int n56,int n64,
2873 int n14,int n25,int n36, int ID)
2875 return SMDS_Mesh::AddVolumeWithID
2876 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2877 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2878 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2879 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2880 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2881 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2882 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2883 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2884 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2885 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2886 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2887 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2888 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2889 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2890 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2894 //=======================================================================
2895 //function : AddVolumeWithID
2896 //purpose : 2d order Pentahedron with 15 nodes
2897 //=======================================================================
2898 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2899 const SMDS_MeshNode * n2,
2900 const SMDS_MeshNode * n3,
2901 const SMDS_MeshNode * n4,
2902 const SMDS_MeshNode * n5,
2903 const SMDS_MeshNode * n6,
2904 const SMDS_MeshNode * n12,
2905 const SMDS_MeshNode * n23,
2906 const SMDS_MeshNode * n31,
2907 const SMDS_MeshNode * n45,
2908 const SMDS_MeshNode * n56,
2909 const SMDS_MeshNode * n64,
2910 const SMDS_MeshNode * n14,
2911 const SMDS_MeshNode * n25,
2912 const SMDS_MeshNode * n36,
2915 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2916 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2918 if(hasConstructionFaces()) {
2919 // creation quadratic faces - not implemented
2922 SMDS_QuadraticVolumeOfNodes * volume =
2923 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2924 n45,n56,n64,n14,n25,n36);
2925 myVolumes.Add(volume);
2927 if (!registerElement(ID, volume)) {
2928 RemoveElement(volume, false);
2935 //=======================================================================
2936 //function : AddVolume
2938 //=======================================================================
2939 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2940 const SMDS_MeshNode * n2,
2941 const SMDS_MeshNode * n3,
2942 const SMDS_MeshNode * n4,
2943 const SMDS_MeshNode * n5,
2944 const SMDS_MeshNode * n6,
2945 const SMDS_MeshNode * n7,
2946 const SMDS_MeshNode * n8,
2947 const SMDS_MeshNode * n12,
2948 const SMDS_MeshNode * n23,
2949 const SMDS_MeshNode * n34,
2950 const SMDS_MeshNode * n41,
2951 const SMDS_MeshNode * n56,
2952 const SMDS_MeshNode * n67,
2953 const SMDS_MeshNode * n78,
2954 const SMDS_MeshNode * n85,
2955 const SMDS_MeshNode * n15,
2956 const SMDS_MeshNode * n26,
2957 const SMDS_MeshNode * n37,
2958 const SMDS_MeshNode * n48)
2960 int ID = myElementIDFactory->GetFreeID();
2961 SMDS_MeshVolume * v =
2962 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2963 n56, n67, n78, n85, n15, n26, n37, n48, ID);
2964 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2968 //=======================================================================
2969 //function : AddVolumeWithID
2971 //=======================================================================
2972 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2973 int n5, int n6, int n7, int n8,
2974 int n12,int n23,int n34,int n41,
2975 int n56,int n67,int n78,int n85,
2976 int n15,int n26,int n37,int n48, int ID)
2978 return SMDS_Mesh::AddVolumeWithID
2979 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2980 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2981 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
2982 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
2983 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
2984 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
2985 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
2986 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
2987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
2993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
2994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
2995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
2997 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
2998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3002 //=======================================================================
3003 //function : AddVolumeWithID
3004 //purpose : 2d order Hexahedrons with 20 nodes
3005 //=======================================================================
3006 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3007 const SMDS_MeshNode * n2,
3008 const SMDS_MeshNode * n3,
3009 const SMDS_MeshNode * n4,
3010 const SMDS_MeshNode * n5,
3011 const SMDS_MeshNode * n6,
3012 const SMDS_MeshNode * n7,
3013 const SMDS_MeshNode * n8,
3014 const SMDS_MeshNode * n12,
3015 const SMDS_MeshNode * n23,
3016 const SMDS_MeshNode * n34,
3017 const SMDS_MeshNode * n41,
3018 const SMDS_MeshNode * n56,
3019 const SMDS_MeshNode * n67,
3020 const SMDS_MeshNode * n78,
3021 const SMDS_MeshNode * n85,
3022 const SMDS_MeshNode * n15,
3023 const SMDS_MeshNode * n26,
3024 const SMDS_MeshNode * n37,
3025 const SMDS_MeshNode * n48,
3028 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3029 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3031 if(hasConstructionFaces()) {
3033 // creation quadratic faces - not implemented
3035 SMDS_QuadraticVolumeOfNodes * volume =
3036 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3037 n56,n67,n78,n85,n15,n26,n37,n48);
3038 myVolumes.Add(volume);
3040 if (!registerElement(ID, volume)) {
3041 RemoveElement(volume, false);