1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMDS : implementaion of Salome mesh data structure
25 #pragma warning(disable:4786)
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
45 #include <sys/sysinfo.h>
48 // number of added entitis to check memory after
49 #define CHECKMEMORY_INTERVAL 1000
51 //================================================================================
53 * \brief Raise an exception if free memory (ram+swap) too low
54 * \param doNotRaise - if true, suppres exception, just return free memory size
55 * \retval int - amount of available memory in MB or negative number in failure case
57 //================================================================================
59 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
63 int err = sysinfo( &si );
67 static int limit = -1;
69 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
71 limit = WEXITSTATUS(status);
76 limit = int( limit * 1.5 );
78 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
82 const unsigned long Mbyte = 1024 * 1024;
83 // compute separately to avoid overflow
85 ( si.freeram * si.mem_unit ) / Mbyte +
86 ( si.freeswap * si.mem_unit ) / Mbyte;
89 return freeMb - limit;
94 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
96 throw std::bad_alloc();
102 ///////////////////////////////////////////////////////////////////////////////
103 /// Create a new mesh object
104 ///////////////////////////////////////////////////////////////////////////////
105 SMDS_Mesh::SMDS_Mesh()
107 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
108 myElementIDFactory(new SMDS_MeshElementIDFactory()),
109 myHasConstructionEdges(false), myHasConstructionFaces(false),
110 myHasInverseElements(true)
114 ///////////////////////////////////////////////////////////////////////////////
115 /// Create a new child mesh
116 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
117 /// (2003-09-08) of SMESH
118 ///////////////////////////////////////////////////////////////////////////////
119 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
120 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
121 myElementIDFactory(parent->myElementIDFactory),
122 myHasConstructionEdges(false), myHasConstructionFaces(false),
123 myHasInverseElements(true)
127 ///////////////////////////////////////////////////////////////////////////////
128 ///Create a submesh and add it to the current mesh
129 ///////////////////////////////////////////////////////////////////////////////
131 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
133 SMDS_Mesh *submesh = new SMDS_Mesh(this);
134 myChildren.insert(myChildren.end(), submesh);
138 ///////////////////////////////////////////////////////////////////////////////
139 ///create a MeshNode and add it to the current Mesh
140 ///An ID is automatically assigned to the node.
141 ///@return : The created node
142 ///////////////////////////////////////////////////////////////////////////////
144 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
146 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
149 ///////////////////////////////////////////////////////////////////////////////
150 ///create a MeshNode and add it to the current Mesh
151 ///@param ID : The ID of the MeshNode to create
152 ///@return : The created node or NULL if a node with this ID already exists
153 ///////////////////////////////////////////////////////////////////////////////
154 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
156 // find the MeshNode corresponding to ID
157 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
159 if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
160 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
162 myNodeIDFactory->BindID(ID,node);
169 ///////////////////////////////////////////////////////////////////////////////
170 /// create a Mesh0DElement and add it to the current Mesh
171 /// @return : The created Mesh0DElement
172 ///////////////////////////////////////////////////////////////////////////////
173 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
175 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
176 if (!node) return NULL;
177 return SMDS_Mesh::Add0DElementWithID(node, ID);
180 ///////////////////////////////////////////////////////////////////////////////
181 /// create a Mesh0DElement and add it to the current Mesh
182 /// @return : The created Mesh0DElement
183 ///////////////////////////////////////////////////////////////////////////////
184 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
186 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
189 ///////////////////////////////////////////////////////////////////////////////
190 /// Create a new Mesh0DElement and at it to the mesh
191 /// @param idnode ID of the node
192 /// @param ID ID of the 0D element to create
193 /// @return The created 0D element or NULL if an element with this
194 /// ID already exists or if input node is not found.
195 ///////////////////////////////////////////////////////////////////////////////
196 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
200 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
202 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
203 if (myElementIDFactory->BindID(ID, el0d)) {
204 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
205 node->AddInverseElement(el0d);
206 my0DElements.Add(el0d);
207 myInfo.myNb0DElements++;
215 ///////////////////////////////////////////////////////////////////////////////
216 /// create a MeshEdge and add it to the current Mesh
217 /// @return : The created MeshEdge
218 ///////////////////////////////////////////////////////////////////////////////
220 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
222 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
223 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
224 if(!node1 || !node2) return NULL;
225 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
228 ///////////////////////////////////////////////////////////////////////////////
229 /// create a MeshEdge and add it to the current Mesh
230 /// @return : The created MeshEdge
231 ///////////////////////////////////////////////////////////////////////////////
233 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
234 const SMDS_MeshNode * node2)
236 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
239 ///////////////////////////////////////////////////////////////////////////////
240 /// Create a new edge and at it to the mesh
241 /// @param idnode1 ID of the first node
242 /// @param idnode2 ID of the second node
243 /// @param ID ID of the edge to create
244 /// @return The created edge or NULL if an element with this ID already exists or
245 /// if input nodes are not found.
246 ///////////////////////////////////////////////////////////////////////////////
248 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
249 const SMDS_MeshNode * n2,
252 if ( !n1 || !n2 ) return 0;
254 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
256 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
257 if(myElementIDFactory->BindID(ID, edge)) {
258 SMDS_MeshNode *node1,*node2;
259 node1=const_cast<SMDS_MeshNode*>(n1);
260 node2=const_cast<SMDS_MeshNode*>(n2);
261 node1->AddInverseElement(edge);
262 node2->AddInverseElement(edge);
273 ///////////////////////////////////////////////////////////////////////////////
274 /// Add a triangle defined by its nodes. An ID is automatically affected to the
276 ///////////////////////////////////////////////////////////////////////////////
278 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
279 const SMDS_MeshNode * n2,
280 const SMDS_MeshNode * n3)
282 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
285 ///////////////////////////////////////////////////////////////////////////////
286 /// Add a triangle defined by its nodes IDs
287 ///////////////////////////////////////////////////////////////////////////////
289 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
291 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
292 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
293 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
294 if(!node1 || !node2 || !node3) return NULL;
295 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
298 ///////////////////////////////////////////////////////////////////////////////
299 /// Add a triangle defined by its nodes
300 ///////////////////////////////////////////////////////////////////////////////
302 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
303 const SMDS_MeshNode * n2,
304 const SMDS_MeshNode * n3,
307 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
309 if (face && !registerElement(ID, face)) {
310 RemoveElement(face, false);
316 ///////////////////////////////////////////////////////////////////////////////
317 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
319 ///////////////////////////////////////////////////////////////////////////////
321 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
322 const SMDS_MeshNode * n2,
323 const SMDS_MeshNode * n3,
324 const SMDS_MeshNode * n4)
326 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
329 ///////////////////////////////////////////////////////////////////////////////
330 /// Add a quadrangle defined by its nodes IDs
331 ///////////////////////////////////////////////////////////////////////////////
333 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
339 SMDS_MeshNode *node1, *node2, *node3, *node4;
340 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
341 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
342 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
343 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
344 if(!node1 || !node2 || !node3 || !node4) return NULL;
345 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
348 ///////////////////////////////////////////////////////////////////////////////
349 /// Add a quadrangle defined by its nodes
350 ///////////////////////////////////////////////////////////////////////////////
352 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
353 const SMDS_MeshNode * n2,
354 const SMDS_MeshNode * n3,
355 const SMDS_MeshNode * n4,
358 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
360 if (face && !registerElement(ID, face)) {
361 RemoveElement(face, false);
367 ///////////////////////////////////////////////////////////////////////////////
368 /// Add a triangle defined by its edges. An ID is automatically assigned to the
370 ///////////////////////////////////////////////////////////////////////////////
372 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
373 const SMDS_MeshEdge * e2,
374 const SMDS_MeshEdge * e3)
376 if (!hasConstructionEdges())
378 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
381 ///////////////////////////////////////////////////////////////////////////////
382 /// Add a triangle defined by its edges
383 ///////////////////////////////////////////////////////////////////////////////
385 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
386 const SMDS_MeshEdge * e2,
387 const SMDS_MeshEdge * e3,
390 if (!hasConstructionEdges())
392 if ( !e1 || !e2 || !e3 ) return 0;
394 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
396 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
398 myInfo.myNbTriangles++;
400 if (!registerElement(ID, face)) {
401 RemoveElement(face, false);
407 ///////////////////////////////////////////////////////////////////////////////
408 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
410 ///////////////////////////////////////////////////////////////////////////////
412 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
413 const SMDS_MeshEdge * e2,
414 const SMDS_MeshEdge * e3,
415 const SMDS_MeshEdge * e4)
417 if (!hasConstructionEdges())
419 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
422 ///////////////////////////////////////////////////////////////////////////////
423 /// Add a quadrangle defined by its edges
424 ///////////////////////////////////////////////////////////////////////////////
426 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
427 const SMDS_MeshEdge * e2,
428 const SMDS_MeshEdge * e3,
429 const SMDS_MeshEdge * e4,
432 if (!hasConstructionEdges())
434 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
435 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
436 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
438 myInfo.myNbQuadrangles++;
440 if (!registerElement(ID, face))
442 RemoveElement(face, false);
448 ///////////////////////////////////////////////////////////////////////////////
449 ///Create a new tetrahedron and add it to the mesh.
450 ///@return The created tetrahedron
451 ///////////////////////////////////////////////////////////////////////////////
453 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
454 const SMDS_MeshNode * n2,
455 const SMDS_MeshNode * n3,
456 const SMDS_MeshNode * n4)
458 int ID = myElementIDFactory->GetFreeID();
459 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
460 if(v==NULL) myElementIDFactory->ReleaseID(ID);
464 ///////////////////////////////////////////////////////////////////////////////
465 ///Create a new tetrahedron and add it to the mesh.
466 ///@param ID The ID of the new volume
467 ///@return The created tetrahedron or NULL if an element with this ID already exists
468 ///or if input nodes are not found.
469 ///////////////////////////////////////////////////////////////////////////////
471 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
477 SMDS_MeshNode *node1, *node2, *node3, *node4;
478 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
479 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
480 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
481 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
482 if(!node1 || !node2 || !node3 || !node4) return NULL;
483 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
486 ///////////////////////////////////////////////////////////////////////////////
487 ///Create a new tetrahedron and add it to the mesh.
488 ///@param ID The ID of the new volume
489 ///@return The created tetrahedron
490 ///////////////////////////////////////////////////////////////////////////////
492 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
493 const SMDS_MeshNode * n2,
494 const SMDS_MeshNode * n3,
495 const SMDS_MeshNode * n4,
498 SMDS_MeshVolume* volume = 0;
499 if ( !n1 || !n2 || !n3 || !n4) return volume;
500 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
501 if(hasConstructionFaces()) {
502 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
503 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
504 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
505 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
506 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
507 myVolumes.Add(volume);
510 else if(hasConstructionEdges()) {
511 MESSAGE("Error : Not implemented");
515 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
516 myVolumes.Add(volume);
520 if (!registerElement(ID, volume)) {
521 RemoveElement(volume, false);
527 ///////////////////////////////////////////////////////////////////////////////
528 ///Create a new pyramid and add it to the mesh.
529 ///Nodes 1,2,3 and 4 define the base of the pyramid
530 ///@return The created pyramid
531 ///////////////////////////////////////////////////////////////////////////////
533 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
534 const SMDS_MeshNode * n2,
535 const SMDS_MeshNode * n3,
536 const SMDS_MeshNode * n4,
537 const SMDS_MeshNode * n5)
539 int ID = myElementIDFactory->GetFreeID();
540 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
541 if(v==NULL) myElementIDFactory->ReleaseID(ID);
545 ///////////////////////////////////////////////////////////////////////////////
546 ///Create a new pyramid and add it to the mesh.
547 ///Nodes 1,2,3 and 4 define the base of the pyramid
548 ///@param ID The ID of the new volume
549 ///@return The created pyramid or NULL if an element with this ID already exists
550 ///or if input nodes are not found.
551 ///////////////////////////////////////////////////////////////////////////////
553 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
560 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
561 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
562 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
563 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
564 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
565 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
566 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
567 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
570 ///////////////////////////////////////////////////////////////////////////////
571 ///Create a new pyramid and add it to the mesh.
572 ///Nodes 1,2,3 and 4 define the base of the pyramid
573 ///@param ID The ID of the new volume
574 ///@return The created pyramid
575 ///////////////////////////////////////////////////////////////////////////////
577 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
578 const SMDS_MeshNode * n2,
579 const SMDS_MeshNode * n3,
580 const SMDS_MeshNode * n4,
581 const SMDS_MeshNode * n5,
584 SMDS_MeshVolume* volume = 0;
585 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
586 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
587 if(hasConstructionFaces()) {
588 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
589 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
590 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
591 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
592 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
593 myVolumes.Add(volume);
594 myInfo.myNbPyramids++;
596 else if(hasConstructionEdges()) {
597 MESSAGE("Error : Not implemented");
601 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
602 myVolumes.Add(volume);
603 myInfo.myNbPyramids++;
606 if (!registerElement(ID, volume)) {
607 RemoveElement(volume, false);
613 ///////////////////////////////////////////////////////////////////////////////
614 ///Create a new prism and add it to the mesh.
615 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
616 ///@return The created prism
617 ///////////////////////////////////////////////////////////////////////////////
619 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
620 const SMDS_MeshNode * n2,
621 const SMDS_MeshNode * n3,
622 const SMDS_MeshNode * n4,
623 const SMDS_MeshNode * n5,
624 const SMDS_MeshNode * n6)
626 int ID = myElementIDFactory->GetFreeID();
627 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
628 if(v==NULL) myElementIDFactory->ReleaseID(ID);
632 ///////////////////////////////////////////////////////////////////////////////
633 ///Create a new prism and add it to the mesh.
634 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
635 ///@param ID The ID of the new volume
636 ///@return The created prism or NULL if an element with this ID already exists
637 ///or if input nodes are not found.
638 ///////////////////////////////////////////////////////////////////////////////
640 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
648 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
649 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
650 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
651 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
652 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
653 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
654 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
655 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
656 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
659 ///////////////////////////////////////////////////////////////////////////////
660 ///Create a new prism and add it to the mesh.
661 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
662 ///@param ID The ID of the new volume
663 ///@return The created prism
664 ///////////////////////////////////////////////////////////////////////////////
666 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
667 const SMDS_MeshNode * n2,
668 const SMDS_MeshNode * n3,
669 const SMDS_MeshNode * n4,
670 const SMDS_MeshNode * n5,
671 const SMDS_MeshNode * n6,
674 SMDS_MeshVolume* volume = 0;
675 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
676 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
677 if(hasConstructionFaces()) {
678 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
679 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
680 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
681 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
682 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
683 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
684 myVolumes.Add(volume);
687 else if(hasConstructionEdges()) {
688 MESSAGE("Error : Not implemented");
692 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
693 myVolumes.Add(volume);
697 if (!registerElement(ID, volume)) {
698 RemoveElement(volume, false);
704 ///////////////////////////////////////////////////////////////////////////////
705 ///Create a new hexahedron and add it to the mesh.
706 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
707 ///@return The created hexahedron
708 ///////////////////////////////////////////////////////////////////////////////
710 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
711 const SMDS_MeshNode * n2,
712 const SMDS_MeshNode * n3,
713 const SMDS_MeshNode * n4,
714 const SMDS_MeshNode * n5,
715 const SMDS_MeshNode * n6,
716 const SMDS_MeshNode * n7,
717 const SMDS_MeshNode * n8)
719 int ID = myElementIDFactory->GetFreeID();
720 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
721 if(v==NULL) myElementIDFactory->ReleaseID(ID);
725 ///////////////////////////////////////////////////////////////////////////////
726 ///Create a new hexahedron and add it to the mesh.
727 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
728 ///@param ID The ID of the new volume
729 ///@return The created hexahedron or NULL if an element with this ID already
730 ///exists or if input nodes are not found.
731 ///////////////////////////////////////////////////////////////////////////////
733 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
743 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
744 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
745 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
746 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
747 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
748 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
749 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
750 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
751 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
752 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
754 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
758 ///////////////////////////////////////////////////////////////////////////////
759 ///Create a new hexahedron and add it to the mesh.
760 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
761 ///@param ID The ID of the new volume
762 ///@return The created prism or NULL if an element with this ID already exists
763 ///or if input nodes are not found.
764 ///////////////////////////////////////////////////////////////////////////////
766 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
767 const SMDS_MeshNode * n2,
768 const SMDS_MeshNode * n3,
769 const SMDS_MeshNode * n4,
770 const SMDS_MeshNode * n5,
771 const SMDS_MeshNode * n6,
772 const SMDS_MeshNode * n7,
773 const SMDS_MeshNode * n8,
776 SMDS_MeshVolume* volume = 0;
777 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
778 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
779 if(hasConstructionFaces()) {
780 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
781 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
782 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
783 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
784 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
785 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
786 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
787 myVolumes.Add(volume);
790 else if(hasConstructionEdges()) {
791 MESSAGE("Error : Not implemented");
795 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
796 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
797 myVolumes.Add(volume);
801 if (!registerElement(ID, volume)) {
802 RemoveElement(volume, false);
808 ///////////////////////////////////////////////////////////////////////////////
809 ///Create a new tetrahedron defined by its faces and add it to the mesh.
810 ///@return The created tetrahedron
811 ///////////////////////////////////////////////////////////////////////////////
813 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
814 const SMDS_MeshFace * f2,
815 const SMDS_MeshFace * f3,
816 const SMDS_MeshFace * f4)
818 if (!hasConstructionFaces())
820 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
823 ///////////////////////////////////////////////////////////////////////////////
824 ///Create a new tetrahedron defined by its faces and add it to the mesh.
825 ///@param ID The ID of the new volume
826 ///@return The created tetrahedron
827 ///////////////////////////////////////////////////////////////////////////////
829 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
830 const SMDS_MeshFace * f2,
831 const SMDS_MeshFace * f3,
832 const SMDS_MeshFace * f4,
835 if (!hasConstructionFaces())
837 if ( !f1 || !f2 || !f3 || !f4) return 0;
838 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
839 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
840 myVolumes.Add(volume);
843 if (!registerElement(ID, volume)) {
844 RemoveElement(volume, false);
850 ///////////////////////////////////////////////////////////////////////////////
851 ///Create a new pyramid defined by its faces and add it to the mesh.
852 ///@return The created pyramid
853 ///////////////////////////////////////////////////////////////////////////////
855 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
856 const SMDS_MeshFace * f2,
857 const SMDS_MeshFace * f3,
858 const SMDS_MeshFace * f4,
859 const SMDS_MeshFace * f5)
861 if (!hasConstructionFaces())
863 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
866 ///////////////////////////////////////////////////////////////////////////////
867 ///Create a new pyramid defined by its faces and add it to the mesh.
868 ///@param ID The ID of the new volume
869 ///@return The created pyramid
870 ///////////////////////////////////////////////////////////////////////////////
872 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
873 const SMDS_MeshFace * f2,
874 const SMDS_MeshFace * f3,
875 const SMDS_MeshFace * f4,
876 const SMDS_MeshFace * f5,
879 if (!hasConstructionFaces())
881 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
882 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
883 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
884 myVolumes.Add(volume);
885 myInfo.myNbPyramids++;
887 if (!registerElement(ID, volume)) {
888 RemoveElement(volume, false);
894 ///////////////////////////////////////////////////////////////////////////////
895 ///Create a new prism defined by its faces and add it to the mesh.
896 ///@return The created prism
897 ///////////////////////////////////////////////////////////////////////////////
899 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
900 const SMDS_MeshFace * f2,
901 const SMDS_MeshFace * f3,
902 const SMDS_MeshFace * f4,
903 const SMDS_MeshFace * f5,
904 const SMDS_MeshFace * f6)
906 if (!hasConstructionFaces())
908 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
911 ///////////////////////////////////////////////////////////////////////////////
912 ///Create a new prism defined by its faces and add it to the mesh.
913 ///@param ID The ID of the new volume
914 ///@return The created prism
915 ///////////////////////////////////////////////////////////////////////////////
917 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
918 const SMDS_MeshFace * f2,
919 const SMDS_MeshFace * f3,
920 const SMDS_MeshFace * f4,
921 const SMDS_MeshFace * f5,
922 const SMDS_MeshFace * f6,
925 if (!hasConstructionFaces())
927 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
928 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
929 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
930 myVolumes.Add(volume);
933 if (!registerElement(ID, volume)) {
934 RemoveElement(volume, false);
940 ///////////////////////////////////////////////////////////////////////////////
941 /// Add a polygon defined by its nodes IDs
942 ///////////////////////////////////////////////////////////////////////////////
944 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
947 int nbNodes = nodes_ids.size();
948 vector<const SMDS_MeshNode*> nodes (nbNodes);
949 for (int i = 0; i < nbNodes; i++) {
950 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
951 if (!nodes[i]) return NULL;
953 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
956 ///////////////////////////////////////////////////////////////////////////////
957 /// Add a polygon defined by its nodes
958 ///////////////////////////////////////////////////////////////////////////////
960 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
961 (vector<const SMDS_MeshNode*> nodes,
964 SMDS_MeshFace * face;
966 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
967 if (hasConstructionEdges())
969 MESSAGE("Error : Not implemented");
974 for ( int i = 0; i < nodes.size(); ++i )
975 if ( !nodes[ i ] ) return 0;
976 face = new SMDS_PolygonalFaceOfNodes(nodes);
978 myInfo.myNbPolygons++;
981 if (!registerElement(ID, face)) {
982 RemoveElement(face, false);
988 ///////////////////////////////////////////////////////////////////////////////
989 /// Add a polygon defined by its nodes.
990 /// An ID is automatically affected to the created face.
991 ///////////////////////////////////////////////////////////////////////////////
993 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
995 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
998 ///////////////////////////////////////////////////////////////////////////////
999 /// Create a new polyhedral volume and add it to the mesh.
1000 /// @param ID The ID of the new volume
1001 /// @return The created volume or NULL if an element with this ID already exists
1002 /// or if input nodes are not found.
1003 ///////////////////////////////////////////////////////////////////////////////
1005 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1006 (vector<int> nodes_ids,
1007 vector<int> quantities,
1010 int nbNodes = nodes_ids.size();
1011 vector<const SMDS_MeshNode*> nodes (nbNodes);
1012 for (int i = 0; i < nbNodes; i++) {
1013 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1014 if (!nodes[i]) return NULL;
1016 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1019 ///////////////////////////////////////////////////////////////////////////////
1020 /// Create a new polyhedral volume and add it to the mesh.
1021 /// @param ID The ID of the new volume
1022 /// @return The created volume
1023 ///////////////////////////////////////////////////////////////////////////////
1025 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1026 (vector<const SMDS_MeshNode*> nodes,
1027 vector<int> quantities,
1030 SMDS_MeshVolume* volume;
1031 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1032 if (hasConstructionFaces()) {
1033 MESSAGE("Error : Not implemented");
1035 } else if (hasConstructionEdges()) {
1036 MESSAGE("Error : Not implemented");
1039 for ( int i = 0; i < nodes.size(); ++i )
1040 if ( !nodes[ i ] ) return 0;
1041 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1042 myVolumes.Add(volume);
1043 myInfo.myNbPolyhedrons++;
1046 if (!registerElement(ID, volume)) {
1047 RemoveElement(volume, false);
1053 ///////////////////////////////////////////////////////////////////////////////
1054 /// Create a new polyhedral volume and add it to the mesh.
1055 /// @return The created volume
1056 ///////////////////////////////////////////////////////////////////////////////
1058 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1059 (vector<const SMDS_MeshNode*> nodes,
1060 vector<int> quantities)
1062 int ID = myElementIDFactory->GetFreeID();
1063 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1064 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1068 ///////////////////////////////////////////////////////////////////////////////
1069 /// Registers element with the given ID, maintains inverse connections
1070 ///////////////////////////////////////////////////////////////////////////////
1071 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1073 if (myElementIDFactory->BindID(ID, element)) {
1074 SMDS_ElemIteratorPtr it = element->nodesIterator();
1075 while (it->more()) {
1076 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1077 (const_cast<SMDS_MeshElement*>(it->next()));
1078 node->AddInverseElement(element);
1085 ///////////////////////////////////////////////////////////////////////////////
1086 /// Return the node whose ID is 'ID'.
1087 ///////////////////////////////////////////////////////////////////////////////
1088 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1090 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1093 ///////////////////////////////////////////////////////////////////////////////
1094 ///Create a triangle and add it to the current mesh. This methode do not bind a
1095 ///ID to the create triangle.
1096 ///////////////////////////////////////////////////////////////////////////////
1097 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1098 const SMDS_MeshNode * node2,
1099 const SMDS_MeshNode * node3)
1101 if ( !node1 || !node2 || !node3) return 0;
1102 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1103 if(hasConstructionEdges())
1105 SMDS_MeshEdge *edge1, *edge2, *edge3;
1106 edge1=FindEdgeOrCreate(node1,node2);
1107 edge2=FindEdgeOrCreate(node2,node3);
1108 edge3=FindEdgeOrCreate(node3,node1);
1110 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1112 myInfo.myNbTriangles++;
1117 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1119 myInfo.myNbTriangles++;
1124 ///////////////////////////////////////////////////////////////////////////////
1125 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1126 ///a ID to the create triangle.
1127 ///////////////////////////////////////////////////////////////////////////////
1128 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1129 const SMDS_MeshNode * node2,
1130 const SMDS_MeshNode * node3,
1131 const SMDS_MeshNode * node4)
1133 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1134 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1135 if(hasConstructionEdges())
1137 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1138 edge1=FindEdgeOrCreate(node1,node2);
1139 edge2=FindEdgeOrCreate(node2,node3);
1140 edge3=FindEdgeOrCreate(node3,node4);
1141 edge4=FindEdgeOrCreate(node4,node1);
1143 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1145 myInfo.myNbQuadrangles++;
1150 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1152 myInfo.myNbQuadrangles++;
1157 ///////////////////////////////////////////////////////////////////////////////
1158 /// Remove a node and all the elements which own this node
1159 ///////////////////////////////////////////////////////////////////////////////
1161 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1163 RemoveElement(node, true);
1166 ///////////////////////////////////////////////////////////////////////////////
1167 /// Remove an edge and all the elements which own this edge
1168 ///////////////////////////////////////////////////////////////////////////////
1170 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1172 RemoveElement(elem0d,true);
1175 ///////////////////////////////////////////////////////////////////////////////
1176 /// Remove an edge and all the elements which own this edge
1177 ///////////////////////////////////////////////////////////////////////////////
1179 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1181 RemoveElement(edge,true);
1184 ///////////////////////////////////////////////////////////////////////////////
1185 /// Remove an face and all the elements which own this face
1186 ///////////////////////////////////////////////////////////////////////////////
1188 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1190 RemoveElement(face, true);
1193 ///////////////////////////////////////////////////////////////////////////////
1195 ///////////////////////////////////////////////////////////////////////////////
1197 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1199 RemoveElement(volume, true);
1202 //=======================================================================
1203 //function : RemoveFromParent
1205 //=======================================================================
1207 bool SMDS_Mesh::RemoveFromParent()
1209 if (myParent==NULL) return false;
1210 else return (myParent->RemoveSubMesh(this));
1213 //=======================================================================
1214 //function : RemoveSubMesh
1216 //=======================================================================
1218 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1222 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1223 for (; itmsh!=myChildren.end() && !found; itmsh++)
1225 SMDS_Mesh * submesh = *itmsh;
1226 if (submesh == aMesh)
1229 myChildren.erase(itmsh);
1236 //=======================================================================
1237 //function : ChangeElementNodes
1239 //=======================================================================
1241 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1242 const SMDS_MeshNode * nodes[],
1245 // keep current nodes of elem
1246 set<const SMDS_MeshElement*> oldNodes;
1247 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1249 oldNodes.insert( itn->next() );
1251 if ( !element->IsPoly() )
1252 myInfo.remove( element ); // element may change type
1256 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1257 switch ( elem->GetType() )
1259 case SMDSAbs_0DElement: {
1260 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1261 Ok = elem0d->ChangeNode( nodes[0] );
1264 case SMDSAbs_Edge: {
1265 if ( nbnodes == 2 ) {
1266 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1267 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1269 else if ( nbnodes == 3 ) {
1270 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1271 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1275 case SMDSAbs_Face: {
1276 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1277 Ok = face->ChangeNodes( nodes, nbnodes );
1279 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1280 Ok = QF->ChangeNodes( nodes, nbnodes );
1282 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1283 Ok = face->ChangeNodes(nodes, nbnodes);
1286 case SMDSAbs_Volume: {
1287 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1288 Ok = vol->ChangeNodes( nodes, nbnodes );
1290 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1291 Ok = QV->ChangeNodes( nodes, nbnodes );
1295 MESSAGE ( "WRONG ELEM TYPE");
1298 if ( Ok ) { // update InverseElements
1300 set<const SMDS_MeshElement*>::iterator it;
1302 // AddInverseElement to new nodes
1303 for ( int i = 0; i < nbnodes; i++ ) {
1304 it = oldNodes.find( nodes[i] );
1305 if ( it == oldNodes.end() )
1307 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1309 // remove from oldNodes a node that remains in elem
1310 oldNodes.erase( it );
1312 // RemoveInverseElement from the nodes removed from elem
1313 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1315 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1316 (const_cast<SMDS_MeshElement *>( *it ));
1317 n->RemoveInverseElement( elem );
1321 if ( !element->IsPoly() )
1322 myInfo.add( element ); // element may change type
1327 //=======================================================================
1328 //function : ChangePolyhedronNodes
1329 //purpose : to change nodes of polyhedral volume
1330 //=======================================================================
1331 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1332 const vector<const SMDS_MeshNode*>& nodes,
1333 const vector<int> & quantities)
1335 if (elem->GetType() != SMDSAbs_Volume) {
1336 MESSAGE("WRONG ELEM TYPE");
1340 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1345 // keep current nodes of elem
1346 set<const SMDS_MeshElement*> oldNodes;
1347 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1348 while (itn->more()) {
1349 oldNodes.insert(itn->next());
1353 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1358 // update InverseElements
1360 // AddInverseElement to new nodes
1361 int nbnodes = nodes.size();
1362 set<const SMDS_MeshElement*>::iterator it;
1363 for (int i = 0; i < nbnodes; i++) {
1364 it = oldNodes.find(nodes[i]);
1365 if (it == oldNodes.end()) {
1367 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1369 // remove from oldNodes a node that remains in elem
1374 // RemoveInverseElement from the nodes removed from elem
1375 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1376 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1377 (const_cast<SMDS_MeshElement *>( *it ));
1378 n->RemoveInverseElement(elem);
1385 //=======================================================================
1386 //function : Find0DElement
1388 //=======================================================================
1389 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1391 const SMDS_MeshNode * node = FindNode(idnode);
1392 if(node == NULL) return NULL;
1393 return Find0DElement(node);
1396 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1398 if (!node) return 0;
1399 const SMDS_Mesh0DElement* toReturn = NULL;
1400 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1401 while (it1->more() && (toReturn == NULL)) {
1402 const SMDS_MeshElement* e = it1->next();
1403 if (e->NbNodes() == 1) {
1404 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1410 //=======================================================================
1411 //function : Find0DElementOrCreate
1413 //=======================================================================
1414 SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1416 if (!node) return 0;
1417 SMDS_Mesh0DElement * toReturn = NULL;
1418 toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1419 if (toReturn == NULL) {
1420 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1421 toReturn = new SMDS_Mesh0DElement(node);
1422 my0DElements.Add(toReturn);
1423 myInfo.myNb0DElements++;
1429 //=======================================================================
1430 //function : FindEdge
1432 //=======================================================================
1434 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1436 const SMDS_MeshNode * node1=FindNode(idnode1);
1437 const SMDS_MeshNode * node2=FindNode(idnode2);
1438 if((node1==NULL)||(node2==NULL)) return NULL;
1439 return FindEdge(node1,node2);
1442 //#include "Profiler.h"
1443 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1444 const SMDS_MeshNode * node2)
1446 if ( !node1 ) return 0;
1447 const SMDS_MeshEdge * toReturn=NULL;
1450 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1453 while(it1->more()) {
1454 const SMDS_MeshElement * e = it1->next();
1455 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1456 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1465 //=======================================================================
1466 //function : FindEdgeOrCreate
1468 //=======================================================================
1470 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1471 const SMDS_MeshNode * node2)
1473 if ( !node1 || !node2) return 0;
1474 SMDS_MeshEdge * toReturn=NULL;
1475 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1476 if(toReturn==NULL) {
1477 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1478 toReturn=new SMDS_MeshEdge(node1,node2);
1479 myEdges.Add(toReturn);
1486 //=======================================================================
1487 //function : FindEdge
1489 //=======================================================================
1491 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1494 const SMDS_MeshNode * node1=FindNode(idnode1);
1495 const SMDS_MeshNode * node2=FindNode(idnode2);
1496 const SMDS_MeshNode * node3=FindNode(idnode3);
1497 return FindEdge(node1,node2,node3);
1500 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1501 const SMDS_MeshNode * node2,
1502 const SMDS_MeshNode * node3)
1504 if ( !node1 ) return 0;
1505 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1506 while(it1->more()) {
1507 const SMDS_MeshElement * e = it1->next();
1508 if ( e->NbNodes() == 3 ) {
1509 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1510 while(it2->more()) {
1511 const SMDS_MeshElement* n = it2->next();
1521 return static_cast<const SMDS_MeshEdge *> (e);
1528 //=======================================================================
1529 //function : FindFace
1531 //=======================================================================
1533 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1536 const SMDS_MeshNode * node1=FindNode(idnode1);
1537 const SMDS_MeshNode * node2=FindNode(idnode2);
1538 const SMDS_MeshNode * node3=FindNode(idnode3);
1539 return FindFace(node1, node2, node3);
1542 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1543 const SMDS_MeshNode *node2,
1544 const SMDS_MeshNode *node3)
1546 if ( !node1 ) return 0;
1547 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1548 while(it1->more()) {
1549 const SMDS_MeshElement * e = it1->next();
1550 if ( e->NbNodes() == 3 ) {
1551 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1552 while(it2->more()) {
1553 const SMDS_MeshElement* n = it2->next();
1563 return static_cast<const SMDS_MeshFace *> (e);
1569 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1570 const SMDS_MeshNode *node2,
1571 const SMDS_MeshNode *node3)
1573 SMDS_MeshFace * toReturn=NULL;
1574 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1575 if(toReturn==NULL) {
1576 toReturn = createTriangle(node1,node2,node3);
1582 //=======================================================================
1583 //function : FindFace
1585 //=======================================================================
1587 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1588 int idnode3, int idnode4) const
1590 const SMDS_MeshNode * node1=FindNode(idnode1);
1591 const SMDS_MeshNode * node2=FindNode(idnode2);
1592 const SMDS_MeshNode * node3=FindNode(idnode3);
1593 const SMDS_MeshNode * node4=FindNode(idnode4);
1594 return FindFace(node1, node2, node3, node4);
1597 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1598 const SMDS_MeshNode *node2,
1599 const SMDS_MeshNode *node3,
1600 const SMDS_MeshNode *node4)
1602 if ( !node1 ) return 0;
1603 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1604 while(it1->more()) {
1605 const SMDS_MeshElement * e = it1->next();
1606 if ( e->NbNodes() == 4 ) {
1607 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1608 while(it2->more()) {
1609 const SMDS_MeshElement* n = it2->next();
1620 return static_cast<const SMDS_MeshFace *> (e);
1626 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1627 const SMDS_MeshNode *node2,
1628 const SMDS_MeshNode *node3,
1629 const SMDS_MeshNode *node4)
1631 SMDS_MeshFace * toReturn=NULL;
1632 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1633 if(toReturn==NULL) {
1634 toReturn=createQuadrangle(node1,node2,node3,node4);
1640 //=======================================================================
1641 //function : FindFace
1642 //purpose :quadratic triangle
1643 //=======================================================================
1645 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1646 int idnode3, int idnode4,
1647 int idnode5, int idnode6) const
1649 const SMDS_MeshNode * node1 = FindNode(idnode1);
1650 const SMDS_MeshNode * node2 = FindNode(idnode2);
1651 const SMDS_MeshNode * node3 = FindNode(idnode3);
1652 const SMDS_MeshNode * node4 = FindNode(idnode4);
1653 const SMDS_MeshNode * node5 = FindNode(idnode5);
1654 const SMDS_MeshNode * node6 = FindNode(idnode6);
1655 return FindFace(node1, node2, node3, node4, node5, node6);
1658 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1659 const SMDS_MeshNode *node2,
1660 const SMDS_MeshNode *node3,
1661 const SMDS_MeshNode *node4,
1662 const SMDS_MeshNode *node5,
1663 const SMDS_MeshNode *node6)
1665 if ( !node1 ) return 0;
1666 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1667 while(it1->more()) {
1668 const SMDS_MeshElement * e = it1->next();
1669 if ( e->NbNodes() == 6 ) {
1670 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1671 while(it2->more()) {
1672 const SMDS_MeshElement* n = it2->next();
1685 return static_cast<const SMDS_MeshFace *> (e);
1692 //=======================================================================
1693 //function : FindFace
1694 //purpose : quadratic quadrangle
1695 //=======================================================================
1697 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1698 int idnode3, int idnode4,
1699 int idnode5, int idnode6,
1700 int idnode7, int idnode8) const
1702 const SMDS_MeshNode * node1 = FindNode(idnode1);
1703 const SMDS_MeshNode * node2 = FindNode(idnode2);
1704 const SMDS_MeshNode * node3 = FindNode(idnode3);
1705 const SMDS_MeshNode * node4 = FindNode(idnode4);
1706 const SMDS_MeshNode * node5 = FindNode(idnode5);
1707 const SMDS_MeshNode * node6 = FindNode(idnode6);
1708 const SMDS_MeshNode * node7 = FindNode(idnode7);
1709 const SMDS_MeshNode * node8 = FindNode(idnode8);
1710 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1713 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1714 const SMDS_MeshNode *node2,
1715 const SMDS_MeshNode *node3,
1716 const SMDS_MeshNode *node4,
1717 const SMDS_MeshNode *node5,
1718 const SMDS_MeshNode *node6,
1719 const SMDS_MeshNode *node7,
1720 const SMDS_MeshNode *node8)
1722 if ( !node1 ) return 0;
1723 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1724 while(it1->more()) {
1725 const SMDS_MeshElement * e = it1->next();
1726 if ( e->NbNodes() == 8 ) {
1727 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1728 while(it2->more()) {
1729 const SMDS_MeshElement* n = it2->next();
1744 return static_cast<const SMDS_MeshFace *> (e);
1751 //=======================================================================
1752 //function : FindElement
1754 //=======================================================================
1756 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1758 return myElementIDFactory->MeshElement(IDelem);
1761 //=======================================================================
1762 //function : FindFace
1763 //purpose : find polygon
1764 //=======================================================================
1766 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
1768 int nbnodes = nodes_ids.size();
1769 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1770 for (int inode = 0; inode < nbnodes; inode++) {
1771 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1772 if (node == NULL) return NULL;
1773 poly_nodes[inode] = node;
1775 return FindFace(poly_nodes);
1778 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
1780 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1784 //================================================================================
1786 * \brief Return element based on all given nodes
1787 * \param nodes - node of element
1788 * \param type - type of element
1789 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1790 * \retval const SMDS_MeshElement* - found element or NULL
1792 //================================================================================
1794 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
1795 const SMDSAbs_ElementType type,
1796 const bool noMedium)
1798 if ( nodes.size() > 0 && nodes[0] )
1800 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1803 const SMDS_MeshElement* e = itF->next();
1804 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1805 if ( nbNodesToCheck == nodes.size() )
1807 for ( int i = 1; e && i < nodes.size(); ++ i )
1809 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1810 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1814 return static_cast<const SMDS_MeshFace *> (e);
1821 //=======================================================================
1822 //function : DumpNodes
1824 //=======================================================================
1826 void SMDS_Mesh::DumpNodes() const
1828 MESSAGE("dump nodes of mesh : ");
1829 SMDS_NodeIteratorPtr itnode=nodesIterator();
1830 while(itnode->more()) MESSAGE(itnode->next());
1833 //=======================================================================
1834 //function : Dump0DElements
1836 //=======================================================================
1837 void SMDS_Mesh::Dump0DElements() const
1839 MESSAGE("dump 0D elements of mesh : ");
1840 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
1841 while(it0d->more()) MESSAGE(it0d->next());
1844 //=======================================================================
1845 //function : DumpEdges
1847 //=======================================================================
1849 void SMDS_Mesh::DumpEdges() const
1851 MESSAGE("dump edges of mesh : ");
1852 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1853 while(itedge->more()) MESSAGE(itedge->next());
1856 //=======================================================================
1857 //function : DumpFaces
1859 //=======================================================================
1861 void SMDS_Mesh::DumpFaces() const
1863 MESSAGE("dump faces of mesh : ");
1864 SMDS_FaceIteratorPtr itface=facesIterator();
1865 while(itface->more()) MESSAGE(itface->next());
1868 //=======================================================================
1869 //function : DumpVolumes
1871 //=======================================================================
1873 void SMDS_Mesh::DumpVolumes() const
1875 MESSAGE("dump volumes of mesh : ");
1876 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1877 while(itvol->more()) MESSAGE(itvol->next());
1880 //=======================================================================
1881 //function : DebugStats
1883 //=======================================================================
1885 void SMDS_Mesh::DebugStats() const
1887 MESSAGE("Debug stats of mesh : ");
1889 MESSAGE("===== NODES ====="<<NbNodes());
1890 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
1891 MESSAGE("===== EDGES ====="<<NbEdges());
1892 MESSAGE("===== FACES ====="<<NbFaces());
1893 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1895 MESSAGE("End Debug stats of mesh ");
1899 SMDS_NodeIteratorPtr itnode=nodesIterator();
1900 int sizeofnodes = 0;
1901 int sizeoffaces = 0;
1903 while(itnode->more())
1905 const SMDS_MeshNode *node = itnode->next();
1907 sizeofnodes += sizeof(*node);
1909 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1912 const SMDS_MeshElement *me = it->next();
1913 sizeofnodes += sizeof(me);
1917 SMDS_FaceIteratorPtr itface=facesIterator();
1918 while(itface->more())
1920 const SMDS_MeshElement *face = itface->next();
1921 sizeoffaces += sizeof(*face);
1924 MESSAGE("total size of node elements = " << sizeofnodes);;
1925 MESSAGE("total size of face elements = " << sizeoffaces);;
1930 ///////////////////////////////////////////////////////////////////////////////
1931 /// Return the number of nodes
1932 ///////////////////////////////////////////////////////////////////////////////
1933 int SMDS_Mesh::NbNodes() const
1935 return myNodes.Size();
1938 ///////////////////////////////////////////////////////////////////////////////
1939 /// Return the number of 0D elements
1940 ///////////////////////////////////////////////////////////////////////////////
1941 int SMDS_Mesh::Nb0DElements() const
1943 return my0DElements.Size();
1946 ///////////////////////////////////////////////////////////////////////////////
1947 /// Return the number of edges (including construction edges)
1948 ///////////////////////////////////////////////////////////////////////////////
1949 int SMDS_Mesh::NbEdges() const
1951 return myEdges.Size();
1954 ///////////////////////////////////////////////////////////////////////////////
1955 /// Return the number of faces (including construction faces)
1956 ///////////////////////////////////////////////////////////////////////////////
1957 int SMDS_Mesh::NbFaces() const
1959 return myFaces.Size();
1962 ///////////////////////////////////////////////////////////////////////////////
1963 /// Return the number of volumes
1964 ///////////////////////////////////////////////////////////////////////////////
1965 int SMDS_Mesh::NbVolumes() const
1967 return myVolumes.Size();
1970 ///////////////////////////////////////////////////////////////////////////////
1971 /// Return the number of child mesh of this mesh.
1972 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1973 /// (2003-09-08) of SMESH
1974 ///////////////////////////////////////////////////////////////////////////////
1975 int SMDS_Mesh::NbSubMesh() const
1977 return myChildren.size();
1980 ///////////////////////////////////////////////////////////////////////////////
1981 /// Destroy the mesh and all its elements
1982 /// All pointer on elements owned by this mesh become illegals.
1983 ///////////////////////////////////////////////////////////////////////////////
1984 SMDS_Mesh::~SMDS_Mesh()
1986 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1987 while(itc!=myChildren.end())
1995 delete myNodeIDFactory;
1996 delete myElementIDFactory;
2000 SMDS_ElemIteratorPtr eIt = elementsIterator();
2001 while ( eIt->more() )
2002 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2003 SMDS_NodeIteratorPtr itn = nodesIterator();
2005 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2008 SetOfNodes::Iterator itn(myNodes);
2009 for (; itn.More(); itn.Next())
2012 SetOf0DElements::Iterator it0d (my0DElements);
2013 for (; it0d.More(); it0d.Next())
2015 SMDS_MeshElement* elem = it0d.Value();
2019 SetOfEdges::Iterator ite(myEdges);
2020 for (; ite.More(); ite.Next())
2022 SMDS_MeshElement* elem = ite.Value();
2026 SetOfFaces::Iterator itf(myFaces);
2027 for (; itf.More(); itf.Next())
2029 SMDS_MeshElement* elem = itf.Value();
2033 SetOfVolumes::Iterator itv(myVolumes);
2034 for (; itv.More(); itv.Next())
2036 SMDS_MeshElement* elem = itv.Value();
2041 //================================================================================
2043 * \brief Clear all data
2045 //================================================================================
2047 void SMDS_Mesh::Clear()
2049 if (myParent!=NULL) {
2050 SMDS_ElemIteratorPtr eIt = elementsIterator();
2051 while ( eIt->more() )
2052 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2053 SMDS_NodeIteratorPtr itn = nodesIterator();
2055 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2058 myNodeIDFactory->Clear();
2059 myElementIDFactory->Clear();
2062 SMDS_VolumeIteratorPtr itv = volumesIterator();
2067 SMDS_FaceIteratorPtr itf = facesIterator();
2072 SMDS_EdgeIteratorPtr ite = edgesIterator();
2077 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2078 while (it0d->more())
2079 delete it0d->next();
2080 my0DElements.Clear();
2082 SMDS_NodeIteratorPtr itn = nodesIterator();
2087 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2088 while(itc!=myChildren.end())
2094 ///////////////////////////////////////////////////////////////////////////////
2095 /// Return true if this mesh create faces with edges.
2096 /// A false returned value mean that faces are created with nodes. A concequence
2097 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2098 ///////////////////////////////////////////////////////////////////////////////
2099 bool SMDS_Mesh::hasConstructionEdges()
2101 return myHasConstructionEdges;
2104 ///////////////////////////////////////////////////////////////////////////////
2105 /// Return true if this mesh create volumes with faces
2106 /// A false returned value mean that volumes are created with nodes or edges.
2107 /// (see hasConstructionEdges)
2108 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2110 ///////////////////////////////////////////////////////////////////////////////
2111 bool SMDS_Mesh::hasConstructionFaces()
2113 return myHasConstructionFaces;
2116 ///////////////////////////////////////////////////////////////////////////////
2117 /// Return true if nodes are linked to the finit elements, they are belonging to.
2118 /// Currently, It always return true.
2119 ///////////////////////////////////////////////////////////////////////////////
2120 bool SMDS_Mesh::hasInverseElements()
2122 return myHasInverseElements;
2125 ///////////////////////////////////////////////////////////////////////////////
2126 /// Make this mesh creating construction edges (see hasConstructionEdges)
2127 /// @param b true to have construction edges, else false.
2128 ///////////////////////////////////////////////////////////////////////////////
2129 void SMDS_Mesh::setConstructionEdges(bool b)
2131 myHasConstructionEdges=b;
2134 ///////////////////////////////////////////////////////////////////////////////
2135 /// Make this mesh creating construction faces (see hasConstructionFaces)
2136 /// @param b true to have construction faces, else false.
2137 ///////////////////////////////////////////////////////////////////////////////
2138 void SMDS_Mesh::setConstructionFaces(bool b)
2140 myHasConstructionFaces=b;
2143 ///////////////////////////////////////////////////////////////////////////////
2144 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2145 /// @param b true to link nodes to elements, else false.
2146 ///////////////////////////////////////////////////////////////////////////////
2147 void SMDS_Mesh::setInverseElements(bool b)
2149 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2150 myHasInverseElements=b;
2155 ///////////////////////////////////////////////////////////////////////////////
2156 ///Iterator on NCollection_Map
2157 ///////////////////////////////////////////////////////////////////////////////
2158 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2159 struct MYNCollection_Map_Iterator: public FATHER
2161 typename MAP::Iterator myIterator;
2163 MYNCollection_Map_Iterator(const MAP& map):myIterator(map){}
2167 while(myIterator.More())
2169 if(myIterator.Value()->GetID()!=-1)
2178 ELEM current = (ELEM) myIterator.Value();
2183 //================================================================================
2185 * \brief Iterator on elements in id increasing order
2187 //================================================================================
2189 template <typename ELEM=const SMDS_MeshElement*>
2190 class IdSortedIterator : public SMDS_Iterator<ELEM>
2192 const SMDS_MeshElementIDFactory& myIDFact;
2197 IdSortedIterator(const SMDS_MeshElementIDFactory& fact)
2198 :myIDFact( fact ), myID(1), myMaxID( myIDFact.GetMaxID() ), myElem(0)
2208 ELEM current = myElem;
2209 for ( myElem = 0; myID <= myMaxID && !myElem; ++myID )
2210 myElem = (ELEM) myIDFact.MeshElement( myID );
2216 ///////////////////////////////////////////////////////////////////////////////
2217 /// Return an iterator on nodes of the current mesh factory
2218 ///////////////////////////////////////////////////////////////////////////////
2220 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2222 typedef MYNCollection_Map_Iterator
2223 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2224 typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2225 return ( idInceasingOrder ?
2226 SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory )) :
2227 SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2230 ///////////////////////////////////////////////////////////////////////////////
2231 ///Return an iterator on 0D elements of the current mesh.
2232 ///////////////////////////////////////////////////////////////////////////////
2234 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2236 typedef MYNCollection_Map_Iterator
2237 < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2238 return SMDS_0DElementIteratorPtr(new TIterator(my0DElements));
2241 ///////////////////////////////////////////////////////////////////////////////
2242 ///Return an iterator on edges of the current mesh.
2243 ///////////////////////////////////////////////////////////////////////////////
2245 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2247 typedef MYNCollection_Map_Iterator
2248 < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2249 return SMDS_EdgeIteratorPtr(new TIterator(myEdges));
2252 ///////////////////////////////////////////////////////////////////////////////
2253 ///Return an iterator on faces of the current mesh.
2254 ///////////////////////////////////////////////////////////////////////////////
2256 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2258 typedef MYNCollection_Map_Iterator
2259 < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2260 return SMDS_FaceIteratorPtr(new TIterator(myFaces));
2263 ///////////////////////////////////////////////////////////////////////////////
2264 ///Return an iterator on volumes of the current mesh.
2265 ///////////////////////////////////////////////////////////////////////////////
2267 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2269 typedef MYNCollection_Map_Iterator
2270 < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2271 return SMDS_VolumeIteratorPtr(new TIterator(myVolumes));
2274 ///////////////////////////////////////////////////////////////////////////////
2275 /// Return an iterator on elements of the current mesh factory
2276 ///////////////////////////////////////////////////////////////////////////////
2277 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2282 case SMDSAbs_Volume:
2283 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
2285 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
2287 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
2288 case SMDSAbs_0DElement:
2289 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements));
2291 return myNodeIDFactory->elementsIterator();
2294 return myElementIDFactory->elementsIterator();
2297 ///////////////////////////////////////////////////////////////////////////////
2298 /// Do intersection of sets (more than 2)
2299 ///////////////////////////////////////////////////////////////////////////////
2300 static set<const SMDS_MeshElement*> * intersectionOfSets(
2301 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2303 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2304 set<const SMDS_MeshElement*>* rsetB;
2306 for(int i=0; i<numberOfSets-1; i++)
2308 rsetB=new set<const SMDS_MeshElement*>();
2310 rsetA->begin(), rsetA->end(),
2311 vs[i+1].begin(), vs[i+1].end(),
2312 inserter(*rsetB, rsetB->begin()));
2319 ///////////////////////////////////////////////////////////////////////////////
2320 /// Return the list of finit elements owning the given element
2321 ///////////////////////////////////////////////////////////////////////////////
2322 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2324 int numberOfSets=element->NbNodes();
2325 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2327 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2330 while(itNodes->more())
2332 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2333 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2335 //initSet[i]=set<const SMDS_MeshElement*>();
2337 initSet[i].insert(itFe->next());
2341 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2346 ///////////////////////////////////////////////////////////////////////////////
2347 /// Return the list of nodes used only by the given elements
2348 ///////////////////////////////////////////////////////////////////////////////
2349 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2350 set<const SMDS_MeshElement*>& elements)
2352 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2353 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2355 while(itElements!=elements.end())
2357 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2360 while(itNodes->more())
2362 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2363 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2364 set<const SMDS_MeshElement*> s;
2366 s.insert(itFe->next());
2367 if(s==elements) toReturn->insert(n);
2373 ///////////////////////////////////////////////////////////////////////////////
2374 ///Find the children of an element that are made of given nodes
2375 ///@param setOfChildren The set in which matching children will be inserted
2376 ///@param element The element were to search matching children
2377 ///@param nodes The nodes that the children must have to be selected
2378 ///////////////////////////////////////////////////////////////////////////////
2379 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2380 const SMDS_MeshElement * element,
2381 set<const SMDS_MeshElement*>& nodes)
2383 switch(element->GetType())
2386 MESSAGE("Internal Error: This should not happend");
2388 case SMDSAbs_0DElement:
2394 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2397 const SMDS_MeshElement * e=itn->next();
2398 if(nodes.find(e)!=nodes.end())
2400 setOfChildren.insert(element);
2407 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2410 const SMDS_MeshElement * e=itn->next();
2411 if(nodes.find(e)!=nodes.end())
2413 setOfChildren.insert(element);
2417 if(hasConstructionEdges())
2419 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2421 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2424 case SMDSAbs_Volume:
2426 if(hasConstructionFaces())
2428 SMDS_ElemIteratorPtr ite=element->facesIterator();
2430 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2432 else if(hasConstructionEdges())
2434 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2436 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2442 ///////////////////////////////////////////////////////////////////////////////
2443 ///@param elem The element to delete
2444 ///@param removenodes if true remaining nodes will be removed
2445 ///////////////////////////////////////////////////////////////////////////////
2446 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2447 const bool removenodes)
2449 list<const SMDS_MeshElement *> removedElems;
2450 list<const SMDS_MeshElement *> removedNodes;
2451 RemoveElement( elem, removedElems, removedNodes, removenodes );
2454 ///////////////////////////////////////////////////////////////////////////////
2455 ///@param elem The element to delete
2456 ///@param removedElems contains all removed elements
2457 ///@param removedNodes contains all removed nodes
2458 ///@param removenodes if true remaining nodes will be removed
2459 ///////////////////////////////////////////////////////////////////////////////
2460 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2461 list<const SMDS_MeshElement *>& removedElems,
2462 list<const SMDS_MeshElement *>& removedNodes,
2465 // get finite elements built on elem
2466 set<const SMDS_MeshElement*> * s1;
2467 if (elem->GetType() == SMDSAbs_0DElement ||
2468 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2469 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2470 elem->GetType() == SMDSAbs_Volume)
2472 s1 = new set<const SMDS_MeshElement*>();
2476 s1 = getFinitElements(elem);
2478 // get exclusive nodes (which would become free afterwards)
2479 set<const SMDS_MeshElement*> * s2;
2480 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2482 // do not remove nodes except elem
2483 s2 = new set<const SMDS_MeshElement*>();
2488 s2 = getExclusiveNodes(*s1);
2490 // form the set of finite and construction elements to remove
2491 set<const SMDS_MeshElement*> s3;
2492 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2493 while(it!=s1->end())
2495 addChildrenWithNodes(s3, *it ,*s2);
2499 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2501 // remove finite and construction elements
2505 // Remove element from <InverseElements> of its nodes
2506 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2509 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2510 (const_cast<SMDS_MeshElement *>(itn->next()));
2511 n->RemoveInverseElement( (*it) );
2514 switch((*it)->GetType())
2517 MESSAGE("Internal Error: This should not happen");
2519 case SMDSAbs_0DElement:
2520 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2521 (const_cast<SMDS_MeshElement*>(*it)));
2522 //myInfo.Remove0DElement(*it);
2526 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2527 (const_cast<SMDS_MeshElement*>(*it)));
2528 myInfo.RemoveEdge(*it);
2531 myFaces.Remove(static_cast<SMDS_MeshFace*>
2532 (const_cast<SMDS_MeshElement*>(*it)));
2533 myInfo.RemoveFace(*it);
2535 case SMDSAbs_Volume:
2536 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2537 (const_cast<SMDS_MeshElement*>(*it)));
2538 myInfo.RemoveVolume(*it);
2541 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2542 removedElems.push_back( (*it) );
2543 myElementIDFactory->ReleaseID((*it)->GetID());
2548 // remove exclusive (free) nodes
2552 while(it!=s2->end())
2554 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2555 myNodes.Remove(static_cast<SMDS_MeshNode*>
2556 (const_cast<SMDS_MeshElement*>(*it)));
2558 myNodeIDFactory->ReleaseID((*it)->GetID());
2559 removedNodes.push_back( (*it) );
2570 ///////////////////////////////////////////////////////////////////////////////
2571 ///@param elem The element to delete
2572 ///////////////////////////////////////////////////////////////////////////////
2573 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2575 SMDSAbs_ElementType aType = elem->GetType();
2576 if (aType == SMDSAbs_Node) {
2577 // only free node can be removed by this method
2578 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2579 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2580 if (!itFe->more()) { // free node
2581 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2583 myNodeIDFactory->ReleaseID(elem->GetID());
2587 if (hasConstructionEdges() || hasConstructionFaces())
2588 // this methods is only for meshes without descendants
2591 // Remove element from <InverseElements> of its nodes
2592 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2593 while (itn->more()) {
2594 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2595 (const_cast<SMDS_MeshElement *>(itn->next()));
2596 n->RemoveInverseElement(elem);
2599 // in meshes without descendants elements are always free
2601 case SMDSAbs_0DElement:
2602 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2603 (const_cast<SMDS_MeshElement*>(elem)));
2604 //myInfo.Remove0DElement(elem);
2605 myInfo.remove(elem);
2608 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2609 (const_cast<SMDS_MeshElement*>(elem)));
2610 myInfo.RemoveEdge(elem);
2613 myFaces.Remove(static_cast<SMDS_MeshFace*>
2614 (const_cast<SMDS_MeshElement*>(elem)));
2615 myInfo.RemoveFace(elem);
2617 case SMDSAbs_Volume:
2618 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2619 (const_cast<SMDS_MeshElement*>(elem)));
2620 myInfo.RemoveVolume(elem);
2625 myElementIDFactory->ReleaseID(elem->GetID());
2631 * Checks if the element is present in mesh.
2632 * Useful to determine dead pointers.
2634 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2636 // we should not imply on validity of *elem, so iterate on containers
2637 // of all types in the hope of finding <elem> somewhere there
2638 SMDS_NodeIteratorPtr itn = nodesIterator();
2640 if (elem == itn->next())
2642 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2643 while (it0d->more())
2644 if (elem == it0d->next())
2646 SMDS_EdgeIteratorPtr ite = edgesIterator();
2648 if (elem == ite->next())
2650 SMDS_FaceIteratorPtr itf = facesIterator();
2652 if (elem == itf->next())
2654 SMDS_VolumeIteratorPtr itv = volumesIterator();
2656 if (elem == itv->next())
2661 //=======================================================================
2662 //function : MaxNodeID
2664 //=======================================================================
2666 int SMDS_Mesh::MaxNodeID() const
2668 return myNodeIDFactory->GetMaxID();
2671 //=======================================================================
2672 //function : MinNodeID
2674 //=======================================================================
2676 int SMDS_Mesh::MinNodeID() const
2678 return myNodeIDFactory->GetMinID();
2681 //=======================================================================
2682 //function : MaxElementID
2684 //=======================================================================
2686 int SMDS_Mesh::MaxElementID() const
2688 return myElementIDFactory->GetMaxID();
2691 //=======================================================================
2692 //function : MinElementID
2694 //=======================================================================
2696 int SMDS_Mesh::MinElementID() const
2698 return myElementIDFactory->GetMinID();
2701 //=======================================================================
2702 //function : Renumber
2703 //purpose : Renumber all nodes or elements.
2704 //=======================================================================
2706 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2711 SMDS_MeshElementIDFactory * idFactory =
2712 isNodes ? myNodeIDFactory : myElementIDFactory;
2714 // get existing elements in the order of ID increasing
2715 map<int,SMDS_MeshElement*> elemMap;
2716 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2717 while ( idElemIt->more() ) {
2718 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2719 int id = elem->GetID();
2720 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2722 // release their ids
2723 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2725 // for ( ; elemIt != elemMap.end(); elemIt++ )
2727 // int id = (*elemIt).first;
2728 // idFactory->ReleaseID( id );
2732 elemIt = elemMap.begin();
2733 for ( ; elemIt != elemMap.end(); elemIt++ )
2735 idFactory->BindID( ID, (*elemIt).second );
2740 //=======================================================================
2741 //function : GetElementType
2742 //purpose : Return type of element or node with id
2743 //=======================================================================
2745 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2747 SMDS_MeshElement* elem = 0;
2749 elem = myElementIDFactory->MeshElement( id );
2751 elem = myNodeIDFactory->MeshElement( id );
2755 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2759 return elem->GetType();
2764 //********************************************************************
2765 //********************************************************************
2766 //******** *********
2767 //***** Methods for addition of quadratic elements ******
2768 //******** *********
2769 //********************************************************************
2770 //********************************************************************
2772 //=======================================================================
2773 //function : AddEdgeWithID
2775 //=======================================================================
2776 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2778 return SMDS_Mesh::AddEdgeWithID
2779 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2780 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2781 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2785 //=======================================================================
2786 //function : AddEdge
2788 //=======================================================================
2789 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2790 const SMDS_MeshNode* n2,
2791 const SMDS_MeshNode* n12)
2793 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2796 //=======================================================================
2797 //function : AddEdgeWithID
2799 //=======================================================================
2800 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2801 const SMDS_MeshNode * n2,
2802 const SMDS_MeshNode * n12,
2805 if ( !n1 || !n2 || !n12 ) return 0;
2806 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2807 if(myElementIDFactory->BindID(ID, edge)) {
2808 SMDS_MeshNode *node1,*node2, *node12;
2809 node1 = const_cast<SMDS_MeshNode*>(n1);
2810 node2 = const_cast<SMDS_MeshNode*>(n2);
2811 node12 = const_cast<SMDS_MeshNode*>(n12);
2812 node1->AddInverseElement(edge);
2813 node2->AddInverseElement(edge);
2814 node12->AddInverseElement(edge);
2816 myInfo.myNbQuadEdges++;
2826 //=======================================================================
2827 //function : AddFace
2829 //=======================================================================
2830 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2831 const SMDS_MeshNode * n2,
2832 const SMDS_MeshNode * n3,
2833 const SMDS_MeshNode * n12,
2834 const SMDS_MeshNode * n23,
2835 const SMDS_MeshNode * n31)
2837 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2838 myElementIDFactory->GetFreeID());
2841 //=======================================================================
2842 //function : AddFaceWithID
2844 //=======================================================================
2845 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2846 int n12,int n23,int n31, int ID)
2848 return SMDS_Mesh::AddFaceWithID
2849 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2850 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2851 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2852 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2853 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2854 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2858 //=======================================================================
2859 //function : AddFaceWithID
2861 //=======================================================================
2862 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2863 const SMDS_MeshNode * n2,
2864 const SMDS_MeshNode * n3,
2865 const SMDS_MeshNode * n12,
2866 const SMDS_MeshNode * n23,
2867 const SMDS_MeshNode * n31,
2870 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2871 if(hasConstructionEdges()) {
2872 // creation quadratic edges - not implemented
2875 SMDS_QuadraticFaceOfNodes* face =
2876 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2878 myInfo.myNbQuadTriangles++;
2880 if (!registerElement(ID, face)) {
2881 RemoveElement(face, false);
2888 //=======================================================================
2889 //function : AddFace
2891 //=======================================================================
2892 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2893 const SMDS_MeshNode * n2,
2894 const SMDS_MeshNode * n3,
2895 const SMDS_MeshNode * n4,
2896 const SMDS_MeshNode * n12,
2897 const SMDS_MeshNode * n23,
2898 const SMDS_MeshNode * n34,
2899 const SMDS_MeshNode * n41)
2901 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2902 myElementIDFactory->GetFreeID());
2905 //=======================================================================
2906 //function : AddFaceWithID
2908 //=======================================================================
2909 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2910 int n12,int n23,int n34,int n41, int ID)
2912 return SMDS_Mesh::AddFaceWithID
2913 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2914 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2915 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2916 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2917 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2918 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2919 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2920 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2924 //=======================================================================
2925 //function : AddFaceWithID
2927 //=======================================================================
2928 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2929 const SMDS_MeshNode * n2,
2930 const SMDS_MeshNode * n3,
2931 const SMDS_MeshNode * n4,
2932 const SMDS_MeshNode * n12,
2933 const SMDS_MeshNode * n23,
2934 const SMDS_MeshNode * n34,
2935 const SMDS_MeshNode * n41,
2938 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2939 if(hasConstructionEdges()) {
2940 // creation quadratic edges - not implemented
2942 SMDS_QuadraticFaceOfNodes* face =
2943 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2945 myInfo.myNbQuadQuadrangles++;
2947 if (!registerElement(ID, face)) {
2948 RemoveElement(face, false);
2955 //=======================================================================
2956 //function : AddVolume
2958 //=======================================================================
2959 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2960 const SMDS_MeshNode * n2,
2961 const SMDS_MeshNode * n3,
2962 const SMDS_MeshNode * n4,
2963 const SMDS_MeshNode * n12,
2964 const SMDS_MeshNode * n23,
2965 const SMDS_MeshNode * n31,
2966 const SMDS_MeshNode * n14,
2967 const SMDS_MeshNode * n24,
2968 const SMDS_MeshNode * n34)
2970 int ID = myElementIDFactory->GetFreeID();
2971 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2972 n31, n14, n24, n34, ID);
2973 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2977 //=======================================================================
2978 //function : AddVolumeWithID
2980 //=======================================================================
2981 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2982 int n12,int n23,int n31,
2983 int n14,int n24,int n34, int ID)
2985 return SMDS_Mesh::AddVolumeWithID
2986 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2999 //=======================================================================
3000 //function : AddVolumeWithID
3001 //purpose : 2d order tetrahedron of 10 nodes
3002 //=======================================================================
3003 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3004 const SMDS_MeshNode * n2,
3005 const SMDS_MeshNode * n3,
3006 const SMDS_MeshNode * n4,
3007 const SMDS_MeshNode * n12,
3008 const SMDS_MeshNode * n23,
3009 const SMDS_MeshNode * n31,
3010 const SMDS_MeshNode * n14,
3011 const SMDS_MeshNode * n24,
3012 const SMDS_MeshNode * n34,
3015 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3017 if(hasConstructionFaces()) {
3018 // creation quadratic faces - not implemented
3021 SMDS_QuadraticVolumeOfNodes * volume =
3022 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3023 myVolumes.Add(volume);
3024 myInfo.myNbQuadTetras++;
3026 if (!registerElement(ID, volume)) {
3027 RemoveElement(volume, false);
3034 //=======================================================================
3035 //function : AddVolume
3037 //=======================================================================
3038 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3039 const SMDS_MeshNode * n2,
3040 const SMDS_MeshNode * n3,
3041 const SMDS_MeshNode * n4,
3042 const SMDS_MeshNode * n5,
3043 const SMDS_MeshNode * n12,
3044 const SMDS_MeshNode * n23,
3045 const SMDS_MeshNode * n34,
3046 const SMDS_MeshNode * n41,
3047 const SMDS_MeshNode * n15,
3048 const SMDS_MeshNode * n25,
3049 const SMDS_MeshNode * n35,
3050 const SMDS_MeshNode * n45)
3052 int ID = myElementIDFactory->GetFreeID();
3053 SMDS_MeshVolume * v =
3054 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3055 n15, n25, n35, n45, ID);
3056 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3060 //=======================================================================
3061 //function : AddVolumeWithID
3063 //=======================================================================
3064 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3065 int n12,int n23,int n34,int n41,
3066 int n15,int n25,int n35,int n45, int ID)
3068 return SMDS_Mesh::AddVolumeWithID
3069 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3070 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3071 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3072 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3073 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3074 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3075 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3076 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3077 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3078 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3079 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3080 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3081 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3085 //=======================================================================
3086 //function : AddVolumeWithID
3087 //purpose : 2d order pyramid of 13 nodes
3088 //=======================================================================
3089 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3090 const SMDS_MeshNode * n2,
3091 const SMDS_MeshNode * n3,
3092 const SMDS_MeshNode * n4,
3093 const SMDS_MeshNode * n5,
3094 const SMDS_MeshNode * n12,
3095 const SMDS_MeshNode * n23,
3096 const SMDS_MeshNode * n34,
3097 const SMDS_MeshNode * n41,
3098 const SMDS_MeshNode * n15,
3099 const SMDS_MeshNode * n25,
3100 const SMDS_MeshNode * n35,
3101 const SMDS_MeshNode * n45,
3104 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3105 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3107 if(hasConstructionFaces()) {
3108 // creation quadratic faces - not implemented
3111 SMDS_QuadraticVolumeOfNodes * volume =
3112 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3113 n34,n41,n15,n25,n35,n45);
3114 myVolumes.Add(volume);
3115 myInfo.myNbQuadPyramids++;
3117 if (!registerElement(ID, volume)) {
3118 RemoveElement(volume, false);
3125 //=======================================================================
3126 //function : AddVolume
3128 //=======================================================================
3129 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3130 const SMDS_MeshNode * n2,
3131 const SMDS_MeshNode * n3,
3132 const SMDS_MeshNode * n4,
3133 const SMDS_MeshNode * n5,
3134 const SMDS_MeshNode * n6,
3135 const SMDS_MeshNode * n12,
3136 const SMDS_MeshNode * n23,
3137 const SMDS_MeshNode * n31,
3138 const SMDS_MeshNode * n45,
3139 const SMDS_MeshNode * n56,
3140 const SMDS_MeshNode * n64,
3141 const SMDS_MeshNode * n14,
3142 const SMDS_MeshNode * n25,
3143 const SMDS_MeshNode * n36)
3145 int ID = myElementIDFactory->GetFreeID();
3146 SMDS_MeshVolume * v =
3147 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3148 n45, n56, n64, n14, n25, n36, ID);
3149 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3153 //=======================================================================
3154 //function : AddVolumeWithID
3156 //=======================================================================
3157 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3158 int n4, int n5, int n6,
3159 int n12,int n23,int n31,
3160 int n45,int n56,int n64,
3161 int n14,int n25,int n36, int ID)
3163 return SMDS_Mesh::AddVolumeWithID
3164 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3165 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3166 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3167 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3168 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3169 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3170 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3171 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3172 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3173 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3174 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3175 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3176 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3177 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3178 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3182 //=======================================================================
3183 //function : AddVolumeWithID
3184 //purpose : 2d order Pentahedron with 15 nodes
3185 //=======================================================================
3186 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3187 const SMDS_MeshNode * n2,
3188 const SMDS_MeshNode * n3,
3189 const SMDS_MeshNode * n4,
3190 const SMDS_MeshNode * n5,
3191 const SMDS_MeshNode * n6,
3192 const SMDS_MeshNode * n12,
3193 const SMDS_MeshNode * n23,
3194 const SMDS_MeshNode * n31,
3195 const SMDS_MeshNode * n45,
3196 const SMDS_MeshNode * n56,
3197 const SMDS_MeshNode * n64,
3198 const SMDS_MeshNode * n14,
3199 const SMDS_MeshNode * n25,
3200 const SMDS_MeshNode * n36,
3203 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3204 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3206 if(hasConstructionFaces()) {
3207 // creation quadratic faces - not implemented
3210 SMDS_QuadraticVolumeOfNodes * volume =
3211 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3212 n45,n56,n64,n14,n25,n36);
3213 myVolumes.Add(volume);
3214 myInfo.myNbQuadPrisms++;
3216 if (!registerElement(ID, volume)) {
3217 RemoveElement(volume, false);
3224 //=======================================================================
3225 //function : AddVolume
3227 //=======================================================================
3228 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3229 const SMDS_MeshNode * n2,
3230 const SMDS_MeshNode * n3,
3231 const SMDS_MeshNode * n4,
3232 const SMDS_MeshNode * n5,
3233 const SMDS_MeshNode * n6,
3234 const SMDS_MeshNode * n7,
3235 const SMDS_MeshNode * n8,
3236 const SMDS_MeshNode * n12,
3237 const SMDS_MeshNode * n23,
3238 const SMDS_MeshNode * n34,
3239 const SMDS_MeshNode * n41,
3240 const SMDS_MeshNode * n56,
3241 const SMDS_MeshNode * n67,
3242 const SMDS_MeshNode * n78,
3243 const SMDS_MeshNode * n85,
3244 const SMDS_MeshNode * n15,
3245 const SMDS_MeshNode * n26,
3246 const SMDS_MeshNode * n37,
3247 const SMDS_MeshNode * n48)
3249 int ID = myElementIDFactory->GetFreeID();
3250 SMDS_MeshVolume * v =
3251 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3252 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3253 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3257 //=======================================================================
3258 //function : AddVolumeWithID
3260 //=======================================================================
3261 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3262 int n5, int n6, int n7, int n8,
3263 int n12,int n23,int n34,int n41,
3264 int n56,int n67,int n78,int n85,
3265 int n15,int n26,int n37,int n48, int ID)
3267 return SMDS_Mesh::AddVolumeWithID
3268 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3269 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3270 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3271 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3272 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3273 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3274 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3275 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3276 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3277 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3278 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3279 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3280 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3281 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3282 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3283 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3291 //=======================================================================
3292 //function : AddVolumeWithID
3293 //purpose : 2d order Hexahedrons with 20 nodes
3294 //=======================================================================
3295 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3296 const SMDS_MeshNode * n2,
3297 const SMDS_MeshNode * n3,
3298 const SMDS_MeshNode * n4,
3299 const SMDS_MeshNode * n5,
3300 const SMDS_MeshNode * n6,
3301 const SMDS_MeshNode * n7,
3302 const SMDS_MeshNode * n8,
3303 const SMDS_MeshNode * n12,
3304 const SMDS_MeshNode * n23,
3305 const SMDS_MeshNode * n34,
3306 const SMDS_MeshNode * n41,
3307 const SMDS_MeshNode * n56,
3308 const SMDS_MeshNode * n67,
3309 const SMDS_MeshNode * n78,
3310 const SMDS_MeshNode * n85,
3311 const SMDS_MeshNode * n15,
3312 const SMDS_MeshNode * n26,
3313 const SMDS_MeshNode * n37,
3314 const SMDS_MeshNode * n48,
3317 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3318 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3320 if(hasConstructionFaces()) {
3322 // creation quadratic faces - not implemented
3324 SMDS_QuadraticVolumeOfNodes * volume =
3325 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3326 n56,n67,n78,n85,n15,n26,n37,n48);
3327 myVolumes.Add(volume);
3328 myInfo.myNbQuadHexas++;
3330 if (!registerElement(ID, volume)) {
3331 RemoveElement(volume, false);