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 /// Return an iterator on elements of the current mesh factory
2024 ///////////////////////////////////////////////////////////////////////////////
2025 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
2027 return myElementIDFactory->elementsIterator();
2030 ///////////////////////////////////////////////////////////////////////////////
2031 ///Return an iterator on edges of the current mesh.
2032 ///////////////////////////////////////////////////////////////////////////////
2033 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
2035 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
2036 SetOfEdges::Iterator myIterator;
2038 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
2043 while(myIterator.More())
2045 if(myIterator.Value()->GetID()!=-1)
2052 const SMDS_MeshEdge* next()
2054 const SMDS_MeshEdge* current = myIterator.Value();
2060 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2062 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
2065 ///////////////////////////////////////////////////////////////////////////////
2066 ///Return an iterator on faces of the current mesh.
2067 ///////////////////////////////////////////////////////////////////////////////
2068 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
2070 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
2071 SetOfFaces::Iterator myIterator;
2073 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
2078 while(myIterator.More())
2080 if(myIterator.Value()->GetID()!=-1)
2087 const SMDS_MeshFace* next()
2089 const SMDS_MeshFace* current = myIterator.Value();
2095 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2097 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2100 ///////////////////////////////////////////////////////////////////////////////
2101 ///Return an iterator on volumes of the current mesh.
2102 ///////////////////////////////////////////////////////////////////////////////
2103 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2105 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2106 SetOfVolumes::Iterator myIterator;
2108 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2113 return myIterator.More() != Standard_False;
2116 const SMDS_MeshVolume* next()
2118 const SMDS_MeshVolume* current = myIterator.Value();
2124 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2126 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2129 ///////////////////////////////////////////////////////////////////////////////
2130 /// Do intersection of sets (more than 2)
2131 ///////////////////////////////////////////////////////////////////////////////
2132 static set<const SMDS_MeshElement*> * intersectionOfSets(
2133 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2135 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2136 set<const SMDS_MeshElement*>* rsetB;
2138 for(int i=0; i<numberOfSets-1; i++)
2140 rsetB=new set<const SMDS_MeshElement*>();
2142 rsetA->begin(), rsetA->end(),
2143 vs[i+1].begin(), vs[i+1].end(),
2144 inserter(*rsetB, rsetB->begin()));
2151 ///////////////////////////////////////////////////////////////////////////////
2152 /// Return the list of finit elements owning the given element
2153 ///////////////////////////////////////////////////////////////////////////////
2154 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2156 int numberOfSets=element->NbNodes();
2157 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2159 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2162 while(itNodes->more())
2164 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2165 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2167 //initSet[i]=set<const SMDS_MeshElement*>();
2169 initSet[i].insert(itFe->next());
2173 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2178 ///////////////////////////////////////////////////////////////////////////////
2179 /// Return the list of nodes used only by the given elements
2180 ///////////////////////////////////////////////////////////////////////////////
2181 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2182 set<const SMDS_MeshElement*>& elements)
2184 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2185 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2187 while(itElements!=elements.end())
2189 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2192 while(itNodes->more())
2194 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2195 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2196 set<const SMDS_MeshElement*> s;
2198 s.insert(itFe->next());
2199 if(s==elements) toReturn->insert(n);
2205 ///////////////////////////////////////////////////////////////////////////////
2206 ///Find the children of an element that are made of given nodes
2207 ///@param setOfChildren The set in which matching children will be inserted
2208 ///@param element The element were to search matching children
2209 ///@param nodes The nodes that the children must have to be selected
2210 ///////////////////////////////////////////////////////////////////////////////
2211 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2212 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2215 switch(element->GetType())
2218 MESSAGE("Internal Error: This should not append");
2222 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2225 const SMDS_MeshElement * e=itn->next();
2226 if(nodes.find(e)!=nodes.end())
2228 setOfChildren.insert(element);
2235 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2238 const SMDS_MeshElement * e=itn->next();
2239 if(nodes.find(e)!=nodes.end())
2241 setOfChildren.insert(element);
2245 if(hasConstructionEdges())
2247 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2249 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2252 case SMDSAbs_Volume:
2254 if(hasConstructionFaces())
2256 SMDS_ElemIteratorPtr ite=element->facesIterator();
2258 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2260 else if(hasConstructionEdges())
2262 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2264 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2270 ///////////////////////////////////////////////////////////////////////////////
2271 ///@param elem The element to delete
2272 ///@param removenodes if true remaining nodes will be removed
2273 ///////////////////////////////////////////////////////////////////////////////
2274 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2275 const bool removenodes)
2277 list<const SMDS_MeshElement *> removedElems;
2278 list<const SMDS_MeshElement *> removedNodes;
2279 RemoveElement( elem, removedElems, removedNodes, removenodes );
2282 ///////////////////////////////////////////////////////////////////////////////
2283 ///@param elem The element to delete
2284 ///@param removedElems contains all removed elements
2285 ///@param removedNodes contains all removed nodes
2286 ///@param removenodes if true remaining nodes will be removed
2287 ///////////////////////////////////////////////////////////////////////////////
2288 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2289 list<const SMDS_MeshElement *>& removedElems,
2290 list<const SMDS_MeshElement *>& removedNodes,
2293 // get finite elements built on elem
2294 set<const SMDS_MeshElement*> * s1;
2295 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2296 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2297 elem->GetType() == SMDSAbs_Volume)
2299 s1 = new set<const SMDS_MeshElement*>();
2303 s1 = getFinitElements(elem);
2305 // get exclusive nodes (which would become free afterwards)
2306 set<const SMDS_MeshElement*> * s2;
2307 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2309 // do not remove nodes except elem
2310 s2 = new set<const SMDS_MeshElement*>();
2315 s2 = getExclusiveNodes(*s1);
2317 // form the set of finite and construction elements to remove
2318 set<const SMDS_MeshElement*> s3;
2319 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2320 while(it!=s1->end())
2322 addChildrenWithNodes(s3, *it ,*s2);
2326 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2328 // remove finite and construction elements
2332 // Remove element from <InverseElements> of its nodes
2333 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2336 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2337 (const_cast<SMDS_MeshElement *>(itn->next()));
2338 n->RemoveInverseElement( (*it) );
2341 switch((*it)->GetType())
2344 MESSAGE("Internal Error: This should not happen");
2347 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2348 (const_cast<SMDS_MeshElement*>(*it)));
2349 myInfo.RemoveEdge(*it);
2352 myFaces.Remove(static_cast<SMDS_MeshFace*>
2353 (const_cast<SMDS_MeshElement*>(*it)));
2354 myInfo.RemoveFace(*it);
2356 case SMDSAbs_Volume:
2357 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2358 (const_cast<SMDS_MeshElement*>(*it)));
2359 myInfo.RemoveVolume(*it);
2362 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2363 removedElems.push_back( (*it) );
2364 myElementIDFactory->ReleaseID((*it)->GetID());
2369 // remove exclusive (free) nodes
2373 while(it!=s2->end())
2375 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2376 myNodes.Remove(static_cast<SMDS_MeshNode*>
2377 (const_cast<SMDS_MeshElement*>(*it)));
2379 myNodeIDFactory->ReleaseID((*it)->GetID());
2380 removedNodes.push_back( (*it) );
2391 ///////////////////////////////////////////////////////////////////////////////
2392 ///@param elem The element to delete
2393 ///////////////////////////////////////////////////////////////////////////////
2394 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2396 SMDSAbs_ElementType aType = elem->GetType();
2397 if (aType == SMDSAbs_Node) {
2398 // only free node can be removed by this method
2399 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2400 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2401 if (!itFe->more()) { // free node
2402 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2404 myNodeIDFactory->ReleaseID(elem->GetID());
2408 if (hasConstructionEdges() || hasConstructionFaces())
2409 // this methods is only for meshes without descendants
2412 // Remove element from <InverseElements> of its nodes
2413 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2414 while (itn->more()) {
2415 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2416 (const_cast<SMDS_MeshElement *>(itn->next()));
2417 n->RemoveInverseElement(elem);
2420 // in meshes without descendants elements are always free
2423 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2424 (const_cast<SMDS_MeshElement*>(elem)));
2425 myInfo.RemoveEdge(elem);
2428 myFaces.Remove(static_cast<SMDS_MeshFace*>
2429 (const_cast<SMDS_MeshElement*>(elem)));
2430 myInfo.RemoveFace(elem);
2432 case SMDSAbs_Volume:
2433 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2434 (const_cast<SMDS_MeshElement*>(elem)));
2435 myInfo.RemoveVolume(elem);
2440 myElementIDFactory->ReleaseID(elem->GetID());
2446 * Checks if the element is present in mesh.
2447 * Useful to determine dead pointers.
2449 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2451 // we should not imply on validity of *elem, so iterate on containers
2452 // of all types in the hope of finding <elem> somewhere there
2453 SMDS_NodeIteratorPtr itn = nodesIterator();
2455 if (elem == itn->next())
2457 SMDS_EdgeIteratorPtr ite = edgesIterator();
2459 if (elem == ite->next())
2461 SMDS_FaceIteratorPtr itf = facesIterator();
2463 if (elem == itf->next())
2465 SMDS_VolumeIteratorPtr itv = volumesIterator();
2467 if (elem == itv->next())
2472 //=======================================================================
2473 //function : MaxNodeID
2475 //=======================================================================
2477 int SMDS_Mesh::MaxNodeID() const
2479 return myNodeIDFactory->GetMaxID();
2482 //=======================================================================
2483 //function : MinNodeID
2485 //=======================================================================
2487 int SMDS_Mesh::MinNodeID() const
2489 return myNodeIDFactory->GetMinID();
2492 //=======================================================================
2493 //function : MaxElementID
2495 //=======================================================================
2497 int SMDS_Mesh::MaxElementID() const
2499 return myElementIDFactory->GetMaxID();
2502 //=======================================================================
2503 //function : MinElementID
2505 //=======================================================================
2507 int SMDS_Mesh::MinElementID() const
2509 return myElementIDFactory->GetMinID();
2512 //=======================================================================
2513 //function : Renumber
2514 //purpose : Renumber all nodes or elements.
2515 //=======================================================================
2517 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2522 SMDS_MeshElementIDFactory * idFactory =
2523 isNodes ? myNodeIDFactory : myElementIDFactory;
2525 // get existing elements in the order of ID increasing
2526 map<int,SMDS_MeshElement*> elemMap;
2527 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2528 while ( idElemIt->more() ) {
2529 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2530 int id = elem->GetID();
2531 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2533 // release their ids
2534 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2536 // for ( ; elemIt != elemMap.end(); elemIt++ )
2538 // int id = (*elemIt).first;
2539 // idFactory->ReleaseID( id );
2543 elemIt = elemMap.begin();
2544 for ( ; elemIt != elemMap.end(); elemIt++ )
2546 idFactory->BindID( ID, (*elemIt).second );
2551 //=======================================================================
2552 //function : GetElementType
2553 //purpose : Return type of element or node with id
2554 //=======================================================================
2556 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2558 SMDS_MeshElement* elem = 0;
2560 elem = myElementIDFactory->MeshElement( id );
2562 elem = myNodeIDFactory->MeshElement( id );
2566 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2570 return elem->GetType();
2575 //********************************************************************
2576 //********************************************************************
2577 //******** *********
2578 //***** Methods for addition of quadratic elements ******
2579 //******** *********
2580 //********************************************************************
2581 //********************************************************************
2583 //=======================================================================
2584 //function : AddEdgeWithID
2586 //=======================================================================
2587 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2589 return SMDS_Mesh::AddEdgeWithID
2590 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2591 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2592 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2596 //=======================================================================
2597 //function : AddEdge
2599 //=======================================================================
2600 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2601 const SMDS_MeshNode* n2,
2602 const SMDS_MeshNode* n12)
2604 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2607 //=======================================================================
2608 //function : AddEdgeWithID
2610 //=======================================================================
2611 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2612 const SMDS_MeshNode * n2,
2613 const SMDS_MeshNode * n12,
2616 if ( !n1 || !n2 || !n12 ) return 0;
2617 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2618 if(myElementIDFactory->BindID(ID, edge)) {
2619 SMDS_MeshNode *node1,*node2, *node12;
2620 node1 = const_cast<SMDS_MeshNode*>(n1);
2621 node2 = const_cast<SMDS_MeshNode*>(n2);
2622 node12 = const_cast<SMDS_MeshNode*>(n12);
2623 node1->AddInverseElement(edge);
2624 node2->AddInverseElement(edge);
2625 node12->AddInverseElement(edge);
2627 myInfo.myNbQuadEdges++;
2637 //=======================================================================
2638 //function : AddFace
2640 //=======================================================================
2641 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2642 const SMDS_MeshNode * n2,
2643 const SMDS_MeshNode * n3,
2644 const SMDS_MeshNode * n12,
2645 const SMDS_MeshNode * n23,
2646 const SMDS_MeshNode * n31)
2648 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2649 myElementIDFactory->GetFreeID());
2652 //=======================================================================
2653 //function : AddFaceWithID
2655 //=======================================================================
2656 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2657 int n12,int n23,int n31, int ID)
2659 return SMDS_Mesh::AddFaceWithID
2660 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2661 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2662 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2663 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2664 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2665 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2669 //=======================================================================
2670 //function : AddFaceWithID
2672 //=======================================================================
2673 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2674 const SMDS_MeshNode * n2,
2675 const SMDS_MeshNode * n3,
2676 const SMDS_MeshNode * n12,
2677 const SMDS_MeshNode * n23,
2678 const SMDS_MeshNode * n31,
2681 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2682 if(hasConstructionEdges()) {
2683 // creation quadratic edges - not implemented
2686 SMDS_QuadraticFaceOfNodes* face =
2687 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2689 myInfo.myNbQuadTriangles++;
2691 if (!registerElement(ID, face)) {
2692 RemoveElement(face, false);
2699 //=======================================================================
2700 //function : AddFace
2702 //=======================================================================
2703 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2704 const SMDS_MeshNode * n2,
2705 const SMDS_MeshNode * n3,
2706 const SMDS_MeshNode * n4,
2707 const SMDS_MeshNode * n12,
2708 const SMDS_MeshNode * n23,
2709 const SMDS_MeshNode * n34,
2710 const SMDS_MeshNode * n41)
2712 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2713 myElementIDFactory->GetFreeID());
2716 //=======================================================================
2717 //function : AddFaceWithID
2719 //=======================================================================
2720 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2721 int n12,int n23,int n34,int n41, int ID)
2723 return SMDS_Mesh::AddFaceWithID
2724 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2725 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2726 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2727 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2728 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2729 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2730 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2731 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2735 //=======================================================================
2736 //function : AddFaceWithID
2738 //=======================================================================
2739 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2740 const SMDS_MeshNode * n2,
2741 const SMDS_MeshNode * n3,
2742 const SMDS_MeshNode * n4,
2743 const SMDS_MeshNode * n12,
2744 const SMDS_MeshNode * n23,
2745 const SMDS_MeshNode * n34,
2746 const SMDS_MeshNode * n41,
2749 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2750 if(hasConstructionEdges()) {
2751 // creation quadratic edges - not implemented
2753 SMDS_QuadraticFaceOfNodes* face =
2754 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2756 myInfo.myNbQuadQuadrangles++;
2758 if (!registerElement(ID, face)) {
2759 RemoveElement(face, false);
2766 //=======================================================================
2767 //function : AddVolume
2769 //=======================================================================
2770 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2771 const SMDS_MeshNode * n2,
2772 const SMDS_MeshNode * n3,
2773 const SMDS_MeshNode * n4,
2774 const SMDS_MeshNode * n12,
2775 const SMDS_MeshNode * n23,
2776 const SMDS_MeshNode * n31,
2777 const SMDS_MeshNode * n14,
2778 const SMDS_MeshNode * n24,
2779 const SMDS_MeshNode * n34)
2781 int ID = myElementIDFactory->GetFreeID();
2782 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2783 n31, n14, n24, n34, ID);
2784 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2788 //=======================================================================
2789 //function : AddVolumeWithID
2791 //=======================================================================
2792 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2793 int n12,int n23,int n31,
2794 int n14,int n24,int n34, int ID)
2796 return SMDS_Mesh::AddVolumeWithID
2797 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2798 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2799 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2800 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2801 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2802 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2803 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2804 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2805 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2806 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2810 //=======================================================================
2811 //function : AddVolumeWithID
2812 //purpose : 2d order tetrahedron of 10 nodes
2813 //=======================================================================
2814 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2815 const SMDS_MeshNode * n2,
2816 const SMDS_MeshNode * n3,
2817 const SMDS_MeshNode * n4,
2818 const SMDS_MeshNode * n12,
2819 const SMDS_MeshNode * n23,
2820 const SMDS_MeshNode * n31,
2821 const SMDS_MeshNode * n14,
2822 const SMDS_MeshNode * n24,
2823 const SMDS_MeshNode * n34,
2826 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2828 if(hasConstructionFaces()) {
2829 // creation quadratic faces - not implemented
2832 SMDS_QuadraticVolumeOfNodes * volume =
2833 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2834 myVolumes.Add(volume);
2835 myInfo.myNbQuadTetras++;
2837 if (!registerElement(ID, volume)) {
2838 RemoveElement(volume, false);
2845 //=======================================================================
2846 //function : AddVolume
2848 //=======================================================================
2849 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2850 const SMDS_MeshNode * n2,
2851 const SMDS_MeshNode * n3,
2852 const SMDS_MeshNode * n4,
2853 const SMDS_MeshNode * n5,
2854 const SMDS_MeshNode * n12,
2855 const SMDS_MeshNode * n23,
2856 const SMDS_MeshNode * n34,
2857 const SMDS_MeshNode * n41,
2858 const SMDS_MeshNode * n15,
2859 const SMDS_MeshNode * n25,
2860 const SMDS_MeshNode * n35,
2861 const SMDS_MeshNode * n45)
2863 int ID = myElementIDFactory->GetFreeID();
2864 SMDS_MeshVolume * v =
2865 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2866 n15, n25, n35, n45, ID);
2867 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2871 //=======================================================================
2872 //function : AddVolumeWithID
2874 //=======================================================================
2875 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2876 int n12,int n23,int n34,int n41,
2877 int n15,int n25,int n35,int n45, int ID)
2879 return SMDS_Mesh::AddVolumeWithID
2880 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2881 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2882 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2883 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2884 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2885 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2886 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2887 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2888 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2889 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2890 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2891 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2892 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2896 //=======================================================================
2897 //function : AddVolumeWithID
2898 //purpose : 2d order pyramid of 13 nodes
2899 //=======================================================================
2900 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2901 const SMDS_MeshNode * n2,
2902 const SMDS_MeshNode * n3,
2903 const SMDS_MeshNode * n4,
2904 const SMDS_MeshNode * n5,
2905 const SMDS_MeshNode * n12,
2906 const SMDS_MeshNode * n23,
2907 const SMDS_MeshNode * n34,
2908 const SMDS_MeshNode * n41,
2909 const SMDS_MeshNode * n15,
2910 const SMDS_MeshNode * n25,
2911 const SMDS_MeshNode * n35,
2912 const SMDS_MeshNode * n45,
2915 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2916 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2918 if(hasConstructionFaces()) {
2919 // creation quadratic faces - not implemented
2922 SMDS_QuadraticVolumeOfNodes * volume =
2923 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2924 n34,n41,n15,n25,n35,n45);
2925 myVolumes.Add(volume);
2926 myInfo.myNbQuadPyramids++;
2928 if (!registerElement(ID, volume)) {
2929 RemoveElement(volume, false);
2936 //=======================================================================
2937 //function : AddVolume
2939 //=======================================================================
2940 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2941 const SMDS_MeshNode * n2,
2942 const SMDS_MeshNode * n3,
2943 const SMDS_MeshNode * n4,
2944 const SMDS_MeshNode * n5,
2945 const SMDS_MeshNode * n6,
2946 const SMDS_MeshNode * n12,
2947 const SMDS_MeshNode * n23,
2948 const SMDS_MeshNode * n31,
2949 const SMDS_MeshNode * n45,
2950 const SMDS_MeshNode * n56,
2951 const SMDS_MeshNode * n64,
2952 const SMDS_MeshNode * n14,
2953 const SMDS_MeshNode * n25,
2954 const SMDS_MeshNode * n36)
2956 int ID = myElementIDFactory->GetFreeID();
2957 SMDS_MeshVolume * v =
2958 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2959 n45, n56, n64, n14, n25, n36, ID);
2960 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2964 //=======================================================================
2965 //function : AddVolumeWithID
2967 //=======================================================================
2968 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2969 int n4, int n5, int n6,
2970 int n12,int n23,int n31,
2971 int n45,int n56,int n64,
2972 int n14,int n25,int n36, int ID)
2974 return SMDS_Mesh::AddVolumeWithID
2975 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2976 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2977 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2978 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2979 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2980 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2981 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2982 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2983 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2984 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2985 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2986 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2993 //=======================================================================
2994 //function : AddVolumeWithID
2995 //purpose : 2d order Pentahedron with 15 nodes
2996 //=======================================================================
2997 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2998 const SMDS_MeshNode * n2,
2999 const SMDS_MeshNode * n3,
3000 const SMDS_MeshNode * n4,
3001 const SMDS_MeshNode * n5,
3002 const SMDS_MeshNode * n6,
3003 const SMDS_MeshNode * n12,
3004 const SMDS_MeshNode * n23,
3005 const SMDS_MeshNode * n31,
3006 const SMDS_MeshNode * n45,
3007 const SMDS_MeshNode * n56,
3008 const SMDS_MeshNode * n64,
3009 const SMDS_MeshNode * n14,
3010 const SMDS_MeshNode * n25,
3011 const SMDS_MeshNode * n36,
3014 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3015 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3017 if(hasConstructionFaces()) {
3018 // creation quadratic faces - not implemented
3021 SMDS_QuadraticVolumeOfNodes * volume =
3022 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3023 n45,n56,n64,n14,n25,n36);
3024 myVolumes.Add(volume);
3025 myInfo.myNbQuadPrisms++;
3027 if (!registerElement(ID, volume)) {
3028 RemoveElement(volume, false);
3035 //=======================================================================
3036 //function : AddVolume
3038 //=======================================================================
3039 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3040 const SMDS_MeshNode * n2,
3041 const SMDS_MeshNode * n3,
3042 const SMDS_MeshNode * n4,
3043 const SMDS_MeshNode * n5,
3044 const SMDS_MeshNode * n6,
3045 const SMDS_MeshNode * n7,
3046 const SMDS_MeshNode * n8,
3047 const SMDS_MeshNode * n12,
3048 const SMDS_MeshNode * n23,
3049 const SMDS_MeshNode * n34,
3050 const SMDS_MeshNode * n41,
3051 const SMDS_MeshNode * n56,
3052 const SMDS_MeshNode * n67,
3053 const SMDS_MeshNode * n78,
3054 const SMDS_MeshNode * n85,
3055 const SMDS_MeshNode * n15,
3056 const SMDS_MeshNode * n26,
3057 const SMDS_MeshNode * n37,
3058 const SMDS_MeshNode * n48)
3060 int ID = myElementIDFactory->GetFreeID();
3061 SMDS_MeshVolume * v =
3062 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3063 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3064 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3068 //=======================================================================
3069 //function : AddVolumeWithID
3071 //=======================================================================
3072 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3073 int n5, int n6, int n7, int n8,
3074 int n12,int n23,int n34,int n41,
3075 int n56,int n67,int n78,int n85,
3076 int n15,int n26,int n37,int n48, int ID)
3078 return SMDS_Mesh::AddVolumeWithID
3079 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3080 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3081 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3082 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3083 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3084 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3085 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3086 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3087 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3088 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3089 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3090 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3091 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3092 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3093 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3094 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3095 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3096 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3097 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3098 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3102 //=======================================================================
3103 //function : AddVolumeWithID
3104 //purpose : 2d order Hexahedrons with 20 nodes
3105 //=======================================================================
3106 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3107 const SMDS_MeshNode * n2,
3108 const SMDS_MeshNode * n3,
3109 const SMDS_MeshNode * n4,
3110 const SMDS_MeshNode * n5,
3111 const SMDS_MeshNode * n6,
3112 const SMDS_MeshNode * n7,
3113 const SMDS_MeshNode * n8,
3114 const SMDS_MeshNode * n12,
3115 const SMDS_MeshNode * n23,
3116 const SMDS_MeshNode * n34,
3117 const SMDS_MeshNode * n41,
3118 const SMDS_MeshNode * n56,
3119 const SMDS_MeshNode * n67,
3120 const SMDS_MeshNode * n78,
3121 const SMDS_MeshNode * n85,
3122 const SMDS_MeshNode * n15,
3123 const SMDS_MeshNode * n26,
3124 const SMDS_MeshNode * n37,
3125 const SMDS_MeshNode * n48,
3128 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3129 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3131 if(hasConstructionFaces()) {
3133 // creation quadratic faces - not implemented
3135 SMDS_QuadraticVolumeOfNodes * volume =
3136 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3137 n56,n67,n78,n85,n15,n26,n37,n48);
3138 myVolumes.Add(volume);
3139 myInfo.myNbQuadHexas++;
3141 if (!registerElement(ID, volume)) {
3142 RemoveElement(volume, false);