1 // Copyright (C) 2007-2010 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
23 // SMESH SMDS : implementaion of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "utilities.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_VolumeOfNodes.hxx"
32 #include "SMDS_VolumeOfFaces.hxx"
33 #include "SMDS_FaceOfNodes.hxx"
34 #include "SMDS_FaceOfEdges.hxx"
35 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
36 #include "SMDS_PolygonalFaceOfNodes.hxx"
37 #include "SMDS_QuadraticEdge.hxx"
38 #include "SMDS_QuadraticFaceOfNodes.hxx"
39 #include "SMDS_QuadraticVolumeOfNodes.hxx"
46 #include <sys/sysinfo.h>
49 // number of added entitis to check memory after
50 #define CHECKMEMORY_INTERVAL 1000
52 //================================================================================
54 * \brief Raise an exception if free memory (ram+swap) too low
55 * \param doNotRaise - if true, suppres exception, just return free memory size
56 * \retval int - amount of available memory in MB or negative number in failure case
58 //================================================================================
60 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
64 int err = sysinfo( &si );
68 static int limit = -1;
70 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
72 limit = WEXITSTATUS(status);
77 limit = int( limit * 1.5 );
79 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
83 const unsigned long Mbyte = 1024 * 1024;
84 // compute separately to avoid overflow
86 ( si.freeram * si.mem_unit ) / Mbyte +
87 ( si.freeswap * si.mem_unit ) / Mbyte;
90 return freeMb - limit;
95 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
97 throw std::bad_alloc();
103 ///////////////////////////////////////////////////////////////////////////////
104 /// Create a new mesh object
105 ///////////////////////////////////////////////////////////////////////////////
106 SMDS_Mesh::SMDS_Mesh()
108 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
109 myElementIDFactory(new SMDS_MeshElementIDFactory()),
110 myHasConstructionEdges(false), myHasConstructionFaces(false),
111 myHasInverseElements(true)
115 ///////////////////////////////////////////////////////////////////////////////
116 /// Create a new child mesh
117 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
118 /// (2003-09-08) of SMESH
119 ///////////////////////////////////////////////////////////////////////////////
120 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
121 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
122 myElementIDFactory(parent->myElementIDFactory),
123 myHasConstructionEdges(false), myHasConstructionFaces(false),
124 myHasInverseElements(true)
128 ///////////////////////////////////////////////////////////////////////////////
129 ///Create a submesh and add it to the current mesh
130 ///////////////////////////////////////////////////////////////////////////////
132 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
134 SMDS_Mesh *submesh = new SMDS_Mesh(this);
135 myChildren.insert(myChildren.end(), submesh);
139 ///////////////////////////////////////////////////////////////////////////////
140 ///create a MeshNode and add it to the current Mesh
141 ///An ID is automatically assigned to the node.
142 ///@return : The created node
143 ///////////////////////////////////////////////////////////////////////////////
145 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
147 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
150 ///////////////////////////////////////////////////////////////////////////////
151 ///create a MeshNode and add it to the current Mesh
152 ///@param ID : The ID of the MeshNode to create
153 ///@return : The created node or NULL if a node with this ID already exists
154 ///////////////////////////////////////////////////////////////////////////////
155 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
157 // find the MeshNode corresponding to ID
158 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
160 if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
161 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
163 myNodeIDFactory->BindID(ID,node);
170 ///////////////////////////////////////////////////////////////////////////////
171 /// create a Mesh0DElement and add it to the current Mesh
172 /// @return : The created Mesh0DElement
173 ///////////////////////////////////////////////////////////////////////////////
174 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
176 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
177 if (!node) return NULL;
178 return SMDS_Mesh::Add0DElementWithID(node, ID);
181 ///////////////////////////////////////////////////////////////////////////////
182 /// create a Mesh0DElement and add it to the current Mesh
183 /// @return : The created Mesh0DElement
184 ///////////////////////////////////////////////////////////////////////////////
185 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
187 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
190 ///////////////////////////////////////////////////////////////////////////////
191 /// Create a new Mesh0DElement and at it to the mesh
192 /// @param idnode ID of the node
193 /// @param ID ID of the 0D element to create
194 /// @return The created 0D element or NULL if an element with this
195 /// ID already exists or if input node is not found.
196 ///////////////////////////////////////////////////////////////////////////////
197 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
201 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
203 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
204 if (myElementIDFactory->BindID(ID, el0d)) {
205 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
206 node->AddInverseElement(el0d);
207 my0DElements.Add(el0d);
208 myInfo.myNb0DElements++;
216 ///////////////////////////////////////////////////////////////////////////////
217 /// create a MeshEdge and add it to the current Mesh
218 /// @return : The created MeshEdge
219 ///////////////////////////////////////////////////////////////////////////////
221 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
223 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
224 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
225 if(!node1 || !node2) return NULL;
226 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
229 ///////////////////////////////////////////////////////////////////////////////
230 /// create a MeshEdge and add it to the current Mesh
231 /// @return : The created MeshEdge
232 ///////////////////////////////////////////////////////////////////////////////
234 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
235 const SMDS_MeshNode * node2)
237 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
240 ///////////////////////////////////////////////////////////////////////////////
241 /// Create a new edge and at it to the mesh
242 /// @param idnode1 ID of the first node
243 /// @param idnode2 ID of the second node
244 /// @param ID ID of the edge to create
245 /// @return The created edge or NULL if an element with this ID already exists or
246 /// if input nodes are not found.
247 ///////////////////////////////////////////////////////////////////////////////
249 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
250 const SMDS_MeshNode * n2,
253 if ( !n1 || !n2 ) return 0;
255 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
257 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
258 if(myElementIDFactory->BindID(ID, edge)) {
259 SMDS_MeshNode *node1,*node2;
260 node1=const_cast<SMDS_MeshNode*>(n1);
261 node2=const_cast<SMDS_MeshNode*>(n2);
262 node1->AddInverseElement(edge);
263 node2->AddInverseElement(edge);
274 ///////////////////////////////////////////////////////////////////////////////
275 /// Add a triangle defined by its nodes. An ID is automatically affected to the
277 ///////////////////////////////////////////////////////////////////////////////
279 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
280 const SMDS_MeshNode * n2,
281 const SMDS_MeshNode * n3)
283 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
286 ///////////////////////////////////////////////////////////////////////////////
287 /// Add a triangle defined by its nodes IDs
288 ///////////////////////////////////////////////////////////////////////////////
290 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
292 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
293 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
294 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
295 if(!node1 || !node2 || !node3) return NULL;
296 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
299 ///////////////////////////////////////////////////////////////////////////////
300 /// Add a triangle defined by its nodes
301 ///////////////////////////////////////////////////////////////////////////////
303 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
304 const SMDS_MeshNode * n2,
305 const SMDS_MeshNode * n3,
308 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
310 if (face && !registerElement(ID, face)) {
311 RemoveElement(face, false);
317 ///////////////////////////////////////////////////////////////////////////////
318 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
320 ///////////////////////////////////////////////////////////////////////////////
322 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
323 const SMDS_MeshNode * n2,
324 const SMDS_MeshNode * n3,
325 const SMDS_MeshNode * n4)
327 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
330 ///////////////////////////////////////////////////////////////////////////////
331 /// Add a quadrangle defined by its nodes IDs
332 ///////////////////////////////////////////////////////////////////////////////
334 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
340 SMDS_MeshNode *node1, *node2, *node3, *node4;
341 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
342 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
343 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
344 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
345 if(!node1 || !node2 || !node3 || !node4) return NULL;
346 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
349 ///////////////////////////////////////////////////////////////////////////////
350 /// Add a quadrangle defined by its nodes
351 ///////////////////////////////////////////////////////////////////////////////
353 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
354 const SMDS_MeshNode * n2,
355 const SMDS_MeshNode * n3,
356 const SMDS_MeshNode * n4,
359 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
361 if (face && !registerElement(ID, face)) {
362 RemoveElement(face, false);
368 ///////////////////////////////////////////////////////////////////////////////
369 /// Add a triangle defined by its edges. An ID is automatically assigned to the
371 ///////////////////////////////////////////////////////////////////////////////
373 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
374 const SMDS_MeshEdge * e2,
375 const SMDS_MeshEdge * e3)
377 if (!hasConstructionEdges())
379 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
382 ///////////////////////////////////////////////////////////////////////////////
383 /// Add a triangle defined by its edges
384 ///////////////////////////////////////////////////////////////////////////////
386 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
387 const SMDS_MeshEdge * e2,
388 const SMDS_MeshEdge * e3,
391 if (!hasConstructionEdges())
393 if ( !e1 || !e2 || !e3 ) return 0;
395 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
397 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
399 myInfo.myNbTriangles++;
401 if (!registerElement(ID, face)) {
402 RemoveElement(face, false);
408 ///////////////////////////////////////////////////////////////////////////////
409 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
411 ///////////////////////////////////////////////////////////////////////////////
413 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
414 const SMDS_MeshEdge * e2,
415 const SMDS_MeshEdge * e3,
416 const SMDS_MeshEdge * e4)
418 if (!hasConstructionEdges())
420 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
423 ///////////////////////////////////////////////////////////////////////////////
424 /// Add a quadrangle defined by its edges
425 ///////////////////////////////////////////////////////////////////////////////
427 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
428 const SMDS_MeshEdge * e2,
429 const SMDS_MeshEdge * e3,
430 const SMDS_MeshEdge * e4,
433 if (!hasConstructionEdges())
435 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
436 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
437 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
439 myInfo.myNbQuadrangles++;
441 if (!registerElement(ID, face))
443 RemoveElement(face, false);
449 ///////////////////////////////////////////////////////////////////////////////
450 ///Create a new tetrahedron and add it to the mesh.
451 ///@return The created tetrahedron
452 ///////////////////////////////////////////////////////////////////////////////
454 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
455 const SMDS_MeshNode * n2,
456 const SMDS_MeshNode * n3,
457 const SMDS_MeshNode * n4)
459 int ID = myElementIDFactory->GetFreeID();
460 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
461 if(v==NULL) myElementIDFactory->ReleaseID(ID);
465 ///////////////////////////////////////////////////////////////////////////////
466 ///Create a new tetrahedron and add it to the mesh.
467 ///@param ID The ID of the new volume
468 ///@return The created tetrahedron or NULL if an element with this ID already exists
469 ///or if input nodes are not found.
470 ///////////////////////////////////////////////////////////////////////////////
472 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
478 SMDS_MeshNode *node1, *node2, *node3, *node4;
479 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
480 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
481 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
482 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
483 if(!node1 || !node2 || !node3 || !node4) return NULL;
484 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
487 ///////////////////////////////////////////////////////////////////////////////
488 ///Create a new tetrahedron and add it to the mesh.
489 ///@param ID The ID of the new volume
490 ///@return The created tetrahedron
491 ///////////////////////////////////////////////////////////////////////////////
493 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
494 const SMDS_MeshNode * n2,
495 const SMDS_MeshNode * n3,
496 const SMDS_MeshNode * n4,
499 SMDS_MeshVolume* volume = 0;
500 if ( !n1 || !n2 || !n3 || !n4) return volume;
501 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
502 if(hasConstructionFaces()) {
503 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
504 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
505 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
506 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
507 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
508 myVolumes.Add(volume);
511 else if(hasConstructionEdges()) {
512 MESSAGE("Error : Not implemented");
516 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
517 myVolumes.Add(volume);
521 if (!registerElement(ID, volume)) {
522 RemoveElement(volume, false);
528 ///////////////////////////////////////////////////////////////////////////////
529 ///Create a new pyramid and add it to the mesh.
530 ///Nodes 1,2,3 and 4 define the base of the pyramid
531 ///@return The created pyramid
532 ///////////////////////////////////////////////////////////////////////////////
534 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
535 const SMDS_MeshNode * n2,
536 const SMDS_MeshNode * n3,
537 const SMDS_MeshNode * n4,
538 const SMDS_MeshNode * n5)
540 int ID = myElementIDFactory->GetFreeID();
541 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
542 if(v==NULL) myElementIDFactory->ReleaseID(ID);
546 ///////////////////////////////////////////////////////////////////////////////
547 ///Create a new pyramid and add it to the mesh.
548 ///Nodes 1,2,3 and 4 define the base of the pyramid
549 ///@param ID The ID of the new volume
550 ///@return The created pyramid or NULL if an element with this ID already exists
551 ///or if input nodes are not found.
552 ///////////////////////////////////////////////////////////////////////////////
554 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
561 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
562 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
563 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
564 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
565 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
566 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
567 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
568 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
571 ///////////////////////////////////////////////////////////////////////////////
572 ///Create a new pyramid and add it to the mesh.
573 ///Nodes 1,2,3 and 4 define the base of the pyramid
574 ///@param ID The ID of the new volume
575 ///@return The created pyramid
576 ///////////////////////////////////////////////////////////////////////////////
578 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
579 const SMDS_MeshNode * n2,
580 const SMDS_MeshNode * n3,
581 const SMDS_MeshNode * n4,
582 const SMDS_MeshNode * n5,
585 SMDS_MeshVolume* volume = 0;
586 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
587 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
588 if(hasConstructionFaces()) {
589 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
590 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
591 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
592 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
593 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
594 myVolumes.Add(volume);
595 myInfo.myNbPyramids++;
597 else if(hasConstructionEdges()) {
598 MESSAGE("Error : Not implemented");
602 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
603 myVolumes.Add(volume);
604 myInfo.myNbPyramids++;
607 if (!registerElement(ID, volume)) {
608 RemoveElement(volume, false);
614 ///////////////////////////////////////////////////////////////////////////////
615 ///Create a new prism and add it to the mesh.
616 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
617 ///@return The created prism
618 ///////////////////////////////////////////////////////////////////////////////
620 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
621 const SMDS_MeshNode * n2,
622 const SMDS_MeshNode * n3,
623 const SMDS_MeshNode * n4,
624 const SMDS_MeshNode * n5,
625 const SMDS_MeshNode * n6)
627 int ID = myElementIDFactory->GetFreeID();
628 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
629 if(v==NULL) myElementIDFactory->ReleaseID(ID);
633 ///////////////////////////////////////////////////////////////////////////////
634 ///Create a new prism and add it to the mesh.
635 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
636 ///@param ID The ID of the new volume
637 ///@return The created prism or NULL if an element with this ID already exists
638 ///or if input nodes are not found.
639 ///////////////////////////////////////////////////////////////////////////////
641 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
649 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
650 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
651 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
652 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
653 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
654 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
655 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
656 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
657 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
660 ///////////////////////////////////////////////////////////////////////////////
661 ///Create a new prism and add it to the mesh.
662 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
663 ///@param ID The ID of the new volume
664 ///@return The created prism
665 ///////////////////////////////////////////////////////////////////////////////
667 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
668 const SMDS_MeshNode * n2,
669 const SMDS_MeshNode * n3,
670 const SMDS_MeshNode * n4,
671 const SMDS_MeshNode * n5,
672 const SMDS_MeshNode * n6,
675 SMDS_MeshVolume* volume = 0;
676 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
677 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
678 if(hasConstructionFaces()) {
679 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
680 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
681 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
682 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
683 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
684 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
685 myVolumes.Add(volume);
688 else if(hasConstructionEdges()) {
689 MESSAGE("Error : Not implemented");
693 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
694 myVolumes.Add(volume);
698 if (!registerElement(ID, volume)) {
699 RemoveElement(volume, false);
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new hexahedron and add it to the mesh.
707 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
708 ///@return The created hexahedron
709 ///////////////////////////////////////////////////////////////////////////////
711 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
712 const SMDS_MeshNode * n2,
713 const SMDS_MeshNode * n3,
714 const SMDS_MeshNode * n4,
715 const SMDS_MeshNode * n5,
716 const SMDS_MeshNode * n6,
717 const SMDS_MeshNode * n7,
718 const SMDS_MeshNode * n8)
720 int ID = myElementIDFactory->GetFreeID();
721 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
722 if(v==NULL) myElementIDFactory->ReleaseID(ID);
726 ///////////////////////////////////////////////////////////////////////////////
727 ///Create a new hexahedron and add it to the mesh.
728 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
729 ///@param ID The ID of the new volume
730 ///@return The created hexahedron or NULL if an element with this ID already
731 ///exists or if input nodes are not found.
732 ///////////////////////////////////////////////////////////////////////////////
734 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
744 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
745 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
746 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
747 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
748 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
749 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
750 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
751 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
752 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
753 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
755 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
759 ///////////////////////////////////////////////////////////////////////////////
760 ///Create a new hexahedron and add it to the mesh.
761 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
762 ///@param ID The ID of the new volume
763 ///@return The created prism or NULL if an element with this ID already exists
764 ///or if input nodes are not found.
765 ///////////////////////////////////////////////////////////////////////////////
767 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
768 const SMDS_MeshNode * n2,
769 const SMDS_MeshNode * n3,
770 const SMDS_MeshNode * n4,
771 const SMDS_MeshNode * n5,
772 const SMDS_MeshNode * n6,
773 const SMDS_MeshNode * n7,
774 const SMDS_MeshNode * n8,
777 SMDS_MeshVolume* volume = 0;
778 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
779 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
780 if(hasConstructionFaces()) {
781 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
782 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
783 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
784 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
785 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
786 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
787 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
788 myVolumes.Add(volume);
791 else if(hasConstructionEdges()) {
792 MESSAGE("Error : Not implemented");
796 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
797 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
798 myVolumes.Add(volume);
802 if (!registerElement(ID, volume)) {
803 RemoveElement(volume, false);
809 ///////////////////////////////////////////////////////////////////////////////
810 ///Create a new tetrahedron defined by its faces and add it to the mesh.
811 ///@return The created tetrahedron
812 ///////////////////////////////////////////////////////////////////////////////
814 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
815 const SMDS_MeshFace * f2,
816 const SMDS_MeshFace * f3,
817 const SMDS_MeshFace * f4)
819 if (!hasConstructionFaces())
821 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
824 ///////////////////////////////////////////////////////////////////////////////
825 ///Create a new tetrahedron defined by its faces and add it to the mesh.
826 ///@param ID The ID of the new volume
827 ///@return The created tetrahedron
828 ///////////////////////////////////////////////////////////////////////////////
830 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
831 const SMDS_MeshFace * f2,
832 const SMDS_MeshFace * f3,
833 const SMDS_MeshFace * f4,
836 if (!hasConstructionFaces())
838 if ( !f1 || !f2 || !f3 || !f4) return 0;
839 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
840 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
841 myVolumes.Add(volume);
844 if (!registerElement(ID, volume)) {
845 RemoveElement(volume, false);
851 ///////////////////////////////////////////////////////////////////////////////
852 ///Create a new pyramid defined by its faces and add it to the mesh.
853 ///@return The created pyramid
854 ///////////////////////////////////////////////////////////////////////////////
856 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
857 const SMDS_MeshFace * f2,
858 const SMDS_MeshFace * f3,
859 const SMDS_MeshFace * f4,
860 const SMDS_MeshFace * f5)
862 if (!hasConstructionFaces())
864 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
867 ///////////////////////////////////////////////////////////////////////////////
868 ///Create a new pyramid defined by its faces and add it to the mesh.
869 ///@param ID The ID of the new volume
870 ///@return The created pyramid
871 ///////////////////////////////////////////////////////////////////////////////
873 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
874 const SMDS_MeshFace * f2,
875 const SMDS_MeshFace * f3,
876 const SMDS_MeshFace * f4,
877 const SMDS_MeshFace * f5,
880 if (!hasConstructionFaces())
882 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
883 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
884 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
885 myVolumes.Add(volume);
886 myInfo.myNbPyramids++;
888 if (!registerElement(ID, volume)) {
889 RemoveElement(volume, false);
895 ///////////////////////////////////////////////////////////////////////////////
896 ///Create a new prism defined by its faces and add it to the mesh.
897 ///@return The created prism
898 ///////////////////////////////////////////////////////////////////////////////
900 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
901 const SMDS_MeshFace * f2,
902 const SMDS_MeshFace * f3,
903 const SMDS_MeshFace * f4,
904 const SMDS_MeshFace * f5,
905 const SMDS_MeshFace * f6)
907 if (!hasConstructionFaces())
909 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
912 ///////////////////////////////////////////////////////////////////////////////
913 ///Create a new prism defined by its faces and add it to the mesh.
914 ///@param ID The ID of the new volume
915 ///@return The created prism
916 ///////////////////////////////////////////////////////////////////////////////
918 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
919 const SMDS_MeshFace * f2,
920 const SMDS_MeshFace * f3,
921 const SMDS_MeshFace * f4,
922 const SMDS_MeshFace * f5,
923 const SMDS_MeshFace * f6,
926 if (!hasConstructionFaces())
928 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
929 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
930 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
931 myVolumes.Add(volume);
934 if (!registerElement(ID, volume)) {
935 RemoveElement(volume, false);
941 ///////////////////////////////////////////////////////////////////////////////
942 /// Add a polygon defined by its nodes IDs
943 ///////////////////////////////////////////////////////////////////////////////
945 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
948 int nbNodes = nodes_ids.size();
949 vector<const SMDS_MeshNode*> nodes (nbNodes);
950 for (int i = 0; i < nbNodes; i++) {
951 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
952 if (!nodes[i]) return NULL;
954 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
957 ///////////////////////////////////////////////////////////////////////////////
958 /// Add a polygon defined by its nodes
959 ///////////////////////////////////////////////////////////////////////////////
961 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
962 (vector<const SMDS_MeshNode*> nodes,
965 SMDS_MeshFace * face;
967 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
968 if (hasConstructionEdges())
970 MESSAGE("Error : Not implemented");
975 for ( int i = 0; i < nodes.size(); ++i )
976 if ( !nodes[ i ] ) return 0;
977 face = new SMDS_PolygonalFaceOfNodes(nodes);
979 myInfo.myNbPolygons++;
982 if (!registerElement(ID, face)) {
983 RemoveElement(face, false);
989 ///////////////////////////////////////////////////////////////////////////////
990 /// Add a polygon defined by its nodes.
991 /// An ID is automatically affected to the created face.
992 ///////////////////////////////////////////////////////////////////////////////
994 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
996 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
999 ///////////////////////////////////////////////////////////////////////////////
1000 /// Create a new polyhedral volume and add it to the mesh.
1001 /// @param ID The ID of the new volume
1002 /// @return The created volume or NULL if an element with this ID already exists
1003 /// or if input nodes are not found.
1004 ///////////////////////////////////////////////////////////////////////////////
1006 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1007 (vector<int> nodes_ids,
1008 vector<int> quantities,
1011 int nbNodes = nodes_ids.size();
1012 vector<const SMDS_MeshNode*> nodes (nbNodes);
1013 for (int i = 0; i < nbNodes; i++) {
1014 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1015 if (!nodes[i]) return NULL;
1017 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1020 ///////////////////////////////////////////////////////////////////////////////
1021 /// Create a new polyhedral volume and add it to the mesh.
1022 /// @param ID The ID of the new volume
1023 /// @return The created volume
1024 ///////////////////////////////////////////////////////////////////////////////
1026 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1027 (vector<const SMDS_MeshNode*> nodes,
1028 vector<int> quantities,
1031 SMDS_MeshVolume* volume;
1032 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1033 if (hasConstructionFaces()) {
1034 MESSAGE("Error : Not implemented");
1036 } else if (hasConstructionEdges()) {
1037 MESSAGE("Error : Not implemented");
1040 for ( int i = 0; i < nodes.size(); ++i )
1041 if ( !nodes[ i ] ) return 0;
1042 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1043 myVolumes.Add(volume);
1044 myInfo.myNbPolyhedrons++;
1047 if (!registerElement(ID, volume)) {
1048 RemoveElement(volume, false);
1054 ///////////////////////////////////////////////////////////////////////////////
1055 /// Create a new polyhedral volume and add it to the mesh.
1056 /// @return The created volume
1057 ///////////////////////////////////////////////////////////////////////////////
1059 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1060 (vector<const SMDS_MeshNode*> nodes,
1061 vector<int> quantities)
1063 int ID = myElementIDFactory->GetFreeID();
1064 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1065 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1069 ///////////////////////////////////////////////////////////////////////////////
1070 /// Registers element with the given ID, maintains inverse connections
1071 ///////////////////////////////////////////////////////////////////////////////
1072 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1074 if (myElementIDFactory->BindID(ID, element)) {
1075 SMDS_ElemIteratorPtr it = element->nodesIterator();
1076 while (it->more()) {
1077 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1078 (const_cast<SMDS_MeshElement*>(it->next()));
1079 node->AddInverseElement(element);
1086 ///////////////////////////////////////////////////////////////////////////////
1087 /// Return the node whose ID is 'ID'.
1088 ///////////////////////////////////////////////////////////////////////////////
1089 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1091 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1094 ///////////////////////////////////////////////////////////////////////////////
1095 ///Create a triangle and add it to the current mesh. This methode do not bind a
1096 ///ID to the create triangle.
1097 ///////////////////////////////////////////////////////////////////////////////
1098 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1099 const SMDS_MeshNode * node2,
1100 const SMDS_MeshNode * node3)
1102 if ( !node1 || !node2 || !node3) return 0;
1103 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1104 if(hasConstructionEdges())
1106 SMDS_MeshEdge *edge1, *edge2, *edge3;
1107 edge1=FindEdgeOrCreate(node1,node2);
1108 edge2=FindEdgeOrCreate(node2,node3);
1109 edge3=FindEdgeOrCreate(node3,node1);
1111 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1113 myInfo.myNbTriangles++;
1118 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1120 myInfo.myNbTriangles++;
1125 ///////////////////////////////////////////////////////////////////////////////
1126 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1127 ///a ID to the create triangle.
1128 ///////////////////////////////////////////////////////////////////////////////
1129 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1130 const SMDS_MeshNode * node2,
1131 const SMDS_MeshNode * node3,
1132 const SMDS_MeshNode * node4)
1134 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1135 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1136 if(hasConstructionEdges())
1138 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1139 edge1=FindEdgeOrCreate(node1,node2);
1140 edge2=FindEdgeOrCreate(node2,node3);
1141 edge3=FindEdgeOrCreate(node3,node4);
1142 edge4=FindEdgeOrCreate(node4,node1);
1144 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1146 myInfo.myNbQuadrangles++;
1151 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1153 myInfo.myNbQuadrangles++;
1158 ///////////////////////////////////////////////////////////////////////////////
1159 /// Remove a node and all the elements which own this node
1160 ///////////////////////////////////////////////////////////////////////////////
1162 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1164 RemoveElement(node, true);
1167 ///////////////////////////////////////////////////////////////////////////////
1168 /// Remove an edge and all the elements which own this edge
1169 ///////////////////////////////////////////////////////////////////////////////
1171 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1173 RemoveElement(elem0d,true);
1176 ///////////////////////////////////////////////////////////////////////////////
1177 /// Remove an edge and all the elements which own this edge
1178 ///////////////////////////////////////////////////////////////////////////////
1180 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1182 RemoveElement(edge,true);
1185 ///////////////////////////////////////////////////////////////////////////////
1186 /// Remove an face and all the elements which own this face
1187 ///////////////////////////////////////////////////////////////////////////////
1189 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1191 RemoveElement(face, true);
1194 ///////////////////////////////////////////////////////////////////////////////
1196 ///////////////////////////////////////////////////////////////////////////////
1198 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1200 RemoveElement(volume, true);
1203 //=======================================================================
1204 //function : RemoveFromParent
1206 //=======================================================================
1208 bool SMDS_Mesh::RemoveFromParent()
1210 if (myParent==NULL) return false;
1211 else return (myParent->RemoveSubMesh(this));
1214 //=======================================================================
1215 //function : RemoveSubMesh
1217 //=======================================================================
1219 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1223 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1224 for (; itmsh!=myChildren.end() && !found; itmsh++)
1226 SMDS_Mesh * submesh = *itmsh;
1227 if (submesh == aMesh)
1230 myChildren.erase(itmsh);
1237 //=======================================================================
1238 //function : ChangeElementNodes
1240 //=======================================================================
1242 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1243 const SMDS_MeshNode * nodes[],
1246 // keep current nodes of elem
1247 set<const SMDS_MeshElement*> oldNodes;
1248 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1250 oldNodes.insert( itn->next() );
1252 if ( !element->IsPoly() )
1253 myInfo.remove( element ); // element may change type
1257 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1258 switch ( elem->GetType() )
1260 case SMDSAbs_0DElement: {
1261 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1262 Ok = elem0d->ChangeNode( nodes[0] );
1265 case SMDSAbs_Edge: {
1266 if ( nbnodes == 2 ) {
1267 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1268 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1270 else if ( nbnodes == 3 ) {
1271 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1272 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1276 case SMDSAbs_Face: {
1277 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1278 Ok = face->ChangeNodes( nodes, nbnodes );
1280 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1281 Ok = QF->ChangeNodes( nodes, nbnodes );
1283 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1284 Ok = face->ChangeNodes(nodes, nbnodes);
1287 case SMDSAbs_Volume: {
1288 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1289 Ok = vol->ChangeNodes( nodes, nbnodes );
1291 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1292 Ok = QV->ChangeNodes( nodes, nbnodes );
1296 MESSAGE ( "WRONG ELEM TYPE");
1299 if ( Ok ) { // update InverseElements
1301 set<const SMDS_MeshElement*>::iterator it;
1303 // AddInverseElement to new nodes
1304 for ( int i = 0; i < nbnodes; i++ ) {
1305 it = oldNodes.find( nodes[i] );
1306 if ( it == oldNodes.end() )
1308 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1310 // remove from oldNodes a node that remains in elem
1311 oldNodes.erase( it );
1313 // RemoveInverseElement from the nodes removed from elem
1314 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1316 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1317 (const_cast<SMDS_MeshElement *>( *it ));
1318 n->RemoveInverseElement( elem );
1322 if ( !element->IsPoly() )
1323 myInfo.add( element ); // element may change type
1328 //=======================================================================
1329 //function : ChangePolyhedronNodes
1330 //purpose : to change nodes of polyhedral volume
1331 //=======================================================================
1332 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1333 const vector<const SMDS_MeshNode*>& nodes,
1334 const vector<int> & quantities)
1336 if (elem->GetType() != SMDSAbs_Volume) {
1337 MESSAGE("WRONG ELEM TYPE");
1341 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1346 // keep current nodes of elem
1347 set<const SMDS_MeshElement*> oldNodes;
1348 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1349 while (itn->more()) {
1350 oldNodes.insert(itn->next());
1354 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1359 // update InverseElements
1361 // AddInverseElement to new nodes
1362 int nbnodes = nodes.size();
1363 set<const SMDS_MeshElement*>::iterator it;
1364 for (int i = 0; i < nbnodes; i++) {
1365 it = oldNodes.find(nodes[i]);
1366 if (it == oldNodes.end()) {
1368 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1370 // remove from oldNodes a node that remains in elem
1375 // RemoveInverseElement from the nodes removed from elem
1376 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1377 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1378 (const_cast<SMDS_MeshElement *>( *it ));
1379 n->RemoveInverseElement(elem);
1386 //=======================================================================
1387 //function : Find0DElement
1389 //=======================================================================
1390 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1392 const SMDS_MeshNode * node = FindNode(idnode);
1393 if(node == NULL) return NULL;
1394 return Find0DElement(node);
1397 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1399 if (!node) return 0;
1400 const SMDS_Mesh0DElement* toReturn = NULL;
1401 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1402 while (it1->more() && (toReturn == NULL)) {
1403 const SMDS_MeshElement* e = it1->next();
1404 if (e->NbNodes() == 1) {
1405 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1411 //=======================================================================
1412 //function : Find0DElementOrCreate
1414 //=======================================================================
1415 SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1417 if (!node) return 0;
1418 SMDS_Mesh0DElement * toReturn = NULL;
1419 toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1420 if (toReturn == NULL) {
1421 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1422 toReturn = new SMDS_Mesh0DElement(node);
1423 my0DElements.Add(toReturn);
1424 myInfo.myNb0DElements++;
1430 //=======================================================================
1431 //function : FindEdge
1433 //=======================================================================
1435 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1437 const SMDS_MeshNode * node1=FindNode(idnode1);
1438 const SMDS_MeshNode * node2=FindNode(idnode2);
1439 if((node1==NULL)||(node2==NULL)) return NULL;
1440 return FindEdge(node1,node2);
1443 //#include "Profiler.h"
1444 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1445 const SMDS_MeshNode * node2)
1447 if ( !node1 ) return 0;
1448 const SMDS_MeshEdge * toReturn=NULL;
1451 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1454 while(it1->more()) {
1455 const SMDS_MeshElement * e = it1->next();
1456 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1457 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1466 //=======================================================================
1467 //function : FindEdgeOrCreate
1469 //=======================================================================
1471 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1472 const SMDS_MeshNode * node2)
1474 if ( !node1 || !node2) return 0;
1475 SMDS_MeshEdge * toReturn=NULL;
1476 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1477 if(toReturn==NULL) {
1478 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1479 toReturn=new SMDS_MeshEdge(node1,node2);
1480 myEdges.Add(toReturn);
1487 //=======================================================================
1488 //function : FindEdge
1490 //=======================================================================
1492 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1495 const SMDS_MeshNode * node1=FindNode(idnode1);
1496 const SMDS_MeshNode * node2=FindNode(idnode2);
1497 const SMDS_MeshNode * node3=FindNode(idnode3);
1498 return FindEdge(node1,node2,node3);
1501 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1502 const SMDS_MeshNode * node2,
1503 const SMDS_MeshNode * node3)
1505 if ( !node1 ) return 0;
1506 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1507 while(it1->more()) {
1508 const SMDS_MeshElement * e = it1->next();
1509 if ( e->NbNodes() == 3 ) {
1510 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1511 while(it2->more()) {
1512 const SMDS_MeshElement* n = it2->next();
1522 return static_cast<const SMDS_MeshEdge *> (e);
1529 //=======================================================================
1530 //function : FindFace
1532 //=======================================================================
1534 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1537 const SMDS_MeshNode * node1=FindNode(idnode1);
1538 const SMDS_MeshNode * node2=FindNode(idnode2);
1539 const SMDS_MeshNode * node3=FindNode(idnode3);
1540 return FindFace(node1, node2, node3);
1543 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1544 const SMDS_MeshNode *node2,
1545 const SMDS_MeshNode *node3)
1547 if ( !node1 ) return 0;
1548 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1549 while(it1->more()) {
1550 const SMDS_MeshElement * e = it1->next();
1551 if ( e->NbNodes() == 3 ) {
1552 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1553 while(it2->more()) {
1554 const SMDS_MeshElement* n = it2->next();
1564 return static_cast<const SMDS_MeshFace *> (e);
1570 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1571 const SMDS_MeshNode *node2,
1572 const SMDS_MeshNode *node3)
1574 SMDS_MeshFace * toReturn=NULL;
1575 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1576 if(toReturn==NULL) {
1577 toReturn = createTriangle(node1,node2,node3);
1583 //=======================================================================
1584 //function : FindFace
1586 //=======================================================================
1588 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1589 int idnode3, int idnode4) const
1591 const SMDS_MeshNode * node1=FindNode(idnode1);
1592 const SMDS_MeshNode * node2=FindNode(idnode2);
1593 const SMDS_MeshNode * node3=FindNode(idnode3);
1594 const SMDS_MeshNode * node4=FindNode(idnode4);
1595 return FindFace(node1, node2, node3, node4);
1598 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1599 const SMDS_MeshNode *node2,
1600 const SMDS_MeshNode *node3,
1601 const SMDS_MeshNode *node4)
1603 if ( !node1 ) return 0;
1604 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1605 while(it1->more()) {
1606 const SMDS_MeshElement * e = it1->next();
1607 if ( e->NbNodes() == 4 ) {
1608 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1609 while(it2->more()) {
1610 const SMDS_MeshElement* n = it2->next();
1621 return static_cast<const SMDS_MeshFace *> (e);
1627 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1628 const SMDS_MeshNode *node2,
1629 const SMDS_MeshNode *node3,
1630 const SMDS_MeshNode *node4)
1632 SMDS_MeshFace * toReturn=NULL;
1633 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1634 if(toReturn==NULL) {
1635 toReturn=createQuadrangle(node1,node2,node3,node4);
1641 //=======================================================================
1642 //function : FindFace
1643 //purpose :quadratic triangle
1644 //=======================================================================
1646 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1647 int idnode3, int idnode4,
1648 int idnode5, int idnode6) const
1650 const SMDS_MeshNode * node1 = FindNode(idnode1);
1651 const SMDS_MeshNode * node2 = FindNode(idnode2);
1652 const SMDS_MeshNode * node3 = FindNode(idnode3);
1653 const SMDS_MeshNode * node4 = FindNode(idnode4);
1654 const SMDS_MeshNode * node5 = FindNode(idnode5);
1655 const SMDS_MeshNode * node6 = FindNode(idnode6);
1656 return FindFace(node1, node2, node3, node4, node5, node6);
1659 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1660 const SMDS_MeshNode *node2,
1661 const SMDS_MeshNode *node3,
1662 const SMDS_MeshNode *node4,
1663 const SMDS_MeshNode *node5,
1664 const SMDS_MeshNode *node6)
1666 if ( !node1 ) return 0;
1667 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1668 while(it1->more()) {
1669 const SMDS_MeshElement * e = it1->next();
1670 if ( e->NbNodes() == 6 ) {
1671 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1672 while(it2->more()) {
1673 const SMDS_MeshElement* n = it2->next();
1686 return static_cast<const SMDS_MeshFace *> (e);
1693 //=======================================================================
1694 //function : FindFace
1695 //purpose : quadratic quadrangle
1696 //=======================================================================
1698 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1699 int idnode3, int idnode4,
1700 int idnode5, int idnode6,
1701 int idnode7, int idnode8) const
1703 const SMDS_MeshNode * node1 = FindNode(idnode1);
1704 const SMDS_MeshNode * node2 = FindNode(idnode2);
1705 const SMDS_MeshNode * node3 = FindNode(idnode3);
1706 const SMDS_MeshNode * node4 = FindNode(idnode4);
1707 const SMDS_MeshNode * node5 = FindNode(idnode5);
1708 const SMDS_MeshNode * node6 = FindNode(idnode6);
1709 const SMDS_MeshNode * node7 = FindNode(idnode7);
1710 const SMDS_MeshNode * node8 = FindNode(idnode8);
1711 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1714 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1715 const SMDS_MeshNode *node2,
1716 const SMDS_MeshNode *node3,
1717 const SMDS_MeshNode *node4,
1718 const SMDS_MeshNode *node5,
1719 const SMDS_MeshNode *node6,
1720 const SMDS_MeshNode *node7,
1721 const SMDS_MeshNode *node8)
1723 if ( !node1 ) return 0;
1724 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1725 while(it1->more()) {
1726 const SMDS_MeshElement * e = it1->next();
1727 if ( e->NbNodes() == 8 ) {
1728 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1729 while(it2->more()) {
1730 const SMDS_MeshElement* n = it2->next();
1745 return static_cast<const SMDS_MeshFace *> (e);
1752 //=======================================================================
1753 //function : FindElement
1755 //=======================================================================
1757 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1759 return myElementIDFactory->MeshElement(IDelem);
1762 //=======================================================================
1763 //function : FindFace
1764 //purpose : find polygon
1765 //=======================================================================
1767 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
1769 int nbnodes = nodes_ids.size();
1770 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1771 for (int inode = 0; inode < nbnodes; inode++) {
1772 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1773 if (node == NULL) return NULL;
1774 poly_nodes[inode] = node;
1776 return FindFace(poly_nodes);
1779 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
1781 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1785 //================================================================================
1787 * \brief Return element based on all given nodes
1788 * \param nodes - node of element
1789 * \param type - type of element
1790 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1791 * \retval const SMDS_MeshElement* - found element or NULL
1793 //================================================================================
1795 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
1796 const SMDSAbs_ElementType type,
1797 const bool noMedium)
1799 if ( nodes.size() > 0 && nodes[0] )
1801 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1804 const SMDS_MeshElement* e = itF->next();
1805 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1806 if ( nbNodesToCheck == nodes.size() )
1808 for ( int i = 1; e && i < nodes.size(); ++ i )
1810 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1811 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1815 return static_cast<const SMDS_MeshFace *> (e);
1822 //=======================================================================
1823 //function : DumpNodes
1825 //=======================================================================
1827 void SMDS_Mesh::DumpNodes() const
1829 MESSAGE("dump nodes of mesh : ");
1830 SMDS_NodeIteratorPtr itnode=nodesIterator();
1831 while(itnode->more()) MESSAGE(itnode->next());
1834 //=======================================================================
1835 //function : Dump0DElements
1837 //=======================================================================
1838 void SMDS_Mesh::Dump0DElements() const
1840 MESSAGE("dump 0D elements of mesh : ");
1841 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
1842 while(it0d->more()) MESSAGE(it0d->next());
1845 //=======================================================================
1846 //function : DumpEdges
1848 //=======================================================================
1850 void SMDS_Mesh::DumpEdges() const
1852 MESSAGE("dump edges of mesh : ");
1853 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1854 while(itedge->more()) MESSAGE(itedge->next());
1857 //=======================================================================
1858 //function : DumpFaces
1860 //=======================================================================
1862 void SMDS_Mesh::DumpFaces() const
1864 MESSAGE("dump faces of mesh : ");
1865 SMDS_FaceIteratorPtr itface=facesIterator();
1866 while(itface->more()) MESSAGE(itface->next());
1869 //=======================================================================
1870 //function : DumpVolumes
1872 //=======================================================================
1874 void SMDS_Mesh::DumpVolumes() const
1876 MESSAGE("dump volumes of mesh : ");
1877 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1878 while(itvol->more()) MESSAGE(itvol->next());
1881 //=======================================================================
1882 //function : DebugStats
1884 //=======================================================================
1886 void SMDS_Mesh::DebugStats() const
1888 MESSAGE("Debug stats of mesh : ");
1890 MESSAGE("===== NODES ====="<<NbNodes());
1891 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
1892 MESSAGE("===== EDGES ====="<<NbEdges());
1893 MESSAGE("===== FACES ====="<<NbFaces());
1894 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1896 MESSAGE("End Debug stats of mesh ");
1900 SMDS_NodeIteratorPtr itnode=nodesIterator();
1901 int sizeofnodes = 0;
1902 int sizeoffaces = 0;
1904 while(itnode->more())
1906 const SMDS_MeshNode *node = itnode->next();
1908 sizeofnodes += sizeof(*node);
1910 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1913 const SMDS_MeshElement *me = it->next();
1914 sizeofnodes += sizeof(me);
1918 SMDS_FaceIteratorPtr itface=facesIterator();
1919 while(itface->more())
1921 const SMDS_MeshElement *face = itface->next();
1922 sizeoffaces += sizeof(*face);
1925 MESSAGE("total size of node elements = " << sizeofnodes);;
1926 MESSAGE("total size of face elements = " << sizeoffaces);;
1931 ///////////////////////////////////////////////////////////////////////////////
1932 /// Return the number of nodes
1933 ///////////////////////////////////////////////////////////////////////////////
1934 int SMDS_Mesh::NbNodes() const
1936 return myNodes.Size();
1939 ///////////////////////////////////////////////////////////////////////////////
1940 /// Return the number of 0D elements
1941 ///////////////////////////////////////////////////////////////////////////////
1942 int SMDS_Mesh::Nb0DElements() const
1944 return my0DElements.Size();
1947 ///////////////////////////////////////////////////////////////////////////////
1948 /// Return the number of edges (including construction edges)
1949 ///////////////////////////////////////////////////////////////////////////////
1950 int SMDS_Mesh::NbEdges() const
1952 return myEdges.Size();
1955 ///////////////////////////////////////////////////////////////////////////////
1956 /// Return the number of faces (including construction faces)
1957 ///////////////////////////////////////////////////////////////////////////////
1958 int SMDS_Mesh::NbFaces() const
1960 return myFaces.Size();
1963 ///////////////////////////////////////////////////////////////////////////////
1964 /// Return the number of volumes
1965 ///////////////////////////////////////////////////////////////////////////////
1966 int SMDS_Mesh::NbVolumes() const
1968 return myVolumes.Size();
1971 ///////////////////////////////////////////////////////////////////////////////
1972 /// Return the number of child mesh of this mesh.
1973 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1974 /// (2003-09-08) of SMESH
1975 ///////////////////////////////////////////////////////////////////////////////
1976 int SMDS_Mesh::NbSubMesh() const
1978 return myChildren.size();
1981 ///////////////////////////////////////////////////////////////////////////////
1982 /// Destroy the mesh and all its elements
1983 /// All pointer on elements owned by this mesh become illegals.
1984 ///////////////////////////////////////////////////////////////////////////////
1985 SMDS_Mesh::~SMDS_Mesh()
1987 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1988 while(itc!=myChildren.end())
1996 delete myNodeIDFactory;
1997 delete myElementIDFactory;
2001 SMDS_ElemIteratorPtr eIt = elementsIterator();
2002 while ( eIt->more() )
2003 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2004 SMDS_NodeIteratorPtr itn = nodesIterator();
2006 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2009 SetOfNodes::Iterator itn(myNodes);
2010 for (; itn.More(); itn.Next())
2013 SetOf0DElements::Iterator it0d (my0DElements);
2014 for (; it0d.More(); it0d.Next())
2016 SMDS_MeshElement* elem = it0d.Value();
2020 SetOfEdges::Iterator ite(myEdges);
2021 for (; ite.More(); ite.Next())
2023 SMDS_MeshElement* elem = ite.Value();
2027 SetOfFaces::Iterator itf(myFaces);
2028 for (; itf.More(); itf.Next())
2030 SMDS_MeshElement* elem = itf.Value();
2034 SetOfVolumes::Iterator itv(myVolumes);
2035 for (; itv.More(); itv.Next())
2037 SMDS_MeshElement* elem = itv.Value();
2042 //================================================================================
2044 * \brief Clear all data
2046 //================================================================================
2048 void SMDS_Mesh::Clear()
2050 if (myParent!=NULL) {
2051 SMDS_ElemIteratorPtr eIt = elementsIterator();
2052 while ( eIt->more() )
2053 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2054 SMDS_NodeIteratorPtr itn = nodesIterator();
2056 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2059 myNodeIDFactory->Clear();
2060 myElementIDFactory->Clear();
2063 SMDS_VolumeIteratorPtr itv = volumesIterator();
2068 SMDS_FaceIteratorPtr itf = facesIterator();
2073 SMDS_EdgeIteratorPtr ite = edgesIterator();
2078 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2079 while (it0d->more())
2080 delete it0d->next();
2081 my0DElements.Clear();
2083 SMDS_NodeIteratorPtr itn = nodesIterator();
2088 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2089 while(itc!=myChildren.end())
2095 ///////////////////////////////////////////////////////////////////////////////
2096 /// Return true if this mesh create faces with edges.
2097 /// A false returned value mean that faces are created with nodes. A concequence
2098 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2099 ///////////////////////////////////////////////////////////////////////////////
2100 bool SMDS_Mesh::hasConstructionEdges()
2102 return myHasConstructionEdges;
2105 ///////////////////////////////////////////////////////////////////////////////
2106 /// Return true if this mesh create volumes with faces
2107 /// A false returned value mean that volumes are created with nodes or edges.
2108 /// (see hasConstructionEdges)
2109 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2111 ///////////////////////////////////////////////////////////////////////////////
2112 bool SMDS_Mesh::hasConstructionFaces()
2114 return myHasConstructionFaces;
2117 ///////////////////////////////////////////////////////////////////////////////
2118 /// Return true if nodes are linked to the finit elements, they are belonging to.
2119 /// Currently, It always return true.
2120 ///////////////////////////////////////////////////////////////////////////////
2121 bool SMDS_Mesh::hasInverseElements()
2123 return myHasInverseElements;
2126 ///////////////////////////////////////////////////////////////////////////////
2127 /// Make this mesh creating construction edges (see hasConstructionEdges)
2128 /// @param b true to have construction edges, else false.
2129 ///////////////////////////////////////////////////////////////////////////////
2130 void SMDS_Mesh::setConstructionEdges(bool b)
2132 myHasConstructionEdges=b;
2135 ///////////////////////////////////////////////////////////////////////////////
2136 /// Make this mesh creating construction faces (see hasConstructionFaces)
2137 /// @param b true to have construction faces, else false.
2138 ///////////////////////////////////////////////////////////////////////////////
2139 void SMDS_Mesh::setConstructionFaces(bool b)
2141 myHasConstructionFaces=b;
2144 ///////////////////////////////////////////////////////////////////////////////
2145 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2146 /// @param b true to link nodes to elements, else false.
2147 ///////////////////////////////////////////////////////////////////////////////
2148 void SMDS_Mesh::setInverseElements(bool b)
2150 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2151 myHasInverseElements=b;
2156 ///////////////////////////////////////////////////////////////////////////////
2157 ///Iterator on NCollection_Map
2158 ///////////////////////////////////////////////////////////////////////////////
2159 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2160 struct MYNCollection_Map_Iterator: public FATHER
2162 typename MAP::Iterator myIterator;
2164 MYNCollection_Map_Iterator(const MAP& map):myIterator(map){}
2168 while(myIterator.More())
2170 if(myIterator.Value()->GetID()!=-1)
2179 ELEM current = (ELEM) myIterator.Value();
2184 //================================================================================
2186 * \brief Iterator on elements in id increasing order
2188 //================================================================================
2190 template <typename ELEM=const SMDS_MeshElement*>
2191 class IdSortedIterator : public SMDS_Iterator<ELEM>
2193 const SMDS_MeshElementIDFactory& myIDFact;
2194 int myID, myMaxID, myNbFound, myTotalNb;
2195 SMDSAbs_ElementType myType;
2199 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2200 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2203 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2215 ELEM current = myElem;
2217 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2218 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2219 && myElem->GetType() != myType )
2222 myNbFound += bool(myElem);
2229 ///////////////////////////////////////////////////////////////////////////////
2230 /// Return an iterator on nodes of the current mesh factory
2231 ///////////////////////////////////////////////////////////////////////////////
2233 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2235 typedef MYNCollection_Map_Iterator
2236 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2237 typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2238 return ( idInceasingOrder ?
2239 SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2240 SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2243 ///////////////////////////////////////////////////////////////////////////////
2244 ///Return an iterator on 0D elements of the current mesh.
2245 ///////////////////////////////////////////////////////////////////////////////
2247 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2249 typedef MYNCollection_Map_Iterator
2250 < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2251 typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator;
2252 return ( idInceasingOrder ?
2253 SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2256 SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2259 ///////////////////////////////////////////////////////////////////////////////
2260 ///Return an iterator on edges of the current mesh.
2261 ///////////////////////////////////////////////////////////////////////////////
2263 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2265 typedef MYNCollection_Map_Iterator
2266 < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2267 typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator;
2268 return ( idInceasingOrder ?
2269 SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2272 SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2275 ///////////////////////////////////////////////////////////////////////////////
2276 ///Return an iterator on faces of the current mesh.
2277 ///////////////////////////////////////////////////////////////////////////////
2279 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2281 typedef MYNCollection_Map_Iterator
2282 < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2283 typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator;
2284 return ( idInceasingOrder ?
2285 SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2288 SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2291 ///////////////////////////////////////////////////////////////////////////////
2292 ///Return an iterator on volumes of the current mesh.
2293 ///////////////////////////////////////////////////////////////////////////////
2295 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2297 typedef MYNCollection_Map_Iterator
2298 < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2299 typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator;
2300 return ( idInceasingOrder ?
2301 SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2304 SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2307 ///////////////////////////////////////////////////////////////////////////////
2308 /// Return an iterator on elements of the current mesh factory
2309 ///////////////////////////////////////////////////////////////////////////////
2310 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2315 case SMDSAbs_Volume:
2316 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
2318 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
2320 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
2321 case SMDSAbs_0DElement:
2322 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements));
2324 return myNodeIDFactory->elementsIterator();
2327 return myElementIDFactory->elementsIterator();
2330 ///////////////////////////////////////////////////////////////////////////////
2331 /// Do intersection of sets (more than 2)
2332 ///////////////////////////////////////////////////////////////////////////////
2333 static set<const SMDS_MeshElement*> * intersectionOfSets(
2334 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2336 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2337 set<const SMDS_MeshElement*>* rsetB;
2339 for(int i=0; i<numberOfSets-1; i++)
2341 rsetB=new set<const SMDS_MeshElement*>();
2343 rsetA->begin(), rsetA->end(),
2344 vs[i+1].begin(), vs[i+1].end(),
2345 inserter(*rsetB, rsetB->begin()));
2352 ///////////////////////////////////////////////////////////////////////////////
2353 /// Return the list of finit elements owning the given element
2354 ///////////////////////////////////////////////////////////////////////////////
2355 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2357 int numberOfSets=element->NbNodes();
2358 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2360 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2363 while(itNodes->more())
2365 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2366 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2368 //initSet[i]=set<const SMDS_MeshElement*>();
2370 initSet[i].insert(itFe->next());
2374 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2379 ///////////////////////////////////////////////////////////////////////////////
2380 /// Return the list of nodes used only by the given elements
2381 ///////////////////////////////////////////////////////////////////////////////
2382 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2383 set<const SMDS_MeshElement*>& elements)
2385 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2386 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2388 while(itElements!=elements.end())
2390 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2393 while(itNodes->more())
2395 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2396 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2397 set<const SMDS_MeshElement*> s;
2399 s.insert(itFe->next());
2400 if(s==elements) toReturn->insert(n);
2406 ///////////////////////////////////////////////////////////////////////////////
2407 ///Find the children of an element that are made of given nodes
2408 ///@param setOfChildren The set in which matching children will be inserted
2409 ///@param element The element were to search matching children
2410 ///@param nodes The nodes that the children must have to be selected
2411 ///////////////////////////////////////////////////////////////////////////////
2412 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2413 const SMDS_MeshElement * element,
2414 set<const SMDS_MeshElement*>& nodes)
2416 switch(element->GetType())
2419 MESSAGE("Internal Error: This should not happend");
2421 case SMDSAbs_0DElement:
2427 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2430 const SMDS_MeshElement * e=itn->next();
2431 if(nodes.find(e)!=nodes.end())
2433 setOfChildren.insert(element);
2440 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2443 const SMDS_MeshElement * e=itn->next();
2444 if(nodes.find(e)!=nodes.end())
2446 setOfChildren.insert(element);
2450 if(hasConstructionEdges())
2452 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2454 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2457 case SMDSAbs_Volume:
2459 if(hasConstructionFaces())
2461 SMDS_ElemIteratorPtr ite=element->facesIterator();
2463 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2465 else if(hasConstructionEdges())
2467 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2469 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2475 ///////////////////////////////////////////////////////////////////////////////
2476 ///@param elem The element to delete
2477 ///@param removenodes if true remaining nodes will be removed
2478 ///////////////////////////////////////////////////////////////////////////////
2479 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2480 const bool removenodes)
2482 list<const SMDS_MeshElement *> removedElems;
2483 list<const SMDS_MeshElement *> removedNodes;
2484 RemoveElement( elem, removedElems, removedNodes, removenodes );
2487 ///////////////////////////////////////////////////////////////////////////////
2488 ///@param elem The element to delete
2489 ///@param removedElems contains all removed elements
2490 ///@param removedNodes contains all removed nodes
2491 ///@param removenodes if true remaining nodes will be removed
2492 ///////////////////////////////////////////////////////////////////////////////
2493 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2494 list<const SMDS_MeshElement *>& removedElems,
2495 list<const SMDS_MeshElement *>& removedNodes,
2498 // get finite elements built on elem
2499 set<const SMDS_MeshElement*> * s1;
2500 if (elem->GetType() == SMDSAbs_0DElement ||
2501 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2502 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2503 elem->GetType() == SMDSAbs_Volume)
2505 s1 = new set<const SMDS_MeshElement*>();
2509 s1 = getFinitElements(elem);
2511 // get exclusive nodes (which would become free afterwards)
2512 set<const SMDS_MeshElement*> * s2;
2513 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2515 // do not remove nodes except elem
2516 s2 = new set<const SMDS_MeshElement*>();
2521 s2 = getExclusiveNodes(*s1);
2523 // form the set of finite and construction elements to remove
2524 set<const SMDS_MeshElement*> s3;
2525 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2526 while(it!=s1->end())
2528 addChildrenWithNodes(s3, *it ,*s2);
2532 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2534 // remove finite and construction elements
2538 // Remove element from <InverseElements> of its nodes
2539 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2542 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2543 (const_cast<SMDS_MeshElement *>(itn->next()));
2544 n->RemoveInverseElement( (*it) );
2547 switch((*it)->GetType())
2550 MESSAGE("Internal Error: This should not happen");
2552 case SMDSAbs_0DElement:
2553 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2554 (const_cast<SMDS_MeshElement*>(*it)));
2555 //myInfo.Remove0DElement(*it);
2559 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2560 (const_cast<SMDS_MeshElement*>(*it)));
2561 myInfo.RemoveEdge(*it);
2564 myFaces.Remove(static_cast<SMDS_MeshFace*>
2565 (const_cast<SMDS_MeshElement*>(*it)));
2566 myInfo.RemoveFace(*it);
2568 case SMDSAbs_Volume:
2569 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2570 (const_cast<SMDS_MeshElement*>(*it)));
2571 myInfo.RemoveVolume(*it);
2574 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2575 removedElems.push_back( (*it) );
2576 myElementIDFactory->ReleaseID((*it)->GetID());
2581 // remove exclusive (free) nodes
2585 while(it!=s2->end())
2587 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2588 myNodes.Remove(static_cast<SMDS_MeshNode*>
2589 (const_cast<SMDS_MeshElement*>(*it)));
2591 myNodeIDFactory->ReleaseID((*it)->GetID());
2592 removedNodes.push_back( (*it) );
2603 ///////////////////////////////////////////////////////////////////////////////
2604 ///@param elem The element to delete
2605 ///////////////////////////////////////////////////////////////////////////////
2606 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2608 SMDSAbs_ElementType aType = elem->GetType();
2609 if (aType == SMDSAbs_Node) {
2610 // only free node can be removed by this method
2611 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2612 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2613 if (!itFe->more()) { // free node
2614 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2616 myNodeIDFactory->ReleaseID(elem->GetID());
2620 if (hasConstructionEdges() || hasConstructionFaces())
2621 // this methods is only for meshes without descendants
2624 // Remove element from <InverseElements> of its nodes
2625 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2626 while (itn->more()) {
2627 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2628 (const_cast<SMDS_MeshElement *>(itn->next()));
2629 n->RemoveInverseElement(elem);
2632 // in meshes without descendants elements are always free
2634 case SMDSAbs_0DElement:
2635 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2636 (const_cast<SMDS_MeshElement*>(elem)));
2637 //myInfo.Remove0DElement(elem);
2638 myInfo.remove(elem);
2641 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2642 (const_cast<SMDS_MeshElement*>(elem)));
2643 myInfo.RemoveEdge(elem);
2646 myFaces.Remove(static_cast<SMDS_MeshFace*>
2647 (const_cast<SMDS_MeshElement*>(elem)));
2648 myInfo.RemoveFace(elem);
2650 case SMDSAbs_Volume:
2651 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2652 (const_cast<SMDS_MeshElement*>(elem)));
2653 myInfo.RemoveVolume(elem);
2658 myElementIDFactory->ReleaseID(elem->GetID());
2664 * Checks if the element is present in mesh.
2665 * Useful to determine dead pointers.
2667 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2669 // we should not imply on validity of *elem, so iterate on containers
2670 // of all types in the hope of finding <elem> somewhere there
2671 SMDS_NodeIteratorPtr itn = nodesIterator();
2673 if (elem == itn->next())
2675 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2676 while (it0d->more())
2677 if (elem == it0d->next())
2679 SMDS_EdgeIteratorPtr ite = edgesIterator();
2681 if (elem == ite->next())
2683 SMDS_FaceIteratorPtr itf = facesIterator();
2685 if (elem == itf->next())
2687 SMDS_VolumeIteratorPtr itv = volumesIterator();
2689 if (elem == itv->next())
2694 //=======================================================================
2695 //function : MaxNodeID
2697 //=======================================================================
2699 int SMDS_Mesh::MaxNodeID() const
2701 return myNodeIDFactory->GetMaxID();
2704 //=======================================================================
2705 //function : MinNodeID
2707 //=======================================================================
2709 int SMDS_Mesh::MinNodeID() const
2711 return myNodeIDFactory->GetMinID();
2714 //=======================================================================
2715 //function : MaxElementID
2717 //=======================================================================
2719 int SMDS_Mesh::MaxElementID() const
2721 return myElementIDFactory->GetMaxID();
2724 //=======================================================================
2725 //function : MinElementID
2727 //=======================================================================
2729 int SMDS_Mesh::MinElementID() const
2731 return myElementIDFactory->GetMinID();
2734 //=======================================================================
2735 //function : Renumber
2736 //purpose : Renumber all nodes or elements.
2737 //=======================================================================
2739 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2744 SMDS_MeshElementIDFactory * idFactory =
2745 isNodes ? myNodeIDFactory : myElementIDFactory;
2747 // get existing elements in the order of ID increasing
2748 map<int,SMDS_MeshElement*> elemMap;
2749 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2750 while ( idElemIt->more() ) {
2751 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2752 int id = elem->GetID();
2753 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2755 // release their ids
2756 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2758 // for ( ; elemIt != elemMap.end(); elemIt++ )
2760 // int id = (*elemIt).first;
2761 // idFactory->ReleaseID( id );
2765 elemIt = elemMap.begin();
2766 for ( ; elemIt != elemMap.end(); elemIt++ )
2768 idFactory->BindID( ID, (*elemIt).second );
2773 //=======================================================================
2774 //function : GetElementType
2775 //purpose : Return type of element or node with id
2776 //=======================================================================
2778 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2780 SMDS_MeshElement* elem = 0;
2782 elem = myElementIDFactory->MeshElement( id );
2784 elem = myNodeIDFactory->MeshElement( id );
2788 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2792 return elem->GetType();
2797 //********************************************************************
2798 //********************************************************************
2799 //******** *********
2800 //***** Methods for addition of quadratic elements ******
2801 //******** *********
2802 //********************************************************************
2803 //********************************************************************
2805 //=======================================================================
2806 //function : AddEdgeWithID
2808 //=======================================================================
2809 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2811 return SMDS_Mesh::AddEdgeWithID
2812 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2813 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2814 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2818 //=======================================================================
2819 //function : AddEdge
2821 //=======================================================================
2822 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2823 const SMDS_MeshNode* n2,
2824 const SMDS_MeshNode* n12)
2826 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2829 //=======================================================================
2830 //function : AddEdgeWithID
2832 //=======================================================================
2833 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2834 const SMDS_MeshNode * n2,
2835 const SMDS_MeshNode * n12,
2838 if ( !n1 || !n2 || !n12 ) return 0;
2839 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2840 if(myElementIDFactory->BindID(ID, edge)) {
2841 SMDS_MeshNode *node1,*node2, *node12;
2842 node1 = const_cast<SMDS_MeshNode*>(n1);
2843 node2 = const_cast<SMDS_MeshNode*>(n2);
2844 node12 = const_cast<SMDS_MeshNode*>(n12);
2845 node1->AddInverseElement(edge);
2846 node2->AddInverseElement(edge);
2847 node12->AddInverseElement(edge);
2849 myInfo.myNbQuadEdges++;
2859 //=======================================================================
2860 //function : AddFace
2862 //=======================================================================
2863 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2864 const SMDS_MeshNode * n2,
2865 const SMDS_MeshNode * n3,
2866 const SMDS_MeshNode * n12,
2867 const SMDS_MeshNode * n23,
2868 const SMDS_MeshNode * n31)
2870 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2871 myElementIDFactory->GetFreeID());
2874 //=======================================================================
2875 //function : AddFaceWithID
2877 //=======================================================================
2878 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2879 int n12,int n23,int n31, int ID)
2881 return SMDS_Mesh::AddFaceWithID
2882 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2883 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2884 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2885 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2886 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2887 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2891 //=======================================================================
2892 //function : AddFaceWithID
2894 //=======================================================================
2895 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2896 const SMDS_MeshNode * n2,
2897 const SMDS_MeshNode * n3,
2898 const SMDS_MeshNode * n12,
2899 const SMDS_MeshNode * n23,
2900 const SMDS_MeshNode * n31,
2903 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2904 if(hasConstructionEdges()) {
2905 // creation quadratic edges - not implemented
2908 SMDS_QuadraticFaceOfNodes* face =
2909 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2911 myInfo.myNbQuadTriangles++;
2913 if (!registerElement(ID, face)) {
2914 RemoveElement(face, false);
2921 //=======================================================================
2922 //function : AddFace
2924 //=======================================================================
2925 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2926 const SMDS_MeshNode * n2,
2927 const SMDS_MeshNode * n3,
2928 const SMDS_MeshNode * n4,
2929 const SMDS_MeshNode * n12,
2930 const SMDS_MeshNode * n23,
2931 const SMDS_MeshNode * n34,
2932 const SMDS_MeshNode * n41)
2934 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2935 myElementIDFactory->GetFreeID());
2938 //=======================================================================
2939 //function : AddFaceWithID
2941 //=======================================================================
2942 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2943 int n12,int n23,int n34,int n41, int ID)
2945 return SMDS_Mesh::AddFaceWithID
2946 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2947 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2948 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2949 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2950 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2951 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2952 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2953 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2957 //=======================================================================
2958 //function : AddFaceWithID
2960 //=======================================================================
2961 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2962 const SMDS_MeshNode * n2,
2963 const SMDS_MeshNode * n3,
2964 const SMDS_MeshNode * n4,
2965 const SMDS_MeshNode * n12,
2966 const SMDS_MeshNode * n23,
2967 const SMDS_MeshNode * n34,
2968 const SMDS_MeshNode * n41,
2971 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2972 if(hasConstructionEdges()) {
2973 // creation quadratic edges - not implemented
2975 SMDS_QuadraticFaceOfNodes* face =
2976 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2978 myInfo.myNbQuadQuadrangles++;
2980 if (!registerElement(ID, face)) {
2981 RemoveElement(face, false);
2988 //=======================================================================
2989 //function : AddVolume
2991 //=======================================================================
2992 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2993 const SMDS_MeshNode * n2,
2994 const SMDS_MeshNode * n3,
2995 const SMDS_MeshNode * n4,
2996 const SMDS_MeshNode * n12,
2997 const SMDS_MeshNode * n23,
2998 const SMDS_MeshNode * n31,
2999 const SMDS_MeshNode * n14,
3000 const SMDS_MeshNode * n24,
3001 const SMDS_MeshNode * n34)
3003 int ID = myElementIDFactory->GetFreeID();
3004 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3005 n31, n14, n24, n34, ID);
3006 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3010 //=======================================================================
3011 //function : AddVolumeWithID
3013 //=======================================================================
3014 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3015 int n12,int n23,int n31,
3016 int n14,int n24,int n34, int ID)
3018 return SMDS_Mesh::AddVolumeWithID
3019 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3020 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3021 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3022 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3023 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3024 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3025 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3026 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3027 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3028 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3032 //=======================================================================
3033 //function : AddVolumeWithID
3034 //purpose : 2d order tetrahedron of 10 nodes
3035 //=======================================================================
3036 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3037 const SMDS_MeshNode * n2,
3038 const SMDS_MeshNode * n3,
3039 const SMDS_MeshNode * n4,
3040 const SMDS_MeshNode * n12,
3041 const SMDS_MeshNode * n23,
3042 const SMDS_MeshNode * n31,
3043 const SMDS_MeshNode * n14,
3044 const SMDS_MeshNode * n24,
3045 const SMDS_MeshNode * n34,
3048 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3050 if(hasConstructionFaces()) {
3051 // creation quadratic faces - not implemented
3054 SMDS_QuadraticVolumeOfNodes * volume =
3055 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3056 myVolumes.Add(volume);
3057 myInfo.myNbQuadTetras++;
3059 if (!registerElement(ID, volume)) {
3060 RemoveElement(volume, false);
3067 //=======================================================================
3068 //function : AddVolume
3070 //=======================================================================
3071 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3072 const SMDS_MeshNode * n2,
3073 const SMDS_MeshNode * n3,
3074 const SMDS_MeshNode * n4,
3075 const SMDS_MeshNode * n5,
3076 const SMDS_MeshNode * n12,
3077 const SMDS_MeshNode * n23,
3078 const SMDS_MeshNode * n34,
3079 const SMDS_MeshNode * n41,
3080 const SMDS_MeshNode * n15,
3081 const SMDS_MeshNode * n25,
3082 const SMDS_MeshNode * n35,
3083 const SMDS_MeshNode * n45)
3085 int ID = myElementIDFactory->GetFreeID();
3086 SMDS_MeshVolume * v =
3087 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3088 n15, n25, n35, n45, ID);
3089 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3093 //=======================================================================
3094 //function : AddVolumeWithID
3096 //=======================================================================
3097 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3098 int n12,int n23,int n34,int n41,
3099 int n15,int n25,int n35,int n45, int ID)
3101 return SMDS_Mesh::AddVolumeWithID
3102 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3103 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3104 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3105 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3106 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3107 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3108 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3109 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3110 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3111 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3112 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3113 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3114 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3118 //=======================================================================
3119 //function : AddVolumeWithID
3120 //purpose : 2d order pyramid of 13 nodes
3121 //=======================================================================
3122 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3123 const SMDS_MeshNode * n2,
3124 const SMDS_MeshNode * n3,
3125 const SMDS_MeshNode * n4,
3126 const SMDS_MeshNode * n5,
3127 const SMDS_MeshNode * n12,
3128 const SMDS_MeshNode * n23,
3129 const SMDS_MeshNode * n34,
3130 const SMDS_MeshNode * n41,
3131 const SMDS_MeshNode * n15,
3132 const SMDS_MeshNode * n25,
3133 const SMDS_MeshNode * n35,
3134 const SMDS_MeshNode * n45,
3137 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3138 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3140 if(hasConstructionFaces()) {
3141 // creation quadratic faces - not implemented
3144 SMDS_QuadraticVolumeOfNodes * volume =
3145 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3146 n34,n41,n15,n25,n35,n45);
3147 myVolumes.Add(volume);
3148 myInfo.myNbQuadPyramids++;
3150 if (!registerElement(ID, volume)) {
3151 RemoveElement(volume, false);
3158 //=======================================================================
3159 //function : AddVolume
3161 //=======================================================================
3162 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3163 const SMDS_MeshNode * n2,
3164 const SMDS_MeshNode * n3,
3165 const SMDS_MeshNode * n4,
3166 const SMDS_MeshNode * n5,
3167 const SMDS_MeshNode * n6,
3168 const SMDS_MeshNode * n12,
3169 const SMDS_MeshNode * n23,
3170 const SMDS_MeshNode * n31,
3171 const SMDS_MeshNode * n45,
3172 const SMDS_MeshNode * n56,
3173 const SMDS_MeshNode * n64,
3174 const SMDS_MeshNode * n14,
3175 const SMDS_MeshNode * n25,
3176 const SMDS_MeshNode * n36)
3178 int ID = myElementIDFactory->GetFreeID();
3179 SMDS_MeshVolume * v =
3180 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3181 n45, n56, n64, n14, n25, n36, ID);
3182 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3186 //=======================================================================
3187 //function : AddVolumeWithID
3189 //=======================================================================
3190 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3191 int n4, int n5, int n6,
3192 int n12,int n23,int n31,
3193 int n45,int n56,int n64,
3194 int n14,int n25,int n36, int ID)
3196 return SMDS_Mesh::AddVolumeWithID
3197 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3198 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3199 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3200 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3201 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3202 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3203 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3204 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3205 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3206 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3207 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3208 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3209 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3210 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3211 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3215 //=======================================================================
3216 //function : AddVolumeWithID
3217 //purpose : 2d order Pentahedron with 15 nodes
3218 //=======================================================================
3219 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3220 const SMDS_MeshNode * n2,
3221 const SMDS_MeshNode * n3,
3222 const SMDS_MeshNode * n4,
3223 const SMDS_MeshNode * n5,
3224 const SMDS_MeshNode * n6,
3225 const SMDS_MeshNode * n12,
3226 const SMDS_MeshNode * n23,
3227 const SMDS_MeshNode * n31,
3228 const SMDS_MeshNode * n45,
3229 const SMDS_MeshNode * n56,
3230 const SMDS_MeshNode * n64,
3231 const SMDS_MeshNode * n14,
3232 const SMDS_MeshNode * n25,
3233 const SMDS_MeshNode * n36,
3236 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3237 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3239 if(hasConstructionFaces()) {
3240 // creation quadratic faces - not implemented
3243 SMDS_QuadraticVolumeOfNodes * volume =
3244 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3245 n45,n56,n64,n14,n25,n36);
3246 myVolumes.Add(volume);
3247 myInfo.myNbQuadPrisms++;
3249 if (!registerElement(ID, volume)) {
3250 RemoveElement(volume, false);
3257 //=======================================================================
3258 //function : AddVolume
3260 //=======================================================================
3261 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3262 const SMDS_MeshNode * n2,
3263 const SMDS_MeshNode * n3,
3264 const SMDS_MeshNode * n4,
3265 const SMDS_MeshNode * n5,
3266 const SMDS_MeshNode * n6,
3267 const SMDS_MeshNode * n7,
3268 const SMDS_MeshNode * n8,
3269 const SMDS_MeshNode * n12,
3270 const SMDS_MeshNode * n23,
3271 const SMDS_MeshNode * n34,
3272 const SMDS_MeshNode * n41,
3273 const SMDS_MeshNode * n56,
3274 const SMDS_MeshNode * n67,
3275 const SMDS_MeshNode * n78,
3276 const SMDS_MeshNode * n85,
3277 const SMDS_MeshNode * n15,
3278 const SMDS_MeshNode * n26,
3279 const SMDS_MeshNode * n37,
3280 const SMDS_MeshNode * n48)
3282 int ID = myElementIDFactory->GetFreeID();
3283 SMDS_MeshVolume * v =
3284 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3285 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3286 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3290 //=======================================================================
3291 //function : AddVolumeWithID
3293 //=======================================================================
3294 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3295 int n5, int n6, int n7, int n8,
3296 int n12,int n23,int n34,int n41,
3297 int n56,int n67,int n78,int n85,
3298 int n15,int n26,int n37,int n48, int ID)
3300 return SMDS_Mesh::AddVolumeWithID
3301 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3302 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3303 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3304 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3305 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3306 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3307 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3308 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3309 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3310 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3311 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3312 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3313 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3314 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3315 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3316 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3317 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3318 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3319 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3320 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3324 //=======================================================================
3325 //function : AddVolumeWithID
3326 //purpose : 2d order Hexahedrons with 20 nodes
3327 //=======================================================================
3328 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3329 const SMDS_MeshNode * n2,
3330 const SMDS_MeshNode * n3,
3331 const SMDS_MeshNode * n4,
3332 const SMDS_MeshNode * n5,
3333 const SMDS_MeshNode * n6,
3334 const SMDS_MeshNode * n7,
3335 const SMDS_MeshNode * n8,
3336 const SMDS_MeshNode * n12,
3337 const SMDS_MeshNode * n23,
3338 const SMDS_MeshNode * n34,
3339 const SMDS_MeshNode * n41,
3340 const SMDS_MeshNode * n56,
3341 const SMDS_MeshNode * n67,
3342 const SMDS_MeshNode * n78,
3343 const SMDS_MeshNode * n85,
3344 const SMDS_MeshNode * n15,
3345 const SMDS_MeshNode * n26,
3346 const SMDS_MeshNode * n37,
3347 const SMDS_MeshNode * n48,
3350 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3351 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3353 if(hasConstructionFaces()) {
3355 // creation quadratic faces - not implemented
3357 SMDS_QuadraticVolumeOfNodes * volume =
3358 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3359 n56,n67,n78,n85,n15,n26,n37,n48);
3360 myVolumes.Add(volume);
3361 myInfo.myNbQuadHexas++;
3363 if (!registerElement(ID, volume)) {
3364 RemoveElement(volume, false);