1 // SMESH SMDS : implementaion of Salome mesh data structure
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #pragma warning(disable:4786)
26 #include "utilities.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeOfNodes.hxx"
29 #include "SMDS_VolumeOfFaces.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_FaceOfEdges.hxx"
32 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
33 #include "SMDS_PolygonalFaceOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
43 #include <sys/sysinfo.h>
46 // number of added entitis to check memory after
47 #define CHECKMEMORY_INTERVAL 1000
49 //================================================================================
51 * \brief Raise an exception if free memory (ram+swap) too low
52 * \param doNotRaise - if true, suppres exception, just return free memory size
53 * \retval int - amount of available memory in MB or negative number in failure case
55 //================================================================================
57 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
61 int err = sysinfo( &si );
65 static int limit = -1;
67 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
69 limit = WEXITSTATUS(status);
74 limit = int( limit * 1.5 );
76 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
80 const unsigned long Mbyte = 1024 * 1024;
81 // compute separately to avoid overflow
83 ( si.freeram * si.mem_unit ) / Mbyte +
84 ( si.freeswap * si.mem_unit ) / Mbyte;
87 return freeMb - limit;
92 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
94 throw std::bad_alloc();
100 ///////////////////////////////////////////////////////////////////////////////
101 /// Create a new mesh object
102 ///////////////////////////////////////////////////////////////////////////////
103 SMDS_Mesh::SMDS_Mesh()
105 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
106 myElementIDFactory(new SMDS_MeshElementIDFactory()),
107 myHasConstructionEdges(false), myHasConstructionFaces(false),
108 myHasInverseElements(true)
112 ///////////////////////////////////////////////////////////////////////////////
113 /// Create a new child mesh
114 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
115 /// (2003-09-08) of SMESH
116 ///////////////////////////////////////////////////////////////////////////////
117 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
118 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
119 myElementIDFactory(parent->myElementIDFactory),
120 myHasConstructionEdges(false), myHasConstructionFaces(false),
121 myHasInverseElements(true)
125 ///////////////////////////////////////////////////////////////////////////////
126 ///Create a submesh and add it to the current mesh
127 ///////////////////////////////////////////////////////////////////////////////
129 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
131 SMDS_Mesh *submesh = new SMDS_Mesh(this);
132 myChildren.insert(myChildren.end(), submesh);
136 ///////////////////////////////////////////////////////////////////////////////
137 ///create a MeshNode and add it to the current Mesh
138 ///An ID is automatically assigned to the node.
139 ///@return : The created node
140 ///////////////////////////////////////////////////////////////////////////////
142 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
144 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
147 ///////////////////////////////////////////////////////////////////////////////
148 ///create a MeshNode and add it to the current Mesh
149 ///@param ID : The ID of the MeshNode to create
150 ///@return : The created node or NULL if a node with this ID already exists
151 ///////////////////////////////////////////////////////////////////////////////
152 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
154 // find the MeshNode corresponding to ID
155 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
157 if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
158 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
160 myNodeIDFactory->BindID(ID,node);
167 ///////////////////////////////////////////////////////////////////////////////
168 /// create a MeshEdge and add it to the current Mesh
169 /// @return : The created MeshEdge
170 ///////////////////////////////////////////////////////////////////////////////
172 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
174 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
175 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
176 if(!node1 || !node2) return NULL;
177 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
180 ///////////////////////////////////////////////////////////////////////////////
181 /// create a MeshEdge and add it to the current Mesh
182 /// @return : The created MeshEdge
183 ///////////////////////////////////////////////////////////////////////////////
185 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
186 const SMDS_MeshNode * node2)
188 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
191 ///////////////////////////////////////////////////////////////////////////////
192 /// Create a new edge and at it to the mesh
193 /// @param idnode1 ID of the first node
194 /// @param idnode2 ID of the second node
195 /// @param ID ID of the edge to create
196 /// @return The created edge or NULL if an element with this ID already exists or
197 /// if input nodes are not found.
198 ///////////////////////////////////////////////////////////////////////////////
200 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
201 const SMDS_MeshNode * n2,
204 if ( !n1 || !n2 ) return 0;
206 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
208 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
209 if(myElementIDFactory->BindID(ID, edge)) {
210 SMDS_MeshNode *node1,*node2;
211 node1=const_cast<SMDS_MeshNode*>(n1);
212 node2=const_cast<SMDS_MeshNode*>(n2);
213 node1->AddInverseElement(edge);
214 node2->AddInverseElement(edge);
225 ///////////////////////////////////////////////////////////////////////////////
226 /// Add a triangle defined by its nodes. An ID is automatically affected to the
228 ///////////////////////////////////////////////////////////////////////////////
230 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
231 const SMDS_MeshNode * n2,
232 const SMDS_MeshNode * n3)
234 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
237 ///////////////////////////////////////////////////////////////////////////////
238 /// Add a triangle defined by its nodes IDs
239 ///////////////////////////////////////////////////////////////////////////////
241 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
243 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
244 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
245 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
246 if(!node1 || !node2 || !node3) return NULL;
247 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
250 ///////////////////////////////////////////////////////////////////////////////
251 /// Add a triangle defined by its nodes
252 ///////////////////////////////////////////////////////////////////////////////
254 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
255 const SMDS_MeshNode * n2,
256 const SMDS_MeshNode * n3,
259 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
261 if (face && !registerElement(ID, face)) {
262 RemoveElement(face, false);
268 ///////////////////////////////////////////////////////////////////////////////
269 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
271 ///////////////////////////////////////////////////////////////////////////////
273 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
274 const SMDS_MeshNode * n2,
275 const SMDS_MeshNode * n3,
276 const SMDS_MeshNode * n4)
278 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
281 ///////////////////////////////////////////////////////////////////////////////
282 /// Add a quadrangle defined by its nodes IDs
283 ///////////////////////////////////////////////////////////////////////////////
285 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
291 SMDS_MeshNode *node1, *node2, *node3, *node4;
292 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
293 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
294 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
295 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
296 if(!node1 || !node2 || !node3 || !node4) return NULL;
297 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
300 ///////////////////////////////////////////////////////////////////////////////
301 /// Add a quadrangle defined by its nodes
302 ///////////////////////////////////////////////////////////////////////////////
304 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
305 const SMDS_MeshNode * n2,
306 const SMDS_MeshNode * n3,
307 const SMDS_MeshNode * n4,
310 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
312 if (face && !registerElement(ID, face)) {
313 RemoveElement(face, false);
319 ///////////////////////////////////////////////////////////////////////////////
320 /// Add a triangle defined by its edges. An ID is automatically assigned to the
322 ///////////////////////////////////////////////////////////////////////////////
324 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
325 const SMDS_MeshEdge * e2,
326 const SMDS_MeshEdge * e3)
328 if (!hasConstructionEdges())
330 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
333 ///////////////////////////////////////////////////////////////////////////////
334 /// Add a triangle defined by its edges
335 ///////////////////////////////////////////////////////////////////////////////
337 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
338 const SMDS_MeshEdge * e2,
339 const SMDS_MeshEdge * e3,
342 if (!hasConstructionEdges())
344 if ( !e1 || !e2 || !e3 ) return 0;
346 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
348 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
350 myInfo.myNbTriangles++;
352 if (!registerElement(ID, face)) {
353 RemoveElement(face, false);
359 ///////////////////////////////////////////////////////////////////////////////
360 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
362 ///////////////////////////////////////////////////////////////////////////////
364 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
365 const SMDS_MeshEdge * e2,
366 const SMDS_MeshEdge * e3,
367 const SMDS_MeshEdge * e4)
369 if (!hasConstructionEdges())
371 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
374 ///////////////////////////////////////////////////////////////////////////////
375 /// Add a quadrangle defined by its edges
376 ///////////////////////////////////////////////////////////////////////////////
378 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
379 const SMDS_MeshEdge * e2,
380 const SMDS_MeshEdge * e3,
381 const SMDS_MeshEdge * e4,
384 if (!hasConstructionEdges())
386 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
387 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
388 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
390 myInfo.myNbQuadrangles++;
392 if (!registerElement(ID, face))
394 RemoveElement(face, false);
400 ///////////////////////////////////////////////////////////////////////////////
401 ///Create a new tetrahedron and add it to the mesh.
402 ///@return The created tetrahedron
403 ///////////////////////////////////////////////////////////////////////////////
405 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
406 const SMDS_MeshNode * n2,
407 const SMDS_MeshNode * n3,
408 const SMDS_MeshNode * n4)
410 int ID = myElementIDFactory->GetFreeID();
411 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
412 if(v==NULL) myElementIDFactory->ReleaseID(ID);
416 ///////////////////////////////////////////////////////////////////////////////
417 ///Create a new tetrahedron and add it to the mesh.
418 ///@param ID The ID of the new volume
419 ///@return The created tetrahedron or NULL if an element with this ID already exists
420 ///or if input nodes are not found.
421 ///////////////////////////////////////////////////////////////////////////////
423 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
429 SMDS_MeshNode *node1, *node2, *node3, *node4;
430 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
431 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
432 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
433 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
434 if(!node1 || !node2 || !node3 || !node4) return NULL;
435 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
438 ///////////////////////////////////////////////////////////////////////////////
439 ///Create a new tetrahedron and add it to the mesh.
440 ///@param ID The ID of the new volume
441 ///@return The created tetrahedron
442 ///////////////////////////////////////////////////////////////////////////////
444 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
445 const SMDS_MeshNode * n2,
446 const SMDS_MeshNode * n3,
447 const SMDS_MeshNode * n4,
450 SMDS_MeshVolume* volume = 0;
451 if ( !n1 || !n2 || !n3 || !n4) return volume;
452 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
453 if(hasConstructionFaces()) {
454 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
455 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
456 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
457 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
458 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
459 myVolumes.Add(volume);
462 else if(hasConstructionEdges()) {
463 MESSAGE("Error : Not implemented");
467 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
468 myVolumes.Add(volume);
472 if (!registerElement(ID, volume)) {
473 RemoveElement(volume, false);
479 ///////////////////////////////////////////////////////////////////////////////
480 ///Create a new pyramid and add it to the mesh.
481 ///Nodes 1,2,3 and 4 define the base of the pyramid
482 ///@return The created pyramid
483 ///////////////////////////////////////////////////////////////////////////////
485 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
486 const SMDS_MeshNode * n2,
487 const SMDS_MeshNode * n3,
488 const SMDS_MeshNode * n4,
489 const SMDS_MeshNode * n5)
491 int ID = myElementIDFactory->GetFreeID();
492 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
493 if(v==NULL) myElementIDFactory->ReleaseID(ID);
497 ///////////////////////////////////////////////////////////////////////////////
498 ///Create a new pyramid and add it to the mesh.
499 ///Nodes 1,2,3 and 4 define the base of the pyramid
500 ///@param ID The ID of the new volume
501 ///@return The created pyramid or NULL if an element with this ID already exists
502 ///or if input nodes are not found.
503 ///////////////////////////////////////////////////////////////////////////////
505 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
512 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
513 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
514 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
515 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
516 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
517 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
518 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
519 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
522 ///////////////////////////////////////////////////////////////////////////////
523 ///Create a new pyramid and add it to the mesh.
524 ///Nodes 1,2,3 and 4 define the base of the pyramid
525 ///@param ID The ID of the new volume
526 ///@return The created pyramid
527 ///////////////////////////////////////////////////////////////////////////////
529 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
530 const SMDS_MeshNode * n2,
531 const SMDS_MeshNode * n3,
532 const SMDS_MeshNode * n4,
533 const SMDS_MeshNode * n5,
536 SMDS_MeshVolume* volume = 0;
537 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
538 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
539 if(hasConstructionFaces()) {
540 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
541 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
542 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
543 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
544 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
545 myVolumes.Add(volume);
546 myInfo.myNbPyramids++;
548 else if(hasConstructionEdges()) {
549 MESSAGE("Error : Not implemented");
553 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
554 myVolumes.Add(volume);
555 myInfo.myNbPyramids++;
558 if (!registerElement(ID, volume)) {
559 RemoveElement(volume, false);
565 ///////////////////////////////////////////////////////////////////////////////
566 ///Create a new prism and add it to the mesh.
567 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
568 ///@return The created prism
569 ///////////////////////////////////////////////////////////////////////////////
571 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
572 const SMDS_MeshNode * n2,
573 const SMDS_MeshNode * n3,
574 const SMDS_MeshNode * n4,
575 const SMDS_MeshNode * n5,
576 const SMDS_MeshNode * n6)
578 int ID = myElementIDFactory->GetFreeID();
579 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
580 if(v==NULL) myElementIDFactory->ReleaseID(ID);
584 ///////////////////////////////////////////////////////////////////////////////
585 ///Create a new prism and add it to the mesh.
586 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
587 ///@param ID The ID of the new volume
588 ///@return The created prism or NULL if an element with this ID already exists
589 ///or if input nodes are not found.
590 ///////////////////////////////////////////////////////////////////////////////
592 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
600 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
601 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
602 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
603 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
604 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
605 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
606 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
607 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
608 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
611 ///////////////////////////////////////////////////////////////////////////////
612 ///Create a new prism and add it to the mesh.
613 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
614 ///@param ID The ID of the new volume
615 ///@return The created prism
616 ///////////////////////////////////////////////////////////////////////////////
618 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
619 const SMDS_MeshNode * n2,
620 const SMDS_MeshNode * n3,
621 const SMDS_MeshNode * n4,
622 const SMDS_MeshNode * n5,
623 const SMDS_MeshNode * n6,
626 SMDS_MeshVolume* volume = 0;
627 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
628 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
629 if(hasConstructionFaces()) {
630 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
631 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
632 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
633 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
634 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
635 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
636 myVolumes.Add(volume);
639 else if(hasConstructionEdges()) {
640 MESSAGE("Error : Not implemented");
644 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
645 myVolumes.Add(volume);
649 if (!registerElement(ID, volume)) {
650 RemoveElement(volume, false);
656 ///////////////////////////////////////////////////////////////////////////////
657 ///Create a new hexahedron and add it to the mesh.
658 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
659 ///@return The created hexahedron
660 ///////////////////////////////////////////////////////////////////////////////
662 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
663 const SMDS_MeshNode * n2,
664 const SMDS_MeshNode * n3,
665 const SMDS_MeshNode * n4,
666 const SMDS_MeshNode * n5,
667 const SMDS_MeshNode * n6,
668 const SMDS_MeshNode * n7,
669 const SMDS_MeshNode * n8)
671 int ID = myElementIDFactory->GetFreeID();
672 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
673 if(v==NULL) myElementIDFactory->ReleaseID(ID);
677 ///////////////////////////////////////////////////////////////////////////////
678 ///Create a new hexahedron and add it to the mesh.
679 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
680 ///@param ID The ID of the new volume
681 ///@return The created hexahedron or NULL if an element with this ID already
682 ///exists or if input nodes are not found.
683 ///////////////////////////////////////////////////////////////////////////////
685 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
695 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
696 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
697 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
698 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
699 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
700 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
701 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
702 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
703 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
704 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
706 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
710 ///////////////////////////////////////////////////////////////////////////////
711 ///Create a new hexahedron and add it to the mesh.
712 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
713 ///@param ID The ID of the new volume
714 ///@return The created prism or NULL if an element with this ID already exists
715 ///or if input nodes are not found.
716 ///////////////////////////////////////////////////////////////////////////////
718 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
719 const SMDS_MeshNode * n2,
720 const SMDS_MeshNode * n3,
721 const SMDS_MeshNode * n4,
722 const SMDS_MeshNode * n5,
723 const SMDS_MeshNode * n6,
724 const SMDS_MeshNode * n7,
725 const SMDS_MeshNode * n8,
728 SMDS_MeshVolume* volume = 0;
729 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
730 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
731 if(hasConstructionFaces()) {
732 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
733 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
734 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
735 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
736 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
737 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
738 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
739 myVolumes.Add(volume);
742 else if(hasConstructionEdges()) {
743 MESSAGE("Error : Not implemented");
747 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
748 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
749 myVolumes.Add(volume);
753 if (!registerElement(ID, volume)) {
754 RemoveElement(volume, false);
760 ///////////////////////////////////////////////////////////////////////////////
761 ///Create a new tetrahedron defined by its faces and add it to the mesh.
762 ///@return The created tetrahedron
763 ///////////////////////////////////////////////////////////////////////////////
765 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
766 const SMDS_MeshFace * f2,
767 const SMDS_MeshFace * f3,
768 const SMDS_MeshFace * f4)
770 if (!hasConstructionFaces())
772 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
775 ///////////////////////////////////////////////////////////////////////////////
776 ///Create a new tetrahedron defined by its faces and add it to the mesh.
777 ///@param ID The ID of the new volume
778 ///@return The created tetrahedron
779 ///////////////////////////////////////////////////////////////////////////////
781 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
782 const SMDS_MeshFace * f2,
783 const SMDS_MeshFace * f3,
784 const SMDS_MeshFace * f4,
787 if (!hasConstructionFaces())
789 if ( !f1 || !f2 || !f3 || !f4) return 0;
790 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
791 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
792 myVolumes.Add(volume);
795 if (!registerElement(ID, volume)) {
796 RemoveElement(volume, false);
802 ///////////////////////////////////////////////////////////////////////////////
803 ///Create a new pyramid defined by its faces and add it to the mesh.
804 ///@return The created pyramid
805 ///////////////////////////////////////////////////////////////////////////////
807 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
808 const SMDS_MeshFace * f2,
809 const SMDS_MeshFace * f3,
810 const SMDS_MeshFace * f4,
811 const SMDS_MeshFace * f5)
813 if (!hasConstructionFaces())
815 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
818 ///////////////////////////////////////////////////////////////////////////////
819 ///Create a new pyramid defined by its faces and add it to the mesh.
820 ///@param ID The ID of the new volume
821 ///@return The created pyramid
822 ///////////////////////////////////////////////////////////////////////////////
824 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
825 const SMDS_MeshFace * f2,
826 const SMDS_MeshFace * f3,
827 const SMDS_MeshFace * f4,
828 const SMDS_MeshFace * f5,
831 if (!hasConstructionFaces())
833 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
834 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
835 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
836 myVolumes.Add(volume);
837 myInfo.myNbPyramids++;
839 if (!registerElement(ID, volume)) {
840 RemoveElement(volume, false);
846 ///////////////////////////////////////////////////////////////////////////////
847 ///Create a new prism defined by its faces and add it to the mesh.
848 ///@return The created prism
849 ///////////////////////////////////////////////////////////////////////////////
851 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
852 const SMDS_MeshFace * f2,
853 const SMDS_MeshFace * f3,
854 const SMDS_MeshFace * f4,
855 const SMDS_MeshFace * f5,
856 const SMDS_MeshFace * f6)
858 if (!hasConstructionFaces())
860 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
863 ///////////////////////////////////////////////////////////////////////////////
864 ///Create a new prism defined by its faces and add it to the mesh.
865 ///@param ID The ID of the new volume
866 ///@return The created prism
867 ///////////////////////////////////////////////////////////////////////////////
869 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
870 const SMDS_MeshFace * f2,
871 const SMDS_MeshFace * f3,
872 const SMDS_MeshFace * f4,
873 const SMDS_MeshFace * f5,
874 const SMDS_MeshFace * f6,
877 if (!hasConstructionFaces())
879 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
880 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
881 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
882 myVolumes.Add(volume);
885 if (!registerElement(ID, volume)) {
886 RemoveElement(volume, false);
892 ///////////////////////////////////////////////////////////////////////////////
893 /// Add a polygon defined by its nodes IDs
894 ///////////////////////////////////////////////////////////////////////////////
896 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
899 int nbNodes = nodes_ids.size();
900 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
901 for (int i = 0; i < nbNodes; i++) {
902 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
903 if (!nodes[i]) return NULL;
905 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
908 ///////////////////////////////////////////////////////////////////////////////
909 /// Add a polygon defined by its nodes
910 ///////////////////////////////////////////////////////////////////////////////
912 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
913 (std::vector<const SMDS_MeshNode*> nodes,
916 SMDS_MeshFace * face;
918 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
919 if (hasConstructionEdges())
921 MESSAGE("Error : Not implemented");
926 for ( int i = 0; i < nodes.size(); ++i )
927 if ( !nodes[ i ] ) return 0;
928 face = new SMDS_PolygonalFaceOfNodes(nodes);
930 myInfo.myNbPolygons++;
933 if (!registerElement(ID, face)) {
934 RemoveElement(face, false);
940 ///////////////////////////////////////////////////////////////////////////////
941 /// Add a polygon defined by its nodes.
942 /// An ID is automatically affected to the created face.
943 ///////////////////////////////////////////////////////////////////////////////
945 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
947 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
950 ///////////////////////////////////////////////////////////////////////////////
951 /// Create a new polyhedral volume and add it to the mesh.
952 /// @param ID The ID of the new volume
953 /// @return The created volume or NULL if an element with this ID already exists
954 /// or if input nodes are not found.
955 ///////////////////////////////////////////////////////////////////////////////
957 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
958 (std::vector<int> nodes_ids,
959 std::vector<int> quantities,
962 int nbNodes = nodes_ids.size();
963 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
964 for (int i = 0; i < nbNodes; i++) {
965 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
966 if (!nodes[i]) return NULL;
968 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
971 ///////////////////////////////////////////////////////////////////////////////
972 /// Create a new polyhedral volume and add it to the mesh.
973 /// @param ID The ID of the new volume
974 /// @return The created volume
975 ///////////////////////////////////////////////////////////////////////////////
977 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
978 (std::vector<const SMDS_MeshNode*> nodes,
979 std::vector<int> quantities,
982 SMDS_MeshVolume* volume;
983 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
984 if (hasConstructionFaces()) {
985 MESSAGE("Error : Not implemented");
987 } else if (hasConstructionEdges()) {
988 MESSAGE("Error : Not implemented");
991 for ( int i = 0; i < nodes.size(); ++i )
992 if ( !nodes[ i ] ) return 0;
993 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
994 myVolumes.Add(volume);
995 myInfo.myNbPolyhedrons++;
998 if (!registerElement(ID, volume)) {
999 RemoveElement(volume, false);
1005 ///////////////////////////////////////////////////////////////////////////////
1006 /// Create a new polyhedral volume and add it to the mesh.
1007 /// @return The created volume
1008 ///////////////////////////////////////////////////////////////////////////////
1010 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1011 (std::vector<const SMDS_MeshNode*> nodes,
1012 std::vector<int> quantities)
1014 int ID = myElementIDFactory->GetFreeID();
1015 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1016 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1020 ///////////////////////////////////////////////////////////////////////////////
1021 /// Registers element with the given ID, maintains inverse connections
1022 ///////////////////////////////////////////////////////////////////////////////
1023 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1025 if (myElementIDFactory->BindID(ID, element)) {
1026 SMDS_ElemIteratorPtr it = element->nodesIterator();
1027 while (it->more()) {
1028 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1029 (const_cast<SMDS_MeshElement*>(it->next()));
1030 node->AddInverseElement(element);
1037 ///////////////////////////////////////////////////////////////////////////////
1038 /// Return the node whose ID is 'ID'.
1039 ///////////////////////////////////////////////////////////////////////////////
1040 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1042 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1045 ///////////////////////////////////////////////////////////////////////////////
1046 ///Create a triangle and add it to the current mesh. This methode do not bind a
1047 ///ID to the create triangle.
1048 ///////////////////////////////////////////////////////////////////////////////
1049 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1050 const SMDS_MeshNode * node2,
1051 const SMDS_MeshNode * node3)
1053 if ( !node1 || !node2 || !node3) return 0;
1054 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1055 if(hasConstructionEdges())
1057 SMDS_MeshEdge *edge1, *edge2, *edge3;
1058 edge1=FindEdgeOrCreate(node1,node2);
1059 edge2=FindEdgeOrCreate(node2,node3);
1060 edge3=FindEdgeOrCreate(node3,node1);
1062 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1064 myInfo.myNbTriangles++;
1069 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1071 myInfo.myNbTriangles++;
1076 ///////////////////////////////////////////////////////////////////////////////
1077 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1078 ///a ID to the create triangle.
1079 ///////////////////////////////////////////////////////////////////////////////
1080 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1081 const SMDS_MeshNode * node2,
1082 const SMDS_MeshNode * node3,
1083 const SMDS_MeshNode * node4)
1085 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1086 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1087 if(hasConstructionEdges())
1089 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1090 edge1=FindEdgeOrCreate(node1,node2);
1091 edge2=FindEdgeOrCreate(node2,node3);
1092 edge3=FindEdgeOrCreate(node3,node4);
1093 edge4=FindEdgeOrCreate(node4,node1);
1095 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1097 myInfo.myNbQuadrangles++;
1102 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1104 myInfo.myNbQuadrangles++;
1109 ///////////////////////////////////////////////////////////////////////////////
1110 /// Remove a node and all the elements which own this node
1111 ///////////////////////////////////////////////////////////////////////////////
1113 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1115 RemoveElement(node, true);
1118 ///////////////////////////////////////////////////////////////////////////////
1119 /// Remove an edge and all the elements which own this edge
1120 ///////////////////////////////////////////////////////////////////////////////
1122 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1124 RemoveElement(edge,true);
1127 ///////////////////////////////////////////////////////////////////////////////
1128 /// Remove an face and all the elements which own this face
1129 ///////////////////////////////////////////////////////////////////////////////
1131 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1133 RemoveElement(face, true);
1136 ///////////////////////////////////////////////////////////////////////////////
1138 ///////////////////////////////////////////////////////////////////////////////
1140 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1142 RemoveElement(volume, true);
1145 //=======================================================================
1146 //function : RemoveFromParent
1148 //=======================================================================
1150 bool SMDS_Mesh::RemoveFromParent()
1152 if (myParent==NULL) return false;
1153 else return (myParent->RemoveSubMesh(this));
1156 //=======================================================================
1157 //function : RemoveSubMesh
1159 //=======================================================================
1161 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1165 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1166 for (; itmsh!=myChildren.end() && !found; itmsh++)
1168 SMDS_Mesh * submesh = *itmsh;
1169 if (submesh == aMesh)
1172 myChildren.erase(itmsh);
1179 //=======================================================================
1180 //function : ChangeElementNodes
1182 //=======================================================================
1184 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1185 const SMDS_MeshNode * nodes[],
1188 // keep current nodes of elem
1189 set<const SMDS_MeshElement*> oldNodes;
1190 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1192 oldNodes.insert( itn->next() );
1194 if ( !element->IsPoly() )
1195 myInfo.remove( element ); // element may change type
1199 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1200 switch ( elem->GetType() )
1202 case SMDSAbs_Edge: {
1203 if ( nbnodes == 2 ) {
1204 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1205 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1207 else if ( nbnodes == 3 ) {
1208 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1209 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1213 case SMDSAbs_Face: {
1214 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1215 Ok = face->ChangeNodes( nodes, nbnodes );
1217 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1218 Ok = QF->ChangeNodes( nodes, nbnodes );
1220 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1221 Ok = face->ChangeNodes(nodes, nbnodes);
1224 case SMDSAbs_Volume: {
1225 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1226 Ok = vol->ChangeNodes( nodes, nbnodes );
1228 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1229 Ok = QV->ChangeNodes( nodes, nbnodes );
1233 MESSAGE ( "WRONG ELEM TYPE");
1236 if ( Ok ) { // update InverseElements
1238 set<const SMDS_MeshElement*>::iterator it;
1240 // AddInverseElement to new nodes
1241 for ( int i = 0; i < nbnodes; i++ ) {
1242 it = oldNodes.find( nodes[i] );
1243 if ( it == oldNodes.end() )
1245 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1247 // remove from oldNodes a node that remains in elem
1248 oldNodes.erase( it );
1250 // RemoveInverseElement from the nodes removed from elem
1251 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1253 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1254 (const_cast<SMDS_MeshElement *>( *it ));
1255 n->RemoveInverseElement( elem );
1259 if ( !element->IsPoly() )
1260 myInfo.add( element ); // element may change type
1265 //=======================================================================
1266 //function : ChangePolyhedronNodes
1267 //purpose : to change nodes of polyhedral volume
1268 //=======================================================================
1269 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1270 const vector<const SMDS_MeshNode*>& nodes,
1271 const vector<int> & quantities)
1273 if (elem->GetType() != SMDSAbs_Volume) {
1274 MESSAGE("WRONG ELEM TYPE");
1278 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1283 // keep current nodes of elem
1284 set<const SMDS_MeshElement*> oldNodes;
1285 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1286 while (itn->more()) {
1287 oldNodes.insert(itn->next());
1291 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1296 // update InverseElements
1298 // AddInverseElement to new nodes
1299 int nbnodes = nodes.size();
1300 set<const SMDS_MeshElement*>::iterator it;
1301 for (int i = 0; i < nbnodes; i++) {
1302 it = oldNodes.find(nodes[i]);
1303 if (it == oldNodes.end()) {
1305 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1307 // remove from oldNodes a node that remains in elem
1312 // RemoveInverseElement from the nodes removed from elem
1313 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1314 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1315 (const_cast<SMDS_MeshElement *>( *it ));
1316 n->RemoveInverseElement(elem);
1323 //=======================================================================
1324 //function : FindEdge
1326 //=======================================================================
1328 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1330 const SMDS_MeshNode * node1=FindNode(idnode1);
1331 const SMDS_MeshNode * node2=FindNode(idnode2);
1332 if((node1==NULL)||(node2==NULL)) return NULL;
1333 return FindEdge(node1,node2);
1336 //#include "Profiler.h"
1337 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1338 const SMDS_MeshNode * node2)
1340 if ( !node1 ) return 0;
1341 const SMDS_MeshEdge * toReturn=NULL;
1344 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1347 while(it1->more()) {
1348 const SMDS_MeshElement * e = it1->next();
1349 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1350 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1359 //=======================================================================
1360 //function : FindEdgeOrCreate
1362 //=======================================================================
1364 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1365 const SMDS_MeshNode * node2)
1367 if ( !node1 || !node2) return 0;
1368 SMDS_MeshEdge * toReturn=NULL;
1369 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1370 if(toReturn==NULL) {
1371 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1372 toReturn=new SMDS_MeshEdge(node1,node2);
1373 myEdges.Add(toReturn);
1380 //=======================================================================
1381 //function : FindEdge
1383 //=======================================================================
1385 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1388 const SMDS_MeshNode * node1=FindNode(idnode1);
1389 const SMDS_MeshNode * node2=FindNode(idnode2);
1390 const SMDS_MeshNode * node3=FindNode(idnode3);
1391 return FindEdge(node1,node2,node3);
1394 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1395 const SMDS_MeshNode * node2,
1396 const SMDS_MeshNode * node3)
1398 if ( !node1 ) return 0;
1399 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1400 while(it1->more()) {
1401 const SMDS_MeshElement * e = it1->next();
1402 if ( e->NbNodes() == 3 ) {
1403 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1404 while(it2->more()) {
1405 const SMDS_MeshElement* n = it2->next();
1415 return static_cast<const SMDS_MeshEdge *> (e);
1422 //=======================================================================
1423 //function : FindFace
1425 //=======================================================================
1427 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1430 const SMDS_MeshNode * node1=FindNode(idnode1);
1431 const SMDS_MeshNode * node2=FindNode(idnode2);
1432 const SMDS_MeshNode * node3=FindNode(idnode3);
1433 return FindFace(node1, node2, node3);
1436 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1437 const SMDS_MeshNode *node2,
1438 const SMDS_MeshNode *node3)
1440 if ( !node1 ) return 0;
1441 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1442 while(it1->more()) {
1443 const SMDS_MeshElement * e = it1->next();
1444 if ( e->NbNodes() == 3 ) {
1445 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1446 while(it2->more()) {
1447 const SMDS_MeshElement* n = it2->next();
1457 return static_cast<const SMDS_MeshFace *> (e);
1463 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1464 const SMDS_MeshNode *node2,
1465 const SMDS_MeshNode *node3)
1467 SMDS_MeshFace * toReturn=NULL;
1468 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1469 if(toReturn==NULL) {
1470 toReturn = createTriangle(node1,node2,node3);
1476 //=======================================================================
1477 //function : FindFace
1479 //=======================================================================
1481 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1482 int idnode3, int idnode4) const
1484 const SMDS_MeshNode * node1=FindNode(idnode1);
1485 const SMDS_MeshNode * node2=FindNode(idnode2);
1486 const SMDS_MeshNode * node3=FindNode(idnode3);
1487 const SMDS_MeshNode * node4=FindNode(idnode4);
1488 return FindFace(node1, node2, node3, node4);
1491 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1492 const SMDS_MeshNode *node2,
1493 const SMDS_MeshNode *node3,
1494 const SMDS_MeshNode *node4)
1496 if ( !node1 ) return 0;
1497 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1498 while(it1->more()) {
1499 const SMDS_MeshElement * e = it1->next();
1500 if ( e->NbNodes() == 4 ) {
1501 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1502 while(it2->more()) {
1503 const SMDS_MeshElement* n = it2->next();
1514 return static_cast<const SMDS_MeshFace *> (e);
1520 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1521 const SMDS_MeshNode *node2,
1522 const SMDS_MeshNode *node3,
1523 const SMDS_MeshNode *node4)
1525 SMDS_MeshFace * toReturn=NULL;
1526 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1527 if(toReturn==NULL) {
1528 toReturn=createQuadrangle(node1,node2,node3,node4);
1534 //=======================================================================
1535 //function : FindFace
1536 //purpose :quadratic triangle
1537 //=======================================================================
1539 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1540 int idnode3, int idnode4,
1541 int idnode5, int idnode6) const
1543 const SMDS_MeshNode * node1 = FindNode(idnode1);
1544 const SMDS_MeshNode * node2 = FindNode(idnode2);
1545 const SMDS_MeshNode * node3 = FindNode(idnode3);
1546 const SMDS_MeshNode * node4 = FindNode(idnode4);
1547 const SMDS_MeshNode * node5 = FindNode(idnode5);
1548 const SMDS_MeshNode * node6 = FindNode(idnode6);
1549 return FindFace(node1, node2, node3, node4, node5, node6);
1552 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1553 const SMDS_MeshNode *node2,
1554 const SMDS_MeshNode *node3,
1555 const SMDS_MeshNode *node4,
1556 const SMDS_MeshNode *node5,
1557 const SMDS_MeshNode *node6)
1559 if ( !node1 ) return 0;
1560 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1561 while(it1->more()) {
1562 const SMDS_MeshElement * e = it1->next();
1563 if ( e->NbNodes() == 6 ) {
1564 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1565 while(it2->more()) {
1566 const SMDS_MeshElement* n = it2->next();
1579 return static_cast<const SMDS_MeshFace *> (e);
1586 //=======================================================================
1587 //function : FindFace
1588 //purpose : quadratic quadrangle
1589 //=======================================================================
1591 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1592 int idnode3, int idnode4,
1593 int idnode5, int idnode6,
1594 int idnode7, int idnode8) const
1596 const SMDS_MeshNode * node1 = FindNode(idnode1);
1597 const SMDS_MeshNode * node2 = FindNode(idnode2);
1598 const SMDS_MeshNode * node3 = FindNode(idnode3);
1599 const SMDS_MeshNode * node4 = FindNode(idnode4);
1600 const SMDS_MeshNode * node5 = FindNode(idnode5);
1601 const SMDS_MeshNode * node6 = FindNode(idnode6);
1602 const SMDS_MeshNode * node7 = FindNode(idnode7);
1603 const SMDS_MeshNode * node8 = FindNode(idnode8);
1604 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1607 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1608 const SMDS_MeshNode *node2,
1609 const SMDS_MeshNode *node3,
1610 const SMDS_MeshNode *node4,
1611 const SMDS_MeshNode *node5,
1612 const SMDS_MeshNode *node6,
1613 const SMDS_MeshNode *node7,
1614 const SMDS_MeshNode *node8)
1616 if ( !node1 ) return 0;
1617 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1618 while(it1->more()) {
1619 const SMDS_MeshElement * e = it1->next();
1620 if ( e->NbNodes() == 8 ) {
1621 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1622 while(it2->more()) {
1623 const SMDS_MeshElement* n = it2->next();
1638 return static_cast<const SMDS_MeshFace *> (e);
1645 //=======================================================================
1646 //function : FindElement
1648 //=======================================================================
1650 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1652 return myElementIDFactory->MeshElement(IDelem);
1655 //=======================================================================
1656 //function : FindFace
1657 //purpose : find polygon
1658 //=======================================================================
1660 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1662 int nbnodes = nodes_ids.size();
1663 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1664 for (int inode = 0; inode < nbnodes; inode++) {
1665 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1666 if (node == NULL) return NULL;
1668 return FindFace(poly_nodes);
1671 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1673 if ( nodes.size() > 2 && nodes[0] ) {
1674 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1675 while (itF->more()) {
1676 const SMDS_MeshElement* f = itF->next();
1677 if ( f->NbNodes() == nodes.size() ) {
1678 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1679 while(it2->more()) {
1680 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1686 return static_cast<const SMDS_MeshFace *> (f);
1693 //=======================================================================
1694 //function : DumpNodes
1696 //=======================================================================
1698 void SMDS_Mesh::DumpNodes() const
1700 MESSAGE("dump nodes of mesh : ");
1701 SMDS_NodeIteratorPtr itnode=nodesIterator();
1702 while(itnode->more()) MESSAGE(itnode->next());
1705 //=======================================================================
1706 //function : DumpEdges
1708 //=======================================================================
1710 void SMDS_Mesh::DumpEdges() const
1712 MESSAGE("dump edges of mesh : ");
1713 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1714 while(itedge->more()) MESSAGE(itedge->next());
1717 //=======================================================================
1718 //function : DumpFaces
1720 //=======================================================================
1722 void SMDS_Mesh::DumpFaces() const
1724 MESSAGE("dump faces of mesh : ");
1725 SMDS_FaceIteratorPtr itface=facesIterator();
1726 while(itface->more()) MESSAGE(itface->next());
1729 //=======================================================================
1730 //function : DumpVolumes
1732 //=======================================================================
1734 void SMDS_Mesh::DumpVolumes() const
1736 MESSAGE("dump volumes of mesh : ");
1737 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1738 while(itvol->more()) MESSAGE(itvol->next());
1741 //=======================================================================
1742 //function : DebugStats
1744 //=======================================================================
1746 void SMDS_Mesh::DebugStats() const
1748 MESSAGE("Debug stats of mesh : ");
1750 MESSAGE("===== NODES ====="<<NbNodes());
1751 MESSAGE("===== EDGES ====="<<NbEdges());
1752 MESSAGE("===== FACES ====="<<NbFaces());
1753 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1755 MESSAGE("End Debug stats of mesh ");
1759 SMDS_NodeIteratorPtr itnode=nodesIterator();
1760 int sizeofnodes = 0;
1761 int sizeoffaces = 0;
1763 while(itnode->more())
1765 const SMDS_MeshNode *node = itnode->next();
1767 sizeofnodes += sizeof(*node);
1769 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1772 const SMDS_MeshElement *me = it->next();
1773 sizeofnodes += sizeof(me);
1778 SMDS_FaceIteratorPtr itface=facesIterator();
1779 while(itface->more())
1781 const SMDS_MeshElement *face = itface->next();
1782 sizeoffaces += sizeof(*face);
1785 MESSAGE("total size of node elements = " << sizeofnodes);;
1786 MESSAGE("total size of face elements = " << sizeoffaces);;
1791 ///////////////////////////////////////////////////////////////////////////////
1792 /// Return the number of nodes
1793 ///////////////////////////////////////////////////////////////////////////////
1794 int SMDS_Mesh::NbNodes() const
1796 return myNodes.Size();
1799 ///////////////////////////////////////////////////////////////////////////////
1800 /// Return the number of edges (including construction edges)
1801 ///////////////////////////////////////////////////////////////////////////////
1802 int SMDS_Mesh::NbEdges() const
1804 return myEdges.Size();
1807 ///////////////////////////////////////////////////////////////////////////////
1808 /// Return the number of faces (including construction faces)
1809 ///////////////////////////////////////////////////////////////////////////////
1810 int SMDS_Mesh::NbFaces() const
1812 return myFaces.Size();
1815 ///////////////////////////////////////////////////////////////////////////////
1816 /// Return the number of volumes
1817 ///////////////////////////////////////////////////////////////////////////////
1818 int SMDS_Mesh::NbVolumes() const
1820 return myVolumes.Size();
1823 ///////////////////////////////////////////////////////////////////////////////
1824 /// Return the number of child mesh of this mesh.
1825 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1826 /// (2003-09-08) of SMESH
1827 ///////////////////////////////////////////////////////////////////////////////
1828 int SMDS_Mesh::NbSubMesh() const
1830 return myChildren.size();
1833 ///////////////////////////////////////////////////////////////////////////////
1834 /// Destroy the mesh and all its elements
1835 /// All pointer on elements owned by this mesh become illegals.
1836 ///////////////////////////////////////////////////////////////////////////////
1837 SMDS_Mesh::~SMDS_Mesh()
1839 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1840 while(itc!=myChildren.end())
1848 delete myNodeIDFactory;
1849 delete myElementIDFactory;
1853 SMDS_ElemIteratorPtr eIt = elementsIterator();
1854 while ( eIt->more() )
1855 myElementIDFactory->ReleaseID(eIt->next()->GetID());
1856 SMDS_NodeIteratorPtr itn = nodesIterator();
1858 myNodeIDFactory->ReleaseID(itn->next()->GetID());
1860 SetOfNodes::Iterator itn(myNodes);
1861 for (; itn.More(); itn.Next())
1864 SetOfEdges::Iterator ite(myEdges);
1865 for (; ite.More(); ite.Next())
1867 SMDS_MeshElement* elem = ite.Value();
1871 SetOfFaces::Iterator itf(myFaces);
1872 for (; itf.More(); itf.Next())
1874 SMDS_MeshElement* elem = itf.Value();
1878 SetOfVolumes::Iterator itv(myVolumes);
1879 for (; itv.More(); itv.Next())
1881 SMDS_MeshElement* elem = itv.Value();
1887 //================================================================================
1889 * \brief Clear all data
1891 //================================================================================
1893 void SMDS_Mesh::Clear()
1895 if (myParent!=NULL) {
1896 SMDS_ElemIteratorPtr eIt = elementsIterator();
1897 while ( eIt->more() )
1898 myElementIDFactory->ReleaseID(eIt->next()->GetID());
1899 SMDS_NodeIteratorPtr itn = nodesIterator();
1901 myNodeIDFactory->ReleaseID(itn->next()->GetID());
1904 myNodeIDFactory->Clear();
1905 myElementIDFactory->Clear();
1907 SMDS_VolumeIteratorPtr itv = volumesIterator();
1912 SMDS_FaceIteratorPtr itf = facesIterator();
1917 SMDS_EdgeIteratorPtr ite = edgesIterator();
1922 SMDS_NodeIteratorPtr itn = nodesIterator();
1927 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1928 while(itc!=myChildren.end())
1934 ///////////////////////////////////////////////////////////////////////////////
1935 /// Return true if this mesh create faces with edges.
1936 /// A false returned value mean that faces are created with nodes. A concequence
1937 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1938 ///////////////////////////////////////////////////////////////////////////////
1939 bool SMDS_Mesh::hasConstructionEdges()
1941 return myHasConstructionEdges;
1944 ///////////////////////////////////////////////////////////////////////////////
1945 /// Return true if this mesh create volumes with faces
1946 /// A false returned value mean that volumes are created with nodes or edges.
1947 /// (see hasConstructionEdges)
1948 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1950 ///////////////////////////////////////////////////////////////////////////////
1951 bool SMDS_Mesh::hasConstructionFaces()
1953 return myHasConstructionFaces;
1956 ///////////////////////////////////////////////////////////////////////////////
1957 /// Return true if nodes are linked to the finit elements, they are belonging to.
1958 /// Currently, It always return true.
1959 ///////////////////////////////////////////////////////////////////////////////
1960 bool SMDS_Mesh::hasInverseElements()
1962 return myHasInverseElements;
1965 ///////////////////////////////////////////////////////////////////////////////
1966 /// Make this mesh creating construction edges (see hasConstructionEdges)
1967 /// @param b true to have construction edges, else false.
1968 ///////////////////////////////////////////////////////////////////////////////
1969 void SMDS_Mesh::setConstructionEdges(bool b)
1971 myHasConstructionEdges=b;
1974 ///////////////////////////////////////////////////////////////////////////////
1975 /// Make this mesh creating construction faces (see hasConstructionFaces)
1976 /// @param b true to have construction faces, else false.
1977 ///////////////////////////////////////////////////////////////////////////////
1978 void SMDS_Mesh::setConstructionFaces(bool b)
1980 myHasConstructionFaces=b;
1983 ///////////////////////////////////////////////////////////////////////////////
1984 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1985 /// @param b true to link nodes to elements, else false.
1986 ///////////////////////////////////////////////////////////////////////////////
1987 void SMDS_Mesh::setInverseElements(bool b)
1989 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1990 myHasInverseElements=b;
1993 ///////////////////////////////////////////////////////////////////////////////
1994 /// Return an iterator on nodes of the current mesh factory
1995 ///////////////////////////////////////////////////////////////////////////////
1996 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1998 SMDS_ElemIteratorPtr myIterator;
2000 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
2005 return myIterator->more();
2008 const SMDS_MeshNode* next()
2010 return static_cast<const SMDS_MeshNode*>(myIterator->next());
2014 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2016 return SMDS_NodeIteratorPtr
2017 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2020 ///////////////////////////////////////////////////////////////////////////////
2021 /// Return an iterator on elements of the current mesh factory
2022 ///////////////////////////////////////////////////////////////////////////////
2023 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
2025 return myElementIDFactory->elementsIterator();
2028 ///////////////////////////////////////////////////////////////////////////////
2029 ///Return an iterator on edges of the current mesh.
2030 ///////////////////////////////////////////////////////////////////////////////
2031 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
2033 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
2034 SetOfEdges::Iterator myIterator;
2036 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
2041 while(myIterator.More())
2043 if(myIterator.Value()->GetID()!=-1)
2050 const SMDS_MeshEdge* next()
2052 const SMDS_MeshEdge* current = myIterator.Value();
2058 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2060 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
2063 ///////////////////////////////////////////////////////////////////////////////
2064 ///Return an iterator on faces of the current mesh.
2065 ///////////////////////////////////////////////////////////////////////////////
2066 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
2068 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
2069 SetOfFaces::Iterator myIterator;
2071 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
2076 while(myIterator.More())
2078 if(myIterator.Value()->GetID()!=-1)
2085 const SMDS_MeshFace* next()
2087 const SMDS_MeshFace* current = myIterator.Value();
2093 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2095 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2098 ///////////////////////////////////////////////////////////////////////////////
2099 ///Return an iterator on volumes of the current mesh.
2100 ///////////////////////////////////////////////////////////////////////////////
2101 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2103 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2104 SetOfVolumes::Iterator myIterator;
2106 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2111 return myIterator.More() != Standard_False;
2114 const SMDS_MeshVolume* next()
2116 const SMDS_MeshVolume* current = myIterator.Value();
2122 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2124 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2127 ///////////////////////////////////////////////////////////////////////////////
2128 /// Do intersection of sets (more than 2)
2129 ///////////////////////////////////////////////////////////////////////////////
2130 static set<const SMDS_MeshElement*> * intersectionOfSets(
2131 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2133 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2134 set<const SMDS_MeshElement*>* rsetB;
2136 for(int i=0; i<numberOfSets-1; i++)
2138 rsetB=new set<const SMDS_MeshElement*>();
2140 rsetA->begin(), rsetA->end(),
2141 vs[i+1].begin(), vs[i+1].end(),
2142 inserter(*rsetB, rsetB->begin()));
2149 ///////////////////////////////////////////////////////////////////////////////
2150 /// Return the list of finit elements owning the given element
2151 ///////////////////////////////////////////////////////////////////////////////
2152 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2154 int numberOfSets=element->NbNodes();
2155 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2157 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2160 while(itNodes->more())
2162 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2163 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2165 //initSet[i]=set<const SMDS_MeshElement*>();
2167 initSet[i].insert(itFe->next());
2171 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2176 ///////////////////////////////////////////////////////////////////////////////
2177 /// Return the list of nodes used only by the given elements
2178 ///////////////////////////////////////////////////////////////////////////////
2179 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2180 set<const SMDS_MeshElement*>& elements)
2182 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2183 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2185 while(itElements!=elements.end())
2187 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2190 while(itNodes->more())
2192 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2193 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2194 set<const SMDS_MeshElement*> s;
2196 s.insert(itFe->next());
2197 if(s==elements) toReturn->insert(n);
2203 ///////////////////////////////////////////////////////////////////////////////
2204 ///Find the children of an element that are made of given nodes
2205 ///@param setOfChildren The set in which matching children will be inserted
2206 ///@param element The element were to search matching children
2207 ///@param nodes The nodes that the children must have to be selected
2208 ///////////////////////////////////////////////////////////////////////////////
2209 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2210 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2213 switch(element->GetType())
2216 MESSAGE("Internal Error: This should not append");
2220 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2223 const SMDS_MeshElement * e=itn->next();
2224 if(nodes.find(e)!=nodes.end())
2226 setOfChildren.insert(element);
2233 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2236 const SMDS_MeshElement * e=itn->next();
2237 if(nodes.find(e)!=nodes.end())
2239 setOfChildren.insert(element);
2243 if(hasConstructionEdges())
2245 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2247 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2250 case SMDSAbs_Volume:
2252 if(hasConstructionFaces())
2254 SMDS_ElemIteratorPtr ite=element->facesIterator();
2256 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2258 else if(hasConstructionEdges())
2260 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2262 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2268 ///////////////////////////////////////////////////////////////////////////////
2269 ///@param elem The element to delete
2270 ///@param removenodes if true remaining nodes will be removed
2271 ///////////////////////////////////////////////////////////////////////////////
2272 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2273 const bool removenodes)
2275 list<const SMDS_MeshElement *> removedElems;
2276 list<const SMDS_MeshElement *> removedNodes;
2277 RemoveElement( elem, removedElems, removedNodes, removenodes );
2280 ///////////////////////////////////////////////////////////////////////////////
2281 ///@param elem The element to delete
2282 ///@param removedElems contains all removed elements
2283 ///@param removedNodes contains all removed nodes
2284 ///@param removenodes if true remaining nodes will be removed
2285 ///////////////////////////////////////////////////////////////////////////////
2286 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2287 list<const SMDS_MeshElement *>& removedElems,
2288 list<const SMDS_MeshElement *>& removedNodes,
2291 // get finite elements built on elem
2292 set<const SMDS_MeshElement*> * s1;
2293 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2294 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2295 elem->GetType() == SMDSAbs_Volume)
2297 s1 = new set<const SMDS_MeshElement*>();
2301 s1 = getFinitElements(elem);
2303 // get exclusive nodes (which would become free afterwards)
2304 set<const SMDS_MeshElement*> * s2;
2305 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2307 // do not remove nodes except elem
2308 s2 = new set<const SMDS_MeshElement*>();
2313 s2 = getExclusiveNodes(*s1);
2315 // form the set of finite and construction elements to remove
2316 set<const SMDS_MeshElement*> s3;
2317 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2318 while(it!=s1->end())
2320 addChildrenWithNodes(s3, *it ,*s2);
2324 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2326 // remove finite and construction elements
2330 // Remove element from <InverseElements> of its nodes
2331 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2334 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2335 (const_cast<SMDS_MeshElement *>(itn->next()));
2336 n->RemoveInverseElement( (*it) );
2339 switch((*it)->GetType())
2342 MESSAGE("Internal Error: This should not happen");
2345 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2346 (const_cast<SMDS_MeshElement*>(*it)));
2347 myInfo.RemoveEdge(*it);
2350 myFaces.Remove(static_cast<SMDS_MeshFace*>
2351 (const_cast<SMDS_MeshElement*>(*it)));
2352 myInfo.RemoveFace(*it);
2354 case SMDSAbs_Volume:
2355 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2356 (const_cast<SMDS_MeshElement*>(*it)));
2357 myInfo.RemoveVolume(*it);
2360 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2361 removedElems.push_back( (*it) );
2362 myElementIDFactory->ReleaseID((*it)->GetID());
2367 // remove exclusive (free) nodes
2371 while(it!=s2->end())
2373 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2374 myNodes.Remove(static_cast<SMDS_MeshNode*>
2375 (const_cast<SMDS_MeshElement*>(*it)));
2377 myNodeIDFactory->ReleaseID((*it)->GetID());
2378 removedNodes.push_back( (*it) );
2389 ///////////////////////////////////////////////////////////////////////////////
2390 ///@param elem The element to delete
2391 ///////////////////////////////////////////////////////////////////////////////
2392 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2394 SMDSAbs_ElementType aType = elem->GetType();
2395 if (aType == SMDSAbs_Node) {
2396 // only free node can be removed by this method
2397 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2398 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2399 if (!itFe->more()) { // free node
2400 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2402 myNodeIDFactory->ReleaseID(elem->GetID());
2406 if (hasConstructionEdges() || hasConstructionFaces())
2407 // this methods is only for meshes without descendants
2410 // Remove element from <InverseElements> of its nodes
2411 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2412 while (itn->more()) {
2413 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2414 (const_cast<SMDS_MeshElement *>(itn->next()));
2415 n->RemoveInverseElement(elem);
2418 // in meshes without descendants elements are always free
2421 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2422 (const_cast<SMDS_MeshElement*>(elem)));
2423 myInfo.RemoveEdge(elem);
2426 myFaces.Remove(static_cast<SMDS_MeshFace*>
2427 (const_cast<SMDS_MeshElement*>(elem)));
2428 myInfo.RemoveFace(elem);
2430 case SMDSAbs_Volume:
2431 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2432 (const_cast<SMDS_MeshElement*>(elem)));
2433 myInfo.RemoveVolume(elem);
2438 myElementIDFactory->ReleaseID(elem->GetID());
2444 * Checks if the element is present in mesh.
2445 * Useful to determine dead pointers.
2447 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2449 // we should not imply on validity of *elem, so iterate on containers
2450 // of all types in the hope of finding <elem> somewhere there
2451 SMDS_NodeIteratorPtr itn = nodesIterator();
2453 if (elem == itn->next())
2455 SMDS_EdgeIteratorPtr ite = edgesIterator();
2457 if (elem == ite->next())
2459 SMDS_FaceIteratorPtr itf = facesIterator();
2461 if (elem == itf->next())
2463 SMDS_VolumeIteratorPtr itv = volumesIterator();
2465 if (elem == itv->next())
2470 //=======================================================================
2471 //function : MaxNodeID
2473 //=======================================================================
2475 int SMDS_Mesh::MaxNodeID() const
2477 return myNodeIDFactory->GetMaxID();
2480 //=======================================================================
2481 //function : MinNodeID
2483 //=======================================================================
2485 int SMDS_Mesh::MinNodeID() const
2487 return myNodeIDFactory->GetMinID();
2490 //=======================================================================
2491 //function : MaxElementID
2493 //=======================================================================
2495 int SMDS_Mesh::MaxElementID() const
2497 return myElementIDFactory->GetMaxID();
2500 //=======================================================================
2501 //function : MinElementID
2503 //=======================================================================
2505 int SMDS_Mesh::MinElementID() const
2507 return myElementIDFactory->GetMinID();
2510 //=======================================================================
2511 //function : Renumber
2512 //purpose : Renumber all nodes or elements.
2513 //=======================================================================
2515 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2520 SMDS_MeshElementIDFactory * idFactory =
2521 isNodes ? myNodeIDFactory : myElementIDFactory;
2523 // get existing elements in the order of ID increasing
2524 map<int,SMDS_MeshElement*> elemMap;
2525 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2526 while ( idElemIt->more() ) {
2527 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2528 int id = elem->GetID();
2529 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2531 // release their ids
2532 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2534 // for ( ; elemIt != elemMap.end(); elemIt++ )
2536 // int id = (*elemIt).first;
2537 // idFactory->ReleaseID( id );
2541 elemIt = elemMap.begin();
2542 for ( ; elemIt != elemMap.end(); elemIt++ )
2544 idFactory->BindID( ID, (*elemIt).second );
2549 //=======================================================================
2550 //function : GetElementType
2551 //purpose : Return type of element or node with id
2552 //=======================================================================
2554 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2556 SMDS_MeshElement* elem = 0;
2558 elem = myElementIDFactory->MeshElement( id );
2560 elem = myNodeIDFactory->MeshElement( id );
2564 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2568 return elem->GetType();
2573 //********************************************************************
2574 //********************************************************************
2575 //******** *********
2576 //***** Methods for addition of quadratic elements ******
2577 //******** *********
2578 //********************************************************************
2579 //********************************************************************
2581 //=======================================================================
2582 //function : AddEdgeWithID
2584 //=======================================================================
2585 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2587 return SMDS_Mesh::AddEdgeWithID
2588 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2589 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2590 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2594 //=======================================================================
2595 //function : AddEdge
2597 //=======================================================================
2598 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2599 const SMDS_MeshNode* n2,
2600 const SMDS_MeshNode* n12)
2602 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2605 //=======================================================================
2606 //function : AddEdgeWithID
2608 //=======================================================================
2609 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2610 const SMDS_MeshNode * n2,
2611 const SMDS_MeshNode * n12,
2614 if ( !n1 || !n2 || !n12 ) return 0;
2615 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2616 if(myElementIDFactory->BindID(ID, edge)) {
2617 SMDS_MeshNode *node1,*node2, *node12;
2618 node1 = const_cast<SMDS_MeshNode*>(n1);
2619 node2 = const_cast<SMDS_MeshNode*>(n2);
2620 node12 = const_cast<SMDS_MeshNode*>(n12);
2621 node1->AddInverseElement(edge);
2622 node2->AddInverseElement(edge);
2623 node12->AddInverseElement(edge);
2625 myInfo.myNbQuadEdges++;
2635 //=======================================================================
2636 //function : AddFace
2638 //=======================================================================
2639 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2640 const SMDS_MeshNode * n2,
2641 const SMDS_MeshNode * n3,
2642 const SMDS_MeshNode * n12,
2643 const SMDS_MeshNode * n23,
2644 const SMDS_MeshNode * n31)
2646 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2647 myElementIDFactory->GetFreeID());
2650 //=======================================================================
2651 //function : AddFaceWithID
2653 //=======================================================================
2654 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2655 int n12,int n23,int n31, int ID)
2657 return SMDS_Mesh::AddFaceWithID
2658 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2659 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2660 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2661 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2662 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2663 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2667 //=======================================================================
2668 //function : AddFaceWithID
2670 //=======================================================================
2671 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2672 const SMDS_MeshNode * n2,
2673 const SMDS_MeshNode * n3,
2674 const SMDS_MeshNode * n12,
2675 const SMDS_MeshNode * n23,
2676 const SMDS_MeshNode * n31,
2679 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2680 if(hasConstructionEdges()) {
2681 // creation quadratic edges - not implemented
2684 SMDS_QuadraticFaceOfNodes* face =
2685 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2687 myInfo.myNbQuadTriangles++;
2689 if (!registerElement(ID, face)) {
2690 RemoveElement(face, false);
2697 //=======================================================================
2698 //function : AddFace
2700 //=======================================================================
2701 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2702 const SMDS_MeshNode * n2,
2703 const SMDS_MeshNode * n3,
2704 const SMDS_MeshNode * n4,
2705 const SMDS_MeshNode * n12,
2706 const SMDS_MeshNode * n23,
2707 const SMDS_MeshNode * n34,
2708 const SMDS_MeshNode * n41)
2710 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2711 myElementIDFactory->GetFreeID());
2714 //=======================================================================
2715 //function : AddFaceWithID
2717 //=======================================================================
2718 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2719 int n12,int n23,int n34,int n41, int ID)
2721 return SMDS_Mesh::AddFaceWithID
2722 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2723 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2724 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2725 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2726 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2727 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2728 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2729 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2733 //=======================================================================
2734 //function : AddFaceWithID
2736 //=======================================================================
2737 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2738 const SMDS_MeshNode * n2,
2739 const SMDS_MeshNode * n3,
2740 const SMDS_MeshNode * n4,
2741 const SMDS_MeshNode * n12,
2742 const SMDS_MeshNode * n23,
2743 const SMDS_MeshNode * n34,
2744 const SMDS_MeshNode * n41,
2747 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2748 if(hasConstructionEdges()) {
2749 // creation quadratic edges - not implemented
2751 SMDS_QuadraticFaceOfNodes* face =
2752 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2754 myInfo.myNbQuadQuadrangles++;
2756 if (!registerElement(ID, face)) {
2757 RemoveElement(face, false);
2764 //=======================================================================
2765 //function : AddVolume
2767 //=======================================================================
2768 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2769 const SMDS_MeshNode * n2,
2770 const SMDS_MeshNode * n3,
2771 const SMDS_MeshNode * n4,
2772 const SMDS_MeshNode * n12,
2773 const SMDS_MeshNode * n23,
2774 const SMDS_MeshNode * n31,
2775 const SMDS_MeshNode * n14,
2776 const SMDS_MeshNode * n24,
2777 const SMDS_MeshNode * n34)
2779 int ID = myElementIDFactory->GetFreeID();
2780 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2781 n31, n14, n24, n34, ID);
2782 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2786 //=======================================================================
2787 //function : AddVolumeWithID
2789 //=======================================================================
2790 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2791 int n12,int n23,int n31,
2792 int n14,int n24,int n34, int ID)
2794 return SMDS_Mesh::AddVolumeWithID
2795 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2796 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2797 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2798 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2799 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2800 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2801 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2802 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2803 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2804 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2808 //=======================================================================
2809 //function : AddVolumeWithID
2810 //purpose : 2d order tetrahedron of 10 nodes
2811 //=======================================================================
2812 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2813 const SMDS_MeshNode * n2,
2814 const SMDS_MeshNode * n3,
2815 const SMDS_MeshNode * n4,
2816 const SMDS_MeshNode * n12,
2817 const SMDS_MeshNode * n23,
2818 const SMDS_MeshNode * n31,
2819 const SMDS_MeshNode * n14,
2820 const SMDS_MeshNode * n24,
2821 const SMDS_MeshNode * n34,
2824 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2826 if(hasConstructionFaces()) {
2827 // creation quadratic faces - not implemented
2830 SMDS_QuadraticVolumeOfNodes * volume =
2831 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2832 myVolumes.Add(volume);
2833 myInfo.myNbQuadTetras++;
2835 if (!registerElement(ID, volume)) {
2836 RemoveElement(volume, false);
2843 //=======================================================================
2844 //function : AddVolume
2846 //=======================================================================
2847 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2848 const SMDS_MeshNode * n2,
2849 const SMDS_MeshNode * n3,
2850 const SMDS_MeshNode * n4,
2851 const SMDS_MeshNode * n5,
2852 const SMDS_MeshNode * n12,
2853 const SMDS_MeshNode * n23,
2854 const SMDS_MeshNode * n34,
2855 const SMDS_MeshNode * n41,
2856 const SMDS_MeshNode * n15,
2857 const SMDS_MeshNode * n25,
2858 const SMDS_MeshNode * n35,
2859 const SMDS_MeshNode * n45)
2861 int ID = myElementIDFactory->GetFreeID();
2862 SMDS_MeshVolume * v =
2863 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2864 n15, n25, n35, n45, ID);
2865 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2869 //=======================================================================
2870 //function : AddVolumeWithID
2872 //=======================================================================
2873 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2874 int n12,int n23,int n34,int n41,
2875 int n15,int n25,int n35,int n45, int ID)
2877 return SMDS_Mesh::AddVolumeWithID
2878 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2879 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2880 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2881 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2882 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2883 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2884 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2885 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2886 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2887 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2888 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2889 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2890 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2894 //=======================================================================
2895 //function : AddVolumeWithID
2896 //purpose : 2d order pyramid of 13 nodes
2897 //=======================================================================
2898 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2899 const SMDS_MeshNode * n2,
2900 const SMDS_MeshNode * n3,
2901 const SMDS_MeshNode * n4,
2902 const SMDS_MeshNode * n5,
2903 const SMDS_MeshNode * n12,
2904 const SMDS_MeshNode * n23,
2905 const SMDS_MeshNode * n34,
2906 const SMDS_MeshNode * n41,
2907 const SMDS_MeshNode * n15,
2908 const SMDS_MeshNode * n25,
2909 const SMDS_MeshNode * n35,
2910 const SMDS_MeshNode * n45,
2913 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2914 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2916 if(hasConstructionFaces()) {
2917 // creation quadratic faces - not implemented
2920 SMDS_QuadraticVolumeOfNodes * volume =
2921 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2922 n34,n41,n15,n25,n35,n45);
2923 myVolumes.Add(volume);
2924 myInfo.myNbQuadPyramids++;
2926 if (!registerElement(ID, volume)) {
2927 RemoveElement(volume, false);
2934 //=======================================================================
2935 //function : AddVolume
2937 //=======================================================================
2938 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2939 const SMDS_MeshNode * n2,
2940 const SMDS_MeshNode * n3,
2941 const SMDS_MeshNode * n4,
2942 const SMDS_MeshNode * n5,
2943 const SMDS_MeshNode * n6,
2944 const SMDS_MeshNode * n12,
2945 const SMDS_MeshNode * n23,
2946 const SMDS_MeshNode * n31,
2947 const SMDS_MeshNode * n45,
2948 const SMDS_MeshNode * n56,
2949 const SMDS_MeshNode * n64,
2950 const SMDS_MeshNode * n14,
2951 const SMDS_MeshNode * n25,
2952 const SMDS_MeshNode * n36)
2954 int ID = myElementIDFactory->GetFreeID();
2955 SMDS_MeshVolume * v =
2956 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2957 n45, n56, n64, n14, n25, n36, ID);
2958 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2962 //=======================================================================
2963 //function : AddVolumeWithID
2965 //=======================================================================
2966 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2967 int n4, int n5, int n6,
2968 int n12,int n23,int n31,
2969 int n45,int n56,int n64,
2970 int n14,int n25,int n36, int ID)
2972 return SMDS_Mesh::AddVolumeWithID
2973 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2974 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2975 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2976 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2977 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2978 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2979 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2980 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2981 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2982 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2983 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2984 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2985 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2986 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2991 //=======================================================================
2992 //function : AddVolumeWithID
2993 //purpose : 2d order Pentahedron with 15 nodes
2994 //=======================================================================
2995 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2996 const SMDS_MeshNode * n2,
2997 const SMDS_MeshNode * n3,
2998 const SMDS_MeshNode * n4,
2999 const SMDS_MeshNode * n5,
3000 const SMDS_MeshNode * n6,
3001 const SMDS_MeshNode * n12,
3002 const SMDS_MeshNode * n23,
3003 const SMDS_MeshNode * n31,
3004 const SMDS_MeshNode * n45,
3005 const SMDS_MeshNode * n56,
3006 const SMDS_MeshNode * n64,
3007 const SMDS_MeshNode * n14,
3008 const SMDS_MeshNode * n25,
3009 const SMDS_MeshNode * n36,
3012 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3013 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3015 if(hasConstructionFaces()) {
3016 // creation quadratic faces - not implemented
3019 SMDS_QuadraticVolumeOfNodes * volume =
3020 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3021 n45,n56,n64,n14,n25,n36);
3022 myVolumes.Add(volume);
3023 myInfo.myNbQuadPrisms++;
3025 if (!registerElement(ID, volume)) {
3026 RemoveElement(volume, false);
3033 //=======================================================================
3034 //function : AddVolume
3036 //=======================================================================
3037 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3038 const SMDS_MeshNode * n2,
3039 const SMDS_MeshNode * n3,
3040 const SMDS_MeshNode * n4,
3041 const SMDS_MeshNode * n5,
3042 const SMDS_MeshNode * n6,
3043 const SMDS_MeshNode * n7,
3044 const SMDS_MeshNode * n8,
3045 const SMDS_MeshNode * n12,
3046 const SMDS_MeshNode * n23,
3047 const SMDS_MeshNode * n34,
3048 const SMDS_MeshNode * n41,
3049 const SMDS_MeshNode * n56,
3050 const SMDS_MeshNode * n67,
3051 const SMDS_MeshNode * n78,
3052 const SMDS_MeshNode * n85,
3053 const SMDS_MeshNode * n15,
3054 const SMDS_MeshNode * n26,
3055 const SMDS_MeshNode * n37,
3056 const SMDS_MeshNode * n48)
3058 int ID = myElementIDFactory->GetFreeID();
3059 SMDS_MeshVolume * v =
3060 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3061 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3062 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3066 //=======================================================================
3067 //function : AddVolumeWithID
3069 //=======================================================================
3070 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3071 int n5, int n6, int n7, int n8,
3072 int n12,int n23,int n34,int n41,
3073 int n56,int n67,int n78,int n85,
3074 int n15,int n26,int n37,int n48, int ID)
3076 return SMDS_Mesh::AddVolumeWithID
3077 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3078 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3079 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3080 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3081 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3082 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3083 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3084 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3085 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3086 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3087 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3088 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3089 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3090 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3091 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3092 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3093 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3094 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3095 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3096 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3100 //=======================================================================
3101 //function : AddVolumeWithID
3102 //purpose : 2d order Hexahedrons with 20 nodes
3103 //=======================================================================
3104 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3105 const SMDS_MeshNode * n2,
3106 const SMDS_MeshNode * n3,
3107 const SMDS_MeshNode * n4,
3108 const SMDS_MeshNode * n5,
3109 const SMDS_MeshNode * n6,
3110 const SMDS_MeshNode * n7,
3111 const SMDS_MeshNode * n8,
3112 const SMDS_MeshNode * n12,
3113 const SMDS_MeshNode * n23,
3114 const SMDS_MeshNode * n34,
3115 const SMDS_MeshNode * n41,
3116 const SMDS_MeshNode * n56,
3117 const SMDS_MeshNode * n67,
3118 const SMDS_MeshNode * n78,
3119 const SMDS_MeshNode * n85,
3120 const SMDS_MeshNode * n15,
3121 const SMDS_MeshNode * n26,
3122 const SMDS_MeshNode * n37,
3123 const SMDS_MeshNode * n48,
3126 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3127 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3129 if(hasConstructionFaces()) {
3131 // creation quadratic faces - not implemented
3133 SMDS_QuadraticVolumeOfNodes * volume =
3134 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3135 n56,n67,n78,n85,n15,n26,n37,n48);
3136 myVolumes.Add(volume);
3137 myInfo.myNbQuadHexas++;
3139 if (!registerElement(ID, volume)) {
3140 RemoveElement(volume, false);