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())
1846 SetOfNodes::Iterator itn(myNodes);
1847 for (; itn.More(); itn.Next())
1850 SetOfEdges::Iterator ite(myEdges);
1851 for (; ite.More(); ite.Next())
1853 SMDS_MeshElement* elem = ite.Value();
1855 myElementIDFactory->ReleaseID(elem->GetID());
1859 SetOfFaces::Iterator itf(myFaces);
1860 for (; itf.More(); itf.Next())
1862 SMDS_MeshElement* elem = itf.Value();
1864 myElementIDFactory->ReleaseID(elem->GetID());
1868 SetOfVolumes::Iterator itv(myVolumes);
1869 for (; itv.More(); itv.Next())
1871 SMDS_MeshElement* elem = itv.Value();
1873 myElementIDFactory->ReleaseID(elem->GetID());
1879 delete myNodeIDFactory;
1880 delete myElementIDFactory;
1884 ///////////////////////////////////////////////////////////////////////////////
1885 /// Return true if this mesh create faces with edges.
1886 /// A false returned value mean that faces are created with nodes. A concequence
1887 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1888 ///////////////////////////////////////////////////////////////////////////////
1889 bool SMDS_Mesh::hasConstructionEdges()
1891 return myHasConstructionEdges;
1894 ///////////////////////////////////////////////////////////////////////////////
1895 /// Return true if this mesh create volumes with faces
1896 /// A false returned value mean that volumes are created with nodes or edges.
1897 /// (see hasConstructionEdges)
1898 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1900 ///////////////////////////////////////////////////////////////////////////////
1901 bool SMDS_Mesh::hasConstructionFaces()
1903 return myHasConstructionFaces;
1906 ///////////////////////////////////////////////////////////////////////////////
1907 /// Return true if nodes are linked to the finit elements, they are belonging to.
1908 /// Currently, It always return true.
1909 ///////////////////////////////////////////////////////////////////////////////
1910 bool SMDS_Mesh::hasInverseElements()
1912 return myHasInverseElements;
1915 ///////////////////////////////////////////////////////////////////////////////
1916 /// Make this mesh creating construction edges (see hasConstructionEdges)
1917 /// @param b true to have construction edges, else false.
1918 ///////////////////////////////////////////////////////////////////////////////
1919 void SMDS_Mesh::setConstructionEdges(bool b)
1921 myHasConstructionEdges=b;
1924 ///////////////////////////////////////////////////////////////////////////////
1925 /// Make this mesh creating construction faces (see hasConstructionFaces)
1926 /// @param b true to have construction faces, else false.
1927 ///////////////////////////////////////////////////////////////////////////////
1928 void SMDS_Mesh::setConstructionFaces(bool b)
1930 myHasConstructionFaces=b;
1933 ///////////////////////////////////////////////////////////////////////////////
1934 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1935 /// @param b true to link nodes to elements, else false.
1936 ///////////////////////////////////////////////////////////////////////////////
1937 void SMDS_Mesh::setInverseElements(bool b)
1939 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1940 myHasInverseElements=b;
1943 ///////////////////////////////////////////////////////////////////////////////
1944 /// Return an iterator on nodes of the current mesh factory
1945 ///////////////////////////////////////////////////////////////////////////////
1946 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1948 SMDS_ElemIteratorPtr myIterator;
1950 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1955 return myIterator->more();
1958 const SMDS_MeshNode* next()
1960 return static_cast<const SMDS_MeshNode*>(myIterator->next());
1964 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1966 return SMDS_NodeIteratorPtr
1967 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1970 ///////////////////////////////////////////////////////////////////////////////
1971 /// Return an iterator on elements of the current mesh factory
1972 ///////////////////////////////////////////////////////////////////////////////
1973 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1975 return myElementIDFactory->elementsIterator();
1978 ///////////////////////////////////////////////////////////////////////////////
1979 ///Return an iterator on edges of the current mesh.
1980 ///////////////////////////////////////////////////////////////////////////////
1981 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1983 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1984 SetOfEdges::Iterator myIterator;
1986 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1991 while(myIterator.More())
1993 if(myIterator.Value()->GetID()!=-1)
2000 const SMDS_MeshEdge* next()
2002 const SMDS_MeshEdge* current = myIterator.Value();
2008 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2010 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
2013 ///////////////////////////////////////////////////////////////////////////////
2014 ///Return an iterator on faces of the current mesh.
2015 ///////////////////////////////////////////////////////////////////////////////
2016 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
2018 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
2019 SetOfFaces::Iterator myIterator;
2021 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
2026 while(myIterator.More())
2028 if(myIterator.Value()->GetID()!=-1)
2035 const SMDS_MeshFace* next()
2037 const SMDS_MeshFace* current = myIterator.Value();
2043 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2045 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2048 ///////////////////////////////////////////////////////////////////////////////
2049 ///Return an iterator on volumes of the current mesh.
2050 ///////////////////////////////////////////////////////////////////////////////
2051 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2053 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2054 SetOfVolumes::Iterator myIterator;
2056 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2061 return myIterator.More() != Standard_False;
2064 const SMDS_MeshVolume* next()
2066 const SMDS_MeshVolume* current = myIterator.Value();
2072 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2074 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2077 ///////////////////////////////////////////////////////////////////////////////
2078 /// Do intersection of sets (more than 2)
2079 ///////////////////////////////////////////////////////////////////////////////
2080 static set<const SMDS_MeshElement*> * intersectionOfSets(
2081 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2083 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2084 set<const SMDS_MeshElement*>* rsetB;
2086 for(int i=0; i<numberOfSets-1; i++)
2088 rsetB=new set<const SMDS_MeshElement*>();
2090 rsetA->begin(), rsetA->end(),
2091 vs[i+1].begin(), vs[i+1].end(),
2092 inserter(*rsetB, rsetB->begin()));
2099 ///////////////////////////////////////////////////////////////////////////////
2100 /// Return the list of finit elements owning the given element
2101 ///////////////////////////////////////////////////////////////////////////////
2102 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2104 int numberOfSets=element->NbNodes();
2105 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2107 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2110 while(itNodes->more())
2112 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2113 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2115 //initSet[i]=set<const SMDS_MeshElement*>();
2117 initSet[i].insert(itFe->next());
2121 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2126 ///////////////////////////////////////////////////////////////////////////////
2127 /// Return the list of nodes used only by the given elements
2128 ///////////////////////////////////////////////////////////////////////////////
2129 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2130 set<const SMDS_MeshElement*>& elements)
2132 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2133 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2135 while(itElements!=elements.end())
2137 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2140 while(itNodes->more())
2142 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2143 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2144 set<const SMDS_MeshElement*> s;
2146 s.insert(itFe->next());
2147 if(s==elements) toReturn->insert(n);
2153 ///////////////////////////////////////////////////////////////////////////////
2154 ///Find the children of an element that are made of given nodes
2155 ///@param setOfChildren The set in which matching children will be inserted
2156 ///@param element The element were to search matching children
2157 ///@param nodes The nodes that the children must have to be selected
2158 ///////////////////////////////////////////////////////////////////////////////
2159 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2160 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2163 switch(element->GetType())
2166 MESSAGE("Internal Error: This should not append");
2170 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2173 const SMDS_MeshElement * e=itn->next();
2174 if(nodes.find(e)!=nodes.end())
2176 setOfChildren.insert(element);
2183 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2186 const SMDS_MeshElement * e=itn->next();
2187 if(nodes.find(e)!=nodes.end())
2189 setOfChildren.insert(element);
2193 if(hasConstructionEdges())
2195 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2197 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2200 case SMDSAbs_Volume:
2202 if(hasConstructionFaces())
2204 SMDS_ElemIteratorPtr ite=element->facesIterator();
2206 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2208 else if(hasConstructionEdges())
2210 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2212 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2218 ///////////////////////////////////////////////////////////////////////////////
2219 ///@param elem The element to delete
2220 ///@param removenodes if true remaining nodes will be removed
2221 ///////////////////////////////////////////////////////////////////////////////
2222 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2223 const bool removenodes)
2225 list<const SMDS_MeshElement *> removedElems;
2226 list<const SMDS_MeshElement *> removedNodes;
2227 RemoveElement( elem, removedElems, removedNodes, removenodes );
2230 ///////////////////////////////////////////////////////////////////////////////
2231 ///@param elem The element to delete
2232 ///@param removedElems contains all removed elements
2233 ///@param removedNodes contains all removed nodes
2234 ///@param removenodes if true remaining nodes will be removed
2235 ///////////////////////////////////////////////////////////////////////////////
2236 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2237 list<const SMDS_MeshElement *>& removedElems,
2238 list<const SMDS_MeshElement *>& removedNodes,
2241 // get finite elements built on elem
2242 set<const SMDS_MeshElement*> * s1;
2243 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2244 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2245 elem->GetType() == SMDSAbs_Volume)
2247 s1 = new set<const SMDS_MeshElement*>();
2251 s1 = getFinitElements(elem);
2253 // get exclusive nodes (which would become free afterwards)
2254 set<const SMDS_MeshElement*> * s2;
2255 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2257 // do not remove nodes except elem
2258 s2 = new set<const SMDS_MeshElement*>();
2263 s2 = getExclusiveNodes(*s1);
2265 // form the set of finite and construction elements to remove
2266 set<const SMDS_MeshElement*> s3;
2267 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2268 while(it!=s1->end())
2270 addChildrenWithNodes(s3, *it ,*s2);
2274 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2276 // remove finite and construction elements
2280 // Remove element from <InverseElements> of its nodes
2281 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2284 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2285 (const_cast<SMDS_MeshElement *>(itn->next()));
2286 n->RemoveInverseElement( (*it) );
2289 switch((*it)->GetType())
2292 MESSAGE("Internal Error: This should not happen");
2295 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2296 (const_cast<SMDS_MeshElement*>(*it)));
2297 myInfo.RemoveEdge(*it);
2300 myFaces.Remove(static_cast<SMDS_MeshFace*>
2301 (const_cast<SMDS_MeshElement*>(*it)));
2302 myInfo.RemoveFace(*it);
2304 case SMDSAbs_Volume:
2305 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2306 (const_cast<SMDS_MeshElement*>(*it)));
2307 myInfo.RemoveVolume(*it);
2310 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2311 removedElems.push_back( (*it) );
2312 myElementIDFactory->ReleaseID((*it)->GetID());
2317 // remove exclusive (free) nodes
2321 while(it!=s2->end())
2323 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2324 myNodes.Remove(static_cast<SMDS_MeshNode*>
2325 (const_cast<SMDS_MeshElement*>(*it)));
2327 myNodeIDFactory->ReleaseID((*it)->GetID());
2328 removedNodes.push_back( (*it) );
2339 ///////////////////////////////////////////////////////////////////////////////
2340 ///@param elem The element to delete
2341 ///////////////////////////////////////////////////////////////////////////////
2342 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2344 SMDSAbs_ElementType aType = elem->GetType();
2345 if (aType == SMDSAbs_Node) {
2346 // only free node can be removed by this method
2347 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2348 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2349 if (!itFe->more()) { // free node
2350 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2352 myNodeIDFactory->ReleaseID(elem->GetID());
2356 if (hasConstructionEdges() || hasConstructionFaces())
2357 // this methods is only for meshes without descendants
2360 // Remove element from <InverseElements> of its nodes
2361 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2362 while (itn->more()) {
2363 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2364 (const_cast<SMDS_MeshElement *>(itn->next()));
2365 n->RemoveInverseElement(elem);
2368 // in meshes without descendants elements are always free
2371 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2372 (const_cast<SMDS_MeshElement*>(elem)));
2373 myInfo.RemoveEdge(elem);
2376 myFaces.Remove(static_cast<SMDS_MeshFace*>
2377 (const_cast<SMDS_MeshElement*>(elem)));
2378 myInfo.RemoveFace(elem);
2380 case SMDSAbs_Volume:
2381 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2382 (const_cast<SMDS_MeshElement*>(elem)));
2383 myInfo.RemoveVolume(elem);
2388 myElementIDFactory->ReleaseID(elem->GetID());
2394 * Checks if the element is present in mesh.
2395 * Useful to determine dead pointers.
2397 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2399 // we should not imply on validity of *elem, so iterate on containers
2400 // of all types in the hope of finding <elem> somewhere there
2401 SMDS_NodeIteratorPtr itn = nodesIterator();
2403 if (elem == itn->next())
2405 SMDS_EdgeIteratorPtr ite = edgesIterator();
2407 if (elem == ite->next())
2409 SMDS_FaceIteratorPtr itf = facesIterator();
2411 if (elem == itf->next())
2413 SMDS_VolumeIteratorPtr itv = volumesIterator();
2415 if (elem == itv->next())
2420 //=======================================================================
2421 //function : MaxNodeID
2423 //=======================================================================
2425 int SMDS_Mesh::MaxNodeID() const
2427 return myNodeIDFactory->GetMaxID();
2430 //=======================================================================
2431 //function : MinNodeID
2433 //=======================================================================
2435 int SMDS_Mesh::MinNodeID() const
2437 return myNodeIDFactory->GetMinID();
2440 //=======================================================================
2441 //function : MaxElementID
2443 //=======================================================================
2445 int SMDS_Mesh::MaxElementID() const
2447 return myElementIDFactory->GetMaxID();
2450 //=======================================================================
2451 //function : MinElementID
2453 //=======================================================================
2455 int SMDS_Mesh::MinElementID() const
2457 return myElementIDFactory->GetMinID();
2460 //=======================================================================
2461 //function : Renumber
2462 //purpose : Renumber all nodes or elements.
2463 //=======================================================================
2465 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2470 SMDS_MeshElementIDFactory * idFactory =
2471 isNodes ? myNodeIDFactory : myElementIDFactory;
2473 // get existing elements in the order of ID increasing
2474 map<int,SMDS_MeshElement*> elemMap;
2475 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2476 while ( idElemIt->more() ) {
2477 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2478 int id = elem->GetID();
2479 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2481 // release their ids
2482 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2483 for ( ; elemIt != elemMap.end(); elemIt++ )
2485 int id = (*elemIt).first;
2486 idFactory->ReleaseID( id );
2490 elemIt = elemMap.begin();
2491 for ( ; elemIt != elemMap.end(); elemIt++ )
2493 idFactory->BindID( ID, (*elemIt).second );
2498 //=======================================================================
2499 //function : GetElementType
2500 //purpose : Return type of element or node with id
2501 //=======================================================================
2503 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2505 SMDS_MeshElement* elem = 0;
2507 elem = myElementIDFactory->MeshElement( id );
2509 elem = myNodeIDFactory->MeshElement( id );
2513 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2517 return elem->GetType();
2522 //********************************************************************
2523 //********************************************************************
2524 //******** *********
2525 //***** Methods for addition of quadratic elements ******
2526 //******** *********
2527 //********************************************************************
2528 //********************************************************************
2530 //=======================================================================
2531 //function : AddEdgeWithID
2533 //=======================================================================
2534 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2536 return SMDS_Mesh::AddEdgeWithID
2537 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2538 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2539 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2543 //=======================================================================
2544 //function : AddEdge
2546 //=======================================================================
2547 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2548 const SMDS_MeshNode* n2,
2549 const SMDS_MeshNode* n12)
2551 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2554 //=======================================================================
2555 //function : AddEdgeWithID
2557 //=======================================================================
2558 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2559 const SMDS_MeshNode * n2,
2560 const SMDS_MeshNode * n12,
2563 if ( !n1 || !n2 || !n12 ) return 0;
2564 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2565 if(myElementIDFactory->BindID(ID, edge)) {
2566 SMDS_MeshNode *node1,*node2, *node12;
2567 node1 = const_cast<SMDS_MeshNode*>(n1);
2568 node2 = const_cast<SMDS_MeshNode*>(n2);
2569 node12 = const_cast<SMDS_MeshNode*>(n12);
2570 node1->AddInverseElement(edge);
2571 node2->AddInverseElement(edge);
2572 node12->AddInverseElement(edge);
2574 myInfo.myNbQuadEdges++;
2584 //=======================================================================
2585 //function : AddFace
2587 //=======================================================================
2588 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2589 const SMDS_MeshNode * n2,
2590 const SMDS_MeshNode * n3,
2591 const SMDS_MeshNode * n12,
2592 const SMDS_MeshNode * n23,
2593 const SMDS_MeshNode * n31)
2595 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2596 myElementIDFactory->GetFreeID());
2599 //=======================================================================
2600 //function : AddFaceWithID
2602 //=======================================================================
2603 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2604 int n12,int n23,int n31, int ID)
2606 return SMDS_Mesh::AddFaceWithID
2607 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2608 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2609 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2610 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2611 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2612 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2616 //=======================================================================
2617 //function : AddFaceWithID
2619 //=======================================================================
2620 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2621 const SMDS_MeshNode * n2,
2622 const SMDS_MeshNode * n3,
2623 const SMDS_MeshNode * n12,
2624 const SMDS_MeshNode * n23,
2625 const SMDS_MeshNode * n31,
2628 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2629 if(hasConstructionEdges()) {
2630 // creation quadratic edges - not implemented
2633 SMDS_QuadraticFaceOfNodes* face =
2634 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2636 myInfo.myNbQuadTriangles++;
2638 if (!registerElement(ID, face)) {
2639 RemoveElement(face, false);
2646 //=======================================================================
2647 //function : AddFace
2649 //=======================================================================
2650 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2651 const SMDS_MeshNode * n2,
2652 const SMDS_MeshNode * n3,
2653 const SMDS_MeshNode * n4,
2654 const SMDS_MeshNode * n12,
2655 const SMDS_MeshNode * n23,
2656 const SMDS_MeshNode * n34,
2657 const SMDS_MeshNode * n41)
2659 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2660 myElementIDFactory->GetFreeID());
2663 //=======================================================================
2664 //function : AddFaceWithID
2666 //=======================================================================
2667 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2668 int n12,int n23,int n34,int n41, int ID)
2670 return SMDS_Mesh::AddFaceWithID
2671 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2672 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2673 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2674 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2675 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2676 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2677 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2678 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2682 //=======================================================================
2683 //function : AddFaceWithID
2685 //=======================================================================
2686 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2687 const SMDS_MeshNode * n2,
2688 const SMDS_MeshNode * n3,
2689 const SMDS_MeshNode * n4,
2690 const SMDS_MeshNode * n12,
2691 const SMDS_MeshNode * n23,
2692 const SMDS_MeshNode * n34,
2693 const SMDS_MeshNode * n41,
2696 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2697 if(hasConstructionEdges()) {
2698 // creation quadratic edges - not implemented
2700 SMDS_QuadraticFaceOfNodes* face =
2701 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2703 myInfo.myNbQuadQuadrangles++;
2705 if (!registerElement(ID, face)) {
2706 RemoveElement(face, false);
2713 //=======================================================================
2714 //function : AddVolume
2716 //=======================================================================
2717 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2718 const SMDS_MeshNode * n2,
2719 const SMDS_MeshNode * n3,
2720 const SMDS_MeshNode * n4,
2721 const SMDS_MeshNode * n12,
2722 const SMDS_MeshNode * n23,
2723 const SMDS_MeshNode * n31,
2724 const SMDS_MeshNode * n14,
2725 const SMDS_MeshNode * n24,
2726 const SMDS_MeshNode * n34)
2728 int ID = myElementIDFactory->GetFreeID();
2729 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2730 n31, n14, n24, n34, ID);
2731 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2735 //=======================================================================
2736 //function : AddVolumeWithID
2738 //=======================================================================
2739 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2740 int n12,int n23,int n31,
2741 int n14,int n24,int n34, int ID)
2743 return SMDS_Mesh::AddVolumeWithID
2744 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2745 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2746 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2747 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2748 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2749 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2750 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2751 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2752 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2753 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2757 //=======================================================================
2758 //function : AddVolumeWithID
2759 //purpose : 2d order tetrahedron of 10 nodes
2760 //=======================================================================
2761 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2762 const SMDS_MeshNode * n2,
2763 const SMDS_MeshNode * n3,
2764 const SMDS_MeshNode * n4,
2765 const SMDS_MeshNode * n12,
2766 const SMDS_MeshNode * n23,
2767 const SMDS_MeshNode * n31,
2768 const SMDS_MeshNode * n14,
2769 const SMDS_MeshNode * n24,
2770 const SMDS_MeshNode * n34,
2773 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2775 if(hasConstructionFaces()) {
2776 // creation quadratic faces - not implemented
2779 SMDS_QuadraticVolumeOfNodes * volume =
2780 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2781 myVolumes.Add(volume);
2782 myInfo.myNbQuadTetras++;
2784 if (!registerElement(ID, volume)) {
2785 RemoveElement(volume, false);
2792 //=======================================================================
2793 //function : AddVolume
2795 //=======================================================================
2796 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2797 const SMDS_MeshNode * n2,
2798 const SMDS_MeshNode * n3,
2799 const SMDS_MeshNode * n4,
2800 const SMDS_MeshNode * n5,
2801 const SMDS_MeshNode * n12,
2802 const SMDS_MeshNode * n23,
2803 const SMDS_MeshNode * n34,
2804 const SMDS_MeshNode * n41,
2805 const SMDS_MeshNode * n15,
2806 const SMDS_MeshNode * n25,
2807 const SMDS_MeshNode * n35,
2808 const SMDS_MeshNode * n45)
2810 int ID = myElementIDFactory->GetFreeID();
2811 SMDS_MeshVolume * v =
2812 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2813 n15, n25, n35, n45, ID);
2814 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2818 //=======================================================================
2819 //function : AddVolumeWithID
2821 //=======================================================================
2822 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2823 int n12,int n23,int n34,int n41,
2824 int n15,int n25,int n35,int n45, int ID)
2826 return SMDS_Mesh::AddVolumeWithID
2827 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2828 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2829 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2830 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2831 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2832 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2833 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2834 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2835 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2836 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2837 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2838 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2839 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2843 //=======================================================================
2844 //function : AddVolumeWithID
2845 //purpose : 2d order pyramid of 13 nodes
2846 //=======================================================================
2847 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(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,
2862 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2863 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2865 if(hasConstructionFaces()) {
2866 // creation quadratic faces - not implemented
2869 SMDS_QuadraticVolumeOfNodes * volume =
2870 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2871 n34,n41,n15,n25,n35,n45);
2872 myVolumes.Add(volume);
2873 myInfo.myNbQuadPyramids++;
2875 if (!registerElement(ID, volume)) {
2876 RemoveElement(volume, false);
2883 //=======================================================================
2884 //function : AddVolume
2886 //=======================================================================
2887 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2888 const SMDS_MeshNode * n2,
2889 const SMDS_MeshNode * n3,
2890 const SMDS_MeshNode * n4,
2891 const SMDS_MeshNode * n5,
2892 const SMDS_MeshNode * n6,
2893 const SMDS_MeshNode * n12,
2894 const SMDS_MeshNode * n23,
2895 const SMDS_MeshNode * n31,
2896 const SMDS_MeshNode * n45,
2897 const SMDS_MeshNode * n56,
2898 const SMDS_MeshNode * n64,
2899 const SMDS_MeshNode * n14,
2900 const SMDS_MeshNode * n25,
2901 const SMDS_MeshNode * n36)
2903 int ID = myElementIDFactory->GetFreeID();
2904 SMDS_MeshVolume * v =
2905 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2906 n45, n56, n64, n14, n25, n36, ID);
2907 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2911 //=======================================================================
2912 //function : AddVolumeWithID
2914 //=======================================================================
2915 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2916 int n4, int n5, int n6,
2917 int n12,int n23,int n31,
2918 int n45,int n56,int n64,
2919 int n14,int n25,int n36, int ID)
2921 return SMDS_Mesh::AddVolumeWithID
2922 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2923 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2924 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2925 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2926 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2927 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2928 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2929 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2930 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2931 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2932 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2933 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2934 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2935 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2936 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2940 //=======================================================================
2941 //function : AddVolumeWithID
2942 //purpose : 2d order Pentahedron with 15 nodes
2943 //=======================================================================
2944 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2945 const SMDS_MeshNode * n2,
2946 const SMDS_MeshNode * n3,
2947 const SMDS_MeshNode * n4,
2948 const SMDS_MeshNode * n5,
2949 const SMDS_MeshNode * n6,
2950 const SMDS_MeshNode * n12,
2951 const SMDS_MeshNode * n23,
2952 const SMDS_MeshNode * n31,
2953 const SMDS_MeshNode * n45,
2954 const SMDS_MeshNode * n56,
2955 const SMDS_MeshNode * n64,
2956 const SMDS_MeshNode * n14,
2957 const SMDS_MeshNode * n25,
2958 const SMDS_MeshNode * n36,
2961 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2962 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2964 if(hasConstructionFaces()) {
2965 // creation quadratic faces - not implemented
2968 SMDS_QuadraticVolumeOfNodes * volume =
2969 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2970 n45,n56,n64,n14,n25,n36);
2971 myVolumes.Add(volume);
2972 myInfo.myNbQuadPrisms++;
2974 if (!registerElement(ID, volume)) {
2975 RemoveElement(volume, false);
2982 //=======================================================================
2983 //function : AddVolume
2985 //=======================================================================
2986 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2987 const SMDS_MeshNode * n2,
2988 const SMDS_MeshNode * n3,
2989 const SMDS_MeshNode * n4,
2990 const SMDS_MeshNode * n5,
2991 const SMDS_MeshNode * n6,
2992 const SMDS_MeshNode * n7,
2993 const SMDS_MeshNode * n8,
2994 const SMDS_MeshNode * n12,
2995 const SMDS_MeshNode * n23,
2996 const SMDS_MeshNode * n34,
2997 const SMDS_MeshNode * n41,
2998 const SMDS_MeshNode * n56,
2999 const SMDS_MeshNode * n67,
3000 const SMDS_MeshNode * n78,
3001 const SMDS_MeshNode * n85,
3002 const SMDS_MeshNode * n15,
3003 const SMDS_MeshNode * n26,
3004 const SMDS_MeshNode * n37,
3005 const SMDS_MeshNode * n48)
3007 int ID = myElementIDFactory->GetFreeID();
3008 SMDS_MeshVolume * v =
3009 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3010 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3011 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3015 //=======================================================================
3016 //function : AddVolumeWithID
3018 //=======================================================================
3019 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3020 int n5, int n6, int n7, int n8,
3021 int n12,int n23,int n34,int n41,
3022 int n56,int n67,int n78,int n85,
3023 int n15,int n26,int n37,int n48, int ID)
3025 return SMDS_Mesh::AddVolumeWithID
3026 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3027 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3028 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3029 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3030 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3031 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3032 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3033 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3034 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3035 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3036 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3037 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3038 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3039 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3040 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3041 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3042 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3043 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3044 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3045 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3049 //=======================================================================
3050 //function : AddVolumeWithID
3051 //purpose : 2d order Hexahedrons with 20 nodes
3052 //=======================================================================
3053 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3054 const SMDS_MeshNode * n2,
3055 const SMDS_MeshNode * n3,
3056 const SMDS_MeshNode * n4,
3057 const SMDS_MeshNode * n5,
3058 const SMDS_MeshNode * n6,
3059 const SMDS_MeshNode * n7,
3060 const SMDS_MeshNode * n8,
3061 const SMDS_MeshNode * n12,
3062 const SMDS_MeshNode * n23,
3063 const SMDS_MeshNode * n34,
3064 const SMDS_MeshNode * n41,
3065 const SMDS_MeshNode * n56,
3066 const SMDS_MeshNode * n67,
3067 const SMDS_MeshNode * n78,
3068 const SMDS_MeshNode * n85,
3069 const SMDS_MeshNode * n15,
3070 const SMDS_MeshNode * n26,
3071 const SMDS_MeshNode * n37,
3072 const SMDS_MeshNode * n48,
3075 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3076 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3078 if(hasConstructionFaces()) {
3080 // creation quadratic faces - not implemented
3082 SMDS_QuadraticVolumeOfNodes * volume =
3083 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3084 n56,n67,n78,n85,n15,n26,n37,n48);
3085 myVolumes.Add(volume);
3086 myInfo.myNbQuadHexas++;
3088 if (!registerElement(ID, volume)) {
3089 RemoveElement(volume, false);