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;
2198 IdSortedIterator(const SMDS_MeshElementIDFactory& fact)
2199 :myIDFact( fact ), myID(1), myMaxID( myIDFact.GetMaxID() ), myElem(0)
2209 ELEM current = myElem;
2210 for ( myElem = 0; myID <= myMaxID && !myElem; ++myID )
2211 myElem = (ELEM) myIDFact.MeshElement( myID );
2217 ///////////////////////////////////////////////////////////////////////////////
2218 /// Return an iterator on nodes of the current mesh factory
2219 ///////////////////////////////////////////////////////////////////////////////
2221 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2223 typedef MYNCollection_Map_Iterator
2224 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2225 typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2226 return ( idInceasingOrder ?
2227 SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory )) :
2228 SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2231 ///////////////////////////////////////////////////////////////////////////////
2232 ///Return an iterator on 0D elements of the current mesh.
2233 ///////////////////////////////////////////////////////////////////////////////
2235 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2237 typedef MYNCollection_Map_Iterator
2238 < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2239 return SMDS_0DElementIteratorPtr(new TIterator(my0DElements));
2242 ///////////////////////////////////////////////////////////////////////////////
2243 ///Return an iterator on edges of the current mesh.
2244 ///////////////////////////////////////////////////////////////////////////////
2246 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2248 typedef MYNCollection_Map_Iterator
2249 < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2250 return SMDS_EdgeIteratorPtr(new TIterator(myEdges));
2253 ///////////////////////////////////////////////////////////////////////////////
2254 ///Return an iterator on faces of the current mesh.
2255 ///////////////////////////////////////////////////////////////////////////////
2257 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2259 typedef MYNCollection_Map_Iterator
2260 < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2261 return SMDS_FaceIteratorPtr(new TIterator(myFaces));
2264 ///////////////////////////////////////////////////////////////////////////////
2265 ///Return an iterator on volumes of the current mesh.
2266 ///////////////////////////////////////////////////////////////////////////////
2268 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2270 typedef MYNCollection_Map_Iterator
2271 < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2272 return SMDS_VolumeIteratorPtr(new TIterator(myVolumes));
2275 ///////////////////////////////////////////////////////////////////////////////
2276 /// Return an iterator on elements of the current mesh factory
2277 ///////////////////////////////////////////////////////////////////////////////
2278 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2283 case SMDSAbs_Volume:
2284 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
2286 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
2288 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
2289 case SMDSAbs_0DElement:
2290 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements));
2292 return myNodeIDFactory->elementsIterator();
2295 return myElementIDFactory->elementsIterator();
2298 ///////////////////////////////////////////////////////////////////////////////
2299 /// Do intersection of sets (more than 2)
2300 ///////////////////////////////////////////////////////////////////////////////
2301 static set<const SMDS_MeshElement*> * intersectionOfSets(
2302 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2304 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2305 set<const SMDS_MeshElement*>* rsetB;
2307 for(int i=0; i<numberOfSets-1; i++)
2309 rsetB=new set<const SMDS_MeshElement*>();
2311 rsetA->begin(), rsetA->end(),
2312 vs[i+1].begin(), vs[i+1].end(),
2313 inserter(*rsetB, rsetB->begin()));
2320 ///////////////////////////////////////////////////////////////////////////////
2321 /// Return the list of finit elements owning the given element
2322 ///////////////////////////////////////////////////////////////////////////////
2323 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2325 int numberOfSets=element->NbNodes();
2326 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2328 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2331 while(itNodes->more())
2333 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2334 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2336 //initSet[i]=set<const SMDS_MeshElement*>();
2338 initSet[i].insert(itFe->next());
2342 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2347 ///////////////////////////////////////////////////////////////////////////////
2348 /// Return the list of nodes used only by the given elements
2349 ///////////////////////////////////////////////////////////////////////////////
2350 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2351 set<const SMDS_MeshElement*>& elements)
2353 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2354 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2356 while(itElements!=elements.end())
2358 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2361 while(itNodes->more())
2363 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2364 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2365 set<const SMDS_MeshElement*> s;
2367 s.insert(itFe->next());
2368 if(s==elements) toReturn->insert(n);
2374 ///////////////////////////////////////////////////////////////////////////////
2375 ///Find the children of an element that are made of given nodes
2376 ///@param setOfChildren The set in which matching children will be inserted
2377 ///@param element The element were to search matching children
2378 ///@param nodes The nodes that the children must have to be selected
2379 ///////////////////////////////////////////////////////////////////////////////
2380 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2381 const SMDS_MeshElement * element,
2382 set<const SMDS_MeshElement*>& nodes)
2384 switch(element->GetType())
2387 MESSAGE("Internal Error: This should not happend");
2389 case SMDSAbs_0DElement:
2395 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2398 const SMDS_MeshElement * e=itn->next();
2399 if(nodes.find(e)!=nodes.end())
2401 setOfChildren.insert(element);
2408 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2411 const SMDS_MeshElement * e=itn->next();
2412 if(nodes.find(e)!=nodes.end())
2414 setOfChildren.insert(element);
2418 if(hasConstructionEdges())
2420 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2422 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2425 case SMDSAbs_Volume:
2427 if(hasConstructionFaces())
2429 SMDS_ElemIteratorPtr ite=element->facesIterator();
2431 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2433 else if(hasConstructionEdges())
2435 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2437 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2443 ///////////////////////////////////////////////////////////////////////////////
2444 ///@param elem The element to delete
2445 ///@param removenodes if true remaining nodes will be removed
2446 ///////////////////////////////////////////////////////////////////////////////
2447 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2448 const bool removenodes)
2450 list<const SMDS_MeshElement *> removedElems;
2451 list<const SMDS_MeshElement *> removedNodes;
2452 RemoveElement( elem, removedElems, removedNodes, removenodes );
2455 ///////////////////////////////////////////////////////////////////////////////
2456 ///@param elem The element to delete
2457 ///@param removedElems contains all removed elements
2458 ///@param removedNodes contains all removed nodes
2459 ///@param removenodes if true remaining nodes will be removed
2460 ///////////////////////////////////////////////////////////////////////////////
2461 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2462 list<const SMDS_MeshElement *>& removedElems,
2463 list<const SMDS_MeshElement *>& removedNodes,
2466 // get finite elements built on elem
2467 set<const SMDS_MeshElement*> * s1;
2468 if (elem->GetType() == SMDSAbs_0DElement ||
2469 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2470 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2471 elem->GetType() == SMDSAbs_Volume)
2473 s1 = new set<const SMDS_MeshElement*>();
2477 s1 = getFinitElements(elem);
2479 // get exclusive nodes (which would become free afterwards)
2480 set<const SMDS_MeshElement*> * s2;
2481 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2483 // do not remove nodes except elem
2484 s2 = new set<const SMDS_MeshElement*>();
2489 s2 = getExclusiveNodes(*s1);
2491 // form the set of finite and construction elements to remove
2492 set<const SMDS_MeshElement*> s3;
2493 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2494 while(it!=s1->end())
2496 addChildrenWithNodes(s3, *it ,*s2);
2500 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2502 // remove finite and construction elements
2506 // Remove element from <InverseElements> of its nodes
2507 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2510 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2511 (const_cast<SMDS_MeshElement *>(itn->next()));
2512 n->RemoveInverseElement( (*it) );
2515 switch((*it)->GetType())
2518 MESSAGE("Internal Error: This should not happen");
2520 case SMDSAbs_0DElement:
2521 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2522 (const_cast<SMDS_MeshElement*>(*it)));
2523 //myInfo.Remove0DElement(*it);
2527 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2528 (const_cast<SMDS_MeshElement*>(*it)));
2529 myInfo.RemoveEdge(*it);
2532 myFaces.Remove(static_cast<SMDS_MeshFace*>
2533 (const_cast<SMDS_MeshElement*>(*it)));
2534 myInfo.RemoveFace(*it);
2536 case SMDSAbs_Volume:
2537 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2538 (const_cast<SMDS_MeshElement*>(*it)));
2539 myInfo.RemoveVolume(*it);
2542 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2543 removedElems.push_back( (*it) );
2544 myElementIDFactory->ReleaseID((*it)->GetID());
2549 // remove exclusive (free) nodes
2553 while(it!=s2->end())
2555 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2556 myNodes.Remove(static_cast<SMDS_MeshNode*>
2557 (const_cast<SMDS_MeshElement*>(*it)));
2559 myNodeIDFactory->ReleaseID((*it)->GetID());
2560 removedNodes.push_back( (*it) );
2571 ///////////////////////////////////////////////////////////////////////////////
2572 ///@param elem The element to delete
2573 ///////////////////////////////////////////////////////////////////////////////
2574 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2576 SMDSAbs_ElementType aType = elem->GetType();
2577 if (aType == SMDSAbs_Node) {
2578 // only free node can be removed by this method
2579 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2580 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2581 if (!itFe->more()) { // free node
2582 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2584 myNodeIDFactory->ReleaseID(elem->GetID());
2588 if (hasConstructionEdges() || hasConstructionFaces())
2589 // this methods is only for meshes without descendants
2592 // Remove element from <InverseElements> of its nodes
2593 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2594 while (itn->more()) {
2595 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2596 (const_cast<SMDS_MeshElement *>(itn->next()));
2597 n->RemoveInverseElement(elem);
2600 // in meshes without descendants elements are always free
2602 case SMDSAbs_0DElement:
2603 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2604 (const_cast<SMDS_MeshElement*>(elem)));
2605 //myInfo.Remove0DElement(elem);
2606 myInfo.remove(elem);
2609 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2610 (const_cast<SMDS_MeshElement*>(elem)));
2611 myInfo.RemoveEdge(elem);
2614 myFaces.Remove(static_cast<SMDS_MeshFace*>
2615 (const_cast<SMDS_MeshElement*>(elem)));
2616 myInfo.RemoveFace(elem);
2618 case SMDSAbs_Volume:
2619 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2620 (const_cast<SMDS_MeshElement*>(elem)));
2621 myInfo.RemoveVolume(elem);
2626 myElementIDFactory->ReleaseID(elem->GetID());
2632 * Checks if the element is present in mesh.
2633 * Useful to determine dead pointers.
2635 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2637 // we should not imply on validity of *elem, so iterate on containers
2638 // of all types in the hope of finding <elem> somewhere there
2639 SMDS_NodeIteratorPtr itn = nodesIterator();
2641 if (elem == itn->next())
2643 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2644 while (it0d->more())
2645 if (elem == it0d->next())
2647 SMDS_EdgeIteratorPtr ite = edgesIterator();
2649 if (elem == ite->next())
2651 SMDS_FaceIteratorPtr itf = facesIterator();
2653 if (elem == itf->next())
2655 SMDS_VolumeIteratorPtr itv = volumesIterator();
2657 if (elem == itv->next())
2662 //=======================================================================
2663 //function : MaxNodeID
2665 //=======================================================================
2667 int SMDS_Mesh::MaxNodeID() const
2669 return myNodeIDFactory->GetMaxID();
2672 //=======================================================================
2673 //function : MinNodeID
2675 //=======================================================================
2677 int SMDS_Mesh::MinNodeID() const
2679 return myNodeIDFactory->GetMinID();
2682 //=======================================================================
2683 //function : MaxElementID
2685 //=======================================================================
2687 int SMDS_Mesh::MaxElementID() const
2689 return myElementIDFactory->GetMaxID();
2692 //=======================================================================
2693 //function : MinElementID
2695 //=======================================================================
2697 int SMDS_Mesh::MinElementID() const
2699 return myElementIDFactory->GetMinID();
2702 //=======================================================================
2703 //function : Renumber
2704 //purpose : Renumber all nodes or elements.
2705 //=======================================================================
2707 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2712 SMDS_MeshElementIDFactory * idFactory =
2713 isNodes ? myNodeIDFactory : myElementIDFactory;
2715 // get existing elements in the order of ID increasing
2716 map<int,SMDS_MeshElement*> elemMap;
2717 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2718 while ( idElemIt->more() ) {
2719 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2720 int id = elem->GetID();
2721 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2723 // release their ids
2724 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2726 // for ( ; elemIt != elemMap.end(); elemIt++ )
2728 // int id = (*elemIt).first;
2729 // idFactory->ReleaseID( id );
2733 elemIt = elemMap.begin();
2734 for ( ; elemIt != elemMap.end(); elemIt++ )
2736 idFactory->BindID( ID, (*elemIt).second );
2741 //=======================================================================
2742 //function : GetElementType
2743 //purpose : Return type of element or node with id
2744 //=======================================================================
2746 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2748 SMDS_MeshElement* elem = 0;
2750 elem = myElementIDFactory->MeshElement( id );
2752 elem = myNodeIDFactory->MeshElement( id );
2756 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2760 return elem->GetType();
2765 //********************************************************************
2766 //********************************************************************
2767 //******** *********
2768 //***** Methods for addition of quadratic elements ******
2769 //******** *********
2770 //********************************************************************
2771 //********************************************************************
2773 //=======================================================================
2774 //function : AddEdgeWithID
2776 //=======================================================================
2777 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2779 return SMDS_Mesh::AddEdgeWithID
2780 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2781 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2782 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2786 //=======================================================================
2787 //function : AddEdge
2789 //=======================================================================
2790 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2791 const SMDS_MeshNode* n2,
2792 const SMDS_MeshNode* n12)
2794 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2797 //=======================================================================
2798 //function : AddEdgeWithID
2800 //=======================================================================
2801 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2802 const SMDS_MeshNode * n2,
2803 const SMDS_MeshNode * n12,
2806 if ( !n1 || !n2 || !n12 ) return 0;
2807 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2808 if(myElementIDFactory->BindID(ID, edge)) {
2809 SMDS_MeshNode *node1,*node2, *node12;
2810 node1 = const_cast<SMDS_MeshNode*>(n1);
2811 node2 = const_cast<SMDS_MeshNode*>(n2);
2812 node12 = const_cast<SMDS_MeshNode*>(n12);
2813 node1->AddInverseElement(edge);
2814 node2->AddInverseElement(edge);
2815 node12->AddInverseElement(edge);
2817 myInfo.myNbQuadEdges++;
2827 //=======================================================================
2828 //function : AddFace
2830 //=======================================================================
2831 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2832 const SMDS_MeshNode * n2,
2833 const SMDS_MeshNode * n3,
2834 const SMDS_MeshNode * n12,
2835 const SMDS_MeshNode * n23,
2836 const SMDS_MeshNode * n31)
2838 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2839 myElementIDFactory->GetFreeID());
2842 //=======================================================================
2843 //function : AddFaceWithID
2845 //=======================================================================
2846 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2847 int n12,int n23,int n31, int ID)
2849 return SMDS_Mesh::AddFaceWithID
2850 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2851 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2852 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2853 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2854 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2855 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2859 //=======================================================================
2860 //function : AddFaceWithID
2862 //=======================================================================
2863 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(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,
2871 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2872 if(hasConstructionEdges()) {
2873 // creation quadratic edges - not implemented
2876 SMDS_QuadraticFaceOfNodes* face =
2877 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2879 myInfo.myNbQuadTriangles++;
2881 if (!registerElement(ID, face)) {
2882 RemoveElement(face, false);
2889 //=======================================================================
2890 //function : AddFace
2892 //=======================================================================
2893 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2894 const SMDS_MeshNode * n2,
2895 const SMDS_MeshNode * n3,
2896 const SMDS_MeshNode * n4,
2897 const SMDS_MeshNode * n12,
2898 const SMDS_MeshNode * n23,
2899 const SMDS_MeshNode * n34,
2900 const SMDS_MeshNode * n41)
2902 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2903 myElementIDFactory->GetFreeID());
2906 //=======================================================================
2907 //function : AddFaceWithID
2909 //=======================================================================
2910 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2911 int n12,int n23,int n34,int n41, int ID)
2913 return SMDS_Mesh::AddFaceWithID
2914 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2915 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2916 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2917 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2918 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2919 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2920 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2921 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2925 //=======================================================================
2926 //function : AddFaceWithID
2928 //=======================================================================
2929 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2930 const SMDS_MeshNode * n2,
2931 const SMDS_MeshNode * n3,
2932 const SMDS_MeshNode * n4,
2933 const SMDS_MeshNode * n12,
2934 const SMDS_MeshNode * n23,
2935 const SMDS_MeshNode * n34,
2936 const SMDS_MeshNode * n41,
2939 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2940 if(hasConstructionEdges()) {
2941 // creation quadratic edges - not implemented
2943 SMDS_QuadraticFaceOfNodes* face =
2944 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2946 myInfo.myNbQuadQuadrangles++;
2948 if (!registerElement(ID, face)) {
2949 RemoveElement(face, false);
2956 //=======================================================================
2957 //function : AddVolume
2959 //=======================================================================
2960 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2961 const SMDS_MeshNode * n2,
2962 const SMDS_MeshNode * n3,
2963 const SMDS_MeshNode * n4,
2964 const SMDS_MeshNode * n12,
2965 const SMDS_MeshNode * n23,
2966 const SMDS_MeshNode * n31,
2967 const SMDS_MeshNode * n14,
2968 const SMDS_MeshNode * n24,
2969 const SMDS_MeshNode * n34)
2971 int ID = myElementIDFactory->GetFreeID();
2972 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2973 n31, n14, n24, n34, ID);
2974 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2978 //=======================================================================
2979 //function : AddVolumeWithID
2981 //=======================================================================
2982 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2983 int n12,int n23,int n31,
2984 int n14,int n24,int n34, int ID)
2986 return SMDS_Mesh::AddVolumeWithID
2987 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3000 //=======================================================================
3001 //function : AddVolumeWithID
3002 //purpose : 2d order tetrahedron of 10 nodes
3003 //=======================================================================
3004 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3005 const SMDS_MeshNode * n2,
3006 const SMDS_MeshNode * n3,
3007 const SMDS_MeshNode * n4,
3008 const SMDS_MeshNode * n12,
3009 const SMDS_MeshNode * n23,
3010 const SMDS_MeshNode * n31,
3011 const SMDS_MeshNode * n14,
3012 const SMDS_MeshNode * n24,
3013 const SMDS_MeshNode * n34,
3016 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3018 if(hasConstructionFaces()) {
3019 // creation quadratic faces - not implemented
3022 SMDS_QuadraticVolumeOfNodes * volume =
3023 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3024 myVolumes.Add(volume);
3025 myInfo.myNbQuadTetras++;
3027 if (!registerElement(ID, volume)) {
3028 RemoveElement(volume, false);
3035 //=======================================================================
3036 //function : AddVolume
3038 //=======================================================================
3039 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3040 const SMDS_MeshNode * n2,
3041 const SMDS_MeshNode * n3,
3042 const SMDS_MeshNode * n4,
3043 const SMDS_MeshNode * n5,
3044 const SMDS_MeshNode * n12,
3045 const SMDS_MeshNode * n23,
3046 const SMDS_MeshNode * n34,
3047 const SMDS_MeshNode * n41,
3048 const SMDS_MeshNode * n15,
3049 const SMDS_MeshNode * n25,
3050 const SMDS_MeshNode * n35,
3051 const SMDS_MeshNode * n45)
3053 int ID = myElementIDFactory->GetFreeID();
3054 SMDS_MeshVolume * v =
3055 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3056 n15, n25, n35, n45, ID);
3057 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3061 //=======================================================================
3062 //function : AddVolumeWithID
3064 //=======================================================================
3065 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3066 int n12,int n23,int n34,int n41,
3067 int n15,int n25,int n35,int n45, int ID)
3069 return SMDS_Mesh::AddVolumeWithID
3070 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3071 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3072 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3073 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3074 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3075 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3076 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3077 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3078 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3079 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3080 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3081 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3082 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3086 //=======================================================================
3087 //function : AddVolumeWithID
3088 //purpose : 2d order pyramid of 13 nodes
3089 //=======================================================================
3090 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3091 const SMDS_MeshNode * n2,
3092 const SMDS_MeshNode * n3,
3093 const SMDS_MeshNode * n4,
3094 const SMDS_MeshNode * n5,
3095 const SMDS_MeshNode * n12,
3096 const SMDS_MeshNode * n23,
3097 const SMDS_MeshNode * n34,
3098 const SMDS_MeshNode * n41,
3099 const SMDS_MeshNode * n15,
3100 const SMDS_MeshNode * n25,
3101 const SMDS_MeshNode * n35,
3102 const SMDS_MeshNode * n45,
3105 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3106 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3108 if(hasConstructionFaces()) {
3109 // creation quadratic faces - not implemented
3112 SMDS_QuadraticVolumeOfNodes * volume =
3113 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3114 n34,n41,n15,n25,n35,n45);
3115 myVolumes.Add(volume);
3116 myInfo.myNbQuadPyramids++;
3118 if (!registerElement(ID, volume)) {
3119 RemoveElement(volume, false);
3126 //=======================================================================
3127 //function : AddVolume
3129 //=======================================================================
3130 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3131 const SMDS_MeshNode * n2,
3132 const SMDS_MeshNode * n3,
3133 const SMDS_MeshNode * n4,
3134 const SMDS_MeshNode * n5,
3135 const SMDS_MeshNode * n6,
3136 const SMDS_MeshNode * n12,
3137 const SMDS_MeshNode * n23,
3138 const SMDS_MeshNode * n31,
3139 const SMDS_MeshNode * n45,
3140 const SMDS_MeshNode * n56,
3141 const SMDS_MeshNode * n64,
3142 const SMDS_MeshNode * n14,
3143 const SMDS_MeshNode * n25,
3144 const SMDS_MeshNode * n36)
3146 int ID = myElementIDFactory->GetFreeID();
3147 SMDS_MeshVolume * v =
3148 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3149 n45, n56, n64, n14, n25, n36, ID);
3150 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3154 //=======================================================================
3155 //function : AddVolumeWithID
3157 //=======================================================================
3158 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3159 int n4, int n5, int n6,
3160 int n12,int n23,int n31,
3161 int n45,int n56,int n64,
3162 int n14,int n25,int n36, int ID)
3164 return SMDS_Mesh::AddVolumeWithID
3165 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3166 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3167 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3168 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3169 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3170 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3171 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3172 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3173 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3174 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3175 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3176 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3177 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3178 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3179 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3183 //=======================================================================
3184 //function : AddVolumeWithID
3185 //purpose : 2d order Pentahedron with 15 nodes
3186 //=======================================================================
3187 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3188 const SMDS_MeshNode * n2,
3189 const SMDS_MeshNode * n3,
3190 const SMDS_MeshNode * n4,
3191 const SMDS_MeshNode * n5,
3192 const SMDS_MeshNode * n6,
3193 const SMDS_MeshNode * n12,
3194 const SMDS_MeshNode * n23,
3195 const SMDS_MeshNode * n31,
3196 const SMDS_MeshNode * n45,
3197 const SMDS_MeshNode * n56,
3198 const SMDS_MeshNode * n64,
3199 const SMDS_MeshNode * n14,
3200 const SMDS_MeshNode * n25,
3201 const SMDS_MeshNode * n36,
3204 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3205 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3207 if(hasConstructionFaces()) {
3208 // creation quadratic faces - not implemented
3211 SMDS_QuadraticVolumeOfNodes * volume =
3212 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3213 n45,n56,n64,n14,n25,n36);
3214 myVolumes.Add(volume);
3215 myInfo.myNbQuadPrisms++;
3217 if (!registerElement(ID, volume)) {
3218 RemoveElement(volume, false);
3225 //=======================================================================
3226 //function : AddVolume
3228 //=======================================================================
3229 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3230 const SMDS_MeshNode * n2,
3231 const SMDS_MeshNode * n3,
3232 const SMDS_MeshNode * n4,
3233 const SMDS_MeshNode * n5,
3234 const SMDS_MeshNode * n6,
3235 const SMDS_MeshNode * n7,
3236 const SMDS_MeshNode * n8,
3237 const SMDS_MeshNode * n12,
3238 const SMDS_MeshNode * n23,
3239 const SMDS_MeshNode * n34,
3240 const SMDS_MeshNode * n41,
3241 const SMDS_MeshNode * n56,
3242 const SMDS_MeshNode * n67,
3243 const SMDS_MeshNode * n78,
3244 const SMDS_MeshNode * n85,
3245 const SMDS_MeshNode * n15,
3246 const SMDS_MeshNode * n26,
3247 const SMDS_MeshNode * n37,
3248 const SMDS_MeshNode * n48)
3250 int ID = myElementIDFactory->GetFreeID();
3251 SMDS_MeshVolume * v =
3252 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3253 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3254 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3258 //=======================================================================
3259 //function : AddVolumeWithID
3261 //=======================================================================
3262 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3263 int n5, int n6, int n7, int n8,
3264 int n12,int n23,int n34,int n41,
3265 int n56,int n67,int n78,int n85,
3266 int n15,int n26,int n37,int n48, int ID)
3268 return SMDS_Mesh::AddVolumeWithID
3269 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3270 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3271 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3272 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3273 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3274 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3275 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3276 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3277 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3278 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3279 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3280 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3281 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3282 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3283 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3288 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3292 //=======================================================================
3293 //function : AddVolumeWithID
3294 //purpose : 2d order Hexahedrons with 20 nodes
3295 //=======================================================================
3296 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3297 const SMDS_MeshNode * n2,
3298 const SMDS_MeshNode * n3,
3299 const SMDS_MeshNode * n4,
3300 const SMDS_MeshNode * n5,
3301 const SMDS_MeshNode * n6,
3302 const SMDS_MeshNode * n7,
3303 const SMDS_MeshNode * n8,
3304 const SMDS_MeshNode * n12,
3305 const SMDS_MeshNode * n23,
3306 const SMDS_MeshNode * n34,
3307 const SMDS_MeshNode * n41,
3308 const SMDS_MeshNode * n56,
3309 const SMDS_MeshNode * n67,
3310 const SMDS_MeshNode * n78,
3311 const SMDS_MeshNode * n85,
3312 const SMDS_MeshNode * n15,
3313 const SMDS_MeshNode * n26,
3314 const SMDS_MeshNode * n37,
3315 const SMDS_MeshNode * n48,
3318 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3319 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3321 if(hasConstructionFaces()) {
3323 // creation quadratic faces - not implemented
3325 SMDS_QuadraticVolumeOfNodes * volume =
3326 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3327 n56,n67,n78,n85,n15,n26,n37,n48);
3328 myVolumes.Add(volume);
3329 myInfo.myNbQuadHexas++;
3331 if (!registerElement(ID, volume)) {
3332 RemoveElement(volume, false);