1 // SMESH SMDS : implementaion of Salome mesh data structure
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #pragma warning(disable:4786)
26 #include "utilities.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeOfNodes.hxx"
29 #include "SMDS_VolumeOfFaces.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_FaceOfEdges.hxx"
32 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
33 #include "SMDS_PolygonalFaceOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
43 #include <sys/sysinfo.h>
46 //================================================================================
48 * \brief Raise an exception if free memory (ram+swap) too low
49 * \param doNotRaise - if true, suppres exception, just return free memory size
50 * \retval int - amount of available memory in MB or negative number in failure case
52 //================================================================================
54 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
58 int err = sysinfo( &si );
62 static int limit = -1;
64 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
66 limit = WEXITSTATUS(status);
71 limit = int( limit * 1.5 );
73 cout << "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" << endl;
77 const unsigned long Mbyte = 1024 * 1024;
78 // compute separately to avoid overflow
80 ( si.freeram * si.mem_unit ) / Mbyte +
81 ( si.freeswap * si.mem_unit ) / Mbyte;
84 return freeMb - limit;
89 cout<<"SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" << endl;
91 throw std::bad_alloc();
97 ///////////////////////////////////////////////////////////////////////////////
98 /// Create a new mesh object
99 ///////////////////////////////////////////////////////////////////////////////
100 SMDS_Mesh::SMDS_Mesh()
102 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
103 myElementIDFactory(new SMDS_MeshElementIDFactory()),
104 myHasConstructionEdges(false), myHasConstructionFaces(false),
105 myHasInverseElements(true)
109 ///////////////////////////////////////////////////////////////////////////////
110 /// Create a new child mesh
111 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
112 /// (2003-09-08) of SMESH
113 ///////////////////////////////////////////////////////////////////////////////
114 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
115 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
116 myElementIDFactory(parent->myElementIDFactory),
117 myHasConstructionEdges(false), myHasConstructionFaces(false),
118 myHasInverseElements(true)
122 ///////////////////////////////////////////////////////////////////////////////
123 ///Create a submesh and add it to the current mesh
124 ///////////////////////////////////////////////////////////////////////////////
126 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
128 SMDS_Mesh *submesh = new SMDS_Mesh(this);
129 myChildren.insert(myChildren.end(), submesh);
133 ///////////////////////////////////////////////////////////////////////////////
134 ///create a MeshNode and add it to the current Mesh
135 ///An ID is automatically assigned to the node.
136 ///@return : The created node
137 ///////////////////////////////////////////////////////////////////////////////
139 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
141 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
144 ///////////////////////////////////////////////////////////////////////////////
145 ///create a MeshNode and add it to the current Mesh
146 ///@param ID : The ID of the MeshNode to create
147 ///@return : The created node or NULL if a node with this ID already exists
148 ///////////////////////////////////////////////////////////////////////////////
149 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
151 // find the MeshNode corresponding to ID
152 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
155 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
157 myNodeIDFactory->BindID(ID,node);
164 ///////////////////////////////////////////////////////////////////////////////
165 /// create a MeshEdge and add it to the current Mesh
166 /// @return : The created MeshEdge
167 ///////////////////////////////////////////////////////////////////////////////
169 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
171 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
172 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
173 if(!node1 || !node2) return NULL;
174 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
177 ///////////////////////////////////////////////////////////////////////////////
178 /// create a MeshEdge and add it to the current Mesh
179 /// @return : The created MeshEdge
180 ///////////////////////////////////////////////////////////////////////////////
182 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
183 const SMDS_MeshNode * node2)
185 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
188 ///////////////////////////////////////////////////////////////////////////////
189 /// Create a new edge and at it to the mesh
190 /// @param idnode1 ID of the first node
191 /// @param idnode2 ID of the second node
192 /// @param ID ID of the edge to create
193 /// @return The created edge or NULL if an element with this ID already exists or
194 /// if input nodes are not found.
195 ///////////////////////////////////////////////////////////////////////////////
197 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
198 const SMDS_MeshNode * n2,
201 if ( !n1 || !n2 ) return 0;
204 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
205 if(myElementIDFactory->BindID(ID, edge)) {
206 SMDS_MeshNode *node1,*node2;
207 node1=const_cast<SMDS_MeshNode*>(n1);
208 node2=const_cast<SMDS_MeshNode*>(n2);
209 node1->AddInverseElement(edge);
210 node2->AddInverseElement(edge);
221 ///////////////////////////////////////////////////////////////////////////////
222 /// Add a triangle defined by its nodes. An ID is automatically affected to the
224 ///////////////////////////////////////////////////////////////////////////////
226 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
227 const SMDS_MeshNode * n2,
228 const SMDS_MeshNode * n3)
230 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
233 ///////////////////////////////////////////////////////////////////////////////
234 /// Add a triangle defined by its nodes IDs
235 ///////////////////////////////////////////////////////////////////////////////
237 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
239 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
240 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
241 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
242 if(!node1 || !node2 || !node3) return NULL;
243 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
246 ///////////////////////////////////////////////////////////////////////////////
247 /// Add a triangle defined by its nodes
248 ///////////////////////////////////////////////////////////////////////////////
250 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
251 const SMDS_MeshNode * n2,
252 const SMDS_MeshNode * n3,
255 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
257 if (face && !registerElement(ID, face)) {
258 RemoveElement(face, false);
264 ///////////////////////////////////////////////////////////////////////////////
265 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
267 ///////////////////////////////////////////////////////////////////////////////
269 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
270 const SMDS_MeshNode * n2,
271 const SMDS_MeshNode * n3,
272 const SMDS_MeshNode * n4)
274 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
277 ///////////////////////////////////////////////////////////////////////////////
278 /// Add a quadrangle defined by its nodes IDs
279 ///////////////////////////////////////////////////////////////////////////////
281 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
287 SMDS_MeshNode *node1, *node2, *node3, *node4;
288 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
289 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
290 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
291 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
292 if(!node1 || !node2 || !node3 || !node4) return NULL;
293 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
296 ///////////////////////////////////////////////////////////////////////////////
297 /// Add a quadrangle defined by its nodes
298 ///////////////////////////////////////////////////////////////////////////////
300 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
301 const SMDS_MeshNode * n2,
302 const SMDS_MeshNode * n3,
303 const SMDS_MeshNode * n4,
306 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
308 if (face && !registerElement(ID, face)) {
309 RemoveElement(face, false);
315 ///////////////////////////////////////////////////////////////////////////////
316 /// Add a triangle defined by its edges. An ID is automatically assigned to the
318 ///////////////////////////////////////////////////////////////////////////////
320 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
321 const SMDS_MeshEdge * e2,
322 const SMDS_MeshEdge * e3)
324 if (!hasConstructionEdges())
326 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
329 ///////////////////////////////////////////////////////////////////////////////
330 /// Add a triangle defined by its edges
331 ///////////////////////////////////////////////////////////////////////////////
333 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
334 const SMDS_MeshEdge * e2,
335 const SMDS_MeshEdge * e3,
338 if (!hasConstructionEdges())
340 if ( !e1 || !e2 || !e3 ) return 0;
343 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
345 myInfo.myNbTriangles++;
347 if (!registerElement(ID, face)) {
348 RemoveElement(face, false);
354 ///////////////////////////////////////////////////////////////////////////////
355 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
357 ///////////////////////////////////////////////////////////////////////////////
359 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
360 const SMDS_MeshEdge * e2,
361 const SMDS_MeshEdge * e3,
362 const SMDS_MeshEdge * e4)
364 if (!hasConstructionEdges())
366 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
369 ///////////////////////////////////////////////////////////////////////////////
370 /// Add a quadrangle defined by its edges
371 ///////////////////////////////////////////////////////////////////////////////
373 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
374 const SMDS_MeshEdge * e2,
375 const SMDS_MeshEdge * e3,
376 const SMDS_MeshEdge * e4,
379 if (!hasConstructionEdges())
381 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
383 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
385 myInfo.myNbQuadrangles++;
387 if (!registerElement(ID, face))
389 RemoveElement(face, false);
395 ///////////////////////////////////////////////////////////////////////////////
396 ///Create a new tetrahedron and add it to the mesh.
397 ///@return The created tetrahedron
398 ///////////////////////////////////////////////////////////////////////////////
400 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
401 const SMDS_MeshNode * n2,
402 const SMDS_MeshNode * n3,
403 const SMDS_MeshNode * n4)
405 int ID = myElementIDFactory->GetFreeID();
406 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
407 if(v==NULL) myElementIDFactory->ReleaseID(ID);
411 ///////////////////////////////////////////////////////////////////////////////
412 ///Create a new tetrahedron and add it to the mesh.
413 ///@param ID The ID of the new volume
414 ///@return The created tetrahedron or NULL if an element with this ID already exists
415 ///or if input nodes are not found.
416 ///////////////////////////////////////////////////////////////////////////////
418 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
424 SMDS_MeshNode *node1, *node2, *node3, *node4;
425 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
426 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
427 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
428 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
429 if(!node1 || !node2 || !node3 || !node4) return NULL;
430 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
433 ///////////////////////////////////////////////////////////////////////////////
434 ///Create a new tetrahedron and add it to the mesh.
435 ///@param ID The ID of the new volume
436 ///@return The created tetrahedron
437 ///////////////////////////////////////////////////////////////////////////////
439 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
440 const SMDS_MeshNode * n2,
441 const SMDS_MeshNode * n3,
442 const SMDS_MeshNode * n4,
445 SMDS_MeshVolume* volume = 0;
446 if ( !n1 || !n2 || !n3 || !n4) return volume;
448 if(hasConstructionFaces()) {
449 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
450 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
451 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
452 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
453 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
454 myVolumes.Add(volume);
457 else if(hasConstructionEdges()) {
458 MESSAGE("Error : Not implemented");
462 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
463 myVolumes.Add(volume);
467 if (!registerElement(ID, volume)) {
468 RemoveElement(volume, false);
474 ///////////////////////////////////////////////////////////////////////////////
475 ///Create a new pyramid and add it to the mesh.
476 ///Nodes 1,2,3 and 4 define the base of the pyramid
477 ///@return The created pyramid
478 ///////////////////////////////////////////////////////////////////////////////
480 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
481 const SMDS_MeshNode * n2,
482 const SMDS_MeshNode * n3,
483 const SMDS_MeshNode * n4,
484 const SMDS_MeshNode * n5)
486 int ID = myElementIDFactory->GetFreeID();
487 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
488 if(v==NULL) myElementIDFactory->ReleaseID(ID);
492 ///////////////////////////////////////////////////////////////////////////////
493 ///Create a new pyramid and add it to the mesh.
494 ///Nodes 1,2,3 and 4 define the base of the pyramid
495 ///@param ID The ID of the new volume
496 ///@return The created pyramid or NULL if an element with this ID already exists
497 ///or if input nodes are not found.
498 ///////////////////////////////////////////////////////////////////////////////
500 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
507 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
508 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
509 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
510 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
511 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
512 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
513 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
514 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
517 ///////////////////////////////////////////////////////////////////////////////
518 ///Create a new pyramid and add it to the mesh.
519 ///Nodes 1,2,3 and 4 define the base of the pyramid
520 ///@param ID The ID of the new volume
521 ///@return The created pyramid
522 ///////////////////////////////////////////////////////////////////////////////
524 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
525 const SMDS_MeshNode * n2,
526 const SMDS_MeshNode * n3,
527 const SMDS_MeshNode * n4,
528 const SMDS_MeshNode * n5,
531 SMDS_MeshVolume* volume = 0;
532 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
534 if(hasConstructionFaces()) {
535 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
536 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
537 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
538 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
539 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
540 myVolumes.Add(volume);
541 myInfo.myNbPyramids++;
543 else if(hasConstructionEdges()) {
544 MESSAGE("Error : Not implemented");
548 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
549 myVolumes.Add(volume);
550 myInfo.myNbPyramids++;
553 if (!registerElement(ID, volume)) {
554 RemoveElement(volume, false);
560 ///////////////////////////////////////////////////////////////////////////////
561 ///Create a new prism and add it to the mesh.
562 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
563 ///@return The created prism
564 ///////////////////////////////////////////////////////////////////////////////
566 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
567 const SMDS_MeshNode * n2,
568 const SMDS_MeshNode * n3,
569 const SMDS_MeshNode * n4,
570 const SMDS_MeshNode * n5,
571 const SMDS_MeshNode * n6)
573 int ID = myElementIDFactory->GetFreeID();
574 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
575 if(v==NULL) myElementIDFactory->ReleaseID(ID);
579 ///////////////////////////////////////////////////////////////////////////////
580 ///Create a new prism and add it to the mesh.
581 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
582 ///@param ID The ID of the new volume
583 ///@return The created prism or NULL if an element with this ID already exists
584 ///or if input nodes are not found.
585 ///////////////////////////////////////////////////////////////////////////////
587 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
595 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
596 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
597 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
598 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
599 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
600 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
601 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
602 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
603 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
606 ///////////////////////////////////////////////////////////////////////////////
607 ///Create a new prism and add it to the mesh.
608 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
609 ///@param ID The ID of the new volume
610 ///@return The created prism
611 ///////////////////////////////////////////////////////////////////////////////
613 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
614 const SMDS_MeshNode * n2,
615 const SMDS_MeshNode * n3,
616 const SMDS_MeshNode * n4,
617 const SMDS_MeshNode * n5,
618 const SMDS_MeshNode * n6,
621 SMDS_MeshVolume* volume = 0;
622 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
624 if(hasConstructionFaces()) {
625 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
626 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
627 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
628 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
629 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
630 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
631 myVolumes.Add(volume);
634 else if(hasConstructionEdges()) {
635 MESSAGE("Error : Not implemented");
639 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
640 myVolumes.Add(volume);
644 if (!registerElement(ID, volume)) {
645 RemoveElement(volume, false);
651 ///////////////////////////////////////////////////////////////////////////////
652 ///Create a new hexahedron and add it to the mesh.
653 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
654 ///@return The created hexahedron
655 ///////////////////////////////////////////////////////////////////////////////
657 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
658 const SMDS_MeshNode * n2,
659 const SMDS_MeshNode * n3,
660 const SMDS_MeshNode * n4,
661 const SMDS_MeshNode * n5,
662 const SMDS_MeshNode * n6,
663 const SMDS_MeshNode * n7,
664 const SMDS_MeshNode * n8)
666 int ID = myElementIDFactory->GetFreeID();
667 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
668 if(v==NULL) myElementIDFactory->ReleaseID(ID);
672 ///////////////////////////////////////////////////////////////////////////////
673 ///Create a new hexahedron and add it to the mesh.
674 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
675 ///@param ID The ID of the new volume
676 ///@return The created hexahedron or NULL if an element with this ID already
677 ///exists or if input nodes are not found.
678 ///////////////////////////////////////////////////////////////////////////////
680 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
690 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
691 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
692 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
693 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
694 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
695 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
696 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
697 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
698 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
699 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
701 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new hexahedron and add it to the mesh.
707 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
708 ///@param ID The ID of the new volume
709 ///@return The created prism or NULL if an element with this ID already exists
710 ///or if input nodes are not found.
711 ///////////////////////////////////////////////////////////////////////////////
713 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
714 const SMDS_MeshNode * n2,
715 const SMDS_MeshNode * n3,
716 const SMDS_MeshNode * n4,
717 const SMDS_MeshNode * n5,
718 const SMDS_MeshNode * n6,
719 const SMDS_MeshNode * n7,
720 const SMDS_MeshNode * n8,
723 SMDS_MeshVolume* volume = 0;
724 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
726 if(hasConstructionFaces()) {
727 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
728 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
729 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
730 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
731 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
732 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
733 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
734 myVolumes.Add(volume);
737 else if(hasConstructionEdges()) {
738 MESSAGE("Error : Not implemented");
742 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
743 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
744 myVolumes.Add(volume);
748 if (!registerElement(ID, volume)) {
749 RemoveElement(volume, false);
755 ///////////////////////////////////////////////////////////////////////////////
756 ///Create a new tetrahedron defined by its faces and add it to the mesh.
757 ///@return The created tetrahedron
758 ///////////////////////////////////////////////////////////////////////////////
760 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
761 const SMDS_MeshFace * f2,
762 const SMDS_MeshFace * f3,
763 const SMDS_MeshFace * f4)
765 if (!hasConstructionFaces())
767 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
770 ///////////////////////////////////////////////////////////////////////////////
771 ///Create a new tetrahedron defined by its faces and add it to the mesh.
772 ///@param ID The ID of the new volume
773 ///@return The created tetrahedron
774 ///////////////////////////////////////////////////////////////////////////////
776 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
777 const SMDS_MeshFace * f2,
778 const SMDS_MeshFace * f3,
779 const SMDS_MeshFace * f4,
782 if (!hasConstructionFaces())
784 if ( !f1 || !f2 || !f3 || !f4) return 0;
786 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
787 myVolumes.Add(volume);
790 if (!registerElement(ID, volume)) {
791 RemoveElement(volume, false);
797 ///////////////////////////////////////////////////////////////////////////////
798 ///Create a new pyramid defined by its faces and add it to the mesh.
799 ///@return The created pyramid
800 ///////////////////////////////////////////////////////////////////////////////
802 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
803 const SMDS_MeshFace * f2,
804 const SMDS_MeshFace * f3,
805 const SMDS_MeshFace * f4,
806 const SMDS_MeshFace * f5)
808 if (!hasConstructionFaces())
810 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
813 ///////////////////////////////////////////////////////////////////////////////
814 ///Create a new pyramid defined by its faces and add it to the mesh.
815 ///@param ID The ID of the new volume
816 ///@return The created pyramid
817 ///////////////////////////////////////////////////////////////////////////////
819 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
820 const SMDS_MeshFace * f2,
821 const SMDS_MeshFace * f3,
822 const SMDS_MeshFace * f4,
823 const SMDS_MeshFace * f5,
826 if (!hasConstructionFaces())
828 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
830 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
831 myVolumes.Add(volume);
832 myInfo.myNbPyramids++;
834 if (!registerElement(ID, volume)) {
835 RemoveElement(volume, false);
841 ///////////////////////////////////////////////////////////////////////////////
842 ///Create a new prism defined by its faces and add it to the mesh.
843 ///@return The created prism
844 ///////////////////////////////////////////////////////////////////////////////
846 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
847 const SMDS_MeshFace * f2,
848 const SMDS_MeshFace * f3,
849 const SMDS_MeshFace * f4,
850 const SMDS_MeshFace * f5,
851 const SMDS_MeshFace * f6)
853 if (!hasConstructionFaces())
855 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
858 ///////////////////////////////////////////////////////////////////////////////
859 ///Create a new prism defined by its faces and add it to the mesh.
860 ///@param ID The ID of the new volume
861 ///@return The created prism
862 ///////////////////////////////////////////////////////////////////////////////
864 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
865 const SMDS_MeshFace * f2,
866 const SMDS_MeshFace * f3,
867 const SMDS_MeshFace * f4,
868 const SMDS_MeshFace * f5,
869 const SMDS_MeshFace * f6,
872 if (!hasConstructionFaces())
874 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
876 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
877 myVolumes.Add(volume);
880 if (!registerElement(ID, volume)) {
881 RemoveElement(volume, false);
887 ///////////////////////////////////////////////////////////////////////////////
888 /// Add a polygon defined by its nodes IDs
889 ///////////////////////////////////////////////////////////////////////////////
891 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
894 int nbNodes = nodes_ids.size();
895 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
896 for (int i = 0; i < nbNodes; i++) {
897 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
898 if (!nodes[i]) return NULL;
900 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
903 ///////////////////////////////////////////////////////////////////////////////
904 /// Add a polygon defined by its nodes
905 ///////////////////////////////////////////////////////////////////////////////
907 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
908 (std::vector<const SMDS_MeshNode*> nodes,
911 SMDS_MeshFace * face;
914 if (hasConstructionEdges())
916 MESSAGE("Error : Not implemented");
921 for ( int i = 0; i < nodes.size(); ++i )
922 if ( !nodes[ i ] ) return 0;
923 face = new SMDS_PolygonalFaceOfNodes(nodes);
925 myInfo.myNbPolygons++;
928 if (!registerElement(ID, face)) {
929 RemoveElement(face, false);
935 ///////////////////////////////////////////////////////////////////////////////
936 /// Add a polygon defined by its nodes.
937 /// An ID is automatically affected to the created face.
938 ///////////////////////////////////////////////////////////////////////////////
940 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
942 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
945 ///////////////////////////////////////////////////////////////////////////////
946 /// Create a new polyhedral volume and add it to the mesh.
947 /// @param ID The ID of the new volume
948 /// @return The created volume or NULL if an element with this ID already exists
949 /// or if input nodes are not found.
950 ///////////////////////////////////////////////////////////////////////////////
952 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
953 (std::vector<int> nodes_ids,
954 std::vector<int> quantities,
957 int nbNodes = nodes_ids.size();
958 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
959 for (int i = 0; i < nbNodes; i++) {
960 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
961 if (!nodes[i]) return NULL;
963 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
966 ///////////////////////////////////////////////////////////////////////////////
967 /// Create a new polyhedral volume and add it to the mesh.
968 /// @param ID The ID of the new volume
969 /// @return The created volume
970 ///////////////////////////////////////////////////////////////////////////////
972 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
973 (std::vector<const SMDS_MeshNode*> nodes,
974 std::vector<int> quantities,
977 SMDS_MeshVolume* volume;
979 if (hasConstructionFaces()) {
980 MESSAGE("Error : Not implemented");
982 } else if (hasConstructionEdges()) {
983 MESSAGE("Error : Not implemented");
986 for ( int i = 0; i < nodes.size(); ++i )
987 if ( !nodes[ i ] ) return 0;
988 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
989 myVolumes.Add(volume);
990 myInfo.myNbPolyhedrons++;
993 if (!registerElement(ID, volume)) {
994 RemoveElement(volume, false);
1000 ///////////////////////////////////////////////////////////////////////////////
1001 /// Create a new polyhedral volume and add it to the mesh.
1002 /// @return The created volume
1003 ///////////////////////////////////////////////////////////////////////////////
1005 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1006 (std::vector<const SMDS_MeshNode*> nodes,
1007 std::vector<int> quantities)
1009 int ID = myElementIDFactory->GetFreeID();
1010 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1011 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1015 ///////////////////////////////////////////////////////////////////////////////
1016 /// Registers element with the given ID, maintains inverse connections
1017 ///////////////////////////////////////////////////////////////////////////////
1018 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1020 if (myElementIDFactory->BindID(ID, element)) {
1021 SMDS_ElemIteratorPtr it = element->nodesIterator();
1022 while (it->more()) {
1023 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1024 (const_cast<SMDS_MeshElement*>(it->next()));
1025 node->AddInverseElement(element);
1032 ///////////////////////////////////////////////////////////////////////////////
1033 /// Return the node whose ID is 'ID'.
1034 ///////////////////////////////////////////////////////////////////////////////
1035 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1037 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1040 ///////////////////////////////////////////////////////////////////////////////
1041 ///Create a triangle and add it to the current mesh. This methode do not bind a
1042 ///ID to the create triangle.
1043 ///////////////////////////////////////////////////////////////////////////////
1044 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1045 const SMDS_MeshNode * node2,
1046 const SMDS_MeshNode * node3)
1048 if ( !node1 || !node2 || !node3) return 0;
1050 if(hasConstructionEdges())
1052 SMDS_MeshEdge *edge1, *edge2, *edge3;
1053 edge1=FindEdgeOrCreate(node1,node2);
1054 edge2=FindEdgeOrCreate(node2,node3);
1055 edge3=FindEdgeOrCreate(node3,node1);
1057 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1059 myInfo.myNbTriangles++;
1064 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1066 myInfo.myNbTriangles++;
1071 ///////////////////////////////////////////////////////////////////////////////
1072 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1073 ///a ID to the create triangle.
1074 ///////////////////////////////////////////////////////////////////////////////
1075 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1076 const SMDS_MeshNode * node2,
1077 const SMDS_MeshNode * node3,
1078 const SMDS_MeshNode * node4)
1080 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1082 if(hasConstructionEdges())
1084 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1085 edge1=FindEdgeOrCreate(node1,node2);
1086 edge2=FindEdgeOrCreate(node2,node3);
1087 edge3=FindEdgeOrCreate(node3,node4);
1088 edge4=FindEdgeOrCreate(node4,node1);
1090 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1092 myInfo.myNbQuadrangles++;
1097 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1099 myInfo.myNbQuadrangles++;
1104 ///////////////////////////////////////////////////////////////////////////////
1105 /// Remove a node and all the elements which own this node
1106 ///////////////////////////////////////////////////////////////////////////////
1108 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1110 RemoveElement(node, true);
1113 ///////////////////////////////////////////////////////////////////////////////
1114 /// Remove an edge and all the elements which own this edge
1115 ///////////////////////////////////////////////////////////////////////////////
1117 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1119 RemoveElement(edge,true);
1122 ///////////////////////////////////////////////////////////////////////////////
1123 /// Remove an face and all the elements which own this face
1124 ///////////////////////////////////////////////////////////////////////////////
1126 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1128 RemoveElement(face, true);
1131 ///////////////////////////////////////////////////////////////////////////////
1133 ///////////////////////////////////////////////////////////////////////////////
1135 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1137 RemoveElement(volume, true);
1140 //=======================================================================
1141 //function : RemoveFromParent
1143 //=======================================================================
1145 bool SMDS_Mesh::RemoveFromParent()
1147 if (myParent==NULL) return false;
1148 else return (myParent->RemoveSubMesh(this));
1151 //=======================================================================
1152 //function : RemoveSubMesh
1154 //=======================================================================
1156 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1160 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1161 for (; itmsh!=myChildren.end() && !found; itmsh++)
1163 SMDS_Mesh * submesh = *itmsh;
1164 if (submesh == aMesh)
1167 myChildren.erase(itmsh);
1174 //=======================================================================
1175 //function : ChangeElementNodes
1177 //=======================================================================
1179 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1180 const SMDS_MeshNode * nodes[],
1183 // keep current nodes of elem
1184 set<const SMDS_MeshElement*> oldNodes;
1185 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1187 oldNodes.insert( itn->next() );
1189 if ( !element->IsPoly() )
1190 myInfo.remove( element ); // element may change type
1194 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1195 switch ( elem->GetType() )
1197 case SMDSAbs_Edge: {
1198 if ( nbnodes == 2 ) {
1199 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1200 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1202 else if ( nbnodes == 3 ) {
1203 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1204 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1208 case SMDSAbs_Face: {
1209 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1210 Ok = face->ChangeNodes( nodes, nbnodes );
1212 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1213 Ok = QF->ChangeNodes( nodes, nbnodes );
1215 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1216 Ok = face->ChangeNodes(nodes, nbnodes);
1219 case SMDSAbs_Volume: {
1220 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1221 Ok = vol->ChangeNodes( nodes, nbnodes );
1223 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1224 Ok = QV->ChangeNodes( nodes, nbnodes );
1228 MESSAGE ( "WRONG ELEM TYPE");
1231 if ( Ok ) { // update InverseElements
1233 set<const SMDS_MeshElement*>::iterator it;
1235 // AddInverseElement to new nodes
1236 for ( int i = 0; i < nbnodes; i++ ) {
1237 it = oldNodes.find( nodes[i] );
1238 if ( it == oldNodes.end() )
1240 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1242 // remove from oldNodes a node that remains in elem
1243 oldNodes.erase( it );
1245 // RemoveInverseElement from the nodes removed from elem
1246 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1248 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1249 (const_cast<SMDS_MeshElement *>( *it ));
1250 n->RemoveInverseElement( elem );
1254 if ( !element->IsPoly() )
1255 myInfo.add( element ); // element may change type
1260 //=======================================================================
1261 //function : ChangePolyhedronNodes
1262 //purpose : to change nodes of polyhedral volume
1263 //=======================================================================
1264 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1265 const vector<const SMDS_MeshNode*>& nodes,
1266 const vector<int> & quantities)
1268 if (elem->GetType() != SMDSAbs_Volume) {
1269 MESSAGE("WRONG ELEM TYPE");
1273 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1278 // keep current nodes of elem
1279 set<const SMDS_MeshElement*> oldNodes;
1280 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1281 while (itn->more()) {
1282 oldNodes.insert(itn->next());
1286 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1291 // update InverseElements
1293 // AddInverseElement to new nodes
1294 int nbnodes = nodes.size();
1295 set<const SMDS_MeshElement*>::iterator it;
1296 for (int i = 0; i < nbnodes; i++) {
1297 it = oldNodes.find(nodes[i]);
1298 if (it == oldNodes.end()) {
1300 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1302 // remove from oldNodes a node that remains in elem
1307 // RemoveInverseElement from the nodes removed from elem
1308 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1309 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1310 (const_cast<SMDS_MeshElement *>( *it ));
1311 n->RemoveInverseElement(elem);
1318 //=======================================================================
1319 //function : FindEdge
1321 //=======================================================================
1323 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1325 const SMDS_MeshNode * node1=FindNode(idnode1);
1326 const SMDS_MeshNode * node2=FindNode(idnode2);
1327 if((node1==NULL)||(node2==NULL)) return NULL;
1328 return FindEdge(node1,node2);
1331 //#include "Profiler.h"
1332 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1333 const SMDS_MeshNode * node2)
1335 if ( !node1 ) return 0;
1336 const SMDS_MeshEdge * toReturn=NULL;
1339 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1342 while(it1->more()) {
1343 const SMDS_MeshElement * e = it1->next();
1344 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1345 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1354 //=======================================================================
1355 //function : FindEdgeOrCreate
1357 //=======================================================================
1359 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1360 const SMDS_MeshNode * node2)
1362 if ( !node1 || !node2) return 0;
1363 SMDS_MeshEdge * toReturn=NULL;
1364 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1365 if(toReturn==NULL) {
1367 toReturn=new SMDS_MeshEdge(node1,node2);
1368 myEdges.Add(toReturn);
1375 //=======================================================================
1376 //function : FindEdge
1378 //=======================================================================
1380 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1383 const SMDS_MeshNode * node1=FindNode(idnode1);
1384 const SMDS_MeshNode * node2=FindNode(idnode2);
1385 const SMDS_MeshNode * node3=FindNode(idnode3);
1386 return FindEdge(node1,node2,node3);
1389 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1390 const SMDS_MeshNode * node2,
1391 const SMDS_MeshNode * node3)
1393 if ( !node1 ) return 0;
1394 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1395 while(it1->more()) {
1396 const SMDS_MeshElement * e = it1->next();
1397 if ( e->NbNodes() == 3 ) {
1398 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1399 while(it2->more()) {
1400 const SMDS_MeshElement* n = it2->next();
1410 return static_cast<const SMDS_MeshEdge *> (e);
1417 //=======================================================================
1418 //function : FindFace
1420 //=======================================================================
1422 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1425 const SMDS_MeshNode * node1=FindNode(idnode1);
1426 const SMDS_MeshNode * node2=FindNode(idnode2);
1427 const SMDS_MeshNode * node3=FindNode(idnode3);
1428 return FindFace(node1, node2, node3);
1431 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1432 const SMDS_MeshNode *node2,
1433 const SMDS_MeshNode *node3)
1435 if ( !node1 ) return 0;
1436 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1437 while(it1->more()) {
1438 const SMDS_MeshElement * e = it1->next();
1439 if ( e->NbNodes() == 3 ) {
1440 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1441 while(it2->more()) {
1442 const SMDS_MeshElement* n = it2->next();
1452 return static_cast<const SMDS_MeshFace *> (e);
1458 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1459 const SMDS_MeshNode *node2,
1460 const SMDS_MeshNode *node3)
1462 SMDS_MeshFace * toReturn=NULL;
1463 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1464 if(toReturn==NULL) {
1465 toReturn = createTriangle(node1,node2,node3);
1471 //=======================================================================
1472 //function : FindFace
1474 //=======================================================================
1476 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1477 int idnode3, int idnode4) const
1479 const SMDS_MeshNode * node1=FindNode(idnode1);
1480 const SMDS_MeshNode * node2=FindNode(idnode2);
1481 const SMDS_MeshNode * node3=FindNode(idnode3);
1482 const SMDS_MeshNode * node4=FindNode(idnode4);
1483 return FindFace(node1, node2, node3, node4);
1486 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1487 const SMDS_MeshNode *node2,
1488 const SMDS_MeshNode *node3,
1489 const SMDS_MeshNode *node4)
1491 if ( !node1 ) return 0;
1492 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1493 while(it1->more()) {
1494 const SMDS_MeshElement * e = it1->next();
1495 if ( e->NbNodes() == 4 ) {
1496 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1497 while(it2->more()) {
1498 const SMDS_MeshElement* n = it2->next();
1509 return static_cast<const SMDS_MeshFace *> (e);
1515 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1516 const SMDS_MeshNode *node2,
1517 const SMDS_MeshNode *node3,
1518 const SMDS_MeshNode *node4)
1520 SMDS_MeshFace * toReturn=NULL;
1521 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1522 if(toReturn==NULL) {
1523 toReturn=createQuadrangle(node1,node2,node3,node4);
1529 //=======================================================================
1530 //function : FindFace
1531 //purpose :quadratic triangle
1532 //=======================================================================
1534 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1535 int idnode3, int idnode4,
1536 int idnode5, int idnode6) const
1538 const SMDS_MeshNode * node1 = FindNode(idnode1);
1539 const SMDS_MeshNode * node2 = FindNode(idnode2);
1540 const SMDS_MeshNode * node3 = FindNode(idnode3);
1541 const SMDS_MeshNode * node4 = FindNode(idnode4);
1542 const SMDS_MeshNode * node5 = FindNode(idnode5);
1543 const SMDS_MeshNode * node6 = FindNode(idnode6);
1544 return FindFace(node1, node2, node3, node4, node5, node6);
1547 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1548 const SMDS_MeshNode *node2,
1549 const SMDS_MeshNode *node3,
1550 const SMDS_MeshNode *node4,
1551 const SMDS_MeshNode *node5,
1552 const SMDS_MeshNode *node6)
1554 if ( !node1 ) return 0;
1555 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1556 while(it1->more()) {
1557 const SMDS_MeshElement * e = it1->next();
1558 if ( e->NbNodes() == 6 ) {
1559 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1560 while(it2->more()) {
1561 const SMDS_MeshElement* n = it2->next();
1574 return static_cast<const SMDS_MeshFace *> (e);
1581 //=======================================================================
1582 //function : FindFace
1583 //purpose : quadratic quadrangle
1584 //=======================================================================
1586 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1587 int idnode3, int idnode4,
1588 int idnode5, int idnode6,
1589 int idnode7, int idnode8) const
1591 const SMDS_MeshNode * node1 = FindNode(idnode1);
1592 const SMDS_MeshNode * node2 = FindNode(idnode2);
1593 const SMDS_MeshNode * node3 = FindNode(idnode3);
1594 const SMDS_MeshNode * node4 = FindNode(idnode4);
1595 const SMDS_MeshNode * node5 = FindNode(idnode5);
1596 const SMDS_MeshNode * node6 = FindNode(idnode6);
1597 const SMDS_MeshNode * node7 = FindNode(idnode7);
1598 const SMDS_MeshNode * node8 = FindNode(idnode8);
1599 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1602 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1603 const SMDS_MeshNode *node2,
1604 const SMDS_MeshNode *node3,
1605 const SMDS_MeshNode *node4,
1606 const SMDS_MeshNode *node5,
1607 const SMDS_MeshNode *node6,
1608 const SMDS_MeshNode *node7,
1609 const SMDS_MeshNode *node8)
1611 if ( !node1 ) return 0;
1612 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1613 while(it1->more()) {
1614 const SMDS_MeshElement * e = it1->next();
1615 if ( e->NbNodes() == 8 ) {
1616 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1617 while(it2->more()) {
1618 const SMDS_MeshElement* n = it2->next();
1633 return static_cast<const SMDS_MeshFace *> (e);
1640 //=======================================================================
1641 //function : FindElement
1643 //=======================================================================
1645 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1647 return myElementIDFactory->MeshElement(IDelem);
1650 //=======================================================================
1651 //function : FindFace
1652 //purpose : find polygon
1653 //=======================================================================
1655 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1657 int nbnodes = nodes_ids.size();
1658 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1659 for (int inode = 0; inode < nbnodes; inode++) {
1660 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1661 if (node == NULL) return NULL;
1663 return FindFace(poly_nodes);
1666 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1668 if ( nodes.size() > 2 && nodes[0] ) {
1669 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1670 while (itF->more()) {
1671 const SMDS_MeshElement* f = itF->next();
1672 if ( f->NbNodes() == nodes.size() ) {
1673 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1674 while(it2->more()) {
1675 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1681 return static_cast<const SMDS_MeshFace *> (f);
1688 //=======================================================================
1689 //function : DumpNodes
1691 //=======================================================================
1693 void SMDS_Mesh::DumpNodes() const
1695 MESSAGE("dump nodes of mesh : ");
1696 SMDS_NodeIteratorPtr itnode=nodesIterator();
1697 while(itnode->more()) MESSAGE(itnode->next());
1700 //=======================================================================
1701 //function : DumpEdges
1703 //=======================================================================
1705 void SMDS_Mesh::DumpEdges() const
1707 MESSAGE("dump edges of mesh : ");
1708 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1709 while(itedge->more()) MESSAGE(itedge->next());
1712 //=======================================================================
1713 //function : DumpFaces
1715 //=======================================================================
1717 void SMDS_Mesh::DumpFaces() const
1719 MESSAGE("dump faces of mesh : ");
1720 SMDS_FaceIteratorPtr itface=facesIterator();
1721 while(itface->more()) MESSAGE(itface->next());
1724 //=======================================================================
1725 //function : DumpVolumes
1727 //=======================================================================
1729 void SMDS_Mesh::DumpVolumes() const
1731 MESSAGE("dump volumes of mesh : ");
1732 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1733 while(itvol->more()) MESSAGE(itvol->next());
1736 //=======================================================================
1737 //function : DebugStats
1739 //=======================================================================
1741 void SMDS_Mesh::DebugStats() const
1743 MESSAGE("Debug stats of mesh : ");
1745 MESSAGE("===== NODES ====="<<NbNodes());
1746 MESSAGE("===== EDGES ====="<<NbEdges());
1747 MESSAGE("===== FACES ====="<<NbFaces());
1748 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1750 MESSAGE("End Debug stats of mesh ");
1754 SMDS_NodeIteratorPtr itnode=nodesIterator();
1755 int sizeofnodes = 0;
1756 int sizeoffaces = 0;
1758 while(itnode->more())
1760 const SMDS_MeshNode *node = itnode->next();
1762 sizeofnodes += sizeof(*node);
1764 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1767 const SMDS_MeshElement *me = it->next();
1768 sizeofnodes += sizeof(me);
1773 SMDS_FaceIteratorPtr itface=facesIterator();
1774 while(itface->more())
1776 const SMDS_MeshElement *face = itface->next();
1777 sizeoffaces += sizeof(*face);
1780 MESSAGE("total size of node elements = " << sizeofnodes);;
1781 MESSAGE("total size of face elements = " << sizeoffaces);;
1786 ///////////////////////////////////////////////////////////////////////////////
1787 /// Return the number of nodes
1788 ///////////////////////////////////////////////////////////////////////////////
1789 int SMDS_Mesh::NbNodes() const
1791 return myNodes.Size();
1794 ///////////////////////////////////////////////////////////////////////////////
1795 /// Return the number of edges (including construction edges)
1796 ///////////////////////////////////////////////////////////////////////////////
1797 int SMDS_Mesh::NbEdges() const
1799 return myEdges.Size();
1802 ///////////////////////////////////////////////////////////////////////////////
1803 /// Return the number of faces (including construction faces)
1804 ///////////////////////////////////////////////////////////////////////////////
1805 int SMDS_Mesh::NbFaces() const
1807 return myFaces.Size();
1810 ///////////////////////////////////////////////////////////////////////////////
1811 /// Return the number of volumes
1812 ///////////////////////////////////////////////////////////////////////////////
1813 int SMDS_Mesh::NbVolumes() const
1815 return myVolumes.Size();
1818 ///////////////////////////////////////////////////////////////////////////////
1819 /// Return the number of child mesh of this mesh.
1820 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1821 /// (2003-09-08) of SMESH
1822 ///////////////////////////////////////////////////////////////////////////////
1823 int SMDS_Mesh::NbSubMesh() const
1825 return myChildren.size();
1828 ///////////////////////////////////////////////////////////////////////////////
1829 /// Destroy the mesh and all its elements
1830 /// All pointer on elements owned by this mesh become illegals.
1831 ///////////////////////////////////////////////////////////////////////////////
1832 SMDS_Mesh::~SMDS_Mesh()
1834 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1835 while(itc!=myChildren.end())
1841 SetOfNodes::Iterator itn(myNodes);
1842 for (; itn.More(); itn.Next())
1845 SetOfEdges::Iterator ite(myEdges);
1846 for (; ite.More(); ite.Next())
1848 SMDS_MeshElement* elem = ite.Value();
1850 myElementIDFactory->ReleaseID(elem->GetID());
1854 SetOfFaces::Iterator itf(myFaces);
1855 for (; itf.More(); itf.Next())
1857 SMDS_MeshElement* elem = itf.Value();
1859 myElementIDFactory->ReleaseID(elem->GetID());
1863 SetOfVolumes::Iterator itv(myVolumes);
1864 for (; itv.More(); itv.Next())
1866 SMDS_MeshElement* elem = itv.Value();
1868 myElementIDFactory->ReleaseID(elem->GetID());
1874 delete myNodeIDFactory;
1875 delete myElementIDFactory;
1879 ///////////////////////////////////////////////////////////////////////////////
1880 /// Return true if this mesh create faces with edges.
1881 /// A false returned value mean that faces are created with nodes. A concequence
1882 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1883 ///////////////////////////////////////////////////////////////////////////////
1884 bool SMDS_Mesh::hasConstructionEdges()
1886 return myHasConstructionEdges;
1889 ///////////////////////////////////////////////////////////////////////////////
1890 /// Return true if this mesh create volumes with faces
1891 /// A false returned value mean that volumes are created with nodes or edges.
1892 /// (see hasConstructionEdges)
1893 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1895 ///////////////////////////////////////////////////////////////////////////////
1896 bool SMDS_Mesh::hasConstructionFaces()
1898 return myHasConstructionFaces;
1901 ///////////////////////////////////////////////////////////////////////////////
1902 /// Return true if nodes are linked to the finit elements, they are belonging to.
1903 /// Currently, It always return true.
1904 ///////////////////////////////////////////////////////////////////////////////
1905 bool SMDS_Mesh::hasInverseElements()
1907 return myHasInverseElements;
1910 ///////////////////////////////////////////////////////////////////////////////
1911 /// Make this mesh creating construction edges (see hasConstructionEdges)
1912 /// @param b true to have construction edges, else false.
1913 ///////////////////////////////////////////////////////////////////////////////
1914 void SMDS_Mesh::setConstructionEdges(bool b)
1916 myHasConstructionEdges=b;
1919 ///////////////////////////////////////////////////////////////////////////////
1920 /// Make this mesh creating construction faces (see hasConstructionFaces)
1921 /// @param b true to have construction faces, else false.
1922 ///////////////////////////////////////////////////////////////////////////////
1923 void SMDS_Mesh::setConstructionFaces(bool b)
1925 myHasConstructionFaces=b;
1928 ///////////////////////////////////////////////////////////////////////////////
1929 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1930 /// @param b true to link nodes to elements, else false.
1931 ///////////////////////////////////////////////////////////////////////////////
1932 void SMDS_Mesh::setInverseElements(bool b)
1934 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1935 myHasInverseElements=b;
1938 ///////////////////////////////////////////////////////////////////////////////
1939 /// Return an iterator on nodes of the current mesh factory
1940 ///////////////////////////////////////////////////////////////////////////////
1941 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1943 SMDS_ElemIteratorPtr myIterator;
1945 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1950 return myIterator->more();
1953 const SMDS_MeshNode* next()
1955 return static_cast<const SMDS_MeshNode*>(myIterator->next());
1959 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1961 return SMDS_NodeIteratorPtr
1962 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1965 ///////////////////////////////////////////////////////////////////////////////
1966 /// Return an iterator on elements of the current mesh factory
1967 ///////////////////////////////////////////////////////////////////////////////
1968 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1970 return myElementIDFactory->elementsIterator();
1973 ///////////////////////////////////////////////////////////////////////////////
1974 ///Return an iterator on edges of the current mesh.
1975 ///////////////////////////////////////////////////////////////////////////////
1976 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1978 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1979 SetOfEdges::Iterator myIterator;
1981 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1986 while(myIterator.More())
1988 if(myIterator.Value()->GetID()!=-1)
1995 const SMDS_MeshEdge* next()
1997 const SMDS_MeshEdge* current = myIterator.Value();
2003 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2005 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
2008 ///////////////////////////////////////////////////////////////////////////////
2009 ///Return an iterator on faces of the current mesh.
2010 ///////////////////////////////////////////////////////////////////////////////
2011 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
2013 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
2014 SetOfFaces::Iterator myIterator;
2016 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
2021 while(myIterator.More())
2023 if(myIterator.Value()->GetID()!=-1)
2030 const SMDS_MeshFace* next()
2032 const SMDS_MeshFace* current = myIterator.Value();
2038 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2040 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2043 ///////////////////////////////////////////////////////////////////////////////
2044 ///Return an iterator on volumes of the current mesh.
2045 ///////////////////////////////////////////////////////////////////////////////
2046 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2048 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2049 SetOfVolumes::Iterator myIterator;
2051 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2056 return myIterator.More() != Standard_False;
2059 const SMDS_MeshVolume* next()
2061 const SMDS_MeshVolume* current = myIterator.Value();
2067 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2069 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2072 ///////////////////////////////////////////////////////////////////////////////
2073 /// Do intersection of sets (more than 2)
2074 ///////////////////////////////////////////////////////////////////////////////
2075 static set<const SMDS_MeshElement*> * intersectionOfSets(
2076 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2078 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2079 set<const SMDS_MeshElement*>* rsetB;
2081 for(int i=0; i<numberOfSets-1; i++)
2083 rsetB=new set<const SMDS_MeshElement*>();
2085 rsetA->begin(), rsetA->end(),
2086 vs[i+1].begin(), vs[i+1].end(),
2087 inserter(*rsetB, rsetB->begin()));
2094 ///////////////////////////////////////////////////////////////////////////////
2095 /// Return the list of finit elements owning the given element
2096 ///////////////////////////////////////////////////////////////////////////////
2097 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2099 int numberOfSets=element->NbNodes();
2100 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2102 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2105 while(itNodes->more())
2107 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2108 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2110 //initSet[i]=set<const SMDS_MeshElement*>();
2112 initSet[i].insert(itFe->next());
2116 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2121 ///////////////////////////////////////////////////////////////////////////////
2122 /// Return the list of nodes used only by the given elements
2123 ///////////////////////////////////////////////////////////////////////////////
2124 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2125 set<const SMDS_MeshElement*>& elements)
2127 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2128 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2130 while(itElements!=elements.end())
2132 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2135 while(itNodes->more())
2137 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2138 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2139 set<const SMDS_MeshElement*> s;
2141 s.insert(itFe->next());
2142 if(s==elements) toReturn->insert(n);
2148 ///////////////////////////////////////////////////////////////////////////////
2149 ///Find the children of an element that are made of given nodes
2150 ///@param setOfChildren The set in which matching children will be inserted
2151 ///@param element The element were to search matching children
2152 ///@param nodes The nodes that the children must have to be selected
2153 ///////////////////////////////////////////////////////////////////////////////
2154 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2155 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2158 switch(element->GetType())
2161 MESSAGE("Internal Error: This should not append");
2165 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2168 const SMDS_MeshElement * e=itn->next();
2169 if(nodes.find(e)!=nodes.end())
2171 setOfChildren.insert(element);
2178 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2181 const SMDS_MeshElement * e=itn->next();
2182 if(nodes.find(e)!=nodes.end())
2184 setOfChildren.insert(element);
2188 if(hasConstructionEdges())
2190 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2192 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2195 case SMDSAbs_Volume:
2197 if(hasConstructionFaces())
2199 SMDS_ElemIteratorPtr ite=element->facesIterator();
2201 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2203 else if(hasConstructionEdges())
2205 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2207 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2213 ///////////////////////////////////////////////////////////////////////////////
2214 ///@param elem The element to delete
2215 ///@param removenodes if true remaining nodes will be removed
2216 ///////////////////////////////////////////////////////////////////////////////
2217 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2218 const bool removenodes)
2220 list<const SMDS_MeshElement *> removedElems;
2221 list<const SMDS_MeshElement *> removedNodes;
2222 RemoveElement( elem, removedElems, removedNodes, removenodes );
2225 ///////////////////////////////////////////////////////////////////////////////
2226 ///@param elem The element to delete
2227 ///@param removedElems contains all removed elements
2228 ///@param removedNodes contains all removed nodes
2229 ///@param removenodes if true remaining nodes will be removed
2230 ///////////////////////////////////////////////////////////////////////////////
2231 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2232 list<const SMDS_MeshElement *>& removedElems,
2233 list<const SMDS_MeshElement *>& removedNodes,
2236 // get finite elements built on elem
2237 set<const SMDS_MeshElement*> * s1;
2238 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2239 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2240 elem->GetType() == SMDSAbs_Volume)
2242 s1 = new set<const SMDS_MeshElement*>();
2246 s1 = getFinitElements(elem);
2248 // get exclusive nodes (which would become free afterwards)
2249 set<const SMDS_MeshElement*> * s2;
2250 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2252 // do not remove nodes except elem
2253 s2 = new set<const SMDS_MeshElement*>();
2258 s2 = getExclusiveNodes(*s1);
2260 // form the set of finite and construction elements to remove
2261 set<const SMDS_MeshElement*> s3;
2262 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2263 while(it!=s1->end())
2265 addChildrenWithNodes(s3, *it ,*s2);
2269 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2271 // remove finite and construction elements
2275 // Remove element from <InverseElements> of its nodes
2276 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2279 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2280 (const_cast<SMDS_MeshElement *>(itn->next()));
2281 n->RemoveInverseElement( (*it) );
2284 switch((*it)->GetType())
2287 MESSAGE("Internal Error: This should not happen");
2290 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2291 (const_cast<SMDS_MeshElement*>(*it)));
2292 myInfo.RemoveEdge(*it);
2295 myFaces.Remove(static_cast<SMDS_MeshFace*>
2296 (const_cast<SMDS_MeshElement*>(*it)));
2297 myInfo.RemoveFace(*it);
2299 case SMDSAbs_Volume:
2300 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2301 (const_cast<SMDS_MeshElement*>(*it)));
2302 myInfo.RemoveVolume(*it);
2305 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2306 removedElems.push_back( (*it) );
2307 myElementIDFactory->ReleaseID((*it)->GetID());
2312 // remove exclusive (free) nodes
2316 while(it!=s2->end())
2318 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2319 myNodes.Remove(static_cast<SMDS_MeshNode*>
2320 (const_cast<SMDS_MeshElement*>(*it)));
2322 myNodeIDFactory->ReleaseID((*it)->GetID());
2323 removedNodes.push_back( (*it) );
2334 ///////////////////////////////////////////////////////////////////////////////
2335 ///@param elem The element to delete
2336 ///////////////////////////////////////////////////////////////////////////////
2337 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2339 SMDSAbs_ElementType aType = elem->GetType();
2340 if (aType == SMDSAbs_Node) {
2341 // only free node can be removed by this method
2342 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2343 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2344 if (!itFe->more()) { // free node
2345 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2347 myNodeIDFactory->ReleaseID(elem->GetID());
2351 if (hasConstructionEdges() || hasConstructionFaces())
2352 // this methods is only for meshes without descendants
2355 // Remove element from <InverseElements> of its nodes
2356 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2357 while (itn->more()) {
2358 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2359 (const_cast<SMDS_MeshElement *>(itn->next()));
2360 n->RemoveInverseElement(elem);
2363 // in meshes without descendants elements are always free
2366 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2367 (const_cast<SMDS_MeshElement*>(elem)));
2368 myInfo.RemoveEdge(elem);
2371 myFaces.Remove(static_cast<SMDS_MeshFace*>
2372 (const_cast<SMDS_MeshElement*>(elem)));
2373 myInfo.RemoveFace(elem);
2375 case SMDSAbs_Volume:
2376 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2377 (const_cast<SMDS_MeshElement*>(elem)));
2378 myInfo.RemoveVolume(elem);
2383 myElementIDFactory->ReleaseID(elem->GetID());
2389 * Checks if the element is present in mesh.
2390 * Useful to determine dead pointers.
2392 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2394 // we should not imply on validity of *elem, so iterate on containers
2395 // of all types in the hope of finding <elem> somewhere there
2396 SMDS_NodeIteratorPtr itn = nodesIterator();
2398 if (elem == itn->next())
2400 SMDS_EdgeIteratorPtr ite = edgesIterator();
2402 if (elem == ite->next())
2404 SMDS_FaceIteratorPtr itf = facesIterator();
2406 if (elem == itf->next())
2408 SMDS_VolumeIteratorPtr itv = volumesIterator();
2410 if (elem == itv->next())
2415 //=======================================================================
2416 //function : MaxNodeID
2418 //=======================================================================
2420 int SMDS_Mesh::MaxNodeID() const
2422 return myNodeIDFactory->GetMaxID();
2425 //=======================================================================
2426 //function : MinNodeID
2428 //=======================================================================
2430 int SMDS_Mesh::MinNodeID() const
2432 return myNodeIDFactory->GetMinID();
2435 //=======================================================================
2436 //function : MaxElementID
2438 //=======================================================================
2440 int SMDS_Mesh::MaxElementID() const
2442 return myElementIDFactory->GetMaxID();
2445 //=======================================================================
2446 //function : MinElementID
2448 //=======================================================================
2450 int SMDS_Mesh::MinElementID() const
2452 return myElementIDFactory->GetMinID();
2455 //=======================================================================
2456 //function : Renumber
2457 //purpose : Renumber all nodes or elements.
2458 //=======================================================================
2460 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2465 SMDS_MeshElementIDFactory * idFactory =
2466 isNodes ? myNodeIDFactory : myElementIDFactory;
2468 // get existing elements in the order of ID increasing
2469 map<int,SMDS_MeshElement*> elemMap;
2470 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2471 while ( idElemIt->more() ) {
2472 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2473 int id = elem->GetID();
2474 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2476 // release their ids
2477 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2478 for ( ; elemIt != elemMap.end(); elemIt++ )
2480 int id = (*elemIt).first;
2481 idFactory->ReleaseID( id );
2485 elemIt = elemMap.begin();
2486 for ( ; elemIt != elemMap.end(); elemIt++ )
2488 idFactory->BindID( ID, (*elemIt).second );
2493 //=======================================================================
2494 //function : GetElementType
2495 //purpose : Return type of element or node with id
2496 //=======================================================================
2498 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2500 SMDS_MeshElement* elem = 0;
2502 elem = myElementIDFactory->MeshElement( id );
2504 elem = myNodeIDFactory->MeshElement( id );
2508 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2512 return elem->GetType();
2517 //********************************************************************
2518 //********************************************************************
2519 //******** *********
2520 //***** Methods for addition of quadratic elements ******
2521 //******** *********
2522 //********************************************************************
2523 //********************************************************************
2525 //=======================================================================
2526 //function : AddEdgeWithID
2528 //=======================================================================
2529 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2531 return SMDS_Mesh::AddEdgeWithID
2532 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2533 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2534 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2538 //=======================================================================
2539 //function : AddEdge
2541 //=======================================================================
2542 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2543 const SMDS_MeshNode* n2,
2544 const SMDS_MeshNode* n12)
2546 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2549 //=======================================================================
2550 //function : AddEdgeWithID
2552 //=======================================================================
2553 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2554 const SMDS_MeshNode * n2,
2555 const SMDS_MeshNode * n12,
2558 if ( !n1 || !n2 || !n12 ) return 0;
2559 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2560 if(myElementIDFactory->BindID(ID, edge)) {
2561 SMDS_MeshNode *node1,*node2, *node12;
2562 node1 = const_cast<SMDS_MeshNode*>(n1);
2563 node2 = const_cast<SMDS_MeshNode*>(n2);
2564 node12 = const_cast<SMDS_MeshNode*>(n12);
2565 node1->AddInverseElement(edge);
2566 node2->AddInverseElement(edge);
2567 node12->AddInverseElement(edge);
2569 myInfo.myNbQuadEdges++;
2579 //=======================================================================
2580 //function : AddFace
2582 //=======================================================================
2583 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2584 const SMDS_MeshNode * n2,
2585 const SMDS_MeshNode * n3,
2586 const SMDS_MeshNode * n12,
2587 const SMDS_MeshNode * n23,
2588 const SMDS_MeshNode * n31)
2590 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2591 myElementIDFactory->GetFreeID());
2594 //=======================================================================
2595 //function : AddFaceWithID
2597 //=======================================================================
2598 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2599 int n12,int n23,int n31, int ID)
2601 return SMDS_Mesh::AddFaceWithID
2602 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2603 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2604 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2605 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2606 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2607 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2611 //=======================================================================
2612 //function : AddFaceWithID
2614 //=======================================================================
2615 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2616 const SMDS_MeshNode * n2,
2617 const SMDS_MeshNode * n3,
2618 const SMDS_MeshNode * n12,
2619 const SMDS_MeshNode * n23,
2620 const SMDS_MeshNode * n31,
2623 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2624 if(hasConstructionEdges()) {
2625 // creation quadratic edges - not implemented
2628 SMDS_QuadraticFaceOfNodes* face =
2629 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2631 myInfo.myNbQuadTriangles++;
2633 if (!registerElement(ID, face)) {
2634 RemoveElement(face, false);
2641 //=======================================================================
2642 //function : AddFace
2644 //=======================================================================
2645 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2646 const SMDS_MeshNode * n2,
2647 const SMDS_MeshNode * n3,
2648 const SMDS_MeshNode * n4,
2649 const SMDS_MeshNode * n12,
2650 const SMDS_MeshNode * n23,
2651 const SMDS_MeshNode * n34,
2652 const SMDS_MeshNode * n41)
2654 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2655 myElementIDFactory->GetFreeID());
2658 //=======================================================================
2659 //function : AddFaceWithID
2661 //=======================================================================
2662 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2663 int n12,int n23,int n34,int n41, int ID)
2665 return SMDS_Mesh::AddFaceWithID
2666 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2667 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2668 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2669 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2670 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2671 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2672 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2673 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2677 //=======================================================================
2678 //function : AddFaceWithID
2680 //=======================================================================
2681 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2682 const SMDS_MeshNode * n2,
2683 const SMDS_MeshNode * n3,
2684 const SMDS_MeshNode * n4,
2685 const SMDS_MeshNode * n12,
2686 const SMDS_MeshNode * n23,
2687 const SMDS_MeshNode * n34,
2688 const SMDS_MeshNode * n41,
2691 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2692 if(hasConstructionEdges()) {
2693 // creation quadratic edges - not implemented
2695 SMDS_QuadraticFaceOfNodes* face =
2696 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2698 myInfo.myNbQuadQuadrangles++;
2700 if (!registerElement(ID, face)) {
2701 RemoveElement(face, false);
2708 //=======================================================================
2709 //function : AddVolume
2711 //=======================================================================
2712 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2713 const SMDS_MeshNode * n2,
2714 const SMDS_MeshNode * n3,
2715 const SMDS_MeshNode * n4,
2716 const SMDS_MeshNode * n12,
2717 const SMDS_MeshNode * n23,
2718 const SMDS_MeshNode * n31,
2719 const SMDS_MeshNode * n14,
2720 const SMDS_MeshNode * n24,
2721 const SMDS_MeshNode * n34)
2723 int ID = myElementIDFactory->GetFreeID();
2724 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2725 n31, n14, n24, n34, ID);
2726 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2730 //=======================================================================
2731 //function : AddVolumeWithID
2733 //=======================================================================
2734 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2735 int n12,int n23,int n31,
2736 int n14,int n24,int n34, int ID)
2738 return SMDS_Mesh::AddVolumeWithID
2739 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2740 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2741 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2742 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2743 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2744 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2745 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2746 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2747 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2748 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2752 //=======================================================================
2753 //function : AddVolumeWithID
2754 //purpose : 2d order tetrahedron of 10 nodes
2755 //=======================================================================
2756 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2757 const SMDS_MeshNode * n2,
2758 const SMDS_MeshNode * n3,
2759 const SMDS_MeshNode * n4,
2760 const SMDS_MeshNode * n12,
2761 const SMDS_MeshNode * n23,
2762 const SMDS_MeshNode * n31,
2763 const SMDS_MeshNode * n14,
2764 const SMDS_MeshNode * n24,
2765 const SMDS_MeshNode * n34,
2768 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2770 if(hasConstructionFaces()) {
2771 // creation quadratic faces - not implemented
2774 SMDS_QuadraticVolumeOfNodes * volume =
2775 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2776 myVolumes.Add(volume);
2777 myInfo.myNbQuadTetras++;
2779 if (!registerElement(ID, volume)) {
2780 RemoveElement(volume, false);
2787 //=======================================================================
2788 //function : AddVolume
2790 //=======================================================================
2791 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2792 const SMDS_MeshNode * n2,
2793 const SMDS_MeshNode * n3,
2794 const SMDS_MeshNode * n4,
2795 const SMDS_MeshNode * n5,
2796 const SMDS_MeshNode * n12,
2797 const SMDS_MeshNode * n23,
2798 const SMDS_MeshNode * n34,
2799 const SMDS_MeshNode * n41,
2800 const SMDS_MeshNode * n15,
2801 const SMDS_MeshNode * n25,
2802 const SMDS_MeshNode * n35,
2803 const SMDS_MeshNode * n45)
2805 int ID = myElementIDFactory->GetFreeID();
2806 SMDS_MeshVolume * v =
2807 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2808 n15, n25, n35, n45, ID);
2809 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2813 //=======================================================================
2814 //function : AddVolumeWithID
2816 //=======================================================================
2817 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2818 int n12,int n23,int n34,int n41,
2819 int n15,int n25,int n35,int n45, int ID)
2821 return SMDS_Mesh::AddVolumeWithID
2822 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2823 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2824 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2825 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2826 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2827 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2828 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2829 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2830 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2831 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2832 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2833 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2834 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2838 //=======================================================================
2839 //function : AddVolumeWithID
2840 //purpose : 2d order pyramid of 13 nodes
2841 //=======================================================================
2842 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2843 const SMDS_MeshNode * n2,
2844 const SMDS_MeshNode * n3,
2845 const SMDS_MeshNode * n4,
2846 const SMDS_MeshNode * n5,
2847 const SMDS_MeshNode * n12,
2848 const SMDS_MeshNode * n23,
2849 const SMDS_MeshNode * n34,
2850 const SMDS_MeshNode * n41,
2851 const SMDS_MeshNode * n15,
2852 const SMDS_MeshNode * n25,
2853 const SMDS_MeshNode * n35,
2854 const SMDS_MeshNode * n45,
2857 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2858 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2860 if(hasConstructionFaces()) {
2861 // creation quadratic faces - not implemented
2864 SMDS_QuadraticVolumeOfNodes * volume =
2865 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2866 n34,n41,n15,n25,n35,n45);
2867 myVolumes.Add(volume);
2868 myInfo.myNbQuadPyramids++;
2870 if (!registerElement(ID, volume)) {
2871 RemoveElement(volume, false);
2878 //=======================================================================
2879 //function : AddVolume
2881 //=======================================================================
2882 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2883 const SMDS_MeshNode * n2,
2884 const SMDS_MeshNode * n3,
2885 const SMDS_MeshNode * n4,
2886 const SMDS_MeshNode * n5,
2887 const SMDS_MeshNode * n6,
2888 const SMDS_MeshNode * n12,
2889 const SMDS_MeshNode * n23,
2890 const SMDS_MeshNode * n31,
2891 const SMDS_MeshNode * n45,
2892 const SMDS_MeshNode * n56,
2893 const SMDS_MeshNode * n64,
2894 const SMDS_MeshNode * n14,
2895 const SMDS_MeshNode * n25,
2896 const SMDS_MeshNode * n36)
2898 int ID = myElementIDFactory->GetFreeID();
2899 SMDS_MeshVolume * v =
2900 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2901 n45, n56, n64, n14, n25, n36, ID);
2902 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2906 //=======================================================================
2907 //function : AddVolumeWithID
2909 //=======================================================================
2910 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2911 int n4, int n5, int n6,
2912 int n12,int n23,int n31,
2913 int n45,int n56,int n64,
2914 int n14,int n25,int n36, int ID)
2916 return SMDS_Mesh::AddVolumeWithID
2917 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2918 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2919 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2920 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2921 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2922 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2923 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2924 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2925 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2926 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2927 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2928 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2929 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2930 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2931 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2935 //=======================================================================
2936 //function : AddVolumeWithID
2937 //purpose : 2d order Pentahedron with 15 nodes
2938 //=======================================================================
2939 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2940 const SMDS_MeshNode * n2,
2941 const SMDS_MeshNode * n3,
2942 const SMDS_MeshNode * n4,
2943 const SMDS_MeshNode * n5,
2944 const SMDS_MeshNode * n6,
2945 const SMDS_MeshNode * n12,
2946 const SMDS_MeshNode * n23,
2947 const SMDS_MeshNode * n31,
2948 const SMDS_MeshNode * n45,
2949 const SMDS_MeshNode * n56,
2950 const SMDS_MeshNode * n64,
2951 const SMDS_MeshNode * n14,
2952 const SMDS_MeshNode * n25,
2953 const SMDS_MeshNode * n36,
2956 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2957 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2959 if(hasConstructionFaces()) {
2960 // creation quadratic faces - not implemented
2963 SMDS_QuadraticVolumeOfNodes * volume =
2964 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2965 n45,n56,n64,n14,n25,n36);
2966 myVolumes.Add(volume);
2967 myInfo.myNbQuadPrisms++;
2969 if (!registerElement(ID, volume)) {
2970 RemoveElement(volume, false);
2977 //=======================================================================
2978 //function : AddVolume
2980 //=======================================================================
2981 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2982 const SMDS_MeshNode * n2,
2983 const SMDS_MeshNode * n3,
2984 const SMDS_MeshNode * n4,
2985 const SMDS_MeshNode * n5,
2986 const SMDS_MeshNode * n6,
2987 const SMDS_MeshNode * n7,
2988 const SMDS_MeshNode * n8,
2989 const SMDS_MeshNode * n12,
2990 const SMDS_MeshNode * n23,
2991 const SMDS_MeshNode * n34,
2992 const SMDS_MeshNode * n41,
2993 const SMDS_MeshNode * n56,
2994 const SMDS_MeshNode * n67,
2995 const SMDS_MeshNode * n78,
2996 const SMDS_MeshNode * n85,
2997 const SMDS_MeshNode * n15,
2998 const SMDS_MeshNode * n26,
2999 const SMDS_MeshNode * n37,
3000 const SMDS_MeshNode * n48)
3002 int ID = myElementIDFactory->GetFreeID();
3003 SMDS_MeshVolume * v =
3004 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3005 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3006 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3010 //=======================================================================
3011 //function : AddVolumeWithID
3013 //=======================================================================
3014 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3015 int n5, int n6, int n7, int n8,
3016 int n12,int n23,int n34,int n41,
3017 int n56,int n67,int n78,int n85,
3018 int n15,int n26,int n37,int n48, int ID)
3020 return SMDS_Mesh::AddVolumeWithID
3021 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3022 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3023 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3024 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3025 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3026 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3027 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3028 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3029 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3030 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3031 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3032 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3033 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3034 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3035 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3036 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3037 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3038 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3039 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3040 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3044 //=======================================================================
3045 //function : AddVolumeWithID
3046 //purpose : 2d order Hexahedrons with 20 nodes
3047 //=======================================================================
3048 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3049 const SMDS_MeshNode * n2,
3050 const SMDS_MeshNode * n3,
3051 const SMDS_MeshNode * n4,
3052 const SMDS_MeshNode * n5,
3053 const SMDS_MeshNode * n6,
3054 const SMDS_MeshNode * n7,
3055 const SMDS_MeshNode * n8,
3056 const SMDS_MeshNode * n12,
3057 const SMDS_MeshNode * n23,
3058 const SMDS_MeshNode * n34,
3059 const SMDS_MeshNode * n41,
3060 const SMDS_MeshNode * n56,
3061 const SMDS_MeshNode * n67,
3062 const SMDS_MeshNode * n78,
3063 const SMDS_MeshNode * n85,
3064 const SMDS_MeshNode * n15,
3065 const SMDS_MeshNode * n26,
3066 const SMDS_MeshNode * n37,
3067 const SMDS_MeshNode * n48,
3070 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3071 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3073 if(hasConstructionFaces()) {
3075 // creation quadratic faces - not implemented
3077 SMDS_QuadraticVolumeOfNodes * volume =
3078 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3079 n56,n67,n78,n85,n15,n26,n37,n48);
3080 myVolumes.Add(volume);
3081 myInfo.myNbQuadHexas++;
3083 if (!registerElement(ID, volume)) {
3084 RemoveElement(volume, false);