1 // SMESH SMDS : implementaion of Salome mesh data structure
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #pragma warning(disable:4786)
26 #include "utilities.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeOfNodes.hxx"
29 #include "SMDS_VolumeOfFaces.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_FaceOfEdges.hxx"
32 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
33 #include "SMDS_PolygonalFaceOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
43 #include <sys/sysinfo.h>
47 //================================================================================
49 * \brief Raise an exception if free memory (ram+swap) too low
50 * \param doNotRaise - if true, suppres exception, just return free memory size
51 * \retval int - amount of available memory in MB or negative number in failure case
53 //================================================================================
55 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
59 int err = sysinfo( &si );
63 static int limit = -1;
65 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
67 limit = WEXITSTATUS(status);
72 limit = int( limit * 1.5 );
74 cout << "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" << endl;
78 const unsigned long Mbyte = 1024 * 1024;
79 // compute separately to avoid overflow
81 ( si.freeram * si.mem_unit ) / Mbyte +
82 ( si.freeswap * si.mem_unit ) / Mbyte;
85 return freeMb - limit;
90 cout<<"SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" << endl;
92 throw std::bad_alloc();
98 ///////////////////////////////////////////////////////////////////////////////
99 /// Create a new mesh object
100 ///////////////////////////////////////////////////////////////////////////////
101 SMDS_Mesh::SMDS_Mesh()
103 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
104 myElementIDFactory(new SMDS_MeshElementIDFactory()),
105 myHasConstructionEdges(false), myHasConstructionFaces(false),
106 myHasInverseElements(true)
110 ///////////////////////////////////////////////////////////////////////////////
111 /// Create a new child mesh
112 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
113 /// (2003-09-08) of SMESH
114 ///////////////////////////////////////////////////////////////////////////////
115 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
116 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
117 myElementIDFactory(parent->myElementIDFactory),
118 myHasConstructionEdges(false), myHasConstructionFaces(false),
119 myHasInverseElements(true)
123 ///////////////////////////////////////////////////////////////////////////////
124 ///Create a submesh and add it to the current mesh
125 ///////////////////////////////////////////////////////////////////////////////
127 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
129 SMDS_Mesh *submesh = new SMDS_Mesh(this);
130 myChildren.insert(myChildren.end(), submesh);
134 ///////////////////////////////////////////////////////////////////////////////
135 ///create a MeshNode and add it to the current Mesh
136 ///An ID is automatically assigned to the node.
137 ///@return : The created node
138 ///////////////////////////////////////////////////////////////////////////////
140 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
142 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
145 ///////////////////////////////////////////////////////////////////////////////
146 ///create a MeshNode and add it to the current Mesh
147 ///@param ID : The ID of the MeshNode to create
148 ///@return : The created node or NULL if a node with this ID already exists
149 ///////////////////////////////////////////////////////////////////////////////
150 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
152 // find the MeshNode corresponding to ID
153 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
156 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
158 myNodeIDFactory->BindID(ID,node);
164 ///////////////////////////////////////////////////////////////////////////////
165 /// create a MeshEdge and add it to the current Mesh
166 /// @return : The created MeshEdge
167 ///////////////////////////////////////////////////////////////////////////////
169 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
171 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
172 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
173 if(!node1 || !node2) return NULL;
174 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
177 ///////////////////////////////////////////////////////////////////////////////
178 /// create a MeshEdge and add it to the current Mesh
179 /// @return : The created MeshEdge
180 ///////////////////////////////////////////////////////////////////////////////
182 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
183 const SMDS_MeshNode * node2)
185 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
188 ///////////////////////////////////////////////////////////////////////////////
189 /// Create a new edge and at it to the mesh
190 /// @param idnode1 ID of the first node
191 /// @param idnode2 ID of the second node
192 /// @param ID ID of the edge to create
193 /// @return The created edge or NULL if an element with this ID already exists or
194 /// if input nodes are not found.
195 ///////////////////////////////////////////////////////////////////////////////
197 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
198 const SMDS_MeshNode * n2,
201 if ( !n1 || !n2 ) return 0;
204 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
205 if(myElementIDFactory->BindID(ID, edge)) {
206 SMDS_MeshNode *node1,*node2;
207 node1=const_cast<SMDS_MeshNode*>(n1);
208 node2=const_cast<SMDS_MeshNode*>(n2);
209 node1->AddInverseElement(edge);
210 node2->AddInverseElement(edge);
220 ///////////////////////////////////////////////////////////////////////////////
221 /// Add a triangle defined by its nodes. An ID is automatically affected to the
223 ///////////////////////////////////////////////////////////////////////////////
225 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
226 const SMDS_MeshNode * n2,
227 const SMDS_MeshNode * n3)
229 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
232 ///////////////////////////////////////////////////////////////////////////////
233 /// Add a triangle defined by its nodes IDs
234 ///////////////////////////////////////////////////////////////////////////////
236 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
238 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
239 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
240 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
241 if(!node1 || !node2 || !node3) return NULL;
242 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
245 ///////////////////////////////////////////////////////////////////////////////
246 /// Add a triangle defined by its nodes
247 ///////////////////////////////////////////////////////////////////////////////
249 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
250 const SMDS_MeshNode * n2,
251 const SMDS_MeshNode * n3,
254 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
256 if (face && !registerElement(ID, face)) {
257 RemoveElement(face, false);
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
266 ///////////////////////////////////////////////////////////////////////////////
268 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
269 const SMDS_MeshNode * n2,
270 const SMDS_MeshNode * n3,
271 const SMDS_MeshNode * n4)
273 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
276 ///////////////////////////////////////////////////////////////////////////////
277 /// Add a quadrangle defined by its nodes IDs
278 ///////////////////////////////////////////////////////////////////////////////
280 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
286 SMDS_MeshNode *node1, *node2, *node3, *node4;
287 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
288 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
289 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
290 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
291 if(!node1 || !node2 || !node3 || !node4) return NULL;
292 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
295 ///////////////////////////////////////////////////////////////////////////////
296 /// Add a quadrangle defined by its nodes
297 ///////////////////////////////////////////////////////////////////////////////
299 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
300 const SMDS_MeshNode * n2,
301 const SMDS_MeshNode * n3,
302 const SMDS_MeshNode * n4,
305 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
307 if (face && !registerElement(ID, face)) {
308 RemoveElement(face, false);
314 ///////////////////////////////////////////////////////////////////////////////
315 /// Add a triangle defined by its edges. An ID is automatically assigned to the
317 ///////////////////////////////////////////////////////////////////////////////
319 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
320 const SMDS_MeshEdge * e2,
321 const SMDS_MeshEdge * e3)
323 if (!hasConstructionEdges())
325 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
328 ///////////////////////////////////////////////////////////////////////////////
329 /// Add a triangle defined by its edges
330 ///////////////////////////////////////////////////////////////////////////////
332 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
333 const SMDS_MeshEdge * e2,
334 const SMDS_MeshEdge * e3,
337 if (!hasConstructionEdges())
339 if ( !e1 || !e2 || !e3 ) return 0;
342 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
345 if (!registerElement(ID, face)) {
346 RemoveElement(face, false);
352 ///////////////////////////////////////////////////////////////////////////////
353 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
355 ///////////////////////////////////////////////////////////////////////////////
357 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
358 const SMDS_MeshEdge * e2,
359 const SMDS_MeshEdge * e3,
360 const SMDS_MeshEdge * e4)
362 if (!hasConstructionEdges())
364 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
367 ///////////////////////////////////////////////////////////////////////////////
368 /// Add a quadrangle defined by its edges
369 ///////////////////////////////////////////////////////////////////////////////
371 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
372 const SMDS_MeshEdge * e2,
373 const SMDS_MeshEdge * e3,
374 const SMDS_MeshEdge * e4,
377 if (!hasConstructionEdges())
379 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
381 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
384 if (!registerElement(ID, face))
386 RemoveElement(face, false);
392 ///////////////////////////////////////////////////////////////////////////////
393 ///Create a new tetrahedron and add it to the mesh.
394 ///@return The created tetrahedron
395 ///////////////////////////////////////////////////////////////////////////////
397 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
398 const SMDS_MeshNode * n2,
399 const SMDS_MeshNode * n3,
400 const SMDS_MeshNode * n4)
402 int ID = myElementIDFactory->GetFreeID();
403 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
404 if(v==NULL) myElementIDFactory->ReleaseID(ID);
408 ///////////////////////////////////////////////////////////////////////////////
409 ///Create a new tetrahedron and add it to the mesh.
410 ///@param ID The ID of the new volume
411 ///@return The created tetrahedron or NULL if an element with this ID already exists
412 ///or if input nodes are not found.
413 ///////////////////////////////////////////////////////////////////////////////
415 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
421 SMDS_MeshNode *node1, *node2, *node3, *node4;
422 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
423 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
424 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
425 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
426 if(!node1 || !node2 || !node3 || !node4) return NULL;
427 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
430 ///////////////////////////////////////////////////////////////////////////////
431 ///Create a new tetrahedron and add it to the mesh.
432 ///@param ID The ID of the new volume
433 ///@return The created tetrahedron
434 ///////////////////////////////////////////////////////////////////////////////
436 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
437 const SMDS_MeshNode * n2,
438 const SMDS_MeshNode * n3,
439 const SMDS_MeshNode * n4,
442 SMDS_MeshVolume* volume = 0;
443 if ( !n1 || !n2 || !n3 || !n4) return volume;
445 if(hasConstructionFaces()) {
446 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
447 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
448 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
449 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
450 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
451 myVolumes.Add(volume);
453 else if(hasConstructionEdges()) {
454 MESSAGE("Error : Not implemented");
458 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
459 myVolumes.Add(volume);
462 if (!registerElement(ID, volume)) {
463 RemoveElement(volume, false);
469 ///////////////////////////////////////////////////////////////////////////////
470 ///Create a new pyramid and add it to the mesh.
471 ///Nodes 1,2,3 and 4 define the base of the pyramid
472 ///@return The created pyramid
473 ///////////////////////////////////////////////////////////////////////////////
475 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
476 const SMDS_MeshNode * n2,
477 const SMDS_MeshNode * n3,
478 const SMDS_MeshNode * n4,
479 const SMDS_MeshNode * n5)
481 int ID = myElementIDFactory->GetFreeID();
482 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
483 if(v==NULL) myElementIDFactory->ReleaseID(ID);
487 ///////////////////////////////////////////////////////////////////////////////
488 ///Create a new pyramid and add it to the mesh.
489 ///Nodes 1,2,3 and 4 define the base of the pyramid
490 ///@param ID The ID of the new volume
491 ///@return The created pyramid or NULL if an element with this ID already exists
492 ///or if input nodes are not found.
493 ///////////////////////////////////////////////////////////////////////////////
495 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
502 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
503 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
504 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
505 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
506 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
507 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
508 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
509 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
512 ///////////////////////////////////////////////////////////////////////////////
513 ///Create a new pyramid and add it to the mesh.
514 ///Nodes 1,2,3 and 4 define the base of the pyramid
515 ///@param ID The ID of the new volume
516 ///@return The created pyramid
517 ///////////////////////////////////////////////////////////////////////////////
519 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
520 const SMDS_MeshNode * n2,
521 const SMDS_MeshNode * n3,
522 const SMDS_MeshNode * n4,
523 const SMDS_MeshNode * n5,
526 SMDS_MeshVolume* volume = 0;
527 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
529 if(hasConstructionFaces()) {
530 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
531 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
532 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
533 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
534 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
535 myVolumes.Add(volume);
537 else if(hasConstructionEdges()) {
538 MESSAGE("Error : Not implemented");
542 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
543 myVolumes.Add(volume);
546 if (!registerElement(ID, volume)) {
547 RemoveElement(volume, false);
553 ///////////////////////////////////////////////////////////////////////////////
554 ///Create a new prism and add it to the mesh.
555 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
556 ///@return The created prism
557 ///////////////////////////////////////////////////////////////////////////////
559 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
560 const SMDS_MeshNode * n2,
561 const SMDS_MeshNode * n3,
562 const SMDS_MeshNode * n4,
563 const SMDS_MeshNode * n5,
564 const SMDS_MeshNode * n6)
566 int ID = myElementIDFactory->GetFreeID();
567 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
568 if(v==NULL) myElementIDFactory->ReleaseID(ID);
572 ///////////////////////////////////////////////////////////////////////////////
573 ///Create a new prism and add it to the mesh.
574 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
575 ///@param ID The ID of the new volume
576 ///@return The created prism or NULL if an element with this ID already exists
577 ///or if input nodes are not found.
578 ///////////////////////////////////////////////////////////////////////////////
580 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
588 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
589 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
590 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
591 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
592 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
593 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
594 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
595 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
596 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
599 ///////////////////////////////////////////////////////////////////////////////
600 ///Create a new prism and add it to the mesh.
601 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
602 ///@param ID The ID of the new volume
603 ///@return The created prism
604 ///////////////////////////////////////////////////////////////////////////////
606 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
607 const SMDS_MeshNode * n2,
608 const SMDS_MeshNode * n3,
609 const SMDS_MeshNode * n4,
610 const SMDS_MeshNode * n5,
611 const SMDS_MeshNode * n6,
614 SMDS_MeshVolume* volume = 0;
615 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
617 if(hasConstructionFaces()) {
618 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
619 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
620 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
621 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
622 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
623 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
624 myVolumes.Add(volume);
626 else if(hasConstructionEdges()) {
627 MESSAGE("Error : Not implemented");
631 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
632 myVolumes.Add(volume);
635 if (!registerElement(ID, volume)) {
636 RemoveElement(volume, false);
642 ///////////////////////////////////////////////////////////////////////////////
643 ///Create a new hexahedron and add it to the mesh.
644 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
645 ///@return The created hexahedron
646 ///////////////////////////////////////////////////////////////////////////////
648 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
649 const SMDS_MeshNode * n2,
650 const SMDS_MeshNode * n3,
651 const SMDS_MeshNode * n4,
652 const SMDS_MeshNode * n5,
653 const SMDS_MeshNode * n6,
654 const SMDS_MeshNode * n7,
655 const SMDS_MeshNode * n8)
657 int ID = myElementIDFactory->GetFreeID();
658 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
659 if(v==NULL) myElementIDFactory->ReleaseID(ID);
663 ///////////////////////////////////////////////////////////////////////////////
664 ///Create a new hexahedron and add it to the mesh.
665 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
666 ///@param ID The ID of the new volume
667 ///@return The created hexahedron or NULL if an element with this ID already
668 ///exists or if input nodes are not found.
669 ///////////////////////////////////////////////////////////////////////////////
671 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
681 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
682 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
683 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
684 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
685 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
686 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
687 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
688 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
689 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
690 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
692 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
696 ///////////////////////////////////////////////////////////////////////////////
697 ///Create a new hexahedron and add it to the mesh.
698 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
699 ///@param ID The ID of the new volume
700 ///@return The created prism or NULL if an element with this ID already exists
701 ///or if input nodes are not found.
702 ///////////////////////////////////////////////////////////////////////////////
704 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
705 const SMDS_MeshNode * n2,
706 const SMDS_MeshNode * n3,
707 const SMDS_MeshNode * n4,
708 const SMDS_MeshNode * n5,
709 const SMDS_MeshNode * n6,
710 const SMDS_MeshNode * n7,
711 const SMDS_MeshNode * n8,
714 SMDS_MeshVolume* volume = 0;
715 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
717 if(hasConstructionFaces()) {
718 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
719 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
720 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
721 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
722 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
723 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
724 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
725 myVolumes.Add(volume);
727 else if(hasConstructionEdges()) {
728 MESSAGE("Error : Not implemented");
732 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
733 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
734 myVolumes.Add(volume);
737 if (!registerElement(ID, volume)) {
738 RemoveElement(volume, false);
744 ///////////////////////////////////////////////////////////////////////////////
745 ///Create a new tetrahedron defined by its faces and add it to the mesh.
746 ///@return The created tetrahedron
747 ///////////////////////////////////////////////////////////////////////////////
749 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
750 const SMDS_MeshFace * f2,
751 const SMDS_MeshFace * f3,
752 const SMDS_MeshFace * f4)
754 if (!hasConstructionFaces())
756 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
759 ///////////////////////////////////////////////////////////////////////////////
760 ///Create a new tetrahedron defined by its faces and add it to the mesh.
761 ///@param ID The ID of the new volume
762 ///@return The created tetrahedron
763 ///////////////////////////////////////////////////////////////////////////////
765 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
766 const SMDS_MeshFace * f2,
767 const SMDS_MeshFace * f3,
768 const SMDS_MeshFace * f4,
771 if (!hasConstructionFaces())
773 if ( !f1 || !f2 || !f3 || !f4) return 0;
775 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
776 myVolumes.Add(volume);
778 if (!registerElement(ID, volume)) {
779 RemoveElement(volume, false);
785 ///////////////////////////////////////////////////////////////////////////////
786 ///Create a new pyramid defined by its faces and add it to the mesh.
787 ///@return The created pyramid
788 ///////////////////////////////////////////////////////////////////////////////
790 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
791 const SMDS_MeshFace * f2,
792 const SMDS_MeshFace * f3,
793 const SMDS_MeshFace * f4,
794 const SMDS_MeshFace * f5)
796 if (!hasConstructionFaces())
798 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
801 ///////////////////////////////////////////////////////////////////////////////
802 ///Create a new pyramid defined by its faces and add it to the mesh.
803 ///@param ID The ID of the new volume
804 ///@return The created pyramid
805 ///////////////////////////////////////////////////////////////////////////////
807 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
808 const SMDS_MeshFace * f2,
809 const SMDS_MeshFace * f3,
810 const SMDS_MeshFace * f4,
811 const SMDS_MeshFace * f5,
814 if (!hasConstructionFaces())
816 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
818 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
819 myVolumes.Add(volume);
821 if (!registerElement(ID, volume)) {
822 RemoveElement(volume, false);
828 ///////////////////////////////////////////////////////////////////////////////
829 ///Create a new prism defined by its faces and add it to the mesh.
830 ///@return The created prism
831 ///////////////////////////////////////////////////////////////////////////////
833 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
834 const SMDS_MeshFace * f2,
835 const SMDS_MeshFace * f3,
836 const SMDS_MeshFace * f4,
837 const SMDS_MeshFace * f5,
838 const SMDS_MeshFace * f6)
840 if (!hasConstructionFaces())
842 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
845 ///////////////////////////////////////////////////////////////////////////////
846 ///Create a new prism defined by its faces and add it to the mesh.
847 ///@param ID The ID of the new volume
848 ///@return The created prism
849 ///////////////////////////////////////////////////////////////////////////////
851 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
852 const SMDS_MeshFace * f2,
853 const SMDS_MeshFace * f3,
854 const SMDS_MeshFace * f4,
855 const SMDS_MeshFace * f5,
856 const SMDS_MeshFace * f6,
859 if (!hasConstructionFaces())
861 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
863 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
864 myVolumes.Add(volume);
866 if (!registerElement(ID, volume)) {
867 RemoveElement(volume, false);
873 ///////////////////////////////////////////////////////////////////////////////
874 /// Add a polygon defined by its nodes IDs
875 ///////////////////////////////////////////////////////////////////////////////
877 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
880 int nbNodes = nodes_ids.size();
881 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
882 for (int i = 0; i < nbNodes; i++) {
883 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
884 if (!nodes[i]) return NULL;
886 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
889 ///////////////////////////////////////////////////////////////////////////////
890 /// Add a polygon defined by its nodes
891 ///////////////////////////////////////////////////////////////////////////////
893 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
894 (std::vector<const SMDS_MeshNode*> nodes,
897 SMDS_MeshFace * face;
900 if (hasConstructionEdges())
902 MESSAGE("Error : Not implemented");
907 for ( int i = 0; i < nodes.size(); ++i )
908 if ( !nodes[ i ] ) return 0;
909 face = new SMDS_PolygonalFaceOfNodes(nodes);
913 if (!registerElement(ID, face)) {
914 RemoveElement(face, false);
920 ///////////////////////////////////////////////////////////////////////////////
921 /// Add a polygon defined by its nodes.
922 /// An ID is automatically affected to the created face.
923 ///////////////////////////////////////////////////////////////////////////////
925 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
927 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
930 ///////////////////////////////////////////////////////////////////////////////
931 /// Create a new polyhedral volume and add it to the mesh.
932 /// @param ID The ID of the new volume
933 /// @return The created volume or NULL if an element with this ID already exists
934 /// or if input nodes are not found.
935 ///////////////////////////////////////////////////////////////////////////////
937 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
938 (std::vector<int> nodes_ids,
939 std::vector<int> quantities,
942 int nbNodes = nodes_ids.size();
943 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
944 for (int i = 0; i < nbNodes; i++) {
945 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
946 if (!nodes[i]) return NULL;
948 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
951 ///////////////////////////////////////////////////////////////////////////////
952 /// Create a new polyhedral volume and add it to the mesh.
953 /// @param ID The ID of the new volume
954 /// @return The created volume
955 ///////////////////////////////////////////////////////////////////////////////
957 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
958 (std::vector<const SMDS_MeshNode*> nodes,
959 std::vector<int> quantities,
962 SMDS_MeshVolume* volume;
964 if (hasConstructionFaces()) {
965 MESSAGE("Error : Not implemented");
967 } else if (hasConstructionEdges()) {
968 MESSAGE("Error : Not implemented");
971 for ( int i = 0; i < nodes.size(); ++i )
972 if ( !nodes[ i ] ) return 0;
973 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
974 myVolumes.Add(volume);
977 if (!registerElement(ID, volume)) {
978 RemoveElement(volume, false);
984 ///////////////////////////////////////////////////////////////////////////////
985 /// Create a new polyhedral volume and add it to the mesh.
986 /// @return The created volume
987 ///////////////////////////////////////////////////////////////////////////////
989 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
990 (std::vector<const SMDS_MeshNode*> nodes,
991 std::vector<int> quantities)
993 int ID = myElementIDFactory->GetFreeID();
994 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
995 if (v == NULL) myElementIDFactory->ReleaseID(ID);
999 ///////////////////////////////////////////////////////////////////////////////
1000 /// Registers element with the given ID, maintains inverse connections
1001 ///////////////////////////////////////////////////////////////////////////////
1002 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1004 if (myElementIDFactory->BindID(ID, element)) {
1005 SMDS_ElemIteratorPtr it = element->nodesIterator();
1006 while (it->more()) {
1007 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1008 (const_cast<SMDS_MeshElement*>(it->next()));
1009 node->AddInverseElement(element);
1016 ///////////////////////////////////////////////////////////////////////////////
1017 /// Return the node whose ID is 'ID'.
1018 ///////////////////////////////////////////////////////////////////////////////
1019 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1021 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1024 ///////////////////////////////////////////////////////////////////////////////
1025 ///Create a triangle and add it to the current mesh. This methode do not bind a
1026 ///ID to the create triangle.
1027 ///////////////////////////////////////////////////////////////////////////////
1028 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1029 const SMDS_MeshNode * node2,
1030 const SMDS_MeshNode * node3)
1032 if ( !node1 || !node2 || !node3) return 0;
1034 if(hasConstructionEdges())
1036 SMDS_MeshEdge *edge1, *edge2, *edge3;
1037 edge1=FindEdgeOrCreate(node1,node2);
1038 edge2=FindEdgeOrCreate(node2,node3);
1039 edge3=FindEdgeOrCreate(node3,node1);
1041 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1047 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1053 ///////////////////////////////////////////////////////////////////////////////
1054 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1055 ///a ID to the create triangle.
1056 ///////////////////////////////////////////////////////////////////////////////
1057 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1058 const SMDS_MeshNode * node2,
1059 const SMDS_MeshNode * node3,
1060 const SMDS_MeshNode * node4)
1062 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1064 if(hasConstructionEdges())
1066 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1067 edge1=FindEdgeOrCreate(node1,node2);
1068 edge2=FindEdgeOrCreate(node2,node3);
1069 edge3=FindEdgeOrCreate(node3,node4);
1070 edge4=FindEdgeOrCreate(node4,node1);
1072 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1078 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1084 ///////////////////////////////////////////////////////////////////////////////
1085 /// Remove a node and all the elements which own this node
1086 ///////////////////////////////////////////////////////////////////////////////
1088 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1090 RemoveElement(node, true);
1093 ///////////////////////////////////////////////////////////////////////////////
1094 /// Remove an edge and all the elements which own this edge
1095 ///////////////////////////////////////////////////////////////////////////////
1097 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1099 RemoveElement(edge,true);
1102 ///////////////////////////////////////////////////////////////////////////////
1103 /// Remove an face and all the elements which own this face
1104 ///////////////////////////////////////////////////////////////////////////////
1106 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1108 RemoveElement(face, true);
1111 ///////////////////////////////////////////////////////////////////////////////
1113 ///////////////////////////////////////////////////////////////////////////////
1115 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1117 RemoveElement(volume, true);
1120 //=======================================================================
1121 //function : RemoveFromParent
1123 //=======================================================================
1125 bool SMDS_Mesh::RemoveFromParent()
1127 if (myParent==NULL) return false;
1128 else return (myParent->RemoveSubMesh(this));
1131 //=======================================================================
1132 //function : RemoveSubMesh
1134 //=======================================================================
1136 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1140 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1141 for (; itmsh!=myChildren.end() && !found; itmsh++)
1143 SMDS_Mesh * submesh = *itmsh;
1144 if (submesh == aMesh)
1147 myChildren.erase(itmsh);
1154 //=======================================================================
1155 //function : ChangeElementNodes
1157 //=======================================================================
1159 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
1160 const SMDS_MeshNode * nodes[],
1163 // keep current nodes of elem
1164 set<const SMDS_MeshElement*> oldNodes;
1165 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1167 oldNodes.insert( itn->next() );
1171 switch ( elem->GetType() )
1173 case SMDSAbs_Edge: {
1174 if ( nbnodes == 2 ) {
1175 const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
1177 Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
1179 else if ( nbnodes == 3 ) {
1180 const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
1182 Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1186 case SMDSAbs_Face: {
1187 const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
1189 Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
1192 const SMDS_QuadraticFaceOfNodes* QF =
1193 dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
1195 Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
1199 const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1201 Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1208 //case SMDSAbs_PolygonalFace: {
1209 // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1211 // Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1215 case SMDSAbs_Volume: {
1216 const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
1218 Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
1221 const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
1223 Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
1229 MESSAGE ( "WRONG ELEM TYPE");
1232 if ( Ok ) { // update InverseElements
1234 // AddInverseElement to new nodes
1235 for ( int i = 0; i < nbnodes; i++ )
1236 if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
1238 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1240 // remove from oldNodes a node that remains in elem
1241 oldNodes.erase( nodes[i] );
1244 // RemoveInverseElement from the nodes removed from elem
1245 set<const SMDS_MeshElement*>::iterator it;
1246 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1248 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1249 (const_cast<SMDS_MeshElement *>( *it ));
1250 n->RemoveInverseElement( elem );
1254 //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1259 //=======================================================================
1260 //function : ChangePolyhedronNodes
1261 //purpose : to change nodes of polyhedral volume
1262 //=======================================================================
1263 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1264 std::vector<const SMDS_MeshNode*> nodes,
1265 std::vector<int> quantities)
1267 if (elem->GetType() != SMDSAbs_Volume) {
1268 MESSAGE("WRONG ELEM TYPE");
1272 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1277 // keep current nodes of elem
1278 set<const SMDS_MeshElement*> oldNodes;
1279 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1280 while (itn->more()) {
1281 oldNodes.insert(itn->next());
1285 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1290 // update InverseElements
1292 // AddInverseElement to new nodes
1293 int nbnodes = nodes.size();
1294 for (int i = 0; i < nbnodes; i++) {
1295 if (oldNodes.find(nodes[i]) == oldNodes.end()) {
1297 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1299 // remove from oldNodes a node that remains in elem
1300 oldNodes.erase(nodes[i]);
1304 // RemoveInverseElement from the nodes removed from elem
1305 set<const SMDS_MeshElement*>::iterator it;
1306 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1307 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1308 (const_cast<SMDS_MeshElement *>( *it ));
1309 n->RemoveInverseElement(elem);
1316 //=======================================================================
1317 //function : FindEdge
1319 //=======================================================================
1321 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1323 const SMDS_MeshNode * node1=FindNode(idnode1);
1324 const SMDS_MeshNode * node2=FindNode(idnode2);
1325 if((node1==NULL)||(node2==NULL)) return NULL;
1326 return FindEdge(node1,node2);
1329 //#include "Profiler.h"
1330 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1331 const SMDS_MeshNode * node2)
1333 if ( !node1 ) return 0;
1334 const SMDS_MeshEdge * toReturn=NULL;
1337 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1340 while(it1->more()) {
1341 const SMDS_MeshElement * e = it1->next();
1342 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1343 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1352 //=======================================================================
1353 //function : FindEdgeOrCreate
1355 //=======================================================================
1357 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1358 const SMDS_MeshNode * node2)
1360 if ( !node1 || !node2) return 0;
1361 SMDS_MeshEdge * toReturn=NULL;
1362 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1363 if(toReturn==NULL) {
1365 toReturn=new SMDS_MeshEdge(node1,node2);
1366 myEdges.Add(toReturn);
1372 //=======================================================================
1373 //function : FindEdge
1375 //=======================================================================
1377 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1380 const SMDS_MeshNode * node1=FindNode(idnode1);
1381 const SMDS_MeshNode * node2=FindNode(idnode2);
1382 const SMDS_MeshNode * node3=FindNode(idnode3);
1383 return FindEdge(node1,node2,node3);
1386 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1387 const SMDS_MeshNode * node2,
1388 const SMDS_MeshNode * node3)
1390 if ( !node1 ) return 0;
1391 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1392 while(it1->more()) {
1393 const SMDS_MeshElement * e = it1->next();
1394 if ( e->NbNodes() == 3 ) {
1395 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1396 while(it2->more()) {
1397 const SMDS_MeshElement* n = it2->next();
1407 return static_cast<const SMDS_MeshEdge *> (e);
1414 //=======================================================================
1415 //function : FindFace
1417 //=======================================================================
1419 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1422 const SMDS_MeshNode * node1=FindNode(idnode1);
1423 const SMDS_MeshNode * node2=FindNode(idnode2);
1424 const SMDS_MeshNode * node3=FindNode(idnode3);
1425 return FindFace(node1, node2, node3);
1428 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1429 const SMDS_MeshNode *node2,
1430 const SMDS_MeshNode *node3)
1432 if ( !node1 ) return 0;
1433 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1434 while(it1->more()) {
1435 const SMDS_MeshElement * e = it1->next();
1436 if ( e->NbNodes() == 3 ) {
1437 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1438 while(it2->more()) {
1439 const SMDS_MeshElement* n = it2->next();
1449 return static_cast<const SMDS_MeshFace *> (e);
1455 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1456 const SMDS_MeshNode *node2,
1457 const SMDS_MeshNode *node3)
1459 SMDS_MeshFace * toReturn=NULL;
1460 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1461 if(toReturn==NULL) {
1462 toReturn = createTriangle(node1,node2,node3);
1468 //=======================================================================
1469 //function : FindFace
1471 //=======================================================================
1473 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1474 int idnode3, int idnode4) const
1476 const SMDS_MeshNode * node1=FindNode(idnode1);
1477 const SMDS_MeshNode * node2=FindNode(idnode2);
1478 const SMDS_MeshNode * node3=FindNode(idnode3);
1479 const SMDS_MeshNode * node4=FindNode(idnode4);
1480 return FindFace(node1, node2, node3, node4);
1483 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1484 const SMDS_MeshNode *node2,
1485 const SMDS_MeshNode *node3,
1486 const SMDS_MeshNode *node4)
1488 if ( !node1 ) return 0;
1489 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1490 while(it1->more()) {
1491 const SMDS_MeshElement * e = it1->next();
1492 if ( e->NbNodes() == 4 ) {
1493 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1494 while(it2->more()) {
1495 const SMDS_MeshElement* n = it2->next();
1506 return static_cast<const SMDS_MeshFace *> (e);
1512 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1513 const SMDS_MeshNode *node2,
1514 const SMDS_MeshNode *node3,
1515 const SMDS_MeshNode *node4)
1517 SMDS_MeshFace * toReturn=NULL;
1518 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1519 if(toReturn==NULL) {
1520 toReturn=createQuadrangle(node1,node2,node3,node4);
1526 //=======================================================================
1527 //function : FindFace
1528 //purpose :quadratic triangle
1529 //=======================================================================
1531 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1532 int idnode3, int idnode4,
1533 int idnode5, int idnode6) const
1535 const SMDS_MeshNode * node1 = FindNode(idnode1);
1536 const SMDS_MeshNode * node2 = FindNode(idnode2);
1537 const SMDS_MeshNode * node3 = FindNode(idnode3);
1538 const SMDS_MeshNode * node4 = FindNode(idnode4);
1539 const SMDS_MeshNode * node5 = FindNode(idnode5);
1540 const SMDS_MeshNode * node6 = FindNode(idnode6);
1541 return FindFace(node1, node2, node3, node4, node5, node6);
1544 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1545 const SMDS_MeshNode *node2,
1546 const SMDS_MeshNode *node3,
1547 const SMDS_MeshNode *node4,
1548 const SMDS_MeshNode *node5,
1549 const SMDS_MeshNode *node6)
1551 if ( !node1 ) return 0;
1552 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1553 while(it1->more()) {
1554 const SMDS_MeshElement * e = it1->next();
1555 if ( e->NbNodes() == 6 ) {
1556 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1557 while(it2->more()) {
1558 const SMDS_MeshElement* n = it2->next();
1571 return static_cast<const SMDS_MeshFace *> (e);
1578 //=======================================================================
1579 //function : FindFace
1580 //purpose : quadratic quadrangle
1581 //=======================================================================
1583 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1584 int idnode3, int idnode4,
1585 int idnode5, int idnode6,
1586 int idnode7, int idnode8) const
1588 const SMDS_MeshNode * node1 = FindNode(idnode1);
1589 const SMDS_MeshNode * node2 = FindNode(idnode2);
1590 const SMDS_MeshNode * node3 = FindNode(idnode3);
1591 const SMDS_MeshNode * node4 = FindNode(idnode4);
1592 const SMDS_MeshNode * node5 = FindNode(idnode5);
1593 const SMDS_MeshNode * node6 = FindNode(idnode6);
1594 const SMDS_MeshNode * node7 = FindNode(idnode7);
1595 const SMDS_MeshNode * node8 = FindNode(idnode8);
1596 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1599 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1600 const SMDS_MeshNode *node2,
1601 const SMDS_MeshNode *node3,
1602 const SMDS_MeshNode *node4,
1603 const SMDS_MeshNode *node5,
1604 const SMDS_MeshNode *node6,
1605 const SMDS_MeshNode *node7,
1606 const SMDS_MeshNode *node8)
1608 if ( !node1 ) return 0;
1609 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1610 while(it1->more()) {
1611 const SMDS_MeshElement * e = it1->next();
1612 if ( e->NbNodes() == 8 ) {
1613 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1614 while(it2->more()) {
1615 const SMDS_MeshElement* n = it2->next();
1630 return static_cast<const SMDS_MeshFace *> (e);
1637 //=======================================================================
1638 //function : FindElement
1640 //=======================================================================
1642 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1644 return myElementIDFactory->MeshElement(IDelem);
1647 //=======================================================================
1648 //function : FindFace
1649 //purpose : find polygon
1650 //=======================================================================
1652 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1654 int nbnodes = nodes_ids.size();
1655 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1656 for (int inode = 0; inode < nbnodes; inode++) {
1657 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1658 if (node == NULL) return NULL;
1660 return FindFace(poly_nodes);
1663 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1665 if ( nodes.size() > 2 && nodes[0] ) {
1666 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1667 while (itF->more()) {
1668 const SMDS_MeshElement* f = itF->next();
1669 if ( f->NbNodes() == nodes.size() ) {
1670 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1671 while(it2->more()) {
1672 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1678 return static_cast<const SMDS_MeshFace *> (f);
1685 //=======================================================================
1686 //function : DumpNodes
1688 //=======================================================================
1690 void SMDS_Mesh::DumpNodes() const
1692 MESSAGE("dump nodes of mesh : ");
1693 SMDS_NodeIteratorPtr itnode=nodesIterator();
1694 while(itnode->more()) MESSAGE(itnode->next());
1697 //=======================================================================
1698 //function : DumpEdges
1700 //=======================================================================
1702 void SMDS_Mesh::DumpEdges() const
1704 MESSAGE("dump edges of mesh : ");
1705 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1706 while(itedge->more()) MESSAGE(itedge->next());
1709 //=======================================================================
1710 //function : DumpFaces
1712 //=======================================================================
1714 void SMDS_Mesh::DumpFaces() const
1716 MESSAGE("dump faces of mesh : ");
1717 SMDS_FaceIteratorPtr itface=facesIterator();
1718 while(itface->more()) MESSAGE(itface->next());
1721 //=======================================================================
1722 //function : DumpVolumes
1724 //=======================================================================
1726 void SMDS_Mesh::DumpVolumes() const
1728 MESSAGE("dump volumes of mesh : ");
1729 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1730 while(itvol->more()) MESSAGE(itvol->next());
1733 //=======================================================================
1734 //function : DebugStats
1736 //=======================================================================
1738 void SMDS_Mesh::DebugStats() const
1740 MESSAGE("Debug stats of mesh : ");
1742 MESSAGE("===== NODES ====="<<NbNodes());
1743 MESSAGE("===== EDGES ====="<<NbEdges());
1744 MESSAGE("===== FACES ====="<<NbFaces());
1745 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1747 MESSAGE("End Debug stats of mesh ");
1751 SMDS_NodeIteratorPtr itnode=nodesIterator();
1752 int sizeofnodes = 0;
1753 int sizeoffaces = 0;
1755 while(itnode->more())
1757 const SMDS_MeshNode *node = itnode->next();
1759 sizeofnodes += sizeof(*node);
1761 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1764 const SMDS_MeshElement *me = it->next();
1765 sizeofnodes += sizeof(me);
1770 SMDS_FaceIteratorPtr itface=facesIterator();
1771 while(itface->more())
1773 const SMDS_MeshElement *face = itface->next();
1774 sizeoffaces += sizeof(*face);
1777 MESSAGE("total size of node elements = " << sizeofnodes);;
1778 MESSAGE("total size of face elements = " << sizeoffaces);;
1783 ///////////////////////////////////////////////////////////////////////////////
1784 /// Return the number of nodes
1785 ///////////////////////////////////////////////////////////////////////////////
1786 int SMDS_Mesh::NbNodes() const
1788 return myNodes.Size();
1791 ///////////////////////////////////////////////////////////////////////////////
1792 /// Return the number of edges (including construction edges)
1793 ///////////////////////////////////////////////////////////////////////////////
1794 int SMDS_Mesh::NbEdges() const
1796 return myEdges.Size();
1799 ///////////////////////////////////////////////////////////////////////////////
1800 /// Return the number of faces (including construction faces)
1801 ///////////////////////////////////////////////////////////////////////////////
1802 int SMDS_Mesh::NbFaces() const
1804 return myFaces.Size();
1807 ///////////////////////////////////////////////////////////////////////////////
1808 /// Return the number of volumes
1809 ///////////////////////////////////////////////////////////////////////////////
1810 int SMDS_Mesh::NbVolumes() const
1812 return myVolumes.Size();
1815 ///////////////////////////////////////////////////////////////////////////////
1816 /// Return the number of child mesh of this mesh.
1817 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1818 /// (2003-09-08) of SMESH
1819 ///////////////////////////////////////////////////////////////////////////////
1820 int SMDS_Mesh::NbSubMesh() const
1822 return myChildren.size();
1825 ///////////////////////////////////////////////////////////////////////////////
1826 /// Destroy the mesh and all its elements
1827 /// All pointer on elements owned by this mesh become illegals.
1828 ///////////////////////////////////////////////////////////////////////////////
1829 SMDS_Mesh::~SMDS_Mesh()
1831 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1832 while(itc!=myChildren.end())
1838 SetOfNodes::Iterator itn(myNodes);
1839 for (; itn.More(); itn.Next())
1842 SetOfEdges::Iterator ite(myEdges);
1843 for (; ite.More(); ite.Next())
1845 SMDS_MeshElement* elem = ite.Value();
1847 myElementIDFactory->ReleaseID(elem->GetID());
1851 SetOfFaces::Iterator itf(myFaces);
1852 for (; itf.More(); itf.Next())
1854 SMDS_MeshElement* elem = itf.Value();
1856 myElementIDFactory->ReleaseID(elem->GetID());
1860 SetOfVolumes::Iterator itv(myVolumes);
1861 for (; itv.More(); itv.Next())
1863 SMDS_MeshElement* elem = itv.Value();
1865 myElementIDFactory->ReleaseID(elem->GetID());
1871 delete myNodeIDFactory;
1872 delete myElementIDFactory;
1876 ///////////////////////////////////////////////////////////////////////////////
1877 /// Return true if this mesh create faces with edges.
1878 /// A false returned value mean that faces are created with nodes. A concequence
1879 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1880 ///////////////////////////////////////////////////////////////////////////////
1881 bool SMDS_Mesh::hasConstructionEdges()
1883 return myHasConstructionEdges;
1886 ///////////////////////////////////////////////////////////////////////////////
1887 /// Return true if this mesh create volumes with faces
1888 /// A false returned value mean that volumes are created with nodes or edges.
1889 /// (see hasConstructionEdges)
1890 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1892 ///////////////////////////////////////////////////////////////////////////////
1893 bool SMDS_Mesh::hasConstructionFaces()
1895 return myHasConstructionFaces;
1898 ///////////////////////////////////////////////////////////////////////////////
1899 /// Return true if nodes are linked to the finit elements, they are belonging to.
1900 /// Currently, It always return true.
1901 ///////////////////////////////////////////////////////////////////////////////
1902 bool SMDS_Mesh::hasInverseElements()
1904 return myHasInverseElements;
1907 ///////////////////////////////////////////////////////////////////////////////
1908 /// Make this mesh creating construction edges (see hasConstructionEdges)
1909 /// @param b true to have construction edges, else false.
1910 ///////////////////////////////////////////////////////////////////////////////
1911 void SMDS_Mesh::setConstructionEdges(bool b)
1913 myHasConstructionEdges=b;
1916 ///////////////////////////////////////////////////////////////////////////////
1917 /// Make this mesh creating construction faces (see hasConstructionFaces)
1918 /// @param b true to have construction faces, else false.
1919 ///////////////////////////////////////////////////////////////////////////////
1920 void SMDS_Mesh::setConstructionFaces(bool b)
1922 myHasConstructionFaces=b;
1925 ///////////////////////////////////////////////////////////////////////////////
1926 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1927 /// @param b true to link nodes to elements, else false.
1928 ///////////////////////////////////////////////////////////////////////////////
1929 void SMDS_Mesh::setInverseElements(bool b)
1931 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1932 myHasInverseElements=b;
1935 ///////////////////////////////////////////////////////////////////////////////
1936 /// Return an iterator on nodes of the current mesh factory
1937 ///////////////////////////////////////////////////////////////////////////////
1938 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1940 SMDS_ElemIteratorPtr myIterator;
1942 SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1947 return myIterator->more();
1950 const SMDS_MeshNode* next()
1952 return static_cast<const SMDS_MeshNode*>(myIterator->next());
1956 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1958 return SMDS_NodeIteratorPtr
1959 (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1962 ///////////////////////////////////////////////////////////////////////////////
1963 /// Return an iterator on elements of the current mesh factory
1964 ///////////////////////////////////////////////////////////////////////////////
1965 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1967 return myElementIDFactory->elementsIterator();
1970 ///////////////////////////////////////////////////////////////////////////////
1971 ///Return an iterator on edges of the current mesh.
1972 ///////////////////////////////////////////////////////////////////////////////
1973 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1975 typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1976 SetOfEdges::Iterator myIterator;
1978 SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1983 while(myIterator.More())
1985 if(myIterator.Value()->GetID()!=-1)
1992 const SMDS_MeshEdge* next()
1994 const SMDS_MeshEdge* current = myIterator.Value();
2000 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2002 return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
2005 ///////////////////////////////////////////////////////////////////////////////
2006 ///Return an iterator on faces of the current mesh.
2007 ///////////////////////////////////////////////////////////////////////////////
2008 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
2010 typedef SMDS_Mesh::SetOfFaces SetOfFaces;
2011 SetOfFaces::Iterator myIterator;
2013 SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
2018 while(myIterator.More())
2020 if(myIterator.Value()->GetID()!=-1)
2027 const SMDS_MeshFace* next()
2029 const SMDS_MeshFace* current = myIterator.Value();
2035 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2037 return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2040 ///////////////////////////////////////////////////////////////////////////////
2041 ///Return an iterator on volumes of the current mesh.
2042 ///////////////////////////////////////////////////////////////////////////////
2043 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2045 typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2046 SetOfVolumes::Iterator myIterator;
2048 SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2053 return myIterator.More() != Standard_False;
2056 const SMDS_MeshVolume* next()
2058 const SMDS_MeshVolume* current = myIterator.Value();
2064 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2066 return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2069 ///////////////////////////////////////////////////////////////////////////////
2070 /// Do intersection of sets (more than 2)
2071 ///////////////////////////////////////////////////////////////////////////////
2072 static set<const SMDS_MeshElement*> * intersectionOfSets(
2073 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2075 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2076 set<const SMDS_MeshElement*>* rsetB;
2078 for(int i=0; i<numberOfSets-1; i++)
2080 rsetB=new set<const SMDS_MeshElement*>();
2082 rsetA->begin(), rsetA->end(),
2083 vs[i+1].begin(), vs[i+1].end(),
2084 inserter(*rsetB, rsetB->begin()));
2091 ///////////////////////////////////////////////////////////////////////////////
2092 /// Return the list of finit elements owning the given element
2093 ///////////////////////////////////////////////////////////////////////////////
2094 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2096 int numberOfSets=element->NbNodes();
2097 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2099 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2102 while(itNodes->more())
2104 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2105 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2107 //initSet[i]=set<const SMDS_MeshElement*>();
2109 initSet[i].insert(itFe->next());
2113 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2118 ///////////////////////////////////////////////////////////////////////////////
2119 /// Return the list of nodes used only by the given elements
2120 ///////////////////////////////////////////////////////////////////////////////
2121 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2122 set<const SMDS_MeshElement*>& elements)
2124 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2125 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2127 while(itElements!=elements.end())
2129 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2132 while(itNodes->more())
2134 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2135 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2136 set<const SMDS_MeshElement*> s;
2138 s.insert(itFe->next());
2139 if(s==elements) toReturn->insert(n);
2145 ///////////////////////////////////////////////////////////////////////////////
2146 ///Find the children of an element that are made of given nodes
2147 ///@param setOfChildren The set in which matching children will be inserted
2148 ///@param element The element were to search matching children
2149 ///@param nodes The nodes that the children must have to be selected
2150 ///////////////////////////////////////////////////////////////////////////////
2151 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2152 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2155 switch(element->GetType())
2158 MESSAGE("Internal Error: This should not append");
2162 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2165 const SMDS_MeshElement * e=itn->next();
2166 if(nodes.find(e)!=nodes.end())
2168 setOfChildren.insert(element);
2175 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2178 const SMDS_MeshElement * e=itn->next();
2179 if(nodes.find(e)!=nodes.end())
2181 setOfChildren.insert(element);
2185 if(hasConstructionEdges())
2187 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2189 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2192 case SMDSAbs_Volume:
2194 if(hasConstructionFaces())
2196 SMDS_ElemIteratorPtr ite=element->facesIterator();
2198 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2200 else if(hasConstructionEdges())
2202 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2204 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2210 ///////////////////////////////////////////////////////////////////////////////
2211 ///@param elem The element to delete
2212 ///@param removenodes if true remaining nodes will be removed
2213 ///////////////////////////////////////////////////////////////////////////////
2214 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2215 const bool removenodes)
2217 list<const SMDS_MeshElement *> removedElems;
2218 list<const SMDS_MeshElement *> removedNodes;
2219 RemoveElement( elem, removedElems, removedNodes, removenodes );
2222 ///////////////////////////////////////////////////////////////////////////////
2223 ///@param elem The element to delete
2224 ///@param removedElems contains all removed elements
2225 ///@param removedNodes contains all removed nodes
2226 ///@param removenodes if true remaining nodes will be removed
2227 ///////////////////////////////////////////////////////////////////////////////
2228 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2229 list<const SMDS_MeshElement *>& removedElems,
2230 list<const SMDS_MeshElement *>& removedNodes,
2233 // get finite elements built on elem
2234 set<const SMDS_MeshElement*> * s1;
2235 if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2236 !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2237 elem->GetType() == SMDSAbs_Volume)
2239 s1 = new set<const SMDS_MeshElement*>();
2243 s1 = getFinitElements(elem);
2245 // get exclusive nodes (which would become free afterwards)
2246 set<const SMDS_MeshElement*> * s2;
2247 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2249 // do not remove nodes except elem
2250 s2 = new set<const SMDS_MeshElement*>();
2255 s2 = getExclusiveNodes(*s1);
2257 // form the set of finite and construction elements to remove
2258 set<const SMDS_MeshElement*> s3;
2259 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2260 while(it!=s1->end())
2262 addChildrenWithNodes(s3, *it ,*s2);
2266 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2268 // remove finite and construction elements
2272 // Remove element from <InverseElements> of its nodes
2273 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2276 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2277 (const_cast<SMDS_MeshElement *>(itn->next()));
2278 n->RemoveInverseElement( (*it) );
2281 switch((*it)->GetType())
2284 MESSAGE("Internal Error: This should not happen");
2287 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2288 (const_cast<SMDS_MeshElement*>(*it)));
2291 myFaces.Remove(static_cast<SMDS_MeshFace*>
2292 (const_cast<SMDS_MeshElement*>(*it)));
2294 case SMDSAbs_Volume:
2295 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2296 (const_cast<SMDS_MeshElement*>(*it)));
2299 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2300 removedElems.push_back( (*it) );
2301 myElementIDFactory->ReleaseID((*it)->GetID());
2306 // remove exclusive (free) nodes
2310 while(it!=s2->end())
2312 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2313 myNodes.Remove(static_cast<SMDS_MeshNode*>
2314 (const_cast<SMDS_MeshElement*>(*it)));
2315 myNodeIDFactory->ReleaseID((*it)->GetID());
2316 removedNodes.push_back( (*it) );
2327 ///////////////////////////////////////////////////////////////////////////////
2328 ///@param elem The element to delete
2329 ///////////////////////////////////////////////////////////////////////////////
2330 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2332 SMDSAbs_ElementType aType = elem->GetType();
2333 if (aType == SMDSAbs_Node) {
2334 // only free node can be removed by this method
2335 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2336 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2337 if (!itFe->more()) { // free node
2338 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2339 myNodeIDFactory->ReleaseID(elem->GetID());
2343 if (hasConstructionEdges() || hasConstructionFaces())
2344 // this methods is only for meshes without descendants
2347 // Remove element from <InverseElements> of its nodes
2348 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2349 while (itn->more()) {
2350 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2351 (const_cast<SMDS_MeshElement *>(itn->next()));
2352 n->RemoveInverseElement(elem);
2355 // in meshes without descendants elements are always free
2358 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2359 (const_cast<SMDS_MeshElement*>(elem)));
2362 myFaces.Remove(static_cast<SMDS_MeshFace*>
2363 (const_cast<SMDS_MeshElement*>(elem)));
2365 case SMDSAbs_Volume:
2366 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2367 (const_cast<SMDS_MeshElement*>(elem)));
2372 myElementIDFactory->ReleaseID(elem->GetID());
2378 * Checks if the element is present in mesh.
2379 * Useful to determine dead pointers.
2381 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2383 // we should not imply on validity of *elem, so iterate on containers
2384 // of all types in the hope of finding <elem> somewhere there
2385 SMDS_NodeIteratorPtr itn = nodesIterator();
2387 if (elem == itn->next())
2389 SMDS_EdgeIteratorPtr ite = edgesIterator();
2391 if (elem == ite->next())
2393 SMDS_FaceIteratorPtr itf = facesIterator();
2395 if (elem == itf->next())
2397 SMDS_VolumeIteratorPtr itv = volumesIterator();
2399 if (elem == itv->next())
2404 //=======================================================================
2405 //function : MaxNodeID
2407 //=======================================================================
2409 int SMDS_Mesh::MaxNodeID() const
2411 return myNodeIDFactory->GetMaxID();
2414 //=======================================================================
2415 //function : MinNodeID
2417 //=======================================================================
2419 int SMDS_Mesh::MinNodeID() const
2421 return myNodeIDFactory->GetMinID();
2424 //=======================================================================
2425 //function : MaxElementID
2427 //=======================================================================
2429 int SMDS_Mesh::MaxElementID() const
2431 return myElementIDFactory->GetMaxID();
2434 //=======================================================================
2435 //function : MinElementID
2437 //=======================================================================
2439 int SMDS_Mesh::MinElementID() const
2441 return myElementIDFactory->GetMinID();
2444 //=======================================================================
2445 //function : Renumber
2446 //purpose : Renumber all nodes or elements.
2447 //=======================================================================
2449 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2454 SMDS_MeshElementIDFactory * idFactory =
2455 isNodes ? myNodeIDFactory : myElementIDFactory;
2457 // get existing elements in the order of ID increasing
2458 map<int,SMDS_MeshElement*> elemMap;
2459 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2460 while ( idElemIt->more() ) {
2461 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2462 int id = elem->GetID();
2463 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2465 // release their ids
2466 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2467 for ( ; elemIt != elemMap.end(); elemIt++ )
2469 int id = (*elemIt).first;
2470 idFactory->ReleaseID( id );
2474 elemIt = elemMap.begin();
2475 for ( ; elemIt != elemMap.end(); elemIt++ )
2477 idFactory->BindID( ID, (*elemIt).second );
2482 //=======================================================================
2483 //function : GetElementType
2484 //purpose : Return type of element or node with id
2485 //=======================================================================
2487 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2489 SMDS_MeshElement* elem = 0;
2491 elem = myElementIDFactory->MeshElement( id );
2493 elem = myNodeIDFactory->MeshElement( id );
2497 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2501 return elem->GetType();
2506 //********************************************************************
2507 //********************************************************************
2508 //******** *********
2509 //***** Methods for addition of quadratic elements ******
2510 //******** *********
2511 //********************************************************************
2512 //********************************************************************
2514 //=======================================================================
2515 //function : AddEdgeWithID
2517 //=======================================================================
2518 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2520 return SMDS_Mesh::AddEdgeWithID
2521 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2522 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2523 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2527 //=======================================================================
2528 //function : AddEdge
2530 //=======================================================================
2531 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2532 const SMDS_MeshNode* n2,
2533 const SMDS_MeshNode* n12)
2535 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2538 //=======================================================================
2539 //function : AddEdgeWithID
2541 //=======================================================================
2542 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2543 const SMDS_MeshNode * n2,
2544 const SMDS_MeshNode * n12,
2547 if ( !n1 || !n2 || !n12 ) return 0;
2548 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2549 if(myElementIDFactory->BindID(ID, edge)) {
2550 SMDS_MeshNode *node1,*node2, *node12;
2551 node1 = const_cast<SMDS_MeshNode*>(n1);
2552 node2 = const_cast<SMDS_MeshNode*>(n2);
2553 node12 = const_cast<SMDS_MeshNode*>(n12);
2554 node1->AddInverseElement(edge);
2555 node2->AddInverseElement(edge);
2556 node12->AddInverseElement(edge);
2567 //=======================================================================
2568 //function : AddFace
2570 //=======================================================================
2571 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2572 const SMDS_MeshNode * n2,
2573 const SMDS_MeshNode * n3,
2574 const SMDS_MeshNode * n12,
2575 const SMDS_MeshNode * n23,
2576 const SMDS_MeshNode * n31)
2578 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2579 myElementIDFactory->GetFreeID());
2582 //=======================================================================
2583 //function : AddFaceWithID
2585 //=======================================================================
2586 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2587 int n12,int n23,int n31, int ID)
2589 return SMDS_Mesh::AddFaceWithID
2590 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2591 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2592 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2593 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2594 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2595 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2599 //=======================================================================
2600 //function : AddFaceWithID
2602 //=======================================================================
2603 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2604 const SMDS_MeshNode * n2,
2605 const SMDS_MeshNode * n3,
2606 const SMDS_MeshNode * n12,
2607 const SMDS_MeshNode * n23,
2608 const SMDS_MeshNode * n31,
2611 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2612 if(hasConstructionEdges()) {
2613 // creation quadratic edges - not implemented
2616 SMDS_QuadraticFaceOfNodes* face =
2617 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2620 if (!registerElement(ID, face)) {
2621 RemoveElement(face, false);
2628 //=======================================================================
2629 //function : AddFace
2631 //=======================================================================
2632 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2633 const SMDS_MeshNode * n2,
2634 const SMDS_MeshNode * n3,
2635 const SMDS_MeshNode * n4,
2636 const SMDS_MeshNode * n12,
2637 const SMDS_MeshNode * n23,
2638 const SMDS_MeshNode * n34,
2639 const SMDS_MeshNode * n41)
2641 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2642 myElementIDFactory->GetFreeID());
2645 //=======================================================================
2646 //function : AddFaceWithID
2648 //=======================================================================
2649 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2650 int n12,int n23,int n34,int n41, int ID)
2652 return SMDS_Mesh::AddFaceWithID
2653 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2654 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2655 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2656 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2657 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2658 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2659 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2660 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2664 //=======================================================================
2665 //function : AddFaceWithID
2667 //=======================================================================
2668 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2669 const SMDS_MeshNode * n2,
2670 const SMDS_MeshNode * n3,
2671 const SMDS_MeshNode * n4,
2672 const SMDS_MeshNode * n12,
2673 const SMDS_MeshNode * n23,
2674 const SMDS_MeshNode * n34,
2675 const SMDS_MeshNode * n41,
2678 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2679 if(hasConstructionEdges()) {
2680 // creation quadratic edges - not implemented
2682 SMDS_QuadraticFaceOfNodes* face =
2683 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2686 if (!registerElement(ID, face)) {
2687 RemoveElement(face, false);
2694 //=======================================================================
2695 //function : AddVolume
2697 //=======================================================================
2698 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2699 const SMDS_MeshNode * n2,
2700 const SMDS_MeshNode * n3,
2701 const SMDS_MeshNode * n4,
2702 const SMDS_MeshNode * n12,
2703 const SMDS_MeshNode * n23,
2704 const SMDS_MeshNode * n31,
2705 const SMDS_MeshNode * n14,
2706 const SMDS_MeshNode * n24,
2707 const SMDS_MeshNode * n34)
2709 int ID = myElementIDFactory->GetFreeID();
2710 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2711 n31, n14, n24, n34, ID);
2712 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2716 //=======================================================================
2717 //function : AddVolumeWithID
2719 //=======================================================================
2720 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2721 int n12,int n23,int n31,
2722 int n14,int n24,int n34, int ID)
2724 return SMDS_Mesh::AddVolumeWithID
2725 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2726 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2727 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2728 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2729 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2730 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2731 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2732 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2733 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2734 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2738 //=======================================================================
2739 //function : AddVolumeWithID
2740 //purpose : 2d order tetrahedron of 10 nodes
2741 //=======================================================================
2742 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2743 const SMDS_MeshNode * n2,
2744 const SMDS_MeshNode * n3,
2745 const SMDS_MeshNode * n4,
2746 const SMDS_MeshNode * n12,
2747 const SMDS_MeshNode * n23,
2748 const SMDS_MeshNode * n31,
2749 const SMDS_MeshNode * n14,
2750 const SMDS_MeshNode * n24,
2751 const SMDS_MeshNode * n34,
2754 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2756 if(hasConstructionFaces()) {
2757 // creation quadratic faces - not implemented
2760 SMDS_QuadraticVolumeOfNodes * volume =
2761 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2762 myVolumes.Add(volume);
2764 if (!registerElement(ID, volume)) {
2765 RemoveElement(volume, false);
2772 //=======================================================================
2773 //function : AddVolume
2775 //=======================================================================
2776 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2777 const SMDS_MeshNode * n2,
2778 const SMDS_MeshNode * n3,
2779 const SMDS_MeshNode * n4,
2780 const SMDS_MeshNode * n5,
2781 const SMDS_MeshNode * n12,
2782 const SMDS_MeshNode * n23,
2783 const SMDS_MeshNode * n34,
2784 const SMDS_MeshNode * n41,
2785 const SMDS_MeshNode * n15,
2786 const SMDS_MeshNode * n25,
2787 const SMDS_MeshNode * n35,
2788 const SMDS_MeshNode * n45)
2790 int ID = myElementIDFactory->GetFreeID();
2791 SMDS_MeshVolume * v =
2792 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2793 n15, n25, n35, n45, ID);
2794 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2798 //=======================================================================
2799 //function : AddVolumeWithID
2801 //=======================================================================
2802 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2803 int n12,int n23,int n34,int n41,
2804 int n15,int n25,int n35,int n45, int ID)
2806 return SMDS_Mesh::AddVolumeWithID
2807 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2808 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2809 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2810 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2811 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2812 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2813 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2814 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2815 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2816 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2817 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2818 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2819 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2823 //=======================================================================
2824 //function : AddVolumeWithID
2825 //purpose : 2d order pyramid of 13 nodes
2826 //=======================================================================
2827 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2828 const SMDS_MeshNode * n2,
2829 const SMDS_MeshNode * n3,
2830 const SMDS_MeshNode * n4,
2831 const SMDS_MeshNode * n5,
2832 const SMDS_MeshNode * n12,
2833 const SMDS_MeshNode * n23,
2834 const SMDS_MeshNode * n34,
2835 const SMDS_MeshNode * n41,
2836 const SMDS_MeshNode * n15,
2837 const SMDS_MeshNode * n25,
2838 const SMDS_MeshNode * n35,
2839 const SMDS_MeshNode * n45,
2842 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2843 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2845 if(hasConstructionFaces()) {
2846 // creation quadratic faces - not implemented
2849 SMDS_QuadraticVolumeOfNodes * volume =
2850 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2851 n34,n41,n15,n25,n35,n45);
2852 myVolumes.Add(volume);
2854 if (!registerElement(ID, volume)) {
2855 RemoveElement(volume, false);
2862 //=======================================================================
2863 //function : AddVolume
2865 //=======================================================================
2866 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2867 const SMDS_MeshNode * n2,
2868 const SMDS_MeshNode * n3,
2869 const SMDS_MeshNode * n4,
2870 const SMDS_MeshNode * n5,
2871 const SMDS_MeshNode * n6,
2872 const SMDS_MeshNode * n12,
2873 const SMDS_MeshNode * n23,
2874 const SMDS_MeshNode * n31,
2875 const SMDS_MeshNode * n45,
2876 const SMDS_MeshNode * n56,
2877 const SMDS_MeshNode * n64,
2878 const SMDS_MeshNode * n14,
2879 const SMDS_MeshNode * n25,
2880 const SMDS_MeshNode * n36)
2882 int ID = myElementIDFactory->GetFreeID();
2883 SMDS_MeshVolume * v =
2884 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2885 n45, n56, n64, n14, n25, n36, ID);
2886 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2890 //=======================================================================
2891 //function : AddVolumeWithID
2893 //=======================================================================
2894 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2895 int n4, int n5, int n6,
2896 int n12,int n23,int n31,
2897 int n45,int n56,int n64,
2898 int n14,int n25,int n36, int ID)
2900 return SMDS_Mesh::AddVolumeWithID
2901 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2902 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2903 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2904 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2905 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2906 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2907 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2908 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2909 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2910 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2911 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2912 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2913 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2914 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2915 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2919 //=======================================================================
2920 //function : AddVolumeWithID
2921 //purpose : 2d order Pentahedron with 15 nodes
2922 //=======================================================================
2923 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2924 const SMDS_MeshNode * n2,
2925 const SMDS_MeshNode * n3,
2926 const SMDS_MeshNode * n4,
2927 const SMDS_MeshNode * n5,
2928 const SMDS_MeshNode * n6,
2929 const SMDS_MeshNode * n12,
2930 const SMDS_MeshNode * n23,
2931 const SMDS_MeshNode * n31,
2932 const SMDS_MeshNode * n45,
2933 const SMDS_MeshNode * n56,
2934 const SMDS_MeshNode * n64,
2935 const SMDS_MeshNode * n14,
2936 const SMDS_MeshNode * n25,
2937 const SMDS_MeshNode * n36,
2940 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2941 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2943 if(hasConstructionFaces()) {
2944 // creation quadratic faces - not implemented
2947 SMDS_QuadraticVolumeOfNodes * volume =
2948 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2949 n45,n56,n64,n14,n25,n36);
2950 myVolumes.Add(volume);
2952 if (!registerElement(ID, volume)) {
2953 RemoveElement(volume, false);
2960 //=======================================================================
2961 //function : AddVolume
2963 //=======================================================================
2964 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2965 const SMDS_MeshNode * n2,
2966 const SMDS_MeshNode * n3,
2967 const SMDS_MeshNode * n4,
2968 const SMDS_MeshNode * n5,
2969 const SMDS_MeshNode * n6,
2970 const SMDS_MeshNode * n7,
2971 const SMDS_MeshNode * n8,
2972 const SMDS_MeshNode * n12,
2973 const SMDS_MeshNode * n23,
2974 const SMDS_MeshNode * n34,
2975 const SMDS_MeshNode * n41,
2976 const SMDS_MeshNode * n56,
2977 const SMDS_MeshNode * n67,
2978 const SMDS_MeshNode * n78,
2979 const SMDS_MeshNode * n85,
2980 const SMDS_MeshNode * n15,
2981 const SMDS_MeshNode * n26,
2982 const SMDS_MeshNode * n37,
2983 const SMDS_MeshNode * n48)
2985 int ID = myElementIDFactory->GetFreeID();
2986 SMDS_MeshVolume * v =
2987 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2988 n56, n67, n78, n85, n15, n26, n37, n48, ID);
2989 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2993 //=======================================================================
2994 //function : AddVolumeWithID
2996 //=======================================================================
2997 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2998 int n5, int n6, int n7, int n8,
2999 int n12,int n23,int n34,int n41,
3000 int n56,int n67,int n78,int n85,
3001 int n15,int n26,int n37,int n48, int ID)
3003 return SMDS_Mesh::AddVolumeWithID
3004 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3005 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3006 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3007 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3008 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3009 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3010 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3011 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3012 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3013 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3014 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3015 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3016 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3017 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3018 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3019 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3020 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3021 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3022 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3023 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3027 //=======================================================================
3028 //function : AddVolumeWithID
3029 //purpose : 2d order Hexahedrons with 20 nodes
3030 //=======================================================================
3031 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3032 const SMDS_MeshNode * n2,
3033 const SMDS_MeshNode * n3,
3034 const SMDS_MeshNode * n4,
3035 const SMDS_MeshNode * n5,
3036 const SMDS_MeshNode * n6,
3037 const SMDS_MeshNode * n7,
3038 const SMDS_MeshNode * n8,
3039 const SMDS_MeshNode * n12,
3040 const SMDS_MeshNode * n23,
3041 const SMDS_MeshNode * n34,
3042 const SMDS_MeshNode * n41,
3043 const SMDS_MeshNode * n56,
3044 const SMDS_MeshNode * n67,
3045 const SMDS_MeshNode * n78,
3046 const SMDS_MeshNode * n85,
3047 const SMDS_MeshNode * n15,
3048 const SMDS_MeshNode * n26,
3049 const SMDS_MeshNode * n37,
3050 const SMDS_MeshNode * n48,
3053 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3054 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3056 if(hasConstructionFaces()) {
3058 // creation quadratic faces - not implemented
3060 SMDS_QuadraticVolumeOfNodes * volume =
3061 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3062 n56,n67,n78,n85,n15,n26,n37,n48);
3063 myVolumes.Add(volume);
3065 if (!registerElement(ID, volume)) {
3066 RemoveElement(volume, false);