1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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
22 // SMESH SMDS : implementaion of Salome mesh data structure
25 #pragma warning(disable:4786)
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
45 #include <sys/sysinfo.h>
48 // number of added entitis to check memory after
49 #define CHECKMEMORY_INTERVAL 1000
51 //================================================================================
53 * \brief Raise an exception if free memory (ram+swap) too low
54 * \param doNotRaise - if true, suppres exception, just return free memory size
55 * \retval int - amount of available memory in MB or negative number in failure case
57 //================================================================================
59 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
63 int err = sysinfo( &si );
67 static int limit = -1;
69 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
71 limit = WEXITSTATUS(status);
76 limit = int( limit * 1.5 );
78 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
82 const unsigned long Mbyte = 1024 * 1024;
83 // compute separately to avoid overflow
85 ( si.freeram * si.mem_unit ) / Mbyte +
86 ( si.freeswap * si.mem_unit ) / Mbyte;
89 return freeMb - limit;
94 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
96 throw std::bad_alloc();
102 ///////////////////////////////////////////////////////////////////////////////
103 /// Create a new mesh object
104 ///////////////////////////////////////////////////////////////////////////////
105 SMDS_Mesh::SMDS_Mesh()
107 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
108 myElementIDFactory(new SMDS_MeshElementIDFactory()),
109 myHasConstructionEdges(false), myHasConstructionFaces(false),
110 myHasInverseElements(true)
114 ///////////////////////////////////////////////////////////////////////////////
115 /// Create a new child mesh
116 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
117 /// (2003-09-08) of SMESH
118 ///////////////////////////////////////////////////////////////////////////////
119 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
120 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
121 myElementIDFactory(parent->myElementIDFactory),
122 myHasConstructionEdges(false), myHasConstructionFaces(false),
123 myHasInverseElements(true)
127 ///////////////////////////////////////////////////////////////////////////////
128 ///Create a submesh and add it to the current mesh
129 ///////////////////////////////////////////////////////////////////////////////
131 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
133 SMDS_Mesh *submesh = new SMDS_Mesh(this);
134 myChildren.insert(myChildren.end(), submesh);
138 ///////////////////////////////////////////////////////////////////////////////
139 ///create a MeshNode and add it to the current Mesh
140 ///An ID is automatically assigned to the node.
141 ///@return : The created node
142 ///////////////////////////////////////////////////////////////////////////////
144 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
146 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
149 ///////////////////////////////////////////////////////////////////////////////
150 ///create a MeshNode and add it to the current Mesh
151 ///@param ID : The ID of the MeshNode to create
152 ///@return : The created node or NULL if a node with this ID already exists
153 ///////////////////////////////////////////////////////////////////////////////
154 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
156 // find the MeshNode corresponding to ID
157 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
159 if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
160 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
162 myNodeIDFactory->BindID(ID,node);
169 ///////////////////////////////////////////////////////////////////////////////
170 /// create a MeshEdge and add it to the current Mesh
171 /// @return : The created MeshEdge
172 ///////////////////////////////////////////////////////////////////////////////
174 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
176 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
177 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
178 if(!node1 || !node2) return NULL;
179 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
182 ///////////////////////////////////////////////////////////////////////////////
183 /// create a MeshEdge and add it to the current Mesh
184 /// @return : The created MeshEdge
185 ///////////////////////////////////////////////////////////////////////////////
187 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
188 const SMDS_MeshNode * node2)
190 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
193 ///////////////////////////////////////////////////////////////////////////////
194 /// Create a new edge and at it to the mesh
195 /// @param idnode1 ID of the first node
196 /// @param idnode2 ID of the second node
197 /// @param ID ID of the edge to create
198 /// @return The created edge or NULL if an element with this ID already exists or
199 /// if input nodes are not found.
200 ///////////////////////////////////////////////////////////////////////////////
202 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
203 const SMDS_MeshNode * n2,
206 if ( !n1 || !n2 ) return 0;
208 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
210 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
211 if(myElementIDFactory->BindID(ID, edge)) {
212 SMDS_MeshNode *node1,*node2;
213 node1=const_cast<SMDS_MeshNode*>(n1);
214 node2=const_cast<SMDS_MeshNode*>(n2);
215 node1->AddInverseElement(edge);
216 node2->AddInverseElement(edge);
227 ///////////////////////////////////////////////////////////////////////////////
228 /// Add a triangle defined by its nodes. An ID is automatically affected to the
230 ///////////////////////////////////////////////////////////////////////////////
232 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
233 const SMDS_MeshNode * n2,
234 const SMDS_MeshNode * n3)
236 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
239 ///////////////////////////////////////////////////////////////////////////////
240 /// Add a triangle defined by its nodes IDs
241 ///////////////////////////////////////////////////////////////////////////////
243 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
245 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
246 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
247 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
248 if(!node1 || !node2 || !node3) return NULL;
249 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
252 ///////////////////////////////////////////////////////////////////////////////
253 /// Add a triangle defined by its nodes
254 ///////////////////////////////////////////////////////////////////////////////
256 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
257 const SMDS_MeshNode * n2,
258 const SMDS_MeshNode * n3,
261 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
263 if (face && !registerElement(ID, face)) {
264 RemoveElement(face, false);
270 ///////////////////////////////////////////////////////////////////////////////
271 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
273 ///////////////////////////////////////////////////////////////////////////////
275 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
276 const SMDS_MeshNode * n2,
277 const SMDS_MeshNode * n3,
278 const SMDS_MeshNode * n4)
280 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
283 ///////////////////////////////////////////////////////////////////////////////
284 /// Add a quadrangle defined by its nodes IDs
285 ///////////////////////////////////////////////////////////////////////////////
287 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
293 SMDS_MeshNode *node1, *node2, *node3, *node4;
294 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
295 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
296 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
297 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
298 if(!node1 || !node2 || !node3 || !node4) return NULL;
299 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
302 ///////////////////////////////////////////////////////////////////////////////
303 /// Add a quadrangle defined by its nodes
304 ///////////////////////////////////////////////////////////////////////////////
306 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
307 const SMDS_MeshNode * n2,
308 const SMDS_MeshNode * n3,
309 const SMDS_MeshNode * n4,
312 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
314 if (face && !registerElement(ID, face)) {
315 RemoveElement(face, false);
321 ///////////////////////////////////////////////////////////////////////////////
322 /// Add a triangle defined by its edges. An ID is automatically assigned to the
324 ///////////////////////////////////////////////////////////////////////////////
326 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
327 const SMDS_MeshEdge * e2,
328 const SMDS_MeshEdge * e3)
330 if (!hasConstructionEdges())
332 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
335 ///////////////////////////////////////////////////////////////////////////////
336 /// Add a triangle defined by its edges
337 ///////////////////////////////////////////////////////////////////////////////
339 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
340 const SMDS_MeshEdge * e2,
341 const SMDS_MeshEdge * e3,
344 if (!hasConstructionEdges())
346 if ( !e1 || !e2 || !e3 ) return 0;
348 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
350 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
352 myInfo.myNbTriangles++;
354 if (!registerElement(ID, face)) {
355 RemoveElement(face, false);
361 ///////////////////////////////////////////////////////////////////////////////
362 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
364 ///////////////////////////////////////////////////////////////////////////////
366 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
367 const SMDS_MeshEdge * e2,
368 const SMDS_MeshEdge * e3,
369 const SMDS_MeshEdge * e4)
371 if (!hasConstructionEdges())
373 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
376 ///////////////////////////////////////////////////////////////////////////////
377 /// Add a quadrangle defined by its edges
378 ///////////////////////////////////////////////////////////////////////////////
380 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
381 const SMDS_MeshEdge * e2,
382 const SMDS_MeshEdge * e3,
383 const SMDS_MeshEdge * e4,
386 if (!hasConstructionEdges())
388 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
389 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
390 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
392 myInfo.myNbQuadrangles++;
394 if (!registerElement(ID, face))
396 RemoveElement(face, false);
402 ///////////////////////////////////////////////////////////////////////////////
403 ///Create a new tetrahedron and add it to the mesh.
404 ///@return The created tetrahedron
405 ///////////////////////////////////////////////////////////////////////////////
407 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
408 const SMDS_MeshNode * n2,
409 const SMDS_MeshNode * n3,
410 const SMDS_MeshNode * n4)
412 int ID = myElementIDFactory->GetFreeID();
413 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
414 if(v==NULL) myElementIDFactory->ReleaseID(ID);
418 ///////////////////////////////////////////////////////////////////////////////
419 ///Create a new tetrahedron and add it to the mesh.
420 ///@param ID The ID of the new volume
421 ///@return The created tetrahedron or NULL if an element with this ID already exists
422 ///or if input nodes are not found.
423 ///////////////////////////////////////////////////////////////////////////////
425 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
431 SMDS_MeshNode *node1, *node2, *node3, *node4;
432 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
433 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
434 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
435 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
436 if(!node1 || !node2 || !node3 || !node4) return NULL;
437 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
440 ///////////////////////////////////////////////////////////////////////////////
441 ///Create a new tetrahedron and add it to the mesh.
442 ///@param ID The ID of the new volume
443 ///@return The created tetrahedron
444 ///////////////////////////////////////////////////////////////////////////////
446 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
447 const SMDS_MeshNode * n2,
448 const SMDS_MeshNode * n3,
449 const SMDS_MeshNode * n4,
452 SMDS_MeshVolume* volume = 0;
453 if ( !n1 || !n2 || !n3 || !n4) return volume;
454 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
455 if(hasConstructionFaces()) {
456 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
457 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
458 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
459 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
460 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
461 myVolumes.Add(volume);
464 else if(hasConstructionEdges()) {
465 MESSAGE("Error : Not implemented");
469 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
470 myVolumes.Add(volume);
474 if (!registerElement(ID, volume)) {
475 RemoveElement(volume, false);
481 ///////////////////////////////////////////////////////////////////////////////
482 ///Create a new pyramid and add it to the mesh.
483 ///Nodes 1,2,3 and 4 define the base of the pyramid
484 ///@return The created pyramid
485 ///////////////////////////////////////////////////////////////////////////////
487 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
488 const SMDS_MeshNode * n2,
489 const SMDS_MeshNode * n3,
490 const SMDS_MeshNode * n4,
491 const SMDS_MeshNode * n5)
493 int ID = myElementIDFactory->GetFreeID();
494 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
495 if(v==NULL) myElementIDFactory->ReleaseID(ID);
499 ///////////////////////////////////////////////////////////////////////////////
500 ///Create a new pyramid and add it to the mesh.
501 ///Nodes 1,2,3 and 4 define the base of the pyramid
502 ///@param ID The ID of the new volume
503 ///@return The created pyramid or NULL if an element with this ID already exists
504 ///or if input nodes are not found.
505 ///////////////////////////////////////////////////////////////////////////////
507 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
514 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
515 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
516 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
517 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
518 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
519 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
520 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
521 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
524 ///////////////////////////////////////////////////////////////////////////////
525 ///Create a new pyramid and add it to the mesh.
526 ///Nodes 1,2,3 and 4 define the base of the pyramid
527 ///@param ID The ID of the new volume
528 ///@return The created pyramid
529 ///////////////////////////////////////////////////////////////////////////////
531 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
532 const SMDS_MeshNode * n2,
533 const SMDS_MeshNode * n3,
534 const SMDS_MeshNode * n4,
535 const SMDS_MeshNode * n5,
538 SMDS_MeshVolume* volume = 0;
539 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
540 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
541 if(hasConstructionFaces()) {
542 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
543 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
544 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
545 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
546 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
547 myVolumes.Add(volume);
548 myInfo.myNbPyramids++;
550 else if(hasConstructionEdges()) {
551 MESSAGE("Error : Not implemented");
555 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
556 myVolumes.Add(volume);
557 myInfo.myNbPyramids++;
560 if (!registerElement(ID, volume)) {
561 RemoveElement(volume, false);
567 ///////////////////////////////////////////////////////////////////////////////
568 ///Create a new prism and add it to the mesh.
569 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
570 ///@return The created prism
571 ///////////////////////////////////////////////////////////////////////////////
573 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
574 const SMDS_MeshNode * n2,
575 const SMDS_MeshNode * n3,
576 const SMDS_MeshNode * n4,
577 const SMDS_MeshNode * n5,
578 const SMDS_MeshNode * n6)
580 int ID = myElementIDFactory->GetFreeID();
581 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
582 if(v==NULL) myElementIDFactory->ReleaseID(ID);
586 ///////////////////////////////////////////////////////////////////////////////
587 ///Create a new prism and add it to the mesh.
588 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
589 ///@param ID The ID of the new volume
590 ///@return The created prism or NULL if an element with this ID already exists
591 ///or if input nodes are not found.
592 ///////////////////////////////////////////////////////////////////////////////
594 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
602 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
603 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
604 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
605 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
606 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
607 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
608 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
609 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
610 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
613 ///////////////////////////////////////////////////////////////////////////////
614 ///Create a new prism and add it to the mesh.
615 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
616 ///@param ID The ID of the new volume
617 ///@return The created prism
618 ///////////////////////////////////////////////////////////////////////////////
620 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
621 const SMDS_MeshNode * n2,
622 const SMDS_MeshNode * n3,
623 const SMDS_MeshNode * n4,
624 const SMDS_MeshNode * n5,
625 const SMDS_MeshNode * n6,
628 SMDS_MeshVolume* volume = 0;
629 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
630 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
631 if(hasConstructionFaces()) {
632 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
633 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
634 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
635 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
636 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
637 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
638 myVolumes.Add(volume);
641 else if(hasConstructionEdges()) {
642 MESSAGE("Error : Not implemented");
646 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
647 myVolumes.Add(volume);
651 if (!registerElement(ID, volume)) {
652 RemoveElement(volume, false);
658 ///////////////////////////////////////////////////////////////////////////////
659 ///Create a new hexahedron and add it to the mesh.
660 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
661 ///@return The created hexahedron
662 ///////////////////////////////////////////////////////////////////////////////
664 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
665 const SMDS_MeshNode * n2,
666 const SMDS_MeshNode * n3,
667 const SMDS_MeshNode * n4,
668 const SMDS_MeshNode * n5,
669 const SMDS_MeshNode * n6,
670 const SMDS_MeshNode * n7,
671 const SMDS_MeshNode * n8)
673 int ID = myElementIDFactory->GetFreeID();
674 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
675 if(v==NULL) myElementIDFactory->ReleaseID(ID);
679 ///////////////////////////////////////////////////////////////////////////////
680 ///Create a new hexahedron and add it to the mesh.
681 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
682 ///@param ID The ID of the new volume
683 ///@return The created hexahedron or NULL if an element with this ID already
684 ///exists or if input nodes are not found.
685 ///////////////////////////////////////////////////////////////////////////////
687 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
697 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
698 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
699 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
700 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
701 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
702 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
703 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
704 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
705 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
706 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
708 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
712 ///////////////////////////////////////////////////////////////////////////////
713 ///Create a new hexahedron and add it to the mesh.
714 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
715 ///@param ID The ID of the new volume
716 ///@return The created prism or NULL if an element with this ID already exists
717 ///or if input nodes are not found.
718 ///////////////////////////////////////////////////////////////////////////////
720 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
721 const SMDS_MeshNode * n2,
722 const SMDS_MeshNode * n3,
723 const SMDS_MeshNode * n4,
724 const SMDS_MeshNode * n5,
725 const SMDS_MeshNode * n6,
726 const SMDS_MeshNode * n7,
727 const SMDS_MeshNode * n8,
730 SMDS_MeshVolume* volume = 0;
731 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
732 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
733 if(hasConstructionFaces()) {
734 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
735 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
736 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
737 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
738 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
739 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
740 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
741 myVolumes.Add(volume);
744 else if(hasConstructionEdges()) {
745 MESSAGE("Error : Not implemented");
749 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
750 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
751 myVolumes.Add(volume);
755 if (!registerElement(ID, volume)) {
756 RemoveElement(volume, false);
762 ///////////////////////////////////////////////////////////////////////////////
763 ///Create a new tetrahedron defined by its faces and add it to the mesh.
764 ///@return The created tetrahedron
765 ///////////////////////////////////////////////////////////////////////////////
767 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
768 const SMDS_MeshFace * f2,
769 const SMDS_MeshFace * f3,
770 const SMDS_MeshFace * f4)
772 if (!hasConstructionFaces())
774 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
777 ///////////////////////////////////////////////////////////////////////////////
778 ///Create a new tetrahedron defined by its faces and add it to the mesh.
779 ///@param ID The ID of the new volume
780 ///@return The created tetrahedron
781 ///////////////////////////////////////////////////////////////////////////////
783 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
784 const SMDS_MeshFace * f2,
785 const SMDS_MeshFace * f3,
786 const SMDS_MeshFace * f4,
789 if (!hasConstructionFaces())
791 if ( !f1 || !f2 || !f3 || !f4) return 0;
792 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
793 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
794 myVolumes.Add(volume);
797 if (!registerElement(ID, volume)) {
798 RemoveElement(volume, false);
804 ///////////////////////////////////////////////////////////////////////////////
805 ///Create a new pyramid defined by its faces and add it to the mesh.
806 ///@return The created pyramid
807 ///////////////////////////////////////////////////////////////////////////////
809 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
810 const SMDS_MeshFace * f2,
811 const SMDS_MeshFace * f3,
812 const SMDS_MeshFace * f4,
813 const SMDS_MeshFace * f5)
815 if (!hasConstructionFaces())
817 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
820 ///////////////////////////////////////////////////////////////////////////////
821 ///Create a new pyramid defined by its faces and add it to the mesh.
822 ///@param ID The ID of the new volume
823 ///@return The created pyramid
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,
833 if (!hasConstructionFaces())
835 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
836 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
837 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
838 myVolumes.Add(volume);
839 myInfo.myNbPyramids++;
841 if (!registerElement(ID, volume)) {
842 RemoveElement(volume, false);
848 ///////////////////////////////////////////////////////////////////////////////
849 ///Create a new prism defined by its faces and add it to the mesh.
850 ///@return The created prism
851 ///////////////////////////////////////////////////////////////////////////////
853 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
854 const SMDS_MeshFace * f2,
855 const SMDS_MeshFace * f3,
856 const SMDS_MeshFace * f4,
857 const SMDS_MeshFace * f5,
858 const SMDS_MeshFace * f6)
860 if (!hasConstructionFaces())
862 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
865 ///////////////////////////////////////////////////////////////////////////////
866 ///Create a new prism defined by its faces and add it to the mesh.
867 ///@param ID The ID of the new volume
868 ///@return The created prism
869 ///////////////////////////////////////////////////////////////////////////////
871 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
872 const SMDS_MeshFace * f2,
873 const SMDS_MeshFace * f3,
874 const SMDS_MeshFace * f4,
875 const SMDS_MeshFace * f5,
876 const SMDS_MeshFace * f6,
879 if (!hasConstructionFaces())
881 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
882 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
883 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
884 myVolumes.Add(volume);
887 if (!registerElement(ID, volume)) {
888 RemoveElement(volume, false);
894 ///////////////////////////////////////////////////////////////////////////////
895 /// Add a polygon defined by its nodes IDs
896 ///////////////////////////////////////////////////////////////////////////////
898 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
901 int nbNodes = nodes_ids.size();
902 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
903 for (int i = 0; i < nbNodes; i++) {
904 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
905 if (!nodes[i]) return NULL;
907 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
910 ///////////////////////////////////////////////////////////////////////////////
911 /// Add a polygon defined by its nodes
912 ///////////////////////////////////////////////////////////////////////////////
914 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
915 (std::vector<const SMDS_MeshNode*> nodes,
918 SMDS_MeshFace * face;
920 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
921 if (hasConstructionEdges())
923 MESSAGE("Error : Not implemented");
928 for ( int i = 0; i < nodes.size(); ++i )
929 if ( !nodes[ i ] ) return 0;
930 face = new SMDS_PolygonalFaceOfNodes(nodes);
932 myInfo.myNbPolygons++;
935 if (!registerElement(ID, face)) {
936 RemoveElement(face, false);
942 ///////////////////////////////////////////////////////////////////////////////
943 /// Add a polygon defined by its nodes.
944 /// An ID is automatically affected to the created face.
945 ///////////////////////////////////////////////////////////////////////////////
947 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
949 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
952 ///////////////////////////////////////////////////////////////////////////////
953 /// Create a new polyhedral volume and add it to the mesh.
954 /// @param ID The ID of the new volume
955 /// @return The created volume or NULL if an element with this ID already exists
956 /// or if input nodes are not found.
957 ///////////////////////////////////////////////////////////////////////////////
959 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
960 (std::vector<int> nodes_ids,
961 std::vector<int> quantities,
964 int nbNodes = nodes_ids.size();
965 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
966 for (int i = 0; i < nbNodes; i++) {
967 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
968 if (!nodes[i]) return NULL;
970 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
973 ///////////////////////////////////////////////////////////////////////////////
974 /// Create a new polyhedral volume and add it to the mesh.
975 /// @param ID The ID of the new volume
976 /// @return The created volume
977 ///////////////////////////////////////////////////////////////////////////////
979 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
980 (std::vector<const SMDS_MeshNode*> nodes,
981 std::vector<int> quantities,
984 SMDS_MeshVolume* volume;
985 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
986 if (hasConstructionFaces()) {
987 MESSAGE("Error : Not implemented");
989 } else if (hasConstructionEdges()) {
990 MESSAGE("Error : Not implemented");
993 for ( int i = 0; i < nodes.size(); ++i )
994 if ( !nodes[ i ] ) return 0;
995 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
996 myVolumes.Add(volume);
997 myInfo.myNbPolyhedrons++;
1000 if (!registerElement(ID, volume)) {
1001 RemoveElement(volume, false);
1007 ///////////////////////////////////////////////////////////////////////////////
1008 /// Create a new polyhedral volume and add it to the mesh.
1009 /// @return The created volume
1010 ///////////////////////////////////////////////////////////////////////////////
1012 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1013 (std::vector<const SMDS_MeshNode*> nodes,
1014 std::vector<int> quantities)
1016 int ID = myElementIDFactory->GetFreeID();
1017 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1018 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1022 ///////////////////////////////////////////////////////////////////////////////
1023 /// Registers element with the given ID, maintains inverse connections
1024 ///////////////////////////////////////////////////////////////////////////////
1025 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1027 if (myElementIDFactory->BindID(ID, element)) {
1028 SMDS_ElemIteratorPtr it = element->nodesIterator();
1029 while (it->more()) {
1030 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1031 (const_cast<SMDS_MeshElement*>(it->next()));
1032 node->AddInverseElement(element);
1039 ///////////////////////////////////////////////////////////////////////////////
1040 /// Return the node whose ID is 'ID'.
1041 ///////////////////////////////////////////////////////////////////////////////
1042 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1044 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1047 ///////////////////////////////////////////////////////////////////////////////
1048 ///Create a triangle and add it to the current mesh. This methode do not bind a
1049 ///ID to the create triangle.
1050 ///////////////////////////////////////////////////////////////////////////////
1051 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1052 const SMDS_MeshNode * node2,
1053 const SMDS_MeshNode * node3)
1055 if ( !node1 || !node2 || !node3) return 0;
1056 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1057 if(hasConstructionEdges())
1059 SMDS_MeshEdge *edge1, *edge2, *edge3;
1060 edge1=FindEdgeOrCreate(node1,node2);
1061 edge2=FindEdgeOrCreate(node2,node3);
1062 edge3=FindEdgeOrCreate(node3,node1);
1064 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1066 myInfo.myNbTriangles++;
1071 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1073 myInfo.myNbTriangles++;
1078 ///////////////////////////////////////////////////////////////////////////////
1079 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1080 ///a ID to the create triangle.
1081 ///////////////////////////////////////////////////////////////////////////////
1082 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1083 const SMDS_MeshNode * node2,
1084 const SMDS_MeshNode * node3,
1085 const SMDS_MeshNode * node4)
1087 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1088 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1089 if(hasConstructionEdges())
1091 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1092 edge1=FindEdgeOrCreate(node1,node2);
1093 edge2=FindEdgeOrCreate(node2,node3);
1094 edge3=FindEdgeOrCreate(node3,node4);
1095 edge4=FindEdgeOrCreate(node4,node1);
1097 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1099 myInfo.myNbQuadrangles++;
1104 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1106 myInfo.myNbQuadrangles++;
1111 ///////////////////////////////////////////////////////////////////////////////
1112 /// Remove a node and all the elements which own this node
1113 ///////////////////////////////////////////////////////////////////////////////
1115 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1117 RemoveElement(node, true);
1120 ///////////////////////////////////////////////////////////////////////////////
1121 /// Remove an edge and all the elements which own this edge
1122 ///////////////////////////////////////////////////////////////////////////////
1124 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1126 RemoveElement(edge,true);
1129 ///////////////////////////////////////////////////////////////////////////////
1130 /// Remove an face and all the elements which own this face
1131 ///////////////////////////////////////////////////////////////////////////////
1133 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1135 RemoveElement(face, true);
1138 ///////////////////////////////////////////////////////////////////////////////
1140 ///////////////////////////////////////////////////////////////////////////////
1142 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1144 RemoveElement(volume, true);
1147 //=======================================================================
1148 //function : RemoveFromParent
1150 //=======================================================================
1152 bool SMDS_Mesh::RemoveFromParent()
1154 if (myParent==NULL) return false;
1155 else return (myParent->RemoveSubMesh(this));
1158 //=======================================================================
1159 //function : RemoveSubMesh
1161 //=======================================================================
1163 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1167 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1168 for (; itmsh!=myChildren.end() && !found; itmsh++)
1170 SMDS_Mesh * submesh = *itmsh;
1171 if (submesh == aMesh)
1174 myChildren.erase(itmsh);
1181 //=======================================================================
1182 //function : ChangeElementNodes
1184 //=======================================================================
1186 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1187 const SMDS_MeshNode * nodes[],
1190 // keep current nodes of elem
1191 set<const SMDS_MeshElement*> oldNodes;
1192 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1194 oldNodes.insert( itn->next() );
1196 if ( !element->IsPoly() )
1197 myInfo.remove( element ); // element may change type
1201 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1202 switch ( elem->GetType() )
1204 case SMDSAbs_Edge: {
1205 if ( nbnodes == 2 ) {
1206 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1207 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1209 else if ( nbnodes == 3 ) {
1210 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1211 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1215 case SMDSAbs_Face: {
1216 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1217 Ok = face->ChangeNodes( nodes, nbnodes );
1219 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1220 Ok = QF->ChangeNodes( nodes, nbnodes );
1222 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1223 Ok = face->ChangeNodes(nodes, nbnodes);
1226 case SMDSAbs_Volume: {
1227 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1228 Ok = vol->ChangeNodes( nodes, nbnodes );
1230 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1231 Ok = QV->ChangeNodes( nodes, nbnodes );
1235 MESSAGE ( "WRONG ELEM TYPE");
1238 if ( Ok ) { // update InverseElements
1240 set<const SMDS_MeshElement*>::iterator it;
1242 // AddInverseElement to new nodes
1243 for ( int i = 0; i < nbnodes; i++ ) {
1244 it = oldNodes.find( nodes[i] );
1245 if ( it == oldNodes.end() )
1247 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1249 // remove from oldNodes a node that remains in elem
1250 oldNodes.erase( it );
1252 // RemoveInverseElement from the nodes removed from elem
1253 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1255 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1256 (const_cast<SMDS_MeshElement *>( *it ));
1257 n->RemoveInverseElement( elem );
1261 if ( !element->IsPoly() )
1262 myInfo.add( element ); // element may change type
1267 //=======================================================================
1268 //function : ChangePolyhedronNodes
1269 //purpose : to change nodes of polyhedral volume
1270 //=======================================================================
1271 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1272 const vector<const SMDS_MeshNode*>& nodes,
1273 const vector<int> & quantities)
1275 if (elem->GetType() != SMDSAbs_Volume) {
1276 MESSAGE("WRONG ELEM TYPE");
1280 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1285 // keep current nodes of elem
1286 set<const SMDS_MeshElement*> oldNodes;
1287 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1288 while (itn->more()) {
1289 oldNodes.insert(itn->next());
1293 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1298 // update InverseElements
1300 // AddInverseElement to new nodes
1301 int nbnodes = nodes.size();
1302 set<const SMDS_MeshElement*>::iterator it;
1303 for (int i = 0; i < nbnodes; i++) {
1304 it = oldNodes.find(nodes[i]);
1305 if (it == oldNodes.end()) {
1307 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1309 // remove from oldNodes a node that remains in elem
1314 // RemoveInverseElement from the nodes removed from elem
1315 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1316 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1317 (const_cast<SMDS_MeshElement *>( *it ));
1318 n->RemoveInverseElement(elem);
1325 //=======================================================================
1326 //function : FindEdge
1328 //=======================================================================
1330 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1332 const SMDS_MeshNode * node1=FindNode(idnode1);
1333 const SMDS_MeshNode * node2=FindNode(idnode2);
1334 if((node1==NULL)||(node2==NULL)) return NULL;
1335 return FindEdge(node1,node2);
1338 //#include "Profiler.h"
1339 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1340 const SMDS_MeshNode * node2)
1342 if ( !node1 ) return 0;
1343 const SMDS_MeshEdge * toReturn=NULL;
1346 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1349 while(it1->more()) {
1350 const SMDS_MeshElement * e = it1->next();
1351 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1352 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1361 //=======================================================================
1362 //function : FindEdgeOrCreate
1364 //=======================================================================
1366 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1367 const SMDS_MeshNode * node2)
1369 if ( !node1 || !node2) return 0;
1370 SMDS_MeshEdge * toReturn=NULL;
1371 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1372 if(toReturn==NULL) {
1373 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1374 toReturn=new SMDS_MeshEdge(node1,node2);
1375 myEdges.Add(toReturn);
1382 //=======================================================================
1383 //function : FindEdge
1385 //=======================================================================
1387 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1390 const SMDS_MeshNode * node1=FindNode(idnode1);
1391 const SMDS_MeshNode * node2=FindNode(idnode2);
1392 const SMDS_MeshNode * node3=FindNode(idnode3);
1393 return FindEdge(node1,node2,node3);
1396 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1397 const SMDS_MeshNode * node2,
1398 const SMDS_MeshNode * node3)
1400 if ( !node1 ) return 0;
1401 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1402 while(it1->more()) {
1403 const SMDS_MeshElement * e = it1->next();
1404 if ( e->NbNodes() == 3 ) {
1405 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1406 while(it2->more()) {
1407 const SMDS_MeshElement* n = it2->next();
1417 return static_cast<const SMDS_MeshEdge *> (e);
1424 //=======================================================================
1425 //function : FindFace
1427 //=======================================================================
1429 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1432 const SMDS_MeshNode * node1=FindNode(idnode1);
1433 const SMDS_MeshNode * node2=FindNode(idnode2);
1434 const SMDS_MeshNode * node3=FindNode(idnode3);
1435 return FindFace(node1, node2, node3);
1438 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1439 const SMDS_MeshNode *node2,
1440 const SMDS_MeshNode *node3)
1442 if ( !node1 ) return 0;
1443 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1444 while(it1->more()) {
1445 const SMDS_MeshElement * e = it1->next();
1446 if ( e->NbNodes() == 3 ) {
1447 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1448 while(it2->more()) {
1449 const SMDS_MeshElement* n = it2->next();
1459 return static_cast<const SMDS_MeshFace *> (e);
1465 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1466 const SMDS_MeshNode *node2,
1467 const SMDS_MeshNode *node3)
1469 SMDS_MeshFace * toReturn=NULL;
1470 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1471 if(toReturn==NULL) {
1472 toReturn = createTriangle(node1,node2,node3);
1478 //=======================================================================
1479 //function : FindFace
1481 //=======================================================================
1483 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1484 int idnode3, int idnode4) const
1486 const SMDS_MeshNode * node1=FindNode(idnode1);
1487 const SMDS_MeshNode * node2=FindNode(idnode2);
1488 const SMDS_MeshNode * node3=FindNode(idnode3);
1489 const SMDS_MeshNode * node4=FindNode(idnode4);
1490 return FindFace(node1, node2, node3, node4);
1493 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1494 const SMDS_MeshNode *node2,
1495 const SMDS_MeshNode *node3,
1496 const SMDS_MeshNode *node4)
1498 if ( !node1 ) return 0;
1499 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1500 while(it1->more()) {
1501 const SMDS_MeshElement * e = it1->next();
1502 if ( e->NbNodes() == 4 ) {
1503 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1504 while(it2->more()) {
1505 const SMDS_MeshElement* n = it2->next();
1516 return static_cast<const SMDS_MeshFace *> (e);
1522 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1523 const SMDS_MeshNode *node2,
1524 const SMDS_MeshNode *node3,
1525 const SMDS_MeshNode *node4)
1527 SMDS_MeshFace * toReturn=NULL;
1528 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1529 if(toReturn==NULL) {
1530 toReturn=createQuadrangle(node1,node2,node3,node4);
1536 //=======================================================================
1537 //function : FindFace
1538 //purpose :quadratic triangle
1539 //=======================================================================
1541 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1542 int idnode3, int idnode4,
1543 int idnode5, int idnode6) const
1545 const SMDS_MeshNode * node1 = FindNode(idnode1);
1546 const SMDS_MeshNode * node2 = FindNode(idnode2);
1547 const SMDS_MeshNode * node3 = FindNode(idnode3);
1548 const SMDS_MeshNode * node4 = FindNode(idnode4);
1549 const SMDS_MeshNode * node5 = FindNode(idnode5);
1550 const SMDS_MeshNode * node6 = FindNode(idnode6);
1551 return FindFace(node1, node2, node3, node4, node5, node6);
1554 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1555 const SMDS_MeshNode *node2,
1556 const SMDS_MeshNode *node3,
1557 const SMDS_MeshNode *node4,
1558 const SMDS_MeshNode *node5,
1559 const SMDS_MeshNode *node6)
1561 if ( !node1 ) return 0;
1562 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1563 while(it1->more()) {
1564 const SMDS_MeshElement * e = it1->next();
1565 if ( e->NbNodes() == 6 ) {
1566 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1567 while(it2->more()) {
1568 const SMDS_MeshElement* n = it2->next();
1581 return static_cast<const SMDS_MeshFace *> (e);
1588 //=======================================================================
1589 //function : FindFace
1590 //purpose : quadratic quadrangle
1591 //=======================================================================
1593 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1594 int idnode3, int idnode4,
1595 int idnode5, int idnode6,
1596 int idnode7, int idnode8) const
1598 const SMDS_MeshNode * node1 = FindNode(idnode1);
1599 const SMDS_MeshNode * node2 = FindNode(idnode2);
1600 const SMDS_MeshNode * node3 = FindNode(idnode3);
1601 const SMDS_MeshNode * node4 = FindNode(idnode4);
1602 const SMDS_MeshNode * node5 = FindNode(idnode5);
1603 const SMDS_MeshNode * node6 = FindNode(idnode6);
1604 const SMDS_MeshNode * node7 = FindNode(idnode7);
1605 const SMDS_MeshNode * node8 = FindNode(idnode8);
1606 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1609 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1610 const SMDS_MeshNode *node2,
1611 const SMDS_MeshNode *node3,
1612 const SMDS_MeshNode *node4,
1613 const SMDS_MeshNode *node5,
1614 const SMDS_MeshNode *node6,
1615 const SMDS_MeshNode *node7,
1616 const SMDS_MeshNode *node8)
1618 if ( !node1 ) return 0;
1619 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1620 while(it1->more()) {
1621 const SMDS_MeshElement * e = it1->next();
1622 if ( e->NbNodes() == 8 ) {
1623 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1624 while(it2->more()) {
1625 const SMDS_MeshElement* n = it2->next();
1640 return static_cast<const SMDS_MeshFace *> (e);
1647 //=======================================================================
1648 //function : FindElement
1650 //=======================================================================
1652 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1654 return myElementIDFactory->MeshElement(IDelem);
1657 //=======================================================================
1658 //function : FindFace
1659 //purpose : find polygon
1660 //=======================================================================
1662 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1664 int nbnodes = nodes_ids.size();
1665 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1666 for (int inode = 0; inode < nbnodes; inode++) {
1667 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1668 if (node == NULL) return NULL;
1670 return FindFace(poly_nodes);
1673 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1675 if ( nodes.size() > 2 && nodes[0] ) {
1676 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1677 while (itF->more()) {
1678 const SMDS_MeshElement* f = itF->next();
1679 if ( f->NbNodes() == nodes.size() ) {
1680 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1681 while(it2->more()) {
1682 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1688 return static_cast<const SMDS_MeshFace *> (f);
1695 //=======================================================================
1696 //function : DumpNodes
1698 //=======================================================================
1700 void SMDS_Mesh::DumpNodes() const
1702 MESSAGE("dump nodes of mesh : ");
1703 SMDS_NodeIteratorPtr itnode=nodesIterator();
1704 while(itnode->more()) MESSAGE(itnode->next());
1707 //=======================================================================
1708 //function : DumpEdges
1710 //=======================================================================
1712 void SMDS_Mesh::DumpEdges() const
1714 MESSAGE("dump edges of mesh : ");
1715 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1716 while(itedge->more()) MESSAGE(itedge->next());
1719 //=======================================================================
1720 //function : DumpFaces
1722 //=======================================================================
1724 void SMDS_Mesh::DumpFaces() const
1726 MESSAGE("dump faces of mesh : ");
1727 SMDS_FaceIteratorPtr itface=facesIterator();
1728 while(itface->more()) MESSAGE(itface->next());
1731 //=======================================================================
1732 //function : DumpVolumes
1734 //=======================================================================
1736 void SMDS_Mesh::DumpVolumes() const
1738 MESSAGE("dump volumes of mesh : ");
1739 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1740 while(itvol->more()) MESSAGE(itvol->next());
1743 //=======================================================================
1744 //function : DebugStats
1746 //=======================================================================
1748 void SMDS_Mesh::DebugStats() const
1750 MESSAGE("Debug stats of mesh : ");
1752 MESSAGE("===== NODES ====="<<NbNodes());
1753 MESSAGE("===== EDGES ====="<<NbEdges());
1754 MESSAGE("===== FACES ====="<<NbFaces());
1755 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1757 MESSAGE("End Debug stats of mesh ");
1761 SMDS_NodeIteratorPtr itnode=nodesIterator();
1762 int sizeofnodes = 0;
1763 int sizeoffaces = 0;
1765 while(itnode->more())
1767 const SMDS_MeshNode *node = itnode->next();
1769 sizeofnodes += sizeof(*node);
1771 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1774 const SMDS_MeshElement *me = it->next();
1775 sizeofnodes += sizeof(me);
1780 SMDS_FaceIteratorPtr itface=facesIterator();
1781 while(itface->more())
1783 const SMDS_MeshElement *face = itface->next();
1784 sizeoffaces += sizeof(*face);
1787 MESSAGE("total size of node elements = " << sizeofnodes);;
1788 MESSAGE("total size of face elements = " << sizeoffaces);;
1793 ///////////////////////////////////////////////////////////////////////////////
1794 /// Return the number of nodes
1795 ///////////////////////////////////////////////////////////////////////////////
1796 int SMDS_Mesh::NbNodes() const
1798 return myNodes.Size();
1801 ///////////////////////////////////////////////////////////////////////////////
1802 /// Return the number of edges (including construction edges)
1803 ///////////////////////////////////////////////////////////////////////////////
1804 int SMDS_Mesh::NbEdges() const
1806 return myEdges.Size();
1809 ///////////////////////////////////////////////////////////////////////////////
1810 /// Return the number of faces (including construction faces)
1811 ///////////////////////////////////////////////////////////////////////////////
1812 int SMDS_Mesh::NbFaces() const
1814 return myFaces.Size();
1817 ///////////////////////////////////////////////////////////////////////////////
1818 /// Return the number of volumes
1819 ///////////////////////////////////////////////////////////////////////////////
1820 int SMDS_Mesh::NbVolumes() const
1822 return myVolumes.Size();
1825 ///////////////////////////////////////////////////////////////////////////////
1826 /// Return the number of child mesh of this mesh.
1827 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1828 /// (2003-09-08) of SMESH
1829 ///////////////////////////////////////////////////////////////////////////////
1830 int SMDS_Mesh::NbSubMesh() const
1832 return myChildren.size();
1835 ///////////////////////////////////////////////////////////////////////////////
1836 /// Destroy the mesh and all its elements
1837 /// All pointer on elements owned by this mesh become illegals.
1838 ///////////////////////////////////////////////////////////////////////////////
1839 SMDS_Mesh::~SMDS_Mesh()
1841 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1842 while(itc!=myChildren.end())
1850 delete myNodeIDFactory;
1851 delete myElementIDFactory;
1855 SMDS_ElemIteratorPtr eIt = elementsIterator();
1856 while ( eIt->more() )
1857 myElementIDFactory->ReleaseID(eIt->next()->GetID());
1858 SMDS_NodeIteratorPtr itn = nodesIterator();
1860 myNodeIDFactory->ReleaseID(itn->next()->GetID());
1862 SetOfNodes::Iterator itn(myNodes);
1863 for (; itn.More(); itn.Next())
1866 SetOfEdges::Iterator ite(myEdges);
1867 for (; ite.More(); ite.Next())
1869 SMDS_MeshElement* elem = ite.Value();
1873 SetOfFaces::Iterator itf(myFaces);
1874 for (; itf.More(); itf.Next())
1876 SMDS_MeshElement* elem = itf.Value();
1880 SetOfVolumes::Iterator itv(myVolumes);
1881 for (; itv.More(); itv.Next())
1883 SMDS_MeshElement* elem = itv.Value();
1889 //================================================================================
1891 * \brief Clear all data
1893 //================================================================================
1895 void SMDS_Mesh::Clear()
1897 if (myParent!=NULL) {
1898 SMDS_ElemIteratorPtr eIt = elementsIterator();
1899 while ( eIt->more() )
1900 myElementIDFactory->ReleaseID(eIt->next()->GetID());
1901 SMDS_NodeIteratorPtr itn = nodesIterator();
1903 myNodeIDFactory->ReleaseID(itn->next()->GetID());
1906 myNodeIDFactory->Clear();
1907 myElementIDFactory->Clear();
1909 SMDS_VolumeIteratorPtr itv = volumesIterator();
1914 SMDS_FaceIteratorPtr itf = facesIterator();
1919 SMDS_EdgeIteratorPtr ite = edgesIterator();
1924 SMDS_NodeIteratorPtr itn = nodesIterator();
1929 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1930 while(itc!=myChildren.end())
1936 ///////////////////////////////////////////////////////////////////////////////
1937 /// Return true if this mesh create faces with edges.
1938 /// A false returned value mean that faces are created with nodes. A concequence
1939 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1940 ///////////////////////////////////////////////////////////////////////////////
1941 bool SMDS_Mesh::hasConstructionEdges()
1943 return myHasConstructionEdges;
1946 ///////////////////////////////////////////////////////////////////////////////
1947 /// Return true if this mesh create volumes with faces
1948 /// A false returned value mean that volumes are created with nodes or edges.
1949 /// (see hasConstructionEdges)
1950 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1952 ///////////////////////////////////////////////////////////////////////////////
1953 bool SMDS_Mesh::hasConstructionFaces()
1955 return myHasConstructionFaces;
1958 ///////////////////////////////////////////////////////////////////////////////
1959 /// Return true if nodes are linked to the finit elements, they are belonging to.
1960 /// Currently, It always return true.
1961 ///////////////////////////////////////////////////////////////////////////////
1962 bool SMDS_Mesh::hasInverseElements()
1964 return myHasInverseElements;
1967 ///////////////////////////////////////////////////////////////////////////////
1968 /// Make this mesh creating construction edges (see hasConstructionEdges)
1969 /// @param b true to have construction edges, else false.
1970 ///////////////////////////////////////////////////////////////////////////////
1971 void SMDS_Mesh::setConstructionEdges(bool b)
1973 myHasConstructionEdges=b;
1976 ///////////////////////////////////////////////////////////////////////////////
1977 /// Make this mesh creating construction faces (see hasConstructionFaces)
1978 /// @param b true to have construction faces, else false.
1979 ///////////////////////////////////////////////////////////////////////////////
1980 void SMDS_Mesh::setConstructionFaces(bool b)
1982 myHasConstructionFaces=b;
1985 ///////////////////////////////////////////////////////////////////////////////
1986 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1987 /// @param b true to link nodes to elements, else false.
1988 ///////////////////////////////////////////////////////////////////////////////
1989 void SMDS_Mesh::setInverseElements(bool b)
1991 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1992 myHasInverseElements=b;
1995 ///////////////////////////////////////////////////////////////////////////////
1996 /// Return an iterator on nodes of the current mesh factory
1997 ///////////////////////////////////////////////////////////////////////////////
1998 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
2000 SMDS_ElemIteratorPtr myIterator;
2002 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
2007 return myIterator->more();
2010 const SMDS_MeshNode* next()
2012 return static_cast<const SMDS_MeshNode*>(myIterator->next());
2016 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2018 return SMDS_NodeIteratorPtr
2019 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2022 ///////////////////////////////////////////////////////////////////////////////
2023 ///Iterator on NCollection_Map
2024 ///////////////////////////////////////////////////////////////////////////////
2025 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2026 struct MYNCollection_Map_Iterator: public FATHER
2028 typename MAP::Iterator myIterator;
2030 MYNCollection_Map_Iterator(const MAP& map):myIterator(map){}
2034 while(myIterator.More())
2036 if(myIterator.Value()->GetID()!=-1)
2045 ELEM current = (ELEM) myIterator.Value();
2051 ///////////////////////////////////////////////////////////////////////////////
2052 ///Return an iterator on edges of the current mesh.
2053 ///////////////////////////////////////////////////////////////////////////////
2055 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2057 typedef MYNCollection_Map_Iterator
2058 < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2059 return SMDS_EdgeIteratorPtr(new TIterator(myEdges));
2062 ///////////////////////////////////////////////////////////////////////////////
2063 ///Return an iterator on faces of the current mesh.
2064 ///////////////////////////////////////////////////////////////////////////////
2066 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2068 typedef MYNCollection_Map_Iterator
2069 < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2070 return SMDS_FaceIteratorPtr(new TIterator(myFaces));
2073 ///////////////////////////////////////////////////////////////////////////////
2074 ///Return an iterator on volumes of the current mesh.
2075 ///////////////////////////////////////////////////////////////////////////////
2077 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2079 typedef MYNCollection_Map_Iterator
2080 < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2081 return SMDS_VolumeIteratorPtr(new TIterator(myVolumes));
2084 ///////////////////////////////////////////////////////////////////////////////
2085 /// Return an iterator on elements of the current mesh factory
2086 ///////////////////////////////////////////////////////////////////////////////
2087 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2092 case SMDSAbs_Volume:
2093 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
2095 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
2097 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
2099 return myNodeIDFactory->elementsIterator();
2102 return myElementIDFactory->elementsIterator();
2105 ///////////////////////////////////////////////////////////////////////////////
2106 /// Do intersection of sets (more than 2)
2107 ///////////////////////////////////////////////////////////////////////////////
2108 static set<const SMDS_MeshElement*> * intersectionOfSets(
2109 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2111 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2112 set<const SMDS_MeshElement*>* rsetB;
2114 for(int i=0; i<numberOfSets-1; i++)
2116 rsetB=new set<const SMDS_MeshElement*>();
2118 rsetA->begin(), rsetA->end(),
2119 vs[i+1].begin(), vs[i+1].end(),
2120 inserter(*rsetB, rsetB->begin()));
2127 ///////////////////////////////////////////////////////////////////////////////
2128 /// Return the list of finit elements owning the given element
2129 ///////////////////////////////////////////////////////////////////////////////
2130 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2132 int numberOfSets=element->NbNodes();
2133 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2135 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2138 while(itNodes->more())
2140 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2141 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2143 //initSet[i]=set<const SMDS_MeshElement*>();
2145 initSet[i].insert(itFe->next());
2149 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2154 ///////////////////////////////////////////////////////////////////////////////
2155 /// Return the list of nodes used only by the given elements
2156 ///////////////////////////////////////////////////////////////////////////////
2157 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2158 set<const SMDS_MeshElement*>& elements)
2160 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2161 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2163 while(itElements!=elements.end())
2165 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2168 while(itNodes->more())
2170 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2171 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2172 set<const SMDS_MeshElement*> s;
2174 s.insert(itFe->next());
2175 if(s==elements) toReturn->insert(n);
2181 ///////////////////////////////////////////////////////////////////////////////
2182 ///Find the children of an element that are made of given nodes
2183 ///@param setOfChildren The set in which matching children will be inserted
2184 ///@param element The element were to search matching children
2185 ///@param nodes The nodes that the children must have to be selected
2186 ///////////////////////////////////////////////////////////////////////////////
2187 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2188 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2191 switch(element->GetType())
2194 MESSAGE("Internal Error: This should not append");
2198 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2201 const SMDS_MeshElement * e=itn->next();
2202 if(nodes.find(e)!=nodes.end())
2204 setOfChildren.insert(element);
2211 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2214 const SMDS_MeshElement * e=itn->next();
2215 if(nodes.find(e)!=nodes.end())
2217 setOfChildren.insert(element);
2221 if(hasConstructionEdges())
2223 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2225 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2228 case SMDSAbs_Volume:
2230 if(hasConstructionFaces())
2232 SMDS_ElemIteratorPtr ite=element->facesIterator();
2234 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2236 else if(hasConstructionEdges())
2238 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2240 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2246 ///////////////////////////////////////////////////////////////////////////////
2247 ///@param elem The element to delete
2248 ///@param removenodes if true remaining nodes will be removed
2249 ///////////////////////////////////////////////////////////////////////////////
2250 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2251 const bool removenodes)
2253 list<const SMDS_MeshElement *> removedElems;
2254 list<const SMDS_MeshElement *> removedNodes;
2255 RemoveElement( elem, removedElems, removedNodes, removenodes );
2258 ///////////////////////////////////////////////////////////////////////////////
2259 ///@param elem The element to delete
2260 ///@param removedElems contains all removed elements
2261 ///@param removedNodes contains all removed nodes
2262 ///@param removenodes if true remaining nodes will be removed
2263 ///////////////////////////////////////////////////////////////////////////////
2264 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2265 list<const SMDS_MeshElement *>& removedElems,
2266 list<const SMDS_MeshElement *>& removedNodes,
2269 // get finite elements built on elem
2270 set<const SMDS_MeshElement*> * s1;
2271 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2272 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2273 elem->GetType() == SMDSAbs_Volume)
2275 s1 = new set<const SMDS_MeshElement*>();
2279 s1 = getFinitElements(elem);
2281 // get exclusive nodes (which would become free afterwards)
2282 set<const SMDS_MeshElement*> * s2;
2283 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2285 // do not remove nodes except elem
2286 s2 = new set<const SMDS_MeshElement*>();
2291 s2 = getExclusiveNodes(*s1);
2293 // form the set of finite and construction elements to remove
2294 set<const SMDS_MeshElement*> s3;
2295 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2296 while(it!=s1->end())
2298 addChildrenWithNodes(s3, *it ,*s2);
2302 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2304 // remove finite and construction elements
2308 // Remove element from <InverseElements> of its nodes
2309 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2312 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2313 (const_cast<SMDS_MeshElement *>(itn->next()));
2314 n->RemoveInverseElement( (*it) );
2317 switch((*it)->GetType())
2320 MESSAGE("Internal Error: This should not happen");
2323 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2324 (const_cast<SMDS_MeshElement*>(*it)));
2325 myInfo.RemoveEdge(*it);
2328 myFaces.Remove(static_cast<SMDS_MeshFace*>
2329 (const_cast<SMDS_MeshElement*>(*it)));
2330 myInfo.RemoveFace(*it);
2332 case SMDSAbs_Volume:
2333 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2334 (const_cast<SMDS_MeshElement*>(*it)));
2335 myInfo.RemoveVolume(*it);
2338 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2339 removedElems.push_back( (*it) );
2340 myElementIDFactory->ReleaseID((*it)->GetID());
2345 // remove exclusive (free) nodes
2349 while(it!=s2->end())
2351 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2352 myNodes.Remove(static_cast<SMDS_MeshNode*>
2353 (const_cast<SMDS_MeshElement*>(*it)));
2355 myNodeIDFactory->ReleaseID((*it)->GetID());
2356 removedNodes.push_back( (*it) );
2367 ///////////////////////////////////////////////////////////////////////////////
2368 ///@param elem The element to delete
2369 ///////////////////////////////////////////////////////////////////////////////
2370 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2372 SMDSAbs_ElementType aType = elem->GetType();
2373 if (aType == SMDSAbs_Node) {
2374 // only free node can be removed by this method
2375 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2376 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2377 if (!itFe->more()) { // free node
2378 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2380 myNodeIDFactory->ReleaseID(elem->GetID());
2384 if (hasConstructionEdges() || hasConstructionFaces())
2385 // this methods is only for meshes without descendants
2388 // Remove element from <InverseElements> of its nodes
2389 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2390 while (itn->more()) {
2391 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2392 (const_cast<SMDS_MeshElement *>(itn->next()));
2393 n->RemoveInverseElement(elem);
2396 // in meshes without descendants elements are always free
2399 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2400 (const_cast<SMDS_MeshElement*>(elem)));
2401 myInfo.RemoveEdge(elem);
2404 myFaces.Remove(static_cast<SMDS_MeshFace*>
2405 (const_cast<SMDS_MeshElement*>(elem)));
2406 myInfo.RemoveFace(elem);
2408 case SMDSAbs_Volume:
2409 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2410 (const_cast<SMDS_MeshElement*>(elem)));
2411 myInfo.RemoveVolume(elem);
2416 myElementIDFactory->ReleaseID(elem->GetID());
2422 * Checks if the element is present in mesh.
2423 * Useful to determine dead pointers.
2425 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2427 // we should not imply on validity of *elem, so iterate on containers
2428 // of all types in the hope of finding <elem> somewhere there
2429 SMDS_NodeIteratorPtr itn = nodesIterator();
2431 if (elem == itn->next())
2433 SMDS_EdgeIteratorPtr ite = edgesIterator();
2435 if (elem == ite->next())
2437 SMDS_FaceIteratorPtr itf = facesIterator();
2439 if (elem == itf->next())
2441 SMDS_VolumeIteratorPtr itv = volumesIterator();
2443 if (elem == itv->next())
2448 //=======================================================================
2449 //function : MaxNodeID
2451 //=======================================================================
2453 int SMDS_Mesh::MaxNodeID() const
2455 return myNodeIDFactory->GetMaxID();
2458 //=======================================================================
2459 //function : MinNodeID
2461 //=======================================================================
2463 int SMDS_Mesh::MinNodeID() const
2465 return myNodeIDFactory->GetMinID();
2468 //=======================================================================
2469 //function : MaxElementID
2471 //=======================================================================
2473 int SMDS_Mesh::MaxElementID() const
2475 return myElementIDFactory->GetMaxID();
2478 //=======================================================================
2479 //function : MinElementID
2481 //=======================================================================
2483 int SMDS_Mesh::MinElementID() const
2485 return myElementIDFactory->GetMinID();
2488 //=======================================================================
2489 //function : Renumber
2490 //purpose : Renumber all nodes or elements.
2491 //=======================================================================
2493 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2498 SMDS_MeshElementIDFactory * idFactory =
2499 isNodes ? myNodeIDFactory : myElementIDFactory;
2501 // get existing elements in the order of ID increasing
2502 map<int,SMDS_MeshElement*> elemMap;
2503 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2504 while ( idElemIt->more() ) {
2505 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2506 int id = elem->GetID();
2507 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2509 // release their ids
2510 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2512 // for ( ; elemIt != elemMap.end(); elemIt++ )
2514 // int id = (*elemIt).first;
2515 // idFactory->ReleaseID( id );
2519 elemIt = elemMap.begin();
2520 for ( ; elemIt != elemMap.end(); elemIt++ )
2522 idFactory->BindID( ID, (*elemIt).second );
2527 //=======================================================================
2528 //function : GetElementType
2529 //purpose : Return type of element or node with id
2530 //=======================================================================
2532 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2534 SMDS_MeshElement* elem = 0;
2536 elem = myElementIDFactory->MeshElement( id );
2538 elem = myNodeIDFactory->MeshElement( id );
2542 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2546 return elem->GetType();
2551 //********************************************************************
2552 //********************************************************************
2553 //******** *********
2554 //***** Methods for addition of quadratic elements ******
2555 //******** *********
2556 //********************************************************************
2557 //********************************************************************
2559 //=======================================================================
2560 //function : AddEdgeWithID
2562 //=======================================================================
2563 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2565 return SMDS_Mesh::AddEdgeWithID
2566 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2567 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2568 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2572 //=======================================================================
2573 //function : AddEdge
2575 //=======================================================================
2576 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2577 const SMDS_MeshNode* n2,
2578 const SMDS_MeshNode* n12)
2580 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2583 //=======================================================================
2584 //function : AddEdgeWithID
2586 //=======================================================================
2587 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2588 const SMDS_MeshNode * n2,
2589 const SMDS_MeshNode * n12,
2592 if ( !n1 || !n2 || !n12 ) return 0;
2593 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2594 if(myElementIDFactory->BindID(ID, edge)) {
2595 SMDS_MeshNode *node1,*node2, *node12;
2596 node1 = const_cast<SMDS_MeshNode*>(n1);
2597 node2 = const_cast<SMDS_MeshNode*>(n2);
2598 node12 = const_cast<SMDS_MeshNode*>(n12);
2599 node1->AddInverseElement(edge);
2600 node2->AddInverseElement(edge);
2601 node12->AddInverseElement(edge);
2603 myInfo.myNbQuadEdges++;
2613 //=======================================================================
2614 //function : AddFace
2616 //=======================================================================
2617 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2618 const SMDS_MeshNode * n2,
2619 const SMDS_MeshNode * n3,
2620 const SMDS_MeshNode * n12,
2621 const SMDS_MeshNode * n23,
2622 const SMDS_MeshNode * n31)
2624 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2625 myElementIDFactory->GetFreeID());
2628 //=======================================================================
2629 //function : AddFaceWithID
2631 //=======================================================================
2632 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2633 int n12,int n23,int n31, int ID)
2635 return SMDS_Mesh::AddFaceWithID
2636 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2637 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2638 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2639 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2640 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2641 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2645 //=======================================================================
2646 //function : AddFaceWithID
2648 //=======================================================================
2649 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2650 const SMDS_MeshNode * n2,
2651 const SMDS_MeshNode * n3,
2652 const SMDS_MeshNode * n12,
2653 const SMDS_MeshNode * n23,
2654 const SMDS_MeshNode * n31,
2657 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2658 if(hasConstructionEdges()) {
2659 // creation quadratic edges - not implemented
2662 SMDS_QuadraticFaceOfNodes* face =
2663 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2665 myInfo.myNbQuadTriangles++;
2667 if (!registerElement(ID, face)) {
2668 RemoveElement(face, false);
2675 //=======================================================================
2676 //function : AddFace
2678 //=======================================================================
2679 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2680 const SMDS_MeshNode * n2,
2681 const SMDS_MeshNode * n3,
2682 const SMDS_MeshNode * n4,
2683 const SMDS_MeshNode * n12,
2684 const SMDS_MeshNode * n23,
2685 const SMDS_MeshNode * n34,
2686 const SMDS_MeshNode * n41)
2688 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2689 myElementIDFactory->GetFreeID());
2692 //=======================================================================
2693 //function : AddFaceWithID
2695 //=======================================================================
2696 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2697 int n12,int n23,int n34,int n41, int ID)
2699 return SMDS_Mesh::AddFaceWithID
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(n34),
2707 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2711 //=======================================================================
2712 //function : AddFaceWithID
2714 //=======================================================================
2715 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2716 const SMDS_MeshNode * n2,
2717 const SMDS_MeshNode * n3,
2718 const SMDS_MeshNode * n4,
2719 const SMDS_MeshNode * n12,
2720 const SMDS_MeshNode * n23,
2721 const SMDS_MeshNode * n34,
2722 const SMDS_MeshNode * n41,
2725 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2726 if(hasConstructionEdges()) {
2727 // creation quadratic edges - not implemented
2729 SMDS_QuadraticFaceOfNodes* face =
2730 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2732 myInfo.myNbQuadQuadrangles++;
2734 if (!registerElement(ID, face)) {
2735 RemoveElement(face, false);
2742 //=======================================================================
2743 //function : AddVolume
2745 //=======================================================================
2746 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2747 const SMDS_MeshNode * n2,
2748 const SMDS_MeshNode * n3,
2749 const SMDS_MeshNode * n4,
2750 const SMDS_MeshNode * n12,
2751 const SMDS_MeshNode * n23,
2752 const SMDS_MeshNode * n31,
2753 const SMDS_MeshNode * n14,
2754 const SMDS_MeshNode * n24,
2755 const SMDS_MeshNode * n34)
2757 int ID = myElementIDFactory->GetFreeID();
2758 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2759 n31, n14, n24, n34, ID);
2760 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2764 //=======================================================================
2765 //function : AddVolumeWithID
2767 //=======================================================================
2768 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2769 int n12,int n23,int n31,
2770 int n14,int n24,int n34, int ID)
2772 return SMDS_Mesh::AddVolumeWithID
2773 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2774 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2775 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2776 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2777 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2778 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2779 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2780 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2781 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2782 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2786 //=======================================================================
2787 //function : AddVolumeWithID
2788 //purpose : 2d order tetrahedron of 10 nodes
2789 //=======================================================================
2790 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2791 const SMDS_MeshNode * n2,
2792 const SMDS_MeshNode * n3,
2793 const SMDS_MeshNode * n4,
2794 const SMDS_MeshNode * n12,
2795 const SMDS_MeshNode * n23,
2796 const SMDS_MeshNode * n31,
2797 const SMDS_MeshNode * n14,
2798 const SMDS_MeshNode * n24,
2799 const SMDS_MeshNode * n34,
2802 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2804 if(hasConstructionFaces()) {
2805 // creation quadratic faces - not implemented
2808 SMDS_QuadraticVolumeOfNodes * volume =
2809 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2810 myVolumes.Add(volume);
2811 myInfo.myNbQuadTetras++;
2813 if (!registerElement(ID, volume)) {
2814 RemoveElement(volume, false);
2821 //=======================================================================
2822 //function : AddVolume
2824 //=======================================================================
2825 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2826 const SMDS_MeshNode * n2,
2827 const SMDS_MeshNode * n3,
2828 const SMDS_MeshNode * n4,
2829 const SMDS_MeshNode * n5,
2830 const SMDS_MeshNode * n12,
2831 const SMDS_MeshNode * n23,
2832 const SMDS_MeshNode * n34,
2833 const SMDS_MeshNode * n41,
2834 const SMDS_MeshNode * n15,
2835 const SMDS_MeshNode * n25,
2836 const SMDS_MeshNode * n35,
2837 const SMDS_MeshNode * n45)
2839 int ID = myElementIDFactory->GetFreeID();
2840 SMDS_MeshVolume * v =
2841 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2842 n15, n25, n35, n45, ID);
2843 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2847 //=======================================================================
2848 //function : AddVolumeWithID
2850 //=======================================================================
2851 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2852 int n12,int n23,int n34,int n41,
2853 int n15,int n25,int n35,int n45, int ID)
2855 return SMDS_Mesh::AddVolumeWithID
2856 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2857 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2858 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2859 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2860 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2861 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2862 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2863 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2864 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2865 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2866 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2867 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2868 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2872 //=======================================================================
2873 //function : AddVolumeWithID
2874 //purpose : 2d order pyramid of 13 nodes
2875 //=======================================================================
2876 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2877 const SMDS_MeshNode * n2,
2878 const SMDS_MeshNode * n3,
2879 const SMDS_MeshNode * n4,
2880 const SMDS_MeshNode * n5,
2881 const SMDS_MeshNode * n12,
2882 const SMDS_MeshNode * n23,
2883 const SMDS_MeshNode * n34,
2884 const SMDS_MeshNode * n41,
2885 const SMDS_MeshNode * n15,
2886 const SMDS_MeshNode * n25,
2887 const SMDS_MeshNode * n35,
2888 const SMDS_MeshNode * n45,
2891 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2892 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2894 if(hasConstructionFaces()) {
2895 // creation quadratic faces - not implemented
2898 SMDS_QuadraticVolumeOfNodes * volume =
2899 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2900 n34,n41,n15,n25,n35,n45);
2901 myVolumes.Add(volume);
2902 myInfo.myNbQuadPyramids++;
2904 if (!registerElement(ID, volume)) {
2905 RemoveElement(volume, false);
2912 //=======================================================================
2913 //function : AddVolume
2915 //=======================================================================
2916 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2917 const SMDS_MeshNode * n2,
2918 const SMDS_MeshNode * n3,
2919 const SMDS_MeshNode * n4,
2920 const SMDS_MeshNode * n5,
2921 const SMDS_MeshNode * n6,
2922 const SMDS_MeshNode * n12,
2923 const SMDS_MeshNode * n23,
2924 const SMDS_MeshNode * n31,
2925 const SMDS_MeshNode * n45,
2926 const SMDS_MeshNode * n56,
2927 const SMDS_MeshNode * n64,
2928 const SMDS_MeshNode * n14,
2929 const SMDS_MeshNode * n25,
2930 const SMDS_MeshNode * n36)
2932 int ID = myElementIDFactory->GetFreeID();
2933 SMDS_MeshVolume * v =
2934 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2935 n45, n56, n64, n14, n25, n36, ID);
2936 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2940 //=======================================================================
2941 //function : AddVolumeWithID
2943 //=======================================================================
2944 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2945 int n4, int n5, int n6,
2946 int n12,int n23,int n31,
2947 int n45,int n56,int n64,
2948 int n14,int n25,int n36, int ID)
2950 return SMDS_Mesh::AddVolumeWithID
2951 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2952 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2953 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2954 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2955 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2956 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2957 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2958 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2959 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2960 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2961 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2962 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2963 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2964 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2965 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2969 //=======================================================================
2970 //function : AddVolumeWithID
2971 //purpose : 2d order Pentahedron with 15 nodes
2972 //=======================================================================
2973 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2974 const SMDS_MeshNode * n2,
2975 const SMDS_MeshNode * n3,
2976 const SMDS_MeshNode * n4,
2977 const SMDS_MeshNode * n5,
2978 const SMDS_MeshNode * n6,
2979 const SMDS_MeshNode * n12,
2980 const SMDS_MeshNode * n23,
2981 const SMDS_MeshNode * n31,
2982 const SMDS_MeshNode * n45,
2983 const SMDS_MeshNode * n56,
2984 const SMDS_MeshNode * n64,
2985 const SMDS_MeshNode * n14,
2986 const SMDS_MeshNode * n25,
2987 const SMDS_MeshNode * n36,
2990 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2991 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2993 if(hasConstructionFaces()) {
2994 // creation quadratic faces - not implemented
2997 SMDS_QuadraticVolumeOfNodes * volume =
2998 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2999 n45,n56,n64,n14,n25,n36);
3000 myVolumes.Add(volume);
3001 myInfo.myNbQuadPrisms++;
3003 if (!registerElement(ID, volume)) {
3004 RemoveElement(volume, false);
3011 //=======================================================================
3012 //function : AddVolume
3014 //=======================================================================
3015 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3016 const SMDS_MeshNode * n2,
3017 const SMDS_MeshNode * n3,
3018 const SMDS_MeshNode * n4,
3019 const SMDS_MeshNode * n5,
3020 const SMDS_MeshNode * n6,
3021 const SMDS_MeshNode * n7,
3022 const SMDS_MeshNode * n8,
3023 const SMDS_MeshNode * n12,
3024 const SMDS_MeshNode * n23,
3025 const SMDS_MeshNode * n34,
3026 const SMDS_MeshNode * n41,
3027 const SMDS_MeshNode * n56,
3028 const SMDS_MeshNode * n67,
3029 const SMDS_MeshNode * n78,
3030 const SMDS_MeshNode * n85,
3031 const SMDS_MeshNode * n15,
3032 const SMDS_MeshNode * n26,
3033 const SMDS_MeshNode * n37,
3034 const SMDS_MeshNode * n48)
3036 int ID = myElementIDFactory->GetFreeID();
3037 SMDS_MeshVolume * v =
3038 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3039 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3040 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3044 //=======================================================================
3045 //function : AddVolumeWithID
3047 //=======================================================================
3048 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3049 int n5, int n6, int n7, int n8,
3050 int n12,int n23,int n34,int n41,
3051 int n56,int n67,int n78,int n85,
3052 int n15,int n26,int n37,int n48, int ID)
3054 return SMDS_Mesh::AddVolumeWithID
3055 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3056 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3057 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3058 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3059 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3060 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3061 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3062 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3063 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3064 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3065 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3066 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3067 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3068 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3069 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3070 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3071 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3072 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3073 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3074 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3078 //=======================================================================
3079 //function : AddVolumeWithID
3080 //purpose : 2d order Hexahedrons with 20 nodes
3081 //=======================================================================
3082 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3083 const SMDS_MeshNode * n2,
3084 const SMDS_MeshNode * n3,
3085 const SMDS_MeshNode * n4,
3086 const SMDS_MeshNode * n5,
3087 const SMDS_MeshNode * n6,
3088 const SMDS_MeshNode * n7,
3089 const SMDS_MeshNode * n8,
3090 const SMDS_MeshNode * n12,
3091 const SMDS_MeshNode * n23,
3092 const SMDS_MeshNode * n34,
3093 const SMDS_MeshNode * n41,
3094 const SMDS_MeshNode * n56,
3095 const SMDS_MeshNode * n67,
3096 const SMDS_MeshNode * n78,
3097 const SMDS_MeshNode * n85,
3098 const SMDS_MeshNode * n15,
3099 const SMDS_MeshNode * n26,
3100 const SMDS_MeshNode * n37,
3101 const SMDS_MeshNode * n48,
3104 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3105 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3107 if(hasConstructionFaces()) {
3109 // creation quadratic faces - not implemented
3111 SMDS_QuadraticVolumeOfNodes * volume =
3112 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3113 n56,n67,n78,n85,n15,n26,n37,n48);
3114 myVolumes.Add(volume);
3115 myInfo.myNbQuadHexas++;
3117 if (!registerElement(ID, volume)) {
3118 RemoveElement(volume, false);