1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMDS : implementaion of Salome mesh data structure
25 #pragma warning(disable:4786)
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
39 #include "SMDS_SpacePosition.hxx"
41 #include <vtkUnstructuredGrid.h>
48 #include <sys/sysinfo.h>
51 // number of added entitis to check memory after
52 #define CHECKMEMORY_INTERVAL 1000
54 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
55 int SMDS_Mesh::chunkSize = 1024;
58 //================================================================================
60 * \brief Raise an exception if free memory (ram+swap) too low
61 * \param doNotRaise - if true, suppres exception, just return free memory size
62 * \retval int - amount of available memory in MB or negative number in failure case
64 //================================================================================
66 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
70 int err = sysinfo( &si );
74 static int limit = -1;
76 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
78 limit = WEXITSTATUS(status);
83 limit = int( limit * 1.5 );
85 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
89 const unsigned long Mbyte = 1024 * 1024;
90 // compute separately to avoid overflow
92 ( si.freeram * si.mem_unit ) / Mbyte +
93 ( si.freeswap * si.mem_unit ) / Mbyte;
96 return freeMb - limit;
101 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
103 throw std::bad_alloc();
109 ///////////////////////////////////////////////////////////////////////////////
110 /// Create a new mesh object
111 ///////////////////////////////////////////////////////////////////////////////
112 SMDS_Mesh::SMDS_Mesh()
114 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
115 myElementIDFactory(new SMDS_MeshElementIDFactory()),
116 myHasConstructionEdges(false), myHasConstructionFaces(false),
117 myHasInverseElements(true),
118 myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
119 myNodePool(0), myVolumePool(0)
121 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
122 MESSAGE("myMeshId=" << myMeshId);
123 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
124 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
125 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
126 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
127 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
128 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
129 myNodeIDFactory->SetMesh(this);
130 myElementIDFactory->SetMesh(this);
131 _meshList.push_back(this);
132 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
133 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
137 myIDElements.clear();
139 myGrid = vtkUnstructuredGrid::New();
140 myGrid->Initialize();
142 vtkPoints* points = vtkPoints::New();
143 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
144 myGrid->SetPoints( points );
146 myGrid->BuildLinks();
149 ///////////////////////////////////////////////////////////////////////////////
150 /// Create a new child mesh
151 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
152 /// (2003-09-08) of SMESH
153 ///////////////////////////////////////////////////////////////////////////////
154 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
155 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
156 myElementIDFactory(parent->myElementIDFactory),
157 myHasConstructionEdges(false), myHasConstructionFaces(false),
158 myHasInverseElements(true),
159 myNodePool(parent->myNodePool),
160 myVolumePool(parent->myVolumePool)
164 ///////////////////////////////////////////////////////////////////////////////
165 ///Create a submesh and add it to the current mesh
166 ///////////////////////////////////////////////////////////////////////////////
168 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
170 SMDS_Mesh *submesh = new SMDS_Mesh(this);
171 myChildren.insert(myChildren.end(), submesh);
175 ///////////////////////////////////////////////////////////////////////////////
176 ///create a MeshNode and add it to the current Mesh
177 ///An ID is automatically assigned to the node.
178 ///@return : The created node
179 ///////////////////////////////////////////////////////////////////////////////
181 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
183 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
186 ///////////////////////////////////////////////////////////////////////////////
187 ///create a MeshNode and add it to the current Mesh
188 ///@param ID : The ID of the MeshNode to create
189 ///@return : The created node or NULL if a node with this ID already exists
190 ///////////////////////////////////////////////////////////////////////////////
191 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
193 // find the MeshNode corresponding to ID
194 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
196 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
197 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
198 SMDS_MeshNode * node = myNodePool->getNew();
199 node->init(ID, myMeshId, -1, x, y, z);
200 if (ID >= myNodes.size())
202 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
203 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
206 myNodeIDFactory->BindID(ID,node);
213 ///////////////////////////////////////////////////////////////////////////////
214 /// create a Mesh0DElement and add it to the current Mesh
215 /// @return : The created Mesh0DElement
216 ///////////////////////////////////////////////////////////////////////////////
217 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
219 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
220 if (!node) return NULL;
221 return SMDS_Mesh::Add0DElementWithID(node, ID);
224 ///////////////////////////////////////////////////////////////////////////////
225 /// create a Mesh0DElement and add it to the current Mesh
226 /// @return : The created Mesh0DElement
227 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
230 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
233 ///////////////////////////////////////////////////////////////////////////////
234 /// Create a new Mesh0DElement and at it to the mesh
235 /// @param idnode ID of the node
236 /// @param ID ID of the 0D element to create
237 /// @return The created 0D element or NULL if an element with this
238 /// ID already exists or if input node is not found.
239 ///////////////////////////////////////////////////////////////////////////////
240 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
244 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
245 //MESSAGE("Add0DElementWithID" << ID)
246 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
247 if (myElementIDFactory->BindID(ID, el0d)) {
248 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
249 //node->AddInverseElement(el0d);// --- fait avec BindID
250 adjustmyCellsCapacity(ID);
252 myInfo.myNb0DElements++;
260 ///////////////////////////////////////////////////////////////////////////////
261 /// create a MeshEdge and add it to the current Mesh
262 /// @return : The created MeshEdge
263 ///////////////////////////////////////////////////////////////////////////////
265 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
267 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
268 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
269 if(!node1 || !node2) return NULL;
270 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
273 ///////////////////////////////////////////////////////////////////////////////
274 /// create a MeshEdge and add it to the current Mesh
275 /// @return : The created MeshEdge
276 ///////////////////////////////////////////////////////////////////////////////
278 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
279 const SMDS_MeshNode * node2)
281 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
284 ///////////////////////////////////////////////////////////////////////////////
285 /// Create a new edge and at it to the mesh
286 /// @param idnode1 ID of the first node
287 /// @param idnode2 ID of the second node
288 /// @param ID ID of the edge to create
289 /// @return The created edge or NULL if an element with this ID already exists or
290 /// if input nodes are not found.
291 ///////////////////////////////////////////////////////////////////////////////
293 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
294 const SMDS_MeshNode * n2,
297 if ( !n1 || !n2 ) return 0;
299 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
300 //MESSAGE("AddEdgeWithID " << ID)
301 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
302 adjustmyCellsCapacity(ID);
306 if (edge && !registerElement(ID, edge))
308 RemoveElement(edge, false);
314 ///////////////////////////////////////////////////////////////////////////////
315 /// Add a triangle defined by its nodes. An ID is automatically affected to the
317 ///////////////////////////////////////////////////////////////////////////////
319 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
320 const SMDS_MeshNode * n2,
321 const SMDS_MeshNode * n3)
323 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
326 ///////////////////////////////////////////////////////////////////////////////
327 /// Add a triangle defined by its nodes IDs
328 ///////////////////////////////////////////////////////////////////////////////
330 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
332 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
333 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
334 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
335 if(!node1 || !node2 || !node3) return NULL;
336 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
339 ///////////////////////////////////////////////////////////////////////////////
340 /// Add a triangle defined by its nodes
341 ///////////////////////////////////////////////////////////////////////////////
343 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
344 const SMDS_MeshNode * n2,
345 const SMDS_MeshNode * n3,
348 //MESSAGE("AddFaceWithID " << ID)
349 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
351 if (face && !registerElement(ID, face)) {
352 RemoveElement(face, false);
358 ///////////////////////////////////////////////////////////////////////////////
359 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
361 ///////////////////////////////////////////////////////////////////////////////
363 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
364 const SMDS_MeshNode * n2,
365 const SMDS_MeshNode * n3,
366 const SMDS_MeshNode * n4)
368 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
371 ///////////////////////////////////////////////////////////////////////////////
372 /// Add a quadrangle defined by its nodes IDs
373 ///////////////////////////////////////////////////////////////////////////////
375 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
381 SMDS_MeshNode *node1, *node2, *node3, *node4;
382 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
383 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
384 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
385 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
386 if(!node1 || !node2 || !node3 || !node4) return NULL;
387 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
390 ///////////////////////////////////////////////////////////////////////////////
391 /// Add a quadrangle defined by its nodes
392 ///////////////////////////////////////////////////////////////////////////////
394 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
395 const SMDS_MeshNode * n2,
396 const SMDS_MeshNode * n3,
397 const SMDS_MeshNode * n4,
400 //MESSAGE("AddFaceWithID " << ID);
401 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
403 if (face && !registerElement(ID, face)) {
404 RemoveElement(face, false);
410 ///////////////////////////////////////////////////////////////////////////////
411 /// Add a triangle defined by its edges. An ID is automatically assigned to the
413 ///////////////////////////////////////////////////////////////////////////////
415 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
416 const SMDS_MeshEdge * e2,
417 const SMDS_MeshEdge * e3)
419 if (!hasConstructionEdges())
421 //MESSAGE("AddFaceWithID");
422 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
425 ///////////////////////////////////////////////////////////////////////////////
426 /// Add a triangle defined by its edges
427 ///////////////////////////////////////////////////////////////////////////////
429 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
430 const SMDS_MeshEdge * e2,
431 const SMDS_MeshEdge * e3,
434 if (!hasConstructionEdges())
436 if ( !e1 || !e2 || !e3 ) return 0;
438 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
439 //MESSAGE("AddFaceWithID" << ID);
441 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
442 adjustmyCellsCapacity(ID);
444 myInfo.myNbTriangles++;
446 if (!registerElement(ID, face)) {
447 RemoveElement(face, false);
453 ///////////////////////////////////////////////////////////////////////////////
454 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
456 ///////////////////////////////////////////////////////////////////////////////
458 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
459 const SMDS_MeshEdge * e2,
460 const SMDS_MeshEdge * e3,
461 const SMDS_MeshEdge * e4)
463 if (!hasConstructionEdges())
465 //MESSAGE("AddFaceWithID" );
466 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
469 ///////////////////////////////////////////////////////////////////////////////
470 /// Add a quadrangle defined by its edges
471 ///////////////////////////////////////////////////////////////////////////////
473 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
474 const SMDS_MeshEdge * e2,
475 const SMDS_MeshEdge * e3,
476 const SMDS_MeshEdge * e4,
479 if (!hasConstructionEdges())
481 //MESSAGE("AddFaceWithID" << ID);
482 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
483 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
484 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
485 adjustmyCellsCapacity(ID);
487 myInfo.myNbQuadrangles++;
489 if (!registerElement(ID, face))
491 RemoveElement(face, false);
497 ///////////////////////////////////////////////////////////////////////////////
498 ///Create a new tetrahedron and add it to the mesh.
499 ///@return The created tetrahedron
500 ///////////////////////////////////////////////////////////////////////////////
502 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
503 const SMDS_MeshNode * n2,
504 const SMDS_MeshNode * n3,
505 const SMDS_MeshNode * n4)
507 int ID = myElementIDFactory->GetFreeID();
508 //MESSAGE("AddVolumeWithID " << ID);
509 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
510 if(v==NULL) myElementIDFactory->ReleaseID(ID);
514 ///////////////////////////////////////////////////////////////////////////////
515 ///Create a new tetrahedron and add it to the mesh.
516 ///@param ID The ID of the new volume
517 ///@return The created tetrahedron or NULL if an element with this ID already exists
518 ///or if input nodes are not found.
519 ///////////////////////////////////////////////////////////////////////////////
521 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
527 //MESSAGE("AddVolumeWithID" << ID);
528 SMDS_MeshNode *node1, *node2, *node3, *node4;
529 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
530 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
531 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
532 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
533 if(!node1 || !node2 || !node3 || !node4) return NULL;
534 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
537 ///////////////////////////////////////////////////////////////////////////////
538 ///Create a new tetrahedron and add it to the mesh.
539 ///@param ID The ID of the new volume
540 ///@return The created tetrahedron
541 ///////////////////////////////////////////////////////////////////////////////
543 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
544 const SMDS_MeshNode * n2,
545 const SMDS_MeshNode * n3,
546 const SMDS_MeshNode * n4,
549 //MESSAGE("AddVolumeWithID " << ID);
550 SMDS_MeshVolume* volume = 0;
551 if ( !n1 || !n2 || !n3 || !n4) return volume;
552 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
553 if(hasConstructionFaces()) {
554 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
555 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
556 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
557 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
558 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
559 adjustmyCellsCapacity(ID);
560 myCells[ID] = volume;
563 else if(hasConstructionEdges()) {
564 MESSAGE("Error : Not implemented");
568 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
569 adjustmyCellsCapacity(ID);
570 myCells[ID] = volume;
574 if (!registerElement(ID, volume)) {
575 RemoveElement(volume, false);
581 ///////////////////////////////////////////////////////////////////////////////
582 ///Create a new pyramid and add it to the mesh.
583 ///Nodes 1,2,3 and 4 define the base of the pyramid
584 ///@return The created pyramid
585 ///////////////////////////////////////////////////////////////////////////////
587 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
588 const SMDS_MeshNode * n2,
589 const SMDS_MeshNode * n3,
590 const SMDS_MeshNode * n4,
591 const SMDS_MeshNode * n5)
593 int ID = myElementIDFactory->GetFreeID();
594 //MESSAGE("AddVolumeWithID " << ID);
595 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
596 if(v==NULL) myElementIDFactory->ReleaseID(ID);
600 ///////////////////////////////////////////////////////////////////////////////
601 ///Create a new pyramid and add it to the mesh.
602 ///Nodes 1,2,3 and 4 define the base of the pyramid
603 ///@param ID The ID of the new volume
604 ///@return The created pyramid or NULL if an element with this ID already exists
605 ///or if input nodes are not found.
606 ///////////////////////////////////////////////////////////////////////////////
608 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
615 //MESSAGE("AddVolumeWithID " << ID);
616 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
617 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
618 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
619 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
620 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
621 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
622 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
623 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
626 ///////////////////////////////////////////////////////////////////////////////
627 ///Create a new pyramid and add it to the mesh.
628 ///Nodes 1,2,3 and 4 define the base of the pyramid
629 ///@param ID The ID of the new volume
630 ///@return The created pyramid
631 ///////////////////////////////////////////////////////////////////////////////
633 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
634 const SMDS_MeshNode * n2,
635 const SMDS_MeshNode * n3,
636 const SMDS_MeshNode * n4,
637 const SMDS_MeshNode * n5,
640 //MESSAGE("AddVolumeWithID " << ID);
641 SMDS_MeshVolume* volume = 0;
642 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
643 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
644 if(hasConstructionFaces()) {
645 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
646 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
647 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
648 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
649 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
650 adjustmyCellsCapacity(ID);
651 myCells[ID] = volume;
652 myInfo.myNbPyramids++;
654 else if(hasConstructionEdges()) {
655 MESSAGE("Error : Not implemented");
659 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
660 adjustmyCellsCapacity(ID);
661 myCells[ID] = volume;
662 myInfo.myNbPyramids++;
665 if (!registerElement(ID, volume)) {
666 RemoveElement(volume, false);
672 ///////////////////////////////////////////////////////////////////////////////
673 ///Create a new prism and add it to the mesh.
674 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
675 ///@return The created prism
676 ///////////////////////////////////////////////////////////////////////////////
678 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
679 const SMDS_MeshNode * n2,
680 const SMDS_MeshNode * n3,
681 const SMDS_MeshNode * n4,
682 const SMDS_MeshNode * n5,
683 const SMDS_MeshNode * n6)
685 int ID = myElementIDFactory->GetFreeID();
686 //MESSAGE("AddVolumeWithID " << ID);
687 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
688 if(v==NULL) myElementIDFactory->ReleaseID(ID);
692 ///////////////////////////////////////////////////////////////////////////////
693 ///Create a new prism and add it to the mesh.
694 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
695 ///@param ID The ID of the new volume
696 ///@return The created prism or NULL if an element with this ID already exists
697 ///or if input nodes are not found.
698 ///////////////////////////////////////////////////////////////////////////////
700 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
708 //MESSAGE("AddVolumeWithID " << ID);
709 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
710 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
711 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
712 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
713 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
714 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
715 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
716 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
717 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
720 ///////////////////////////////////////////////////////////////////////////////
721 ///Create a new prism and add it to the mesh.
722 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
723 ///@param ID The ID of the new volume
724 ///@return The created prism
725 ///////////////////////////////////////////////////////////////////////////////
727 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
728 const SMDS_MeshNode * n2,
729 const SMDS_MeshNode * n3,
730 const SMDS_MeshNode * n4,
731 const SMDS_MeshNode * n5,
732 const SMDS_MeshNode * n6,
735 //MESSAGE("AddVolumeWithID " << ID);
736 SMDS_MeshVolume* volume = 0;
737 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
738 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
739 if(hasConstructionFaces()) {
740 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
741 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
742 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
743 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
744 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
745 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
746 adjustmyCellsCapacity(ID);
747 myCells[ID] = volume;
750 else if(hasConstructionEdges()) {
751 MESSAGE("Error : Not implemented");
755 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
756 adjustmyCellsCapacity(ID);
757 myCells[ID] = volume;
761 if (!registerElement(ID, volume)) {
762 RemoveElement(volume, false);
768 ///////////////////////////////////////////////////////////////////////////////
769 ///Create a new hexahedron and add it to the mesh.
770 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
771 ///@return The created hexahedron
772 ///////////////////////////////////////////////////////////////////////////////
774 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
775 const SMDS_MeshNode * n2,
776 const SMDS_MeshNode * n3,
777 const SMDS_MeshNode * n4,
778 const SMDS_MeshNode * n5,
779 const SMDS_MeshNode * n6,
780 const SMDS_MeshNode * n7,
781 const SMDS_MeshNode * n8)
783 int ID = myElementIDFactory->GetFreeID();
784 //MESSAGE("AddVolumeWithID " << ID);
785 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
786 if(v==NULL) myElementIDFactory->ReleaseID(ID);
790 ///////////////////////////////////////////////////////////////////////////////
791 ///Create a new hexahedron and add it to the mesh.
792 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
793 ///@param ID The ID of the new volume
794 ///@return The created hexahedron or NULL if an element with this ID already
795 ///exists or if input nodes are not found.
796 ///////////////////////////////////////////////////////////////////////////////
798 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
808 //MESSAGE("AddVolumeWithID " << ID);
809 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
810 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
811 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
812 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
813 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
814 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
815 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
816 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
817 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
818 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
820 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
824 ///////////////////////////////////////////////////////////////////////////////
825 ///Create a new hexahedron and add it to the mesh.
826 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
827 ///@param ID The ID of the new volume
828 ///@return The created prism or NULL if an element with this ID already exists
829 ///or if input nodes are not found.
830 ///////////////////////////////////////////////////////////////////////////////
832 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
833 const SMDS_MeshNode * n2,
834 const SMDS_MeshNode * n3,
835 const SMDS_MeshNode * n4,
836 const SMDS_MeshNode * n5,
837 const SMDS_MeshNode * n6,
838 const SMDS_MeshNode * n7,
839 const SMDS_MeshNode * n8,
842 //MESSAGE("AddVolumeWithID " << ID);
843 SMDS_MeshVolume* volume = 0;
844 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
845 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
846 if(hasConstructionFaces()) {
847 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
848 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
849 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
850 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
851 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
852 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
853 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
854 adjustmyCellsCapacity(ID);
855 myCells[ID] = volume;
858 else if(hasConstructionEdges()) {
859 MESSAGE("Error : Not implemented");
863 // --- retreive nodes ID
864 vector<vtkIdType> nodeIds;
866 nodeIds.push_back(n1->getId());
867 nodeIds.push_back(n2->getId());
868 nodeIds.push_back(n3->getId());
869 nodeIds.push_back(n4->getId());
870 nodeIds.push_back(n5->getId());
871 nodeIds.push_back(n6->getId());
872 nodeIds.push_back(n7->getId());
873 nodeIds.push_back(n8->getId());
875 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
876 volvtk->init(nodeIds, this);
878 adjustmyCellsCapacity(ID);
879 myCells[ID] = volume;
883 if (!registerElement(ID, volume)) {
884 RemoveElement(volume, false);
890 ///////////////////////////////////////////////////////////////////////////////
891 ///Create a new tetrahedron defined by its faces and add it to the mesh.
892 ///@return The created tetrahedron
893 ///////////////////////////////////////////////////////////////////////////////
895 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
896 const SMDS_MeshFace * f2,
897 const SMDS_MeshFace * f3,
898 const SMDS_MeshFace * f4)
900 //MESSAGE("AddVolumeWithID");
901 if (!hasConstructionFaces())
903 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
906 ///////////////////////////////////////////////////////////////////////////////
907 ///Create a new tetrahedron defined by its faces and add it to the mesh.
908 ///@param ID The ID of the new volume
909 ///@return The created tetrahedron
910 ///////////////////////////////////////////////////////////////////////////////
912 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
913 const SMDS_MeshFace * f2,
914 const SMDS_MeshFace * f3,
915 const SMDS_MeshFace * f4,
918 //MESSAGE("AddVolumeWithID" << ID);
919 if (!hasConstructionFaces())
921 if ( !f1 || !f2 || !f3 || !f4) return 0;
922 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
923 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
924 adjustmyCellsCapacity(ID);
925 myCells[ID] = volume;
928 if (!registerElement(ID, volume)) {
929 RemoveElement(volume, false);
935 ///////////////////////////////////////////////////////////////////////////////
936 ///Create a new pyramid defined by its faces and add it to the mesh.
937 ///@return The created pyramid
938 ///////////////////////////////////////////////////////////////////////////////
940 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
941 const SMDS_MeshFace * f2,
942 const SMDS_MeshFace * f3,
943 const SMDS_MeshFace * f4,
944 const SMDS_MeshFace * f5)
946 //MESSAGE("AddVolumeWithID");
947 if (!hasConstructionFaces())
949 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
952 ///////////////////////////////////////////////////////////////////////////////
953 ///Create a new pyramid defined by its faces and add it to the mesh.
954 ///@param ID The ID of the new volume
955 ///@return The created pyramid
956 ///////////////////////////////////////////////////////////////////////////////
958 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
959 const SMDS_MeshFace * f2,
960 const SMDS_MeshFace * f3,
961 const SMDS_MeshFace * f4,
962 const SMDS_MeshFace * f5,
965 //MESSAGE("AddVolumeWithID" << ID);
966 if (!hasConstructionFaces())
968 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
969 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
970 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
971 adjustmyCellsCapacity(ID);
972 myCells[ID] = volume;
973 myInfo.myNbPyramids++;
975 if (!registerElement(ID, volume)) {
976 RemoveElement(volume, false);
982 ///////////////////////////////////////////////////////////////////////////////
983 ///Create a new prism defined by its faces and add it to the mesh.
984 ///@return The created prism
985 ///////////////////////////////////////////////////////////////////////////////
987 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
988 const SMDS_MeshFace * f2,
989 const SMDS_MeshFace * f3,
990 const SMDS_MeshFace * f4,
991 const SMDS_MeshFace * f5,
992 const SMDS_MeshFace * f6)
994 //MESSAGE("AddVolumeWithID" );
995 if (!hasConstructionFaces())
997 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1000 ///////////////////////////////////////////////////////////////////////////////
1001 ///Create a new prism defined by its faces and add it to the mesh.
1002 ///@param ID The ID of the new volume
1003 ///@return The created prism
1004 ///////////////////////////////////////////////////////////////////////////////
1006 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1007 const SMDS_MeshFace * f2,
1008 const SMDS_MeshFace * f3,
1009 const SMDS_MeshFace * f4,
1010 const SMDS_MeshFace * f5,
1011 const SMDS_MeshFace * f6,
1014 //MESSAGE("AddVolumeWithID" << ID);
1015 if (!hasConstructionFaces())
1017 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1018 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1019 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1020 adjustmyCellsCapacity(ID);
1021 myCells[ID] = volume;
1022 myInfo.myNbPrisms++;
1024 if (!registerElement(ID, volume)) {
1025 RemoveElement(volume, false);
1031 ///////////////////////////////////////////////////////////////////////////////
1032 /// Add a polygon defined by its nodes IDs
1033 ///////////////////////////////////////////////////////////////////////////////
1035 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1038 int nbNodes = nodes_ids.size();
1039 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1040 for (int i = 0; i < nbNodes; i++) {
1041 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1042 if (!nodes[i]) return NULL;
1044 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1047 ///////////////////////////////////////////////////////////////////////////////
1048 /// Add a polygon defined by its nodes
1049 ///////////////////////////////////////////////////////////////////////////////
1051 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1052 (std::vector<const SMDS_MeshNode*> nodes,
1055 SMDS_MeshFace * face;
1057 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1058 if (hasConstructionEdges())
1060 MESSAGE("Error : Not implemented");
1065 for ( int i = 0; i < nodes.size(); ++i )
1066 if ( !nodes[ i ] ) return 0;
1067 face = new SMDS_PolygonalFaceOfNodes(nodes);
1068 adjustmyCellsCapacity(ID);
1070 myInfo.myNbPolygons++;
1073 if (!registerElement(ID, face)) {
1074 RemoveElement(face, false);
1080 ///////////////////////////////////////////////////////////////////////////////
1081 /// Add a polygon defined by its nodes.
1082 /// An ID is automatically affected to the created face.
1083 ///////////////////////////////////////////////////////////////////////////////
1085 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1087 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1090 ///////////////////////////////////////////////////////////////////////////////
1091 /// Create a new polyhedral volume and add it to the mesh.
1092 /// @param ID The ID of the new volume
1093 /// @return The created volume or NULL if an element with this ID already exists
1094 /// or if input nodes are not found.
1095 ///////////////////////////////////////////////////////////////////////////////
1097 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1098 (std::vector<int> nodes_ids,
1099 std::vector<int> quantities,
1102 int nbNodes = nodes_ids.size();
1103 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1104 for (int i = 0; i < nbNodes; i++) {
1105 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1106 if (!nodes[i]) return NULL;
1108 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1111 ///////////////////////////////////////////////////////////////////////////////
1112 /// Create a new polyhedral volume and add it to the mesh.
1113 /// @param ID The ID of the new volume
1114 /// @return The created volume
1115 ///////////////////////////////////////////////////////////////////////////////
1117 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1118 (std::vector<const SMDS_MeshNode*> nodes,
1119 std::vector<int> quantities,
1122 SMDS_MeshVolume* volume;
1123 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1124 if (hasConstructionFaces()) {
1125 MESSAGE("Error : Not implemented");
1127 } else if (hasConstructionEdges()) {
1128 MESSAGE("Error : Not implemented");
1131 for ( int i = 0; i < nodes.size(); ++i )
1132 if ( !nodes[ i ] ) return 0;
1133 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1134 adjustmyCellsCapacity(ID);
1135 myCells[ID] = volume;
1136 myInfo.myNbPolyhedrons++;
1139 if (!registerElement(ID, volume)) {
1140 RemoveElement(volume, false);
1146 ///////////////////////////////////////////////////////////////////////////////
1147 /// Create a new polyhedral volume and add it to the mesh.
1148 /// @return The created volume
1149 ///////////////////////////////////////////////////////////////////////////////
1151 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1152 (std::vector<const SMDS_MeshNode*> nodes,
1153 std::vector<int> quantities)
1155 int ID = myElementIDFactory->GetFreeID();
1156 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1157 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1161 ///////////////////////////////////////////////////////////////////////////////
1162 /// Registers element with the given ID, maintains inverse connections
1163 ///////////////////////////////////////////////////////////////////////////////
1164 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1166 //MESSAGE("registerElement " << ID)
1167 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1169 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1174 element->myMeshId = myMeshId;
1176 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1178 int vtkId = cell->getVtkId();
1180 vtkId = myElementIDFactory->SetInVtkGrid(element);
1182 if (ID >= myIDElements.size()) // --- resize local vector
1184 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1185 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1188 myIDElements[ID] = vtkId;
1189 //MESSAGE("smds:" << ID << " vtk:" << cellId );
1191 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1193 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1194 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1196 myVtkIndex[vtkId] = ID;
1198 myElementIDFactory->updateMinMax(ID);
1202 ///////////////////////////////////////////////////////////////////////////////
1203 /// Return the node whose ID is 'ID'.
1204 ///////////////////////////////////////////////////////////////////////////////
1205 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1207 if (ID <0 || ID >= myNodes.size())
1209 return (const SMDS_MeshNode *)myNodes[ID];
1212 ///////////////////////////////////////////////////////////////////////////////
1213 ///Create a triangle and add it to the current mesh. This methode do not bind a
1214 ///ID to the create triangle.
1215 ///////////////////////////////////////////////////////////////////////////////
1216 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1217 const SMDS_MeshNode * node2,
1218 const SMDS_MeshNode * node3)
1220 if ( !node1 || !node2 || !node3) return 0;
1221 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1222 if(hasConstructionEdges())
1224 SMDS_MeshEdge *edge1, *edge2, *edge3;
1225 edge1=FindEdgeOrCreate(node1,node2);
1226 edge2=FindEdgeOrCreate(node2,node3);
1227 edge3=FindEdgeOrCreate(node3,node1);
1229 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1230 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1231 adjustmyCellsCapacity(ID);
1233 myInfo.myNbTriangles++;
1238 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1239 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1240 adjustmyCellsCapacity(ID);
1242 myInfo.myNbTriangles++;
1247 ///////////////////////////////////////////////////////////////////////////////
1248 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1249 ///a ID to the create triangle.
1250 ///////////////////////////////////////////////////////////////////////////////
1251 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1252 const SMDS_MeshNode * node2,
1253 const SMDS_MeshNode * node3,
1254 const SMDS_MeshNode * node4,
1257 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1258 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1259 if(hasConstructionEdges())
1261 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1262 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1263 edge1=FindEdgeOrCreate(node1,node2);
1264 edge2=FindEdgeOrCreate(node2,node3);
1265 edge3=FindEdgeOrCreate(node3,node4);
1266 edge4=FindEdgeOrCreate(node4,node1);
1268 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1269 adjustmyCellsCapacity(ID);
1271 myInfo.myNbQuadrangles++;
1276 //MESSAGE("createQuadrangle " << ID);
1277 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1278 adjustmyCellsCapacity(ID);
1280 myInfo.myNbQuadrangles++;
1285 ///////////////////////////////////////////////////////////////////////////////
1286 /// Remove a node and all the elements which own this node
1287 ///////////////////////////////////////////////////////////////////////////////
1289 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1291 MESSAGE("RemoveNode");
1292 RemoveElement(node, true);
1295 ///////////////////////////////////////////////////////////////////////////////
1296 /// Remove an edge and all the elements which own this edge
1297 ///////////////////////////////////////////////////////////////////////////////
1299 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1301 MESSAGE("Remove0DElement");
1302 RemoveElement(elem0d,true);
1305 ///////////////////////////////////////////////////////////////////////////////
1306 /// Remove an edge and all the elements which own this edge
1307 ///////////////////////////////////////////////////////////////////////////////
1309 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1311 MESSAGE("RemoveEdge");
1312 RemoveElement(edge,true);
1315 ///////////////////////////////////////////////////////////////////////////////
1316 /// Remove an face and all the elements which own this face
1317 ///////////////////////////////////////////////////////////////////////////////
1319 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1321 MESSAGE("RemoveFace");
1322 RemoveElement(face, true);
1325 ///////////////////////////////////////////////////////////////////////////////
1327 ///////////////////////////////////////////////////////////////////////////////
1329 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1331 MESSAGE("RemoveVolume");
1332 RemoveElement(volume, true);
1335 //=======================================================================
1336 //function : RemoveFromParent
1338 //=======================================================================
1340 bool SMDS_Mesh::RemoveFromParent()
1342 if (myParent==NULL) return false;
1343 else return (myParent->RemoveSubMesh(this));
1346 //=======================================================================
1347 //function : RemoveSubMesh
1349 //=======================================================================
1351 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1355 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1356 for (; itmsh!=myChildren.end() && !found; itmsh++)
1358 SMDS_Mesh * submesh = *itmsh;
1359 if (submesh == aMesh)
1362 myChildren.erase(itmsh);
1369 //=======================================================================
1370 //function : ChangeElementNodes
1372 //=======================================================================
1374 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1375 const SMDS_MeshNode * nodes[],
1378 // keep current nodes of elem
1379 set<const SMDS_MeshElement*> oldNodes;
1380 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1382 oldNodes.insert( itn->next() );
1384 if ( !element->IsPoly() )
1385 myInfo.remove( element ); // element may change type
1389 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1390 switch ( elem->GetType() )
1392 case SMDSAbs_0DElement: {
1393 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1394 Ok = elem0d->ChangeNode( nodes[0] );
1397 case SMDSAbs_Edge: {
1398 if ( nbnodes == 2 ) {
1399 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1400 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1402 else if ( nbnodes == 3 ) {
1403 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1404 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1408 case SMDSAbs_Face: {
1409 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1410 Ok = face->ChangeNodes( nodes, nbnodes );
1412 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1413 Ok = QF->ChangeNodes( nodes, nbnodes );
1415 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1416 Ok = face->ChangeNodes(nodes, nbnodes);
1419 case SMDSAbs_Volume: {
1420 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1421 Ok = vol->ChangeNodes( nodes, nbnodes );
1423 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1424 Ok = QV->ChangeNodes( nodes, nbnodes );
1428 MESSAGE ( "WRONG ELEM TYPE");
1431 if ( Ok ) { // update InverseElements
1433 set<const SMDS_MeshElement*>::iterator it;
1435 // AddInverseElement to new nodes
1436 for ( int i = 0; i < nbnodes; i++ ) {
1437 it = oldNodes.find( nodes[i] );
1438 if ( it == oldNodes.end() )
1440 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1442 // remove from oldNodes a node that remains in elem
1443 oldNodes.erase( it );
1445 // RemoveInverseElement from the nodes removed from elem
1446 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1448 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1449 (const_cast<SMDS_MeshElement *>( *it ));
1450 n->RemoveInverseElement( elem );
1454 if ( !element->IsPoly() )
1455 myInfo.add( element ); // element may change type
1460 //=======================================================================
1461 //function : ChangePolyhedronNodes
1462 //purpose : to change nodes of polyhedral volume
1463 //=======================================================================
1464 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1465 const vector<const SMDS_MeshNode*>& nodes,
1466 const vector<int> & quantities)
1468 if (elem->GetType() != SMDSAbs_Volume) {
1469 MESSAGE("WRONG ELEM TYPE");
1473 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1478 // keep current nodes of elem
1479 set<const SMDS_MeshElement*> oldNodes;
1480 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1481 while (itn->more()) {
1482 oldNodes.insert(itn->next());
1486 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1491 // update InverseElements
1493 // AddInverseElement to new nodes
1494 int nbnodes = nodes.size();
1495 set<const SMDS_MeshElement*>::iterator it;
1496 for (int i = 0; i < nbnodes; i++) {
1497 it = oldNodes.find(nodes[i]);
1498 if (it == oldNodes.end()) {
1500 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1502 // remove from oldNodes a node that remains in elem
1507 // RemoveInverseElement from the nodes removed from elem
1508 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1509 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1510 (const_cast<SMDS_MeshElement *>( *it ));
1511 n->RemoveInverseElement(elem);
1518 //=======================================================================
1519 //function : Find0DElement
1521 //=======================================================================
1522 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1524 const SMDS_MeshNode * node = FindNode(idnode);
1525 if(node == NULL) return NULL;
1526 return Find0DElement(node);
1529 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1531 if (!node) return 0;
1532 const SMDS_Mesh0DElement* toReturn = NULL;
1533 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1534 while (it1->more() && (toReturn == NULL)) {
1535 const SMDS_MeshElement* e = it1->next();
1536 if (e->NbNodes() == 1) {
1537 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1543 //=======================================================================
1544 //function : Find0DElementOrCreate
1546 //=======================================================================
1547 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1549 // if (!node) return 0;
1550 // SMDS_Mesh0DElement * toReturn = NULL;
1551 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1552 // if (toReturn == NULL) {
1553 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1554 // toReturn = new SMDS_Mesh0DElement(node);
1555 // my0DElements.Add(toReturn);
1556 // myInfo.myNb0DElements++;
1562 //=======================================================================
1563 //function : FindEdge
1565 //=======================================================================
1567 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1569 const SMDS_MeshNode * node1=FindNode(idnode1);
1570 const SMDS_MeshNode * node2=FindNode(idnode2);
1571 if((node1==NULL)||(node2==NULL)) return NULL;
1572 return FindEdge(node1,node2);
1575 //#include "Profiler.h"
1576 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1577 const SMDS_MeshNode * node2)
1579 if ( !node1 ) return 0;
1580 const SMDS_MeshEdge * toReturn=NULL;
1583 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1586 while(it1->more()) {
1587 const SMDS_MeshElement * e = it1->next();
1588 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1589 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1598 //=======================================================================
1599 //function : FindEdgeOrCreate
1601 //=======================================================================
1603 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1604 const SMDS_MeshNode * node2)
1606 if ( !node1 || !node2) return 0;
1607 SMDS_MeshEdge * toReturn=NULL;
1608 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1609 if(toReturn==NULL) {
1610 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1611 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1612 adjustmyCellsCapacity(ID);
1613 toReturn=new SMDS_MeshEdge(node1,node2);
1614 myCells[ID] = toReturn;
1621 //=======================================================================
1622 //function : FindEdge
1624 //=======================================================================
1626 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1629 const SMDS_MeshNode * node1=FindNode(idnode1);
1630 const SMDS_MeshNode * node2=FindNode(idnode2);
1631 const SMDS_MeshNode * node3=FindNode(idnode3);
1632 return FindEdge(node1,node2,node3);
1635 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1636 const SMDS_MeshNode * node2,
1637 const SMDS_MeshNode * node3)
1639 if ( !node1 ) return 0;
1640 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1641 while(it1->more()) {
1642 const SMDS_MeshElement * e = it1->next();
1643 if ( e->NbNodes() == 3 ) {
1644 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1645 while(it2->more()) {
1646 const SMDS_MeshElement* n = it2->next();
1656 return static_cast<const SMDS_MeshEdge *> (e);
1663 //=======================================================================
1664 //function : FindFace
1666 //=======================================================================
1668 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1671 const SMDS_MeshNode * node1=FindNode(idnode1);
1672 const SMDS_MeshNode * node2=FindNode(idnode2);
1673 const SMDS_MeshNode * node3=FindNode(idnode3);
1674 return FindFace(node1, node2, node3);
1677 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1678 const SMDS_MeshNode *node2,
1679 const SMDS_MeshNode *node3)
1681 if ( !node1 ) return 0;
1682 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1683 while(it1->more()) {
1684 const SMDS_MeshElement * e = it1->next();
1685 if ( e->NbNodes() == 3 ) {
1686 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1687 while(it2->more()) {
1688 const SMDS_MeshElement* n = it2->next();
1698 return static_cast<const SMDS_MeshFace *> (e);
1704 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1705 const SMDS_MeshNode *node2,
1706 const SMDS_MeshNode *node3)
1708 SMDS_MeshFace * toReturn=NULL;
1709 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1710 if(toReturn==NULL) {
1711 toReturn = createTriangle(node1,node2,node3);
1717 //=======================================================================
1718 //function : FindFace
1720 //=======================================================================
1722 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1723 int idnode3, int idnode4) const
1725 const SMDS_MeshNode * node1=FindNode(idnode1);
1726 const SMDS_MeshNode * node2=FindNode(idnode2);
1727 const SMDS_MeshNode * node3=FindNode(idnode3);
1728 const SMDS_MeshNode * node4=FindNode(idnode4);
1729 return FindFace(node1, node2, node3, node4);
1732 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1733 const SMDS_MeshNode *node2,
1734 const SMDS_MeshNode *node3,
1735 const SMDS_MeshNode *node4)
1737 if ( !node1 ) return 0;
1738 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1739 while(it1->more()) {
1740 const SMDS_MeshElement * e = it1->next();
1741 if ( e->NbNodes() == 4 ) {
1742 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1743 while(it2->more()) {
1744 const SMDS_MeshElement* n = it2->next();
1755 return static_cast<const SMDS_MeshFace *> (e);
1761 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1762 const SMDS_MeshNode *node2,
1763 const SMDS_MeshNode *node3,
1764 const SMDS_MeshNode *node4)
1766 SMDS_MeshFace * toReturn=NULL;
1767 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1768 if(toReturn==NULL) {
1769 int ID = myElementIDFactory->GetFreeID();
1770 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1776 //=======================================================================
1777 //function : FindFace
1778 //purpose :quadratic triangle
1779 //=======================================================================
1781 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1782 int idnode3, int idnode4,
1783 int idnode5, int idnode6) const
1785 const SMDS_MeshNode * node1 = FindNode(idnode1);
1786 const SMDS_MeshNode * node2 = FindNode(idnode2);
1787 const SMDS_MeshNode * node3 = FindNode(idnode3);
1788 const SMDS_MeshNode * node4 = FindNode(idnode4);
1789 const SMDS_MeshNode * node5 = FindNode(idnode5);
1790 const SMDS_MeshNode * node6 = FindNode(idnode6);
1791 return FindFace(node1, node2, node3, node4, node5, node6);
1794 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1795 const SMDS_MeshNode *node2,
1796 const SMDS_MeshNode *node3,
1797 const SMDS_MeshNode *node4,
1798 const SMDS_MeshNode *node5,
1799 const SMDS_MeshNode *node6)
1801 if ( !node1 ) return 0;
1802 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1803 while(it1->more()) {
1804 const SMDS_MeshElement * e = it1->next();
1805 if ( e->NbNodes() == 6 ) {
1806 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1807 while(it2->more()) {
1808 const SMDS_MeshElement* n = it2->next();
1821 return static_cast<const SMDS_MeshFace *> (e);
1828 //=======================================================================
1829 //function : FindFace
1830 //purpose : quadratic quadrangle
1831 //=======================================================================
1833 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1834 int idnode3, int idnode4,
1835 int idnode5, int idnode6,
1836 int idnode7, int idnode8) const
1838 const SMDS_MeshNode * node1 = FindNode(idnode1);
1839 const SMDS_MeshNode * node2 = FindNode(idnode2);
1840 const SMDS_MeshNode * node3 = FindNode(idnode3);
1841 const SMDS_MeshNode * node4 = FindNode(idnode4);
1842 const SMDS_MeshNode * node5 = FindNode(idnode5);
1843 const SMDS_MeshNode * node6 = FindNode(idnode6);
1844 const SMDS_MeshNode * node7 = FindNode(idnode7);
1845 const SMDS_MeshNode * node8 = FindNode(idnode8);
1846 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1849 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1850 const SMDS_MeshNode *node2,
1851 const SMDS_MeshNode *node3,
1852 const SMDS_MeshNode *node4,
1853 const SMDS_MeshNode *node5,
1854 const SMDS_MeshNode *node6,
1855 const SMDS_MeshNode *node7,
1856 const SMDS_MeshNode *node8)
1858 if ( !node1 ) return 0;
1859 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1860 while(it1->more()) {
1861 const SMDS_MeshElement * e = it1->next();
1862 if ( e->NbNodes() == 8 ) {
1863 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1864 while(it2->more()) {
1865 const SMDS_MeshElement* n = it2->next();
1880 return static_cast<const SMDS_MeshFace *> (e);
1887 //=======================================================================
1888 //function : FindElement
1890 //=======================================================================
1892 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1894 if ((IDelem < 0) || IDelem >= myCells.size())
1896 return myCells[IDelem];
1899 //=======================================================================
1900 //function : FindFace
1901 //purpose : find polygon
1902 //=======================================================================
1904 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1906 int nbnodes = nodes_ids.size();
1907 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1908 for (int inode = 0; inode < nbnodes; inode++) {
1909 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1910 if (node == NULL) return NULL;
1911 poly_nodes[inode] = node;
1913 return FindFace(poly_nodes);
1916 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1918 if ( nodes.size() > 2 && nodes[0] ) {
1919 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1920 while (itF->more()) {
1921 const SMDS_MeshElement* f = itF->next();
1922 if ( f->NbNodes() == nodes.size() ) {
1923 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1924 while(it2->more()) {
1925 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1931 return static_cast<const SMDS_MeshFace *> (f);
1938 //=======================================================================
1939 //function : DumpNodes
1941 //=======================================================================
1943 void SMDS_Mesh::DumpNodes() const
1945 MESSAGE("dump nodes of mesh : ");
1946 SMDS_NodeIteratorPtr itnode=nodesIterator();
1947 while(itnode->more()) ; //MESSAGE(itnode->next());
1950 //=======================================================================
1951 //function : Dump0DElements
1953 //=======================================================================
1954 void SMDS_Mesh::Dump0DElements() const
1956 MESSAGE("dump 0D elements of mesh : ");
1957 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
1958 while(it0d->more()) ; //MESSAGE(it0d->next());
1961 //=======================================================================
1962 //function : DumpEdges
1964 //=======================================================================
1966 void SMDS_Mesh::DumpEdges() const
1968 MESSAGE("dump edges of mesh : ");
1969 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1970 while(itedge->more()) ; //MESSAGE(itedge->next());
1973 //=======================================================================
1974 //function : DumpFaces
1976 //=======================================================================
1978 void SMDS_Mesh::DumpFaces() const
1980 MESSAGE("dump faces of mesh : ");
1981 SMDS_FaceIteratorPtr itface=facesIterator();
1982 while(itface->more()) ; //MESSAGE(itface->next());
1985 //=======================================================================
1986 //function : DumpVolumes
1988 //=======================================================================
1990 void SMDS_Mesh::DumpVolumes() const
1992 MESSAGE("dump volumes of mesh : ");
1993 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1994 while(itvol->more()) ; //MESSAGE(itvol->next());
1997 //=======================================================================
1998 //function : DebugStats
2000 //=======================================================================
2002 void SMDS_Mesh::DebugStats() const
2004 MESSAGE("Debug stats of mesh : ");
2006 MESSAGE("===== NODES ====="<<NbNodes());
2007 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2008 MESSAGE("===== EDGES ====="<<NbEdges());
2009 MESSAGE("===== FACES ====="<<NbFaces());
2010 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2012 MESSAGE("End Debug stats of mesh ");
2016 SMDS_NodeIteratorPtr itnode=nodesIterator();
2017 int sizeofnodes = 0;
2018 int sizeoffaces = 0;
2020 while(itnode->more())
2022 const SMDS_MeshNode *node = itnode->next();
2024 sizeofnodes += sizeof(*node);
2026 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2029 const SMDS_MeshElement *me = it->next();
2030 sizeofnodes += sizeof(me);
2034 SMDS_FaceIteratorPtr itface=facesIterator();
2035 while(itface->more())
2037 const SMDS_MeshElement *face = itface->next();
2038 sizeoffaces += sizeof(*face);
2041 MESSAGE("total size of node elements = " << sizeofnodes);;
2042 MESSAGE("total size of face elements = " << sizeoffaces);;
2047 ///////////////////////////////////////////////////////////////////////////////
2048 /// Return the number of nodes
2049 ///////////////////////////////////////////////////////////////////////////////
2050 int SMDS_Mesh::NbNodes() const
2052 return myNodes.size();
2055 ///////////////////////////////////////////////////////////////////////////////
2056 /// Return the number of 0D elements
2057 ///////////////////////////////////////////////////////////////////////////////
2058 int SMDS_Mesh::Nb0DElements() const
2060 return myInfo.Nb0DElements(); // -PR- a verfier
2063 ///////////////////////////////////////////////////////////////////////////////
2064 /// Return the number of edges (including construction edges)
2065 ///////////////////////////////////////////////////////////////////////////////
2066 int SMDS_Mesh::NbEdges() const
2068 return myInfo.NbEdges(); // -PR- a verfier
2071 ///////////////////////////////////////////////////////////////////////////////
2072 /// Return the number of faces (including construction faces)
2073 ///////////////////////////////////////////////////////////////////////////////
2074 int SMDS_Mesh::NbFaces() const
2076 return myInfo.NbFaces(); // -PR- a verfier
2079 ///////////////////////////////////////////////////////////////////////////////
2080 /// Return the number of volumes
2081 ///////////////////////////////////////////////////////////////////////////////
2082 int SMDS_Mesh::NbVolumes() const
2084 return myInfo.NbVolumes(); // -PR- a verfier
2087 ///////////////////////////////////////////////////////////////////////////////
2088 /// Return the number of child mesh of this mesh.
2089 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2090 /// (2003-09-08) of SMESH
2091 ///////////////////////////////////////////////////////////////////////////////
2092 int SMDS_Mesh::NbSubMesh() const
2094 return myChildren.size();
2097 ///////////////////////////////////////////////////////////////////////////////
2098 /// Destroy the mesh and all its elements
2099 /// All pointer on elements owned by this mesh become illegals.
2100 ///////////////////////////////////////////////////////////////////////////////
2101 SMDS_Mesh::~SMDS_Mesh()
2103 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2104 while(itc!=myChildren.end())
2112 delete myNodeIDFactory;
2113 delete myElementIDFactory;
2117 SMDS_ElemIteratorPtr eIt = elementsIterator();
2118 while ( eIt->more() )
2119 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2120 SMDS_NodeIteratorPtr itn = nodesIterator();
2122 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2125 // SetOfNodes::Iterator itn(myNodes);
2126 // for (; itn.More(); itn.Next())
2127 // delete itn.Value();
2129 // SetOf0DElements::Iterator it0d (my0DElements);
2130 // for (; it0d.More(); it0d.Next())
2132 // SMDS_MeshElement* elem = it0d.Value();
2136 // SetOfEdges::Iterator ite(myEdges);
2137 // for (; ite.More(); ite.Next())
2139 // SMDS_MeshElement* elem = ite.Value();
2143 // SetOfFaces::Iterator itf(myFaces);
2144 // for (; itf.More(); itf.Next())
2146 // SMDS_MeshElement* elem = itf.Value();
2150 // SetOfVolumes::Iterator itv(myVolumes);
2151 // for (; itv.More(); itv.Next())
2153 // SMDS_MeshElement* elem = itv.Value();
2158 //================================================================================
2160 * \brief Clear all data
2162 //================================================================================
2164 void SMDS_Mesh::Clear()
2166 if (myParent!=NULL) {
2167 SMDS_ElemIteratorPtr eIt = elementsIterator();
2168 while ( eIt->more() )
2169 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2170 SMDS_NodeIteratorPtr itn = nodesIterator();
2172 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2175 myNodeIDFactory->Clear();
2176 myElementIDFactory->Clear();
2179 SMDS_ElemIteratorPtr itv = elementsIterator();
2184 // SMDS_VolumeIteratorPtr itv = volumesIterator();
2185 // while (itv->more())
2186 // delete itv->next();
2187 // myVolumes.Clear();
2189 // SMDS_FaceIteratorPtr itf = facesIterator();
2190 // while (itf->more())
2191 // delete itf->next();
2194 // SMDS_EdgeIteratorPtr ite = edgesIterator();
2195 // while (ite->more())
2196 // delete ite->next();
2199 // SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2200 // while (it0d->more())
2201 // delete it0d->next();
2202 // my0DElements.Clear();
2204 SMDS_NodeIteratorPtr itn = nodesIterator();
2209 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2210 while(itc!=myChildren.end())
2216 ///////////////////////////////////////////////////////////////////////////////
2217 /// Return true if this mesh create faces with edges.
2218 /// A false returned value mean that faces are created with nodes. A concequence
2219 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2220 ///////////////////////////////////////////////////////////////////////////////
2221 bool SMDS_Mesh::hasConstructionEdges()
2223 return myHasConstructionEdges;
2226 ///////////////////////////////////////////////////////////////////////////////
2227 /// Return true if this mesh create volumes with faces
2228 /// A false returned value mean that volumes are created with nodes or edges.
2229 /// (see hasConstructionEdges)
2230 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2232 ///////////////////////////////////////////////////////////////////////////////
2233 bool SMDS_Mesh::hasConstructionFaces()
2235 return myHasConstructionFaces;
2238 ///////////////////////////////////////////////////////////////////////////////
2239 /// Return true if nodes are linked to the finit elements, they are belonging to.
2240 /// Currently, It always return true.
2241 ///////////////////////////////////////////////////////////////////////////////
2242 bool SMDS_Mesh::hasInverseElements()
2244 return myHasInverseElements;
2247 ///////////////////////////////////////////////////////////////////////////////
2248 /// Make this mesh creating construction edges (see hasConstructionEdges)
2249 /// @param b true to have construction edges, else false.
2250 ///////////////////////////////////////////////////////////////////////////////
2251 void SMDS_Mesh::setConstructionEdges(bool b)
2253 myHasConstructionEdges=b;
2256 ///////////////////////////////////////////////////////////////////////////////
2257 /// Make this mesh creating construction faces (see hasConstructionFaces)
2258 /// @param b true to have construction faces, else false.
2259 ///////////////////////////////////////////////////////////////////////////////
2260 void SMDS_Mesh::setConstructionFaces(bool b)
2262 myHasConstructionFaces=b;
2265 ///////////////////////////////////////////////////////////////////////////////
2266 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2267 /// @param b true to link nodes to elements, else false.
2268 ///////////////////////////////////////////////////////////////////////////////
2269 void SMDS_Mesh::setInverseElements(bool b)
2271 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2272 myHasInverseElements=b;
2275 ///////////////////////////////////////////////////////////////////////////////
2276 ///Iterator on NCollection_Map
2277 ///////////////////////////////////////////////////////////////////////////////
2278 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2279 struct MYNode_Map_Iterator: public FATHER
2283 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2290 while (_ctr < _map.size())
2301 ELEM current = _map[_ctr];
2307 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2308 struct MYElem_Map_Iterator: public FATHER
2313 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2321 while (_ctr < _map.size())
2324 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2333 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2339 ///////////////////////////////////////////////////////////////////////////////
2340 /// Return an iterator on nodes of the current mesh factory
2341 ///////////////////////////////////////////////////////////////////////////////
2343 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2345 //return SMDS_NodeIteratorPtr
2346 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2347 typedef MYNode_Map_Iterator
2348 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2349 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2352 ///////////////////////////////////////////////////////////////////////////////
2353 ///Return an iterator on 0D elements of the current mesh.
2354 ///////////////////////////////////////////////////////////////////////////////
2356 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2358 typedef MYElem_Map_Iterator
2359 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2360 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2363 ///////////////////////////////////////////////////////////////////////////////
2364 ///Return an iterator on edges of the current mesh.
2365 ///////////////////////////////////////////////////////////////////////////////
2367 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2369 typedef MYElem_Map_Iterator
2370 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2371 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2374 ///////////////////////////////////////////////////////////////////////////////
2375 ///Return an iterator on faces of the current mesh.
2376 ///////////////////////////////////////////////////////////////////////////////
2378 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2380 typedef MYElem_Map_Iterator
2381 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2382 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2385 ///////////////////////////////////////////////////////////////////////////////
2386 ///Return an iterator on volumes of the current mesh.
2387 ///////////////////////////////////////////////////////////////////////////////
2389 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2391 typedef MYElem_Map_Iterator
2392 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2393 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2396 ///////////////////////////////////////////////////////////////////////////////
2397 /// Return an iterator on elements of the current mesh factory
2398 ///////////////////////////////////////////////////////////////////////////////
2399 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2403 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2405 case SMDSAbs_Volume:
2406 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2408 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2410 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2411 case SMDSAbs_0DElement:
2412 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2414 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2415 //return myNodeIDFactory->elementsIterator();
2418 return myElementIDFactory->elementsIterator();
2421 ///////////////////////////////////////////////////////////////////////////////
2422 /// Do intersection of sets (more than 2)
2423 ///////////////////////////////////////////////////////////////////////////////
2424 static set<const SMDS_MeshElement*> * intersectionOfSets(
2425 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2427 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2428 set<const SMDS_MeshElement*>* rsetB;
2430 for(int i=0; i<numberOfSets-1; i++)
2432 rsetB=new set<const SMDS_MeshElement*>();
2434 rsetA->begin(), rsetA->end(),
2435 vs[i+1].begin(), vs[i+1].end(),
2436 inserter(*rsetB, rsetB->begin()));
2443 ///////////////////////////////////////////////////////////////////////////////
2444 /// Return the list of finit elements owning the given element
2445 ///////////////////////////////////////////////////////////////////////////////
2446 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2448 int numberOfSets=element->NbNodes();
2449 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2451 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2454 while(itNodes->more())
2456 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2457 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2459 //initSet[i]=set<const SMDS_MeshElement*>();
2461 initSet[i].insert(itFe->next());
2465 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2470 ///////////////////////////////////////////////////////////////////////////////
2471 /// Return the list of nodes used only by the given elements
2472 ///////////////////////////////////////////////////////////////////////////////
2473 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2474 set<const SMDS_MeshElement*>& elements)
2476 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2477 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2479 while(itElements!=elements.end())
2481 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2484 while(itNodes->more())
2486 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2487 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2488 set<const SMDS_MeshElement*> s;
2490 s.insert(itFe->next());
2491 if(s==elements) toReturn->insert(n);
2497 ///////////////////////////////////////////////////////////////////////////////
2498 ///Find the children of an element that are made of given nodes
2499 ///@param setOfChildren The set in which matching children will be inserted
2500 ///@param element The element were to search matching children
2501 ///@param nodes The nodes that the children must have to be selected
2502 ///////////////////////////////////////////////////////////////////////////////
2503 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2504 const SMDS_MeshElement * element,
2505 set<const SMDS_MeshElement*>& nodes)
2507 switch(element->GetType())
2510 MESSAGE("Internal Error: This should not happend");
2512 case SMDSAbs_0DElement:
2518 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2521 const SMDS_MeshElement * e=itn->next();
2522 if(nodes.find(e)!=nodes.end())
2524 setOfChildren.insert(element);
2531 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2534 const SMDS_MeshElement * e=itn->next();
2535 if(nodes.find(e)!=nodes.end())
2537 setOfChildren.insert(element);
2541 if(hasConstructionEdges())
2543 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2545 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2548 case SMDSAbs_Volume:
2550 if(hasConstructionFaces())
2552 SMDS_ElemIteratorPtr ite=element->facesIterator();
2554 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2556 else if(hasConstructionEdges())
2558 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2560 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2566 ///////////////////////////////////////////////////////////////////////////////
2567 ///@param elem The element to delete
2568 ///@param removenodes if true remaining nodes will be removed
2569 ///////////////////////////////////////////////////////////////////////////////
2570 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2571 const bool removenodes)
2573 list<const SMDS_MeshElement *> removedElems;
2574 list<const SMDS_MeshElement *> removedNodes;
2575 RemoveElement( elem, removedElems, removedNodes, removenodes );
2578 ///////////////////////////////////////////////////////////////////////////////
2579 ///@param elem The element to delete
2580 ///@param removedElems contains all removed elements
2581 ///@param removedNodes contains all removed nodes
2582 ///@param removenodes if true remaining nodes will be removed
2583 ///////////////////////////////////////////////////////////////////////////////
2584 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2585 list<const SMDS_MeshElement *>& removedElems,
2586 list<const SMDS_MeshElement *>& removedNodes,
2589 // get finite elements built on elem
2590 set<const SMDS_MeshElement*> * s1;
2591 if (elem->GetType() == SMDSAbs_0DElement ||
2592 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2593 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2594 elem->GetType() == SMDSAbs_Volume)
2596 s1 = new set<const SMDS_MeshElement*>();
2600 s1 = getFinitElements(elem);
2602 // get exclusive nodes (which would become free afterwards)
2603 set<const SMDS_MeshElement*> * s2;
2604 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2606 // do not remove nodes except elem
2607 s2 = new set<const SMDS_MeshElement*>();
2612 s2 = getExclusiveNodes(*s1);
2614 // form the set of finite and construction elements to remove
2615 set<const SMDS_MeshElement*> s3;
2616 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2617 while(it!=s1->end())
2619 addChildrenWithNodes(s3, *it ,*s2);
2623 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2625 // remove finite and construction elements
2629 // Remove element from <InverseElements> of its nodes
2630 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2633 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2634 (const_cast<SMDS_MeshElement *>(itn->next()));
2635 n->RemoveInverseElement( (*it) );
2638 switch((*it)->GetType())
2641 MESSAGE("Internal Error: This should not happen");
2643 case SMDSAbs_0DElement:
2644 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2648 myCells[(*it)->GetID()] = 0;
2649 myInfo.RemoveEdge(*it);
2652 myCells[(*it)->GetID()] = 0;
2653 myInfo.RemoveFace(*it);
2655 case SMDSAbs_Volume:
2656 myCells[(*it)->GetID()] = 0;
2657 myInfo.RemoveVolume(*it);
2660 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2661 removedElems.push_back( (*it) );
2662 myElementIDFactory->ReleaseID((*it)->GetID());
2667 // remove exclusive (free) nodes
2671 while(it!=s2->end())
2673 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2674 myNodes[(*it)->GetID()] = 0;
2676 myNodeIDFactory->ReleaseID((*it)->GetID());
2677 removedNodes.push_back( (*it) );
2688 ///////////////////////////////////////////////////////////////////////////////
2689 ///@param elem The element to delete
2690 ///////////////////////////////////////////////////////////////////////////////
2691 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2693 SMDSAbs_ElementType aType = elem->GetType();
2694 if (aType == SMDSAbs_Node) {
2695 // only free node can be removed by this method
2696 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2697 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2698 if (!itFe->more()) { // free node
2699 myNodes[elem->GetID()] = 0;
2701 myNodeIDFactory->ReleaseID(elem->GetID());
2705 if (hasConstructionEdges() || hasConstructionFaces())
2706 // this methods is only for meshes without descendants
2709 // Remove element from <InverseElements> of its nodes
2710 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2711 while (itn->more()) {
2712 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2713 (const_cast<SMDS_MeshElement *>(itn->next()));
2714 n->RemoveInverseElement(elem);
2717 // in meshes without descendants elements are always free
2719 case SMDSAbs_0DElement:
2720 myCells[elem->GetID()] = 0;
2721 myInfo.remove(elem);
2724 myCells[elem->GetID()] = 0;
2725 myInfo.RemoveEdge(elem);
2728 myCells[elem->GetID()] = 0;
2729 myInfo.RemoveFace(elem);
2731 case SMDSAbs_Volume:
2732 myCells[elem->GetID()] = 0;
2733 myInfo.RemoveVolume(elem);
2738 myElementIDFactory->ReleaseID(elem->GetID());
2744 * Checks if the element is present in mesh.
2745 * Useful to determine dead pointers.
2747 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2749 // we should not imply on validity of *elem, so iterate on containers
2750 // of all types in the hope of finding <elem> somewhere there
2751 SMDS_NodeIteratorPtr itn = nodesIterator();
2753 if (elem == itn->next())
2755 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2756 while (it0d->more())
2757 if (elem == it0d->next())
2759 SMDS_EdgeIteratorPtr ite = edgesIterator();
2761 if (elem == ite->next())
2763 SMDS_FaceIteratorPtr itf = facesIterator();
2765 if (elem == itf->next())
2767 SMDS_VolumeIteratorPtr itv = volumesIterator();
2769 if (elem == itv->next())
2774 //=======================================================================
2775 //function : MaxNodeID
2777 //=======================================================================
2779 int SMDS_Mesh::MaxNodeID() const
2784 //=======================================================================
2785 //function : MinNodeID
2787 //=======================================================================
2789 int SMDS_Mesh::MinNodeID() const
2794 //=======================================================================
2795 //function : MaxElementID
2797 //=======================================================================
2799 int SMDS_Mesh::MaxElementID() const
2801 return myElementIDFactory->GetMaxID();
2804 //=======================================================================
2805 //function : MinElementID
2807 //=======================================================================
2809 int SMDS_Mesh::MinElementID() const
2811 return myElementIDFactory->GetMinID();
2814 //=======================================================================
2815 //function : Renumber
2816 //purpose : Renumber all nodes or elements.
2817 //=======================================================================
2819 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2821 MESSAGE("Renumber");
2825 SMDS_MeshNodeIDFactory * idFactory =
2826 isNodes ? myNodeIDFactory : myElementIDFactory;
2828 // get existing elements in the order of ID increasing
2829 map<int,SMDS_MeshElement*> elemMap;
2830 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2831 while ( idElemIt->more() ) {
2832 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2833 int id = elem->GetID();
2834 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2836 // release their ids
2837 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2839 // for ( ; elemIt != elemMap.end(); elemIt++ )
2841 // int id = (*elemIt).first;
2842 // idFactory->ReleaseID( id );
2846 elemIt = elemMap.begin();
2847 for ( ; elemIt != elemMap.end(); elemIt++ )
2849 idFactory->BindID( ID, (*elemIt).second );
2854 //=======================================================================
2855 //function : GetElementType
2856 //purpose : Return type of element or node with id
2857 //=======================================================================
2859 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2861 SMDS_MeshElement* elem = 0;
2863 elem = myElementIDFactory->MeshElement( id );
2865 elem = myNodeIDFactory->MeshElement( id );
2869 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2873 return elem->GetType();
2878 //********************************************************************
2879 //********************************************************************
2880 //******** *********
2881 //***** Methods for addition of quadratic elements ******
2882 //******** *********
2883 //********************************************************************
2884 //********************************************************************
2886 //=======================================================================
2887 //function : AddEdgeWithID
2889 //=======================================================================
2890 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2892 return SMDS_Mesh::AddEdgeWithID
2893 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2894 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2895 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2899 //=======================================================================
2900 //function : AddEdge
2902 //=======================================================================
2903 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2904 const SMDS_MeshNode* n2,
2905 const SMDS_MeshNode* n12)
2907 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2910 //=======================================================================
2911 //function : AddEdgeWithID
2913 //=======================================================================
2914 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2915 const SMDS_MeshNode * n2,
2916 const SMDS_MeshNode * n12,
2919 if ( !n1 || !n2 || !n12 ) return 0;
2920 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2921 if(myElementIDFactory->BindID(ID, edge)) {
2922 SMDS_MeshNode *node1,*node2, *node12;
2923 //node1 = const_cast<SMDS_MeshNode*>(n1);
2924 //node2 = const_cast<SMDS_MeshNode*>(n2);
2925 //node12 = const_cast<SMDS_MeshNode*>(n12);
2926 //node1->AddInverseElement(edge); // --- fait avec BindID
2927 //node2->AddInverseElement(edge);
2928 //node12->AddInverseElement(edge);
2929 adjustmyCellsCapacity(ID);
2931 myInfo.myNbQuadEdges++;
2941 //=======================================================================
2942 //function : AddFace
2944 //=======================================================================
2945 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2946 const SMDS_MeshNode * n2,
2947 const SMDS_MeshNode * n3,
2948 const SMDS_MeshNode * n12,
2949 const SMDS_MeshNode * n23,
2950 const SMDS_MeshNode * n31)
2952 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2953 myElementIDFactory->GetFreeID());
2956 //=======================================================================
2957 //function : AddFaceWithID
2959 //=======================================================================
2960 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2961 int n12,int n23,int n31, int ID)
2963 return SMDS_Mesh::AddFaceWithID
2964 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2965 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2966 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2967 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2968 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2969 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2973 //=======================================================================
2974 //function : AddFaceWithID
2976 //=======================================================================
2977 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2978 const SMDS_MeshNode * n2,
2979 const SMDS_MeshNode * n3,
2980 const SMDS_MeshNode * n12,
2981 const SMDS_MeshNode * n23,
2982 const SMDS_MeshNode * n31,
2985 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2986 if(hasConstructionEdges()) {
2987 // creation quadratic edges - not implemented
2990 SMDS_QuadraticFaceOfNodes* face =
2991 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2992 adjustmyCellsCapacity(ID);
2994 myInfo.myNbQuadTriangles++;
2996 if (!registerElement(ID, face)) {
2997 RemoveElement(face, false);
3004 //=======================================================================
3005 //function : AddFace
3007 //=======================================================================
3008 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3009 const SMDS_MeshNode * n2,
3010 const SMDS_MeshNode * n3,
3011 const SMDS_MeshNode * n4,
3012 const SMDS_MeshNode * n12,
3013 const SMDS_MeshNode * n23,
3014 const SMDS_MeshNode * n34,
3015 const SMDS_MeshNode * n41)
3017 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3018 myElementIDFactory->GetFreeID());
3021 //=======================================================================
3022 //function : AddFaceWithID
3024 //=======================================================================
3025 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3026 int n12,int n23,int n34,int n41, int ID)
3028 return SMDS_Mesh::AddFaceWithID
3029 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3030 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3031 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3032 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3033 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3034 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3035 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3036 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3040 //=======================================================================
3041 //function : AddFaceWithID
3043 //=======================================================================
3044 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3045 const SMDS_MeshNode * n2,
3046 const SMDS_MeshNode * n3,
3047 const SMDS_MeshNode * n4,
3048 const SMDS_MeshNode * n12,
3049 const SMDS_MeshNode * n23,
3050 const SMDS_MeshNode * n34,
3051 const SMDS_MeshNode * n41,
3054 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3055 if(hasConstructionEdges()) {
3056 // creation quadratic edges - not implemented
3058 SMDS_QuadraticFaceOfNodes* face =
3059 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
3060 adjustmyCellsCapacity(ID);
3062 myInfo.myNbQuadQuadrangles++;
3064 if (!registerElement(ID, face)) {
3065 RemoveElement(face, false);
3072 //=======================================================================
3073 //function : AddVolume
3075 //=======================================================================
3076 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3077 const SMDS_MeshNode * n2,
3078 const SMDS_MeshNode * n3,
3079 const SMDS_MeshNode * n4,
3080 const SMDS_MeshNode * n12,
3081 const SMDS_MeshNode * n23,
3082 const SMDS_MeshNode * n31,
3083 const SMDS_MeshNode * n14,
3084 const SMDS_MeshNode * n24,
3085 const SMDS_MeshNode * n34)
3087 int ID = myElementIDFactory->GetFreeID();
3088 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3089 n31, n14, n24, n34, ID);
3090 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3094 //=======================================================================
3095 //function : AddVolumeWithID
3097 //=======================================================================
3098 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3099 int n12,int n23,int n31,
3100 int n14,int n24,int n34, int ID)
3102 return SMDS_Mesh::AddVolumeWithID
3103 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3104 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3105 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3106 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3107 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3108 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3109 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3110 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3111 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3112 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3116 //=======================================================================
3117 //function : AddVolumeWithID
3118 //purpose : 2d order tetrahedron of 10 nodes
3119 //=======================================================================
3120 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3121 const SMDS_MeshNode * n2,
3122 const SMDS_MeshNode * n3,
3123 const SMDS_MeshNode * n4,
3124 const SMDS_MeshNode * n12,
3125 const SMDS_MeshNode * n23,
3126 const SMDS_MeshNode * n31,
3127 const SMDS_MeshNode * n14,
3128 const SMDS_MeshNode * n24,
3129 const SMDS_MeshNode * n34,
3132 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3134 if(hasConstructionFaces()) {
3135 // creation quadratic faces - not implemented
3138 SMDS_QuadraticVolumeOfNodes * volume =
3139 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3140 adjustmyCellsCapacity(ID);
3141 myCells[ID] = volume;
3142 myInfo.myNbQuadTetras++;
3144 if (!registerElement(ID, volume)) {
3145 RemoveElement(volume, false);
3152 //=======================================================================
3153 //function : AddVolume
3155 //=======================================================================
3156 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3157 const SMDS_MeshNode * n2,
3158 const SMDS_MeshNode * n3,
3159 const SMDS_MeshNode * n4,
3160 const SMDS_MeshNode * n5,
3161 const SMDS_MeshNode * n12,
3162 const SMDS_MeshNode * n23,
3163 const SMDS_MeshNode * n34,
3164 const SMDS_MeshNode * n41,
3165 const SMDS_MeshNode * n15,
3166 const SMDS_MeshNode * n25,
3167 const SMDS_MeshNode * n35,
3168 const SMDS_MeshNode * n45)
3170 int ID = myElementIDFactory->GetFreeID();
3171 SMDS_MeshVolume * v =
3172 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3173 n15, n25, n35, n45, ID);
3174 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3178 //=======================================================================
3179 //function : AddVolumeWithID
3181 //=======================================================================
3182 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3183 int n12,int n23,int n34,int n41,
3184 int n15,int n25,int n35,int n45, int ID)
3186 return SMDS_Mesh::AddVolumeWithID
3187 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3188 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3189 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3190 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3191 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3192 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3193 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3194 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3195 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3196 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3197 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3198 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3199 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3203 //=======================================================================
3204 //function : AddVolumeWithID
3205 //purpose : 2d order pyramid of 13 nodes
3206 //=======================================================================
3207 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3208 const SMDS_MeshNode * n2,
3209 const SMDS_MeshNode * n3,
3210 const SMDS_MeshNode * n4,
3211 const SMDS_MeshNode * n5,
3212 const SMDS_MeshNode * n12,
3213 const SMDS_MeshNode * n23,
3214 const SMDS_MeshNode * n34,
3215 const SMDS_MeshNode * n41,
3216 const SMDS_MeshNode * n15,
3217 const SMDS_MeshNode * n25,
3218 const SMDS_MeshNode * n35,
3219 const SMDS_MeshNode * n45,
3222 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3223 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3225 if(hasConstructionFaces()) {
3226 // creation quadratic faces - not implemented
3229 SMDS_QuadraticVolumeOfNodes * volume =
3230 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3231 n34,n41,n15,n25,n35,n45);
3232 adjustmyCellsCapacity(ID);
3233 myCells[ID] = volume;
3234 myInfo.myNbQuadPyramids++;
3236 if (!registerElement(ID, volume)) {
3237 RemoveElement(volume, false);
3244 //=======================================================================
3245 //function : AddVolume
3247 //=======================================================================
3248 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3249 const SMDS_MeshNode * n2,
3250 const SMDS_MeshNode * n3,
3251 const SMDS_MeshNode * n4,
3252 const SMDS_MeshNode * n5,
3253 const SMDS_MeshNode * n6,
3254 const SMDS_MeshNode * n12,
3255 const SMDS_MeshNode * n23,
3256 const SMDS_MeshNode * n31,
3257 const SMDS_MeshNode * n45,
3258 const SMDS_MeshNode * n56,
3259 const SMDS_MeshNode * n64,
3260 const SMDS_MeshNode * n14,
3261 const SMDS_MeshNode * n25,
3262 const SMDS_MeshNode * n36)
3264 int ID = myElementIDFactory->GetFreeID();
3265 SMDS_MeshVolume * v =
3266 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3267 n45, n56, n64, n14, n25, n36, ID);
3268 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3272 //=======================================================================
3273 //function : AddVolumeWithID
3275 //=======================================================================
3276 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3277 int n4, int n5, int n6,
3278 int n12,int n23,int n31,
3279 int n45,int n56,int n64,
3280 int n14,int n25,int n36, int ID)
3282 return SMDS_Mesh::AddVolumeWithID
3283 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3288 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3289 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3290 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3291 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3292 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3293 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3294 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3295 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3296 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3297 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3301 //=======================================================================
3302 //function : AddVolumeWithID
3303 //purpose : 2d order Pentahedron with 15 nodes
3304 //=======================================================================
3305 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3306 const SMDS_MeshNode * n2,
3307 const SMDS_MeshNode * n3,
3308 const SMDS_MeshNode * n4,
3309 const SMDS_MeshNode * n5,
3310 const SMDS_MeshNode * n6,
3311 const SMDS_MeshNode * n12,
3312 const SMDS_MeshNode * n23,
3313 const SMDS_MeshNode * n31,
3314 const SMDS_MeshNode * n45,
3315 const SMDS_MeshNode * n56,
3316 const SMDS_MeshNode * n64,
3317 const SMDS_MeshNode * n14,
3318 const SMDS_MeshNode * n25,
3319 const SMDS_MeshNode * n36,
3322 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3323 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3325 if(hasConstructionFaces()) {
3326 // creation quadratic faces - not implemented
3329 SMDS_QuadraticVolumeOfNodes * volume =
3330 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3331 n45,n56,n64,n14,n25,n36);
3332 adjustmyCellsCapacity(ID);
3333 myCells[ID] = volume;
3334 myInfo.myNbQuadPrisms++;
3336 if (!registerElement(ID, volume)) {
3337 RemoveElement(volume, false);
3344 //=======================================================================
3345 //function : AddVolume
3347 //=======================================================================
3348 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3349 const SMDS_MeshNode * n2,
3350 const SMDS_MeshNode * n3,
3351 const SMDS_MeshNode * n4,
3352 const SMDS_MeshNode * n5,
3353 const SMDS_MeshNode * n6,
3354 const SMDS_MeshNode * n7,
3355 const SMDS_MeshNode * n8,
3356 const SMDS_MeshNode * n12,
3357 const SMDS_MeshNode * n23,
3358 const SMDS_MeshNode * n34,
3359 const SMDS_MeshNode * n41,
3360 const SMDS_MeshNode * n56,
3361 const SMDS_MeshNode * n67,
3362 const SMDS_MeshNode * n78,
3363 const SMDS_MeshNode * n85,
3364 const SMDS_MeshNode * n15,
3365 const SMDS_MeshNode * n26,
3366 const SMDS_MeshNode * n37,
3367 const SMDS_MeshNode * n48)
3369 int ID = myElementIDFactory->GetFreeID();
3370 SMDS_MeshVolume * v =
3371 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3372 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3373 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3377 //=======================================================================
3378 //function : AddVolumeWithID
3380 //=======================================================================
3381 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3382 int n5, int n6, int n7, int n8,
3383 int n12,int n23,int n34,int n41,
3384 int n56,int n67,int n78,int n85,
3385 int n15,int n26,int n37,int n48, int ID)
3387 return SMDS_Mesh::AddVolumeWithID
3388 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3389 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3390 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3391 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3392 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3393 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3394 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3395 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3396 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3397 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3398 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3399 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3400 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3401 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3402 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3403 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3404 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3405 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3406 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3407 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3411 //=======================================================================
3412 //function : AddVolumeWithID
3413 //purpose : 2d order Hexahedrons with 20 nodes
3414 //=======================================================================
3415 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3416 const SMDS_MeshNode * n2,
3417 const SMDS_MeshNode * n3,
3418 const SMDS_MeshNode * n4,
3419 const SMDS_MeshNode * n5,
3420 const SMDS_MeshNode * n6,
3421 const SMDS_MeshNode * n7,
3422 const SMDS_MeshNode * n8,
3423 const SMDS_MeshNode * n12,
3424 const SMDS_MeshNode * n23,
3425 const SMDS_MeshNode * n34,
3426 const SMDS_MeshNode * n41,
3427 const SMDS_MeshNode * n56,
3428 const SMDS_MeshNode * n67,
3429 const SMDS_MeshNode * n78,
3430 const SMDS_MeshNode * n85,
3431 const SMDS_MeshNode * n15,
3432 const SMDS_MeshNode * n26,
3433 const SMDS_MeshNode * n37,
3434 const SMDS_MeshNode * n48,
3437 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3438 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3440 if(hasConstructionFaces()) {
3442 // creation quadratic faces - not implemented
3444 SMDS_QuadraticVolumeOfNodes * volume =
3445 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3446 n56,n67,n78,n85,n15,n26,n37,n48);
3447 adjustmyCellsCapacity(ID);
3448 myCells[ID] = volume;
3449 myInfo.myNbQuadHexas++;
3451 if (!registerElement(ID, volume)) {
3452 RemoveElement(volume, false);
3458 void SMDS_Mesh::updateNodeMinMax()
3461 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3463 myNodeMax=myNodes.size()-1;
3464 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3468 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3470 int val = myIDElements.size();
3471 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3472 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3473 val = myNodes.size();
3474 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3475 myNodes.resize(val +nbNodes, 0);
3478 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3480 int val = myVtkIndex.size();
3481 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3482 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3483 val = myCells.size();
3484 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3485 myNodes.resize(val +nbCells, 0);