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>
42 #include <vtkUnsignedCharArray.h>
49 #include <sys/sysinfo.h>
52 // number of added entities to check memory after
53 #define CHECKMEMORY_INTERVAL 1000
55 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
56 int SMDS_Mesh::chunkSize = 1024;
59 //================================================================================
61 * \brief Raise an exception if free memory (ram+swap) too low
62 * \param doNotRaise - if true, suppres exception, just return free memory size
63 * \retval int - amount of available memory in MB or negative number in failure case
65 //================================================================================
67 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
71 int err = sysinfo( &si );
75 static int limit = -1;
77 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
79 limit = WEXITSTATUS(status);
84 limit = int( limit * 1.5 );
86 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
90 const unsigned long Mbyte = 1024 * 1024;
91 // compute separately to avoid overflow
93 ( si.freeram * si.mem_unit ) / Mbyte +
94 ( si.freeswap * si.mem_unit ) / Mbyte;
97 return freeMb - limit;
102 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
104 throw std::bad_alloc();
110 ///////////////////////////////////////////////////////////////////////////////
111 /// Create a new mesh object
112 ///////////////////////////////////////////////////////////////////////////////
113 SMDS_Mesh::SMDS_Mesh()
115 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
116 myElementIDFactory(new SMDS_MeshElementIDFactory()),
117 myHasConstructionEdges(false), myHasConstructionFaces(false),
118 myHasInverseElements(true),
119 myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
120 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
122 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
123 MESSAGE("myMeshId=" << myMeshId);
124 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
125 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
126 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
127 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
128 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
129 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
130 myNodeIDFactory->SetMesh(this);
131 myElementIDFactory->SetMesh(this);
132 _meshList.push_back(this);
133 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
134 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
135 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
136 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
140 myIDElements.clear();
142 myGrid = vtkUnstructuredGrid::New();
143 myGrid->Initialize();
145 vtkPoints* points = vtkPoints::New();
146 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
147 myGrid->SetPoints( points );
149 myGrid->BuildLinks();
152 ///////////////////////////////////////////////////////////////////////////////
153 /// Create a new child mesh
154 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
155 /// (2003-09-08) of SMESH
156 ///////////////////////////////////////////////////////////////////////////////
157 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
158 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
159 myElementIDFactory(parent->myElementIDFactory),
160 myHasConstructionEdges(false), myHasConstructionFaces(false),
161 myHasInverseElements(true),
162 myNodePool(parent->myNodePool),
163 myEdgePool(parent->myEdgePool),
164 myFacePool(parent->myFacePool),
165 myVolumePool(parent->myVolumePool)
169 ///////////////////////////////////////////////////////////////////////////////
170 ///Create a submesh and add it to the current mesh
171 ///////////////////////////////////////////////////////////////////////////////
173 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
175 SMDS_Mesh *submesh = new SMDS_Mesh(this);
176 myChildren.insert(myChildren.end(), submesh);
180 ///////////////////////////////////////////////////////////////////////////////
181 ///create a MeshNode and add it to the current Mesh
182 ///An ID is automatically assigned to the node.
183 ///@return : The created node
184 ///////////////////////////////////////////////////////////////////////////////
186 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
188 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
191 ///////////////////////////////////////////////////////////////////////////////
192 ///create a MeshNode and add it to the current Mesh
193 ///@param ID : The ID of the MeshNode to create
194 ///@return : The created node or NULL if a node with this ID already exists
195 ///////////////////////////////////////////////////////////////////////////////
196 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
198 // find the MeshNode corresponding to ID
199 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
201 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
202 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
203 SMDS_MeshNode * node = myNodePool->getNew();
204 node->init(ID, myMeshId, -1, x, y, z);
205 if (ID >= myNodes.size())
207 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
208 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
211 myNodeIDFactory->BindID(ID,node);
218 ///////////////////////////////////////////////////////////////////////////////
219 /// create a Mesh0DElement and add it to the current Mesh
220 /// @return : The created Mesh0DElement
221 ///////////////////////////////////////////////////////////////////////////////
222 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
224 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
225 if (!node) return NULL;
226 return SMDS_Mesh::Add0DElementWithID(node, ID);
229 ///////////////////////////////////////////////////////////////////////////////
230 /// create a Mesh0DElement and add it to the current Mesh
231 /// @return : The created Mesh0DElement
232 ///////////////////////////////////////////////////////////////////////////////
233 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
235 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
238 ///////////////////////////////////////////////////////////////////////////////
239 /// Create a new Mesh0DElement and at it to the mesh
240 /// @param idnode ID of the node
241 /// @param ID ID of the 0D element to create
242 /// @return The created 0D element or NULL if an element with this
243 /// ID already exists or if input node is not found.
244 ///////////////////////////////////////////////////////////////////////////////
245 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
249 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
250 //MESSAGE("Add0DElementWithID" << ID)
251 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
252 if (myElementIDFactory->BindID(ID, el0d)) {
253 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
254 //node->AddInverseElement(el0d);// --- fait avec BindID
255 adjustmyCellsCapacity(ID);
257 myInfo.myNb0DElements++;
265 ///////////////////////////////////////////////////////////////////////////////
266 /// create a MeshEdge and add it to the current Mesh
267 /// @return : The created MeshEdge
268 ///////////////////////////////////////////////////////////////////////////////
270 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
272 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
273 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
274 if(!node1 || !node2) return NULL;
275 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
278 ///////////////////////////////////////////////////////////////////////////////
279 /// create a MeshEdge and add it to the current Mesh
280 /// @return : The created MeshEdge
281 ///////////////////////////////////////////////////////////////////////////////
283 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
284 const SMDS_MeshNode * node2)
286 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
289 ///////////////////////////////////////////////////////////////////////////////
290 /// Create a new edge and at it to the mesh
291 /// @param idnode1 ID of the first node
292 /// @param idnode2 ID of the second node
293 /// @param ID ID of the edge to create
294 /// @return The created edge or NULL if an element with this ID already exists or
295 /// if input nodes are not found.
296 ///////////////////////////////////////////////////////////////////////////////
298 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
299 const SMDS_MeshNode * n2,
302 if ( !n1 || !n2 ) return 0;
303 SMDS_MeshEdge * edge = 0;
305 // --- retreive nodes ID
306 vector<vtkIdType> nodeIds;
308 nodeIds.push_back(n1->getId());
309 nodeIds.push_back(n2->getId());
311 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
312 edgevtk->init(nodeIds, this);
314 adjustmyCellsCapacity(ID);
318 if (edge && !registerElement(ID, edge))
320 RemoveElement(edge, false);
326 ///////////////////////////////////////////////////////////////////////////////
327 /// Add a triangle defined by its nodes. An ID is automatically affected to the
329 ///////////////////////////////////////////////////////////////////////////////
331 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
332 const SMDS_MeshNode * n2,
333 const SMDS_MeshNode * n3)
335 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
338 ///////////////////////////////////////////////////////////////////////////////
339 /// Add a triangle defined by its nodes IDs
340 ///////////////////////////////////////////////////////////////////////////////
342 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
344 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
345 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
346 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
347 if(!node1 || !node2 || !node3) return NULL;
348 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
351 ///////////////////////////////////////////////////////////////////////////////
352 /// Add a triangle defined by its nodes
353 ///////////////////////////////////////////////////////////////////////////////
355 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
356 const SMDS_MeshNode * n2,
357 const SMDS_MeshNode * n3,
360 //MESSAGE("AddFaceWithID " << ID)
361 SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
363 if (face && !registerElement(ID, face)) {
364 RemoveElement(face, false);
370 ///////////////////////////////////////////////////////////////////////////////
371 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
373 ///////////////////////////////////////////////////////////////////////////////
375 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
376 const SMDS_MeshNode * n2,
377 const SMDS_MeshNode * n3,
378 const SMDS_MeshNode * n4)
380 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
383 ///////////////////////////////////////////////////////////////////////////////
384 /// Add a quadrangle defined by its nodes IDs
385 ///////////////////////////////////////////////////////////////////////////////
387 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
393 SMDS_MeshNode *node1, *node2, *node3, *node4;
394 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
395 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
396 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
397 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
398 if(!node1 || !node2 || !node3 || !node4) return NULL;
399 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
402 ///////////////////////////////////////////////////////////////////////////////
403 /// Add a quadrangle defined by its nodes
404 ///////////////////////////////////////////////////////////////////////////////
406 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
407 const SMDS_MeshNode * n2,
408 const SMDS_MeshNode * n3,
409 const SMDS_MeshNode * n4,
412 //MESSAGE("AddFaceWithID " << ID);
413 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
415 if (face && !registerElement(ID, face)) {
416 RemoveElement(face, false);
422 ///////////////////////////////////////////////////////////////////////////////
423 /// Add a triangle defined by its edges. An ID is automatically assigned to the
425 ///////////////////////////////////////////////////////////////////////////////
427 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
428 const SMDS_MeshEdge * e2,
429 const SMDS_MeshEdge * e3)
431 if (!hasConstructionEdges())
433 //MESSAGE("AddFaceWithID");
434 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
437 ///////////////////////////////////////////////////////////////////////////////
438 /// Add a triangle defined by its edges
439 ///////////////////////////////////////////////////////////////////////////////
441 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
442 const SMDS_MeshEdge * e2,
443 const SMDS_MeshEdge * e3,
446 if (!hasConstructionEdges())
448 if ( !e1 || !e2 || !e3 ) return 0;
450 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
451 //MESSAGE("AddFaceWithID" << ID);
453 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
454 adjustmyCellsCapacity(ID);
456 myInfo.myNbTriangles++;
458 if (!registerElement(ID, face)) {
459 RemoveElement(face, false);
465 ///////////////////////////////////////////////////////////////////////////////
466 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
468 ///////////////////////////////////////////////////////////////////////////////
470 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
471 const SMDS_MeshEdge * e2,
472 const SMDS_MeshEdge * e3,
473 const SMDS_MeshEdge * e4)
475 if (!hasConstructionEdges())
477 //MESSAGE("AddFaceWithID" );
478 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
481 ///////////////////////////////////////////////////////////////////////////////
482 /// Add a quadrangle defined by its edges
483 ///////////////////////////////////////////////////////////////////////////////
485 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
486 const SMDS_MeshEdge * e2,
487 const SMDS_MeshEdge * e3,
488 const SMDS_MeshEdge * e4,
491 if (!hasConstructionEdges())
493 //MESSAGE("AddFaceWithID" << ID);
494 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
495 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
496 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
497 adjustmyCellsCapacity(ID);
499 myInfo.myNbQuadrangles++;
501 if (!registerElement(ID, face))
503 RemoveElement(face, false);
509 ///////////////////////////////////////////////////////////////////////////////
510 ///Create a new tetrahedron and add it to the mesh.
511 ///@return The created tetrahedron
512 ///////////////////////////////////////////////////////////////////////////////
514 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
515 const SMDS_MeshNode * n2,
516 const SMDS_MeshNode * n3,
517 const SMDS_MeshNode * n4)
519 int ID = myElementIDFactory->GetFreeID();
520 //MESSAGE("AddVolumeWithID " << ID);
521 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
522 if(v==NULL) myElementIDFactory->ReleaseID(ID);
526 ///////////////////////////////////////////////////////////////////////////////
527 ///Create a new tetrahedron and add it to the mesh.
528 ///@param ID The ID of the new volume
529 ///@return The created tetrahedron or NULL if an element with this ID already exists
530 ///or if input nodes are not found.
531 ///////////////////////////////////////////////////////////////////////////////
533 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
539 //MESSAGE("AddVolumeWithID" << ID);
540 SMDS_MeshNode *node1, *node2, *node3, *node4;
541 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
542 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
543 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
544 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
545 if(!node1 || !node2 || !node3 || !node4) return NULL;
546 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
549 ///////////////////////////////////////////////////////////////////////////////
550 ///Create a new tetrahedron and add it to the mesh.
551 ///@param ID The ID of the new volume
552 ///@return The created tetrahedron
553 ///////////////////////////////////////////////////////////////////////////////
555 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
556 const SMDS_MeshNode * n2,
557 const SMDS_MeshNode * n3,
558 const SMDS_MeshNode * n4,
561 //MESSAGE("AddVolumeWithID " << ID);
562 SMDS_MeshVolume* volume = 0;
563 if ( !n1 || !n2 || !n3 || !n4) return volume;
564 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
565 if(hasConstructionFaces()) {
566 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
567 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
568 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
569 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
570 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
571 adjustmyCellsCapacity(ID);
572 myCells[ID] = volume;
575 else if(hasConstructionEdges()) {
576 MESSAGE("Error : Not implemented");
580 // --- retrieve nodes ID
581 vector<vtkIdType> nodeIds;
583 nodeIds.push_back(n1->getId());
584 nodeIds.push_back(n3->getId()); // order SMDS-->VTK
585 nodeIds.push_back(n2->getId());
586 nodeIds.push_back(n4->getId());
588 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
589 volvtk->init(nodeIds, this);
591 adjustmyCellsCapacity(ID);
592 myCells[ID] = volume;
596 if (!registerElement(ID, volume)) {
597 RemoveElement(volume, false);
603 ///////////////////////////////////////////////////////////////////////////////
604 ///Create a new pyramid and add it to the mesh.
605 ///Nodes 1,2,3 and 4 define the base of the pyramid
606 ///@return The created pyramid
607 ///////////////////////////////////////////////////////////////////////////////
609 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
610 const SMDS_MeshNode * n2,
611 const SMDS_MeshNode * n3,
612 const SMDS_MeshNode * n4,
613 const SMDS_MeshNode * n5)
615 int ID = myElementIDFactory->GetFreeID();
616 //MESSAGE("AddVolumeWithID " << ID);
617 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
618 if(v==NULL) myElementIDFactory->ReleaseID(ID);
622 ///////////////////////////////////////////////////////////////////////////////
623 ///Create a new pyramid and add it to the mesh.
624 ///Nodes 1,2,3 and 4 define the base of the pyramid
625 ///@param ID The ID of the new volume
626 ///@return The created pyramid or NULL if an element with this ID already exists
627 ///or if input nodes are not found.
628 ///////////////////////////////////////////////////////////////////////////////
630 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
637 //MESSAGE("AddVolumeWithID " << ID);
638 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
639 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
640 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
641 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
642 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
643 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
644 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
645 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
648 ///////////////////////////////////////////////////////////////////////////////
649 ///Create a new pyramid and add it to the mesh.
650 ///Nodes 1,2,3 and 4 define the base of the pyramid
651 ///@param ID The ID of the new volume
652 ///@return The created pyramid
653 ///////////////////////////////////////////////////////////////////////////////
655 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
656 const SMDS_MeshNode * n2,
657 const SMDS_MeshNode * n3,
658 const SMDS_MeshNode * n4,
659 const SMDS_MeshNode * n5,
662 //MESSAGE("AddVolumeWithID " << ID);
663 SMDS_MeshVolume* volume = 0;
664 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
665 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
666 if(hasConstructionFaces()) {
667 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
668 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
669 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
670 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
671 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
672 adjustmyCellsCapacity(ID);
673 myCells[ID] = volume;
674 myInfo.myNbPyramids++;
676 else if(hasConstructionEdges()) {
677 MESSAGE("Error : Not implemented");
681 // --- retrieve nodes ID
682 vector<vtkIdType> nodeIds;
684 nodeIds.push_back(n1->getId());
685 nodeIds.push_back(n4->getId());
686 nodeIds.push_back(n3->getId());
687 nodeIds.push_back(n2->getId());
688 nodeIds.push_back(n5->getId());
690 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
691 volvtk->init(nodeIds, this);
693 adjustmyCellsCapacity(ID);
694 myCells[ID] = volume;
695 myInfo.myNbPyramids++;
698 if (!registerElement(ID, volume)) {
699 RemoveElement(volume, false);
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new prism and add it to the mesh.
707 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
708 ///@return The created prism
709 ///////////////////////////////////////////////////////////////////////////////
711 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
712 const SMDS_MeshNode * n2,
713 const SMDS_MeshNode * n3,
714 const SMDS_MeshNode * n4,
715 const SMDS_MeshNode * n5,
716 const SMDS_MeshNode * n6)
718 int ID = myElementIDFactory->GetFreeID();
719 //MESSAGE("AddVolumeWithID " << ID);
720 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
721 if(v==NULL) myElementIDFactory->ReleaseID(ID);
725 ///////////////////////////////////////////////////////////////////////////////
726 ///Create a new prism and add it to the mesh.
727 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
728 ///@param ID The ID of the new volume
729 ///@return The created prism or NULL if an element with this ID already exists
730 ///or if input nodes are not found.
731 ///////////////////////////////////////////////////////////////////////////////
733 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
741 //MESSAGE("AddVolumeWithID " << ID);
742 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
743 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
744 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
745 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
746 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
747 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
748 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
749 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
750 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
753 ///////////////////////////////////////////////////////////////////////////////
754 ///Create a new prism and add it to the mesh.
755 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
756 ///@param ID The ID of the new volume
757 ///@return The created prism
758 ///////////////////////////////////////////////////////////////////////////////
760 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
761 const SMDS_MeshNode * n2,
762 const SMDS_MeshNode * n3,
763 const SMDS_MeshNode * n4,
764 const SMDS_MeshNode * n5,
765 const SMDS_MeshNode * n6,
768 //MESSAGE("AddVolumeWithID " << ID);
769 SMDS_MeshVolume* volume = 0;
770 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
771 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
772 if(hasConstructionFaces()) {
773 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
774 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
775 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
776 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
777 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
778 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
779 adjustmyCellsCapacity(ID);
780 myCells[ID] = volume;
783 else if(hasConstructionEdges()) {
784 MESSAGE("Error : Not implemented");
788 // --- retrieve nodes ID
789 vector<vtkIdType> nodeIds;
791 nodeIds.push_back(n1->getId());
792 nodeIds.push_back(n3->getId());
793 nodeIds.push_back(n2->getId());
794 nodeIds.push_back(n4->getId());
795 nodeIds.push_back(n6->getId());
796 nodeIds.push_back(n5->getId());
798 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
799 volvtk->init(nodeIds, this);
801 adjustmyCellsCapacity(ID);
802 myCells[ID] = volume;
806 if (!registerElement(ID, volume)) {
807 RemoveElement(volume, false);
813 ///////////////////////////////////////////////////////////////////////////////
814 ///Create a new hexahedron and add it to the mesh.
815 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
816 ///@return The created hexahedron
817 ///////////////////////////////////////////////////////////////////////////////
819 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
820 const SMDS_MeshNode * n2,
821 const SMDS_MeshNode * n3,
822 const SMDS_MeshNode * n4,
823 const SMDS_MeshNode * n5,
824 const SMDS_MeshNode * n6,
825 const SMDS_MeshNode * n7,
826 const SMDS_MeshNode * n8)
828 int ID = myElementIDFactory->GetFreeID();
829 //MESSAGE("AddVolumeWithID " << ID);
830 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
831 if(v==NULL) myElementIDFactory->ReleaseID(ID);
835 ///////////////////////////////////////////////////////////////////////////////
836 ///Create a new hexahedron and add it to the mesh.
837 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
838 ///@param ID The ID of the new volume
839 ///@return The created hexahedron or NULL if an element with this ID already
840 ///exists or if input nodes are not found.
841 ///////////////////////////////////////////////////////////////////////////////
843 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
853 //MESSAGE("AddVolumeWithID " << ID);
854 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
855 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
856 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
857 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
858 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
859 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
860 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
861 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
862 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
863 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
865 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
869 ///////////////////////////////////////////////////////////////////////////////
870 ///Create a new hexahedron and add it to the mesh.
871 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
872 ///@param ID The ID of the new volume
873 ///@return The created prism or NULL if an element with this ID already exists
874 ///or if input nodes are not found.
875 ///////////////////////////////////////////////////////////////////////////////
877 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
878 const SMDS_MeshNode * n2,
879 const SMDS_MeshNode * n3,
880 const SMDS_MeshNode * n4,
881 const SMDS_MeshNode * n5,
882 const SMDS_MeshNode * n6,
883 const SMDS_MeshNode * n7,
884 const SMDS_MeshNode * n8,
887 //MESSAGE("AddVolumeWithID " << ID);
888 SMDS_MeshVolume* volume = 0;
889 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
890 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
891 if(hasConstructionFaces()) {
892 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
893 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
894 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
895 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
896 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
897 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
898 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
899 adjustmyCellsCapacity(ID);
900 myCells[ID] = volume;
903 else if(hasConstructionEdges()) {
904 MESSAGE("Error : Not implemented");
908 // --- retrieve nodes ID
909 vector<vtkIdType> nodeIds;
911 nodeIds.push_back(n1->getId());
912 nodeIds.push_back(n4->getId());
913 nodeIds.push_back(n3->getId());
914 nodeIds.push_back(n2->getId());
915 nodeIds.push_back(n5->getId());
916 nodeIds.push_back(n8->getId());
917 nodeIds.push_back(n7->getId());
918 nodeIds.push_back(n6->getId());
920 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
921 volvtk->init(nodeIds, this);
923 adjustmyCellsCapacity(ID);
924 myCells[ID] = volume;
928 if (!registerElement(ID, volume)) {
929 RemoveElement(volume, false);
935 ///////////////////////////////////////////////////////////////////////////////
936 ///Create a new tetrahedron defined by its faces and add it to the mesh.
937 ///@return The created tetrahedron
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)
945 //MESSAGE("AddVolumeWithID");
946 if (!hasConstructionFaces())
948 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
951 ///////////////////////////////////////////////////////////////////////////////
952 ///Create a new tetrahedron defined by its faces and add it to the mesh.
953 ///@param ID The ID of the new volume
954 ///@return The created tetrahedron
955 ///////////////////////////////////////////////////////////////////////////////
957 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
958 const SMDS_MeshFace * f2,
959 const SMDS_MeshFace * f3,
960 const SMDS_MeshFace * f4,
963 //MESSAGE("AddVolumeWithID" << ID);
964 if (!hasConstructionFaces())
966 if ( !f1 || !f2 || !f3 || !f4) return 0;
967 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
968 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
969 adjustmyCellsCapacity(ID);
970 myCells[ID] = volume;
973 if (!registerElement(ID, volume)) {
974 RemoveElement(volume, false);
980 ///////////////////////////////////////////////////////////////////////////////
981 ///Create a new pyramid defined by its faces and add it to the mesh.
982 ///@return The created pyramid
983 ///////////////////////////////////////////////////////////////////////////////
985 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
986 const SMDS_MeshFace * f2,
987 const SMDS_MeshFace * f3,
988 const SMDS_MeshFace * f4,
989 const SMDS_MeshFace * f5)
991 //MESSAGE("AddVolumeWithID");
992 if (!hasConstructionFaces())
994 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
997 ///////////////////////////////////////////////////////////////////////////////
998 ///Create a new pyramid defined by its faces and add it to the mesh.
999 ///@param ID The ID of the new volume
1000 ///@return The created pyramid
1001 ///////////////////////////////////////////////////////////////////////////////
1003 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1004 const SMDS_MeshFace * f2,
1005 const SMDS_MeshFace * f3,
1006 const SMDS_MeshFace * f4,
1007 const SMDS_MeshFace * f5,
1010 //MESSAGE("AddVolumeWithID" << ID);
1011 if (!hasConstructionFaces())
1013 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1014 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1015 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1016 adjustmyCellsCapacity(ID);
1017 myCells[ID] = volume;
1018 myInfo.myNbPyramids++;
1020 if (!registerElement(ID, volume)) {
1021 RemoveElement(volume, false);
1027 ///////////////////////////////////////////////////////////////////////////////
1028 ///Create a new prism defined by its faces and add it to the mesh.
1029 ///@return The created prism
1030 ///////////////////////////////////////////////////////////////////////////////
1032 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1033 const SMDS_MeshFace * f2,
1034 const SMDS_MeshFace * f3,
1035 const SMDS_MeshFace * f4,
1036 const SMDS_MeshFace * f5,
1037 const SMDS_MeshFace * f6)
1039 //MESSAGE("AddVolumeWithID" );
1040 if (!hasConstructionFaces())
1042 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1045 ///////////////////////////////////////////////////////////////////////////////
1046 ///Create a new prism defined by its faces and add it to the mesh.
1047 ///@param ID The ID of the new volume
1048 ///@return The created prism
1049 ///////////////////////////////////////////////////////////////////////////////
1051 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1052 const SMDS_MeshFace * f2,
1053 const SMDS_MeshFace * f3,
1054 const SMDS_MeshFace * f4,
1055 const SMDS_MeshFace * f5,
1056 const SMDS_MeshFace * f6,
1059 //MESSAGE("AddVolumeWithID" << ID);
1060 if (!hasConstructionFaces())
1062 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1063 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1064 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1065 adjustmyCellsCapacity(ID);
1066 myCells[ID] = volume;
1067 myInfo.myNbPrisms++;
1069 if (!registerElement(ID, volume)) {
1070 RemoveElement(volume, false);
1076 ///////////////////////////////////////////////////////////////////////////////
1077 /// Add a polygon defined by its nodes IDs
1078 ///////////////////////////////////////////////////////////////////////////////
1080 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1083 int nbNodes = nodes_ids.size();
1084 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1085 for (int i = 0; i < nbNodes; i++) {
1086 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1087 if (!nodes[i]) return NULL;
1089 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1092 ///////////////////////////////////////////////////////////////////////////////
1093 /// Add a polygon defined by its nodes
1094 ///////////////////////////////////////////////////////////////////////////////
1096 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1097 (std::vector<const SMDS_MeshNode*> nodes,
1100 SMDS_MeshFace * face;
1102 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1103 if (hasConstructionEdges())
1105 MESSAGE("Error : Not implemented");
1110 for ( int i = 0; i < nodes.size(); ++i )
1111 if ( !nodes[ i ] ) return 0;
1112 face = new SMDS_PolygonalFaceOfNodes(nodes);
1113 adjustmyCellsCapacity(ID);
1115 myInfo.myNbPolygons++;
1118 if (!registerElement(ID, face)) {
1119 RemoveElement(face, false);
1125 ///////////////////////////////////////////////////////////////////////////////
1126 /// Add a polygon defined by its nodes.
1127 /// An ID is automatically affected to the created face.
1128 ///////////////////////////////////////////////////////////////////////////////
1130 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1132 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1135 ///////////////////////////////////////////////////////////////////////////////
1136 /// Create a new polyhedral volume and add it to the mesh.
1137 /// @param ID The ID of the new volume
1138 /// @return The created volume or NULL if an element with this ID already exists
1139 /// or if input nodes are not found.
1140 ///////////////////////////////////////////////////////////////////////////////
1142 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1143 (std::vector<int> nodes_ids,
1144 std::vector<int> quantities,
1147 int nbNodes = nodes_ids.size();
1148 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1149 for (int i = 0; i < nbNodes; i++) {
1150 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1151 if (!nodes[i]) return NULL;
1153 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1156 ///////////////////////////////////////////////////////////////////////////////
1157 /// Create a new polyhedral volume and add it to the mesh.
1158 /// @param ID The ID of the new volume
1159 /// @return The created volume
1160 ///////////////////////////////////////////////////////////////////////////////
1162 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1163 (std::vector<const SMDS_MeshNode*> nodes,
1164 std::vector<int> quantities,
1167 SMDS_MeshVolume* volume;
1168 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1169 if (hasConstructionFaces()) {
1170 MESSAGE("Error : Not implemented");
1172 } else if (hasConstructionEdges()) {
1173 MESSAGE("Error : Not implemented");
1176 for ( int i = 0; i < nodes.size(); ++i )
1177 if ( !nodes[ i ] ) return 0;
1178 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1179 adjustmyCellsCapacity(ID);
1180 myCells[ID] = volume;
1181 myInfo.myNbPolyhedrons++;
1184 if (!registerElement(ID, volume)) {
1185 RemoveElement(volume, false);
1191 ///////////////////////////////////////////////////////////////////////////////
1192 /// Create a new polyhedral volume and add it to the mesh.
1193 /// @return The created volume
1194 ///////////////////////////////////////////////////////////////////////////////
1196 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1197 (std::vector<const SMDS_MeshNode*> nodes,
1198 std::vector<int> quantities)
1200 int ID = myElementIDFactory->GetFreeID();
1201 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1202 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1206 ///////////////////////////////////////////////////////////////////////////////
1207 /// Registers element with the given ID, maintains inverse connections
1208 ///////////////////////////////////////////////////////////////////////////////
1209 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1211 //MESSAGE("registerElement " << ID)
1212 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1214 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1219 element->myMeshId = myMeshId;
1221 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1223 int vtkId = cell->getVtkId();
1225 vtkId = myElementIDFactory->SetInVtkGrid(element);
1227 if (ID >= myIDElements.size()) // --- resize local vector
1229 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1230 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1233 myIDElements[ID] = vtkId;
1234 //MESSAGE("smds:" << ID << " vtk:" << cellId );
1236 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1238 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1239 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1241 myVtkIndex[vtkId] = ID;
1243 myElementIDFactory->updateMinMax(ID);
1247 ///////////////////////////////////////////////////////////////////////////////
1248 /// Return the node whose ID is 'ID'.
1249 ///////////////////////////////////////////////////////////////////////////////
1250 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1252 if (ID < 0 || ID >= myNodes.size())
1254 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1257 return (const SMDS_MeshNode *)myNodes[ID];
1260 ///////////////////////////////////////////////////////////////////////////////
1261 ///Create a triangle and add it to the current mesh. This method do not bind an
1262 ///ID to the create triangle.
1263 ///////////////////////////////////////////////////////////////////////////////
1264 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1265 const SMDS_MeshNode * node2,
1266 const SMDS_MeshNode * node3,
1269 if ( !node1 || !node2 || !node3) return 0;
1270 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1271 if(hasConstructionEdges())
1273 SMDS_MeshEdge *edge1, *edge2, *edge3;
1274 edge1=FindEdgeOrCreate(node1,node2);
1275 edge2=FindEdgeOrCreate(node2,node3);
1276 edge3=FindEdgeOrCreate(node3,node1);
1278 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1279 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1280 adjustmyCellsCapacity(ID);
1282 myInfo.myNbTriangles++;
1287 // --- retrieve nodes ID
1288 vector<vtkIdType> nodeIds;
1290 nodeIds.push_back(node1->getId());
1291 nodeIds.push_back(node2->getId());
1292 nodeIds.push_back(node3->getId());
1294 SMDS_MeshFace * face = 0;
1295 SMDS_VtkFace *facevtk = myFacePool->getNew();
1296 facevtk->init(nodeIds, this);
1298 adjustmyCellsCapacity(ID);
1300 myInfo.myNbTriangles++;
1305 ///////////////////////////////////////////////////////////////////////////////
1306 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1307 ///a ID to the create triangle.
1308 ///////////////////////////////////////////////////////////////////////////////
1309 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1310 const SMDS_MeshNode * node2,
1311 const SMDS_MeshNode * node3,
1312 const SMDS_MeshNode * node4,
1315 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1316 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1317 if(hasConstructionEdges())
1319 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1320 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1321 edge1=FindEdgeOrCreate(node1,node2);
1322 edge2=FindEdgeOrCreate(node2,node3);
1323 edge3=FindEdgeOrCreate(node3,node4);
1324 edge4=FindEdgeOrCreate(node4,node1);
1326 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1327 adjustmyCellsCapacity(ID);
1329 myInfo.myNbQuadrangles++;
1334 // --- retrieve nodes ID
1335 vector<vtkIdType> nodeIds;
1337 nodeIds.push_back(node1->getId());
1338 nodeIds.push_back(node2->getId());
1339 nodeIds.push_back(node3->getId());
1340 nodeIds.push_back(node4->getId());
1342 SMDS_MeshFace * face = 0;
1343 SMDS_VtkFace *facevtk = myFacePool->getNew();
1344 facevtk->init(nodeIds, this);
1346 adjustmyCellsCapacity(ID);
1348 myInfo.myNbQuadrangles++;
1353 ///////////////////////////////////////////////////////////////////////////////
1354 /// Remove a node and all the elements which own this node
1355 ///////////////////////////////////////////////////////////////////////////////
1357 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1359 MESSAGE("RemoveNode");
1360 RemoveElement(node, true);
1363 ///////////////////////////////////////////////////////////////////////////////
1364 /// Remove an edge and all the elements which own this edge
1365 ///////////////////////////////////////////////////////////////////////////////
1367 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1369 MESSAGE("Remove0DElement");
1370 RemoveElement(elem0d,true);
1373 ///////////////////////////////////////////////////////////////////////////////
1374 /// Remove an edge and all the elements which own this edge
1375 ///////////////////////////////////////////////////////////////////////////////
1377 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1379 MESSAGE("RemoveEdge");
1380 RemoveElement(edge,true);
1383 ///////////////////////////////////////////////////////////////////////////////
1384 /// Remove an face and all the elements which own this face
1385 ///////////////////////////////////////////////////////////////////////////////
1387 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1389 MESSAGE("RemoveFace");
1390 RemoveElement(face, true);
1393 ///////////////////////////////////////////////////////////////////////////////
1395 ///////////////////////////////////////////////////////////////////////////////
1397 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1399 MESSAGE("RemoveVolume");
1400 RemoveElement(volume, true);
1403 //=======================================================================
1404 //function : RemoveFromParent
1406 //=======================================================================
1408 bool SMDS_Mesh::RemoveFromParent()
1410 if (myParent==NULL) return false;
1411 else return (myParent->RemoveSubMesh(this));
1414 //=======================================================================
1415 //function : RemoveSubMesh
1417 //=======================================================================
1419 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1423 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1424 for (; itmsh!=myChildren.end() && !found; itmsh++)
1426 SMDS_Mesh * submesh = *itmsh;
1427 if (submesh == aMesh)
1430 myChildren.erase(itmsh);
1437 //=======================================================================
1438 //function : ChangeElementNodes
1440 //=======================================================================
1442 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1443 const SMDS_MeshNode * nodes[],
1446 MYASSERT(0); // REVOIR LES TYPES
1447 // keep current nodes of elem
1448 set<const SMDS_MeshElement*> oldNodes;
1449 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1451 oldNodes.insert( itn->next() );
1453 if ( !element->IsPoly() )
1454 myInfo.remove( element ); // element may change type
1458 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1459 switch ( elem->GetType() )
1461 case SMDSAbs_0DElement: {
1462 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1463 Ok = elem0d->ChangeNode( nodes[0] );
1466 case SMDSAbs_Edge: {
1467 if ( nbnodes == 2 ) {
1468 if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
1469 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1471 else if ( nbnodes == 3 ) {
1472 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1473 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1477 case SMDSAbs_Face: {
1478 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1479 Ok = face->ChangeNodes( nodes, nbnodes );
1481 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1482 Ok = QF->ChangeNodes( nodes, nbnodes );
1484 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1485 Ok = face->ChangeNodes(nodes, nbnodes);
1488 case SMDSAbs_Volume: {
1489 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1490 Ok = vol->ChangeNodes( nodes, nbnodes );
1492 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1493 Ok = QV->ChangeNodes( nodes, nbnodes );
1497 MESSAGE ( "WRONG ELEM TYPE");
1500 if ( Ok ) { // update InverseElements
1502 set<const SMDS_MeshElement*>::iterator it;
1504 // AddInverseElement to new nodes
1505 for ( int i = 0; i < nbnodes; i++ ) {
1506 it = oldNodes.find( nodes[i] );
1507 if ( it == oldNodes.end() )
1509 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1511 // remove from oldNodes a node that remains in elem
1512 oldNodes.erase( it );
1514 // RemoveInverseElement from the nodes removed from elem
1515 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1517 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1518 (const_cast<SMDS_MeshElement *>( *it ));
1519 n->RemoveInverseElement( elem );
1523 if ( !element->IsPoly() )
1524 myInfo.add( element ); // element may change type
1529 //=======================================================================
1530 //function : ChangePolyhedronNodes
1531 //purpose : to change nodes of polyhedral volume
1532 //=======================================================================
1533 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1534 const vector<const SMDS_MeshNode*>& nodes,
1535 const vector<int> & quantities)
1537 if (elem->GetType() != SMDSAbs_Volume) {
1538 MESSAGE("WRONG ELEM TYPE");
1542 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1547 // keep current nodes of elem
1548 set<const SMDS_MeshElement*> oldNodes;
1549 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1550 while (itn->more()) {
1551 oldNodes.insert(itn->next());
1555 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1560 // update InverseElements
1562 // AddInverseElement to new nodes
1563 int nbnodes = nodes.size();
1564 set<const SMDS_MeshElement*>::iterator it;
1565 for (int i = 0; i < nbnodes; i++) {
1566 it = oldNodes.find(nodes[i]);
1567 if (it == oldNodes.end()) {
1569 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1571 // remove from oldNodes a node that remains in elem
1576 // RemoveInverseElement from the nodes removed from elem
1577 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1578 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1579 (const_cast<SMDS_MeshElement *>( *it ));
1580 n->RemoveInverseElement(elem);
1587 //=======================================================================
1588 //function : Find0DElement
1590 //=======================================================================
1591 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1593 const SMDS_MeshNode * node = FindNode(idnode);
1594 if(node == NULL) return NULL;
1595 return Find0DElement(node);
1598 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1600 if (!node) return 0;
1601 const SMDS_Mesh0DElement* toReturn = NULL;
1602 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1603 while (it1->more() && (toReturn == NULL)) {
1604 const SMDS_MeshElement* e = it1->next();
1605 if (e->NbNodes() == 1) {
1606 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1612 //=======================================================================
1613 //function : Find0DElementOrCreate
1615 //=======================================================================
1616 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1618 // if (!node) return 0;
1619 // SMDS_Mesh0DElement * toReturn = NULL;
1620 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1621 // if (toReturn == NULL) {
1622 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1623 // toReturn = new SMDS_Mesh0DElement(node);
1624 // my0DElements.Add(toReturn);
1625 // myInfo.myNb0DElements++;
1631 //=======================================================================
1632 //function : FindEdge
1634 //=======================================================================
1636 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1638 const SMDS_MeshNode * node1=FindNode(idnode1);
1639 const SMDS_MeshNode * node2=FindNode(idnode2);
1640 if((node1==NULL)||(node2==NULL)) return NULL;
1641 return FindEdge(node1,node2);
1644 //#include "Profiler.h"
1645 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1646 const SMDS_MeshNode * node2)
1648 if ( !node1 ) return 0;
1649 const SMDS_MeshEdge * toReturn=NULL;
1652 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1655 while(it1->more()) {
1656 const SMDS_MeshElement * e = it1->next();
1657 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1658 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1667 //=======================================================================
1668 //function : FindEdgeOrCreate
1670 //=======================================================================
1672 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1673 const SMDS_MeshNode * node2)
1675 if ( !node1 || !node2) return 0;
1676 SMDS_MeshEdge * toReturn=NULL;
1677 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1678 if(toReturn==NULL) {
1679 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1680 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1681 adjustmyCellsCapacity(ID);
1682 vector<vtkIdType> nodeIds;
1684 nodeIds.push_back(node1->getId());
1685 nodeIds.push_back(node2->getId());
1687 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1688 edgevtk->init(nodeIds, this);
1690 myCells[ID] = toReturn;
1697 //=======================================================================
1698 //function : FindEdge
1700 //=======================================================================
1702 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1705 const SMDS_MeshNode * node1=FindNode(idnode1);
1706 const SMDS_MeshNode * node2=FindNode(idnode2);
1707 const SMDS_MeshNode * node3=FindNode(idnode3);
1708 return FindEdge(node1,node2,node3);
1711 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1712 const SMDS_MeshNode * node2,
1713 const SMDS_MeshNode * node3)
1715 if ( !node1 ) return 0;
1716 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1717 while(it1->more()) {
1718 const SMDS_MeshElement * e = it1->next();
1719 if ( e->NbNodes() == 3 ) {
1720 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1721 while(it2->more()) {
1722 const SMDS_MeshElement* n = it2->next();
1732 return static_cast<const SMDS_MeshEdge *> (e);
1739 //=======================================================================
1740 //function : FindFace
1742 //=======================================================================
1744 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1747 const SMDS_MeshNode * node1=FindNode(idnode1);
1748 const SMDS_MeshNode * node2=FindNode(idnode2);
1749 const SMDS_MeshNode * node3=FindNode(idnode3);
1750 return FindFace(node1, node2, node3);
1753 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1754 const SMDS_MeshNode *node2,
1755 const SMDS_MeshNode *node3)
1757 if ( !node1 ) return 0;
1758 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1759 while(it1->more()) {
1760 const SMDS_MeshElement * e = it1->next();
1761 if ( e->NbNodes() == 3 ) {
1762 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1763 while(it2->more()) {
1764 const SMDS_MeshElement* n = it2->next();
1774 return static_cast<const SMDS_MeshFace *> (e);
1780 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1781 const SMDS_MeshNode *node2,
1782 const SMDS_MeshNode *node3)
1784 SMDS_MeshFace * toReturn=NULL;
1785 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1786 if(toReturn==NULL) {
1787 int ID = myElementIDFactory->GetFreeID();
1788 toReturn = createTriangle(node1,node2,node3, ID);
1794 //=======================================================================
1795 //function : FindFace
1797 //=======================================================================
1799 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1800 int idnode3, int idnode4) const
1802 const SMDS_MeshNode * node1=FindNode(idnode1);
1803 const SMDS_MeshNode * node2=FindNode(idnode2);
1804 const SMDS_MeshNode * node3=FindNode(idnode3);
1805 const SMDS_MeshNode * node4=FindNode(idnode4);
1806 return FindFace(node1, node2, node3, node4);
1809 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1810 const SMDS_MeshNode *node2,
1811 const SMDS_MeshNode *node3,
1812 const SMDS_MeshNode *node4)
1814 if ( !node1 ) return 0;
1815 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1816 while(it1->more()) {
1817 const SMDS_MeshElement * e = it1->next();
1818 if ( e->NbNodes() == 4 ) {
1819 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1820 while(it2->more()) {
1821 const SMDS_MeshElement* n = it2->next();
1832 return static_cast<const SMDS_MeshFace *> (e);
1838 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1839 const SMDS_MeshNode *node2,
1840 const SMDS_MeshNode *node3,
1841 const SMDS_MeshNode *node4)
1843 SMDS_MeshFace * toReturn=NULL;
1844 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1845 if(toReturn==NULL) {
1846 int ID = myElementIDFactory->GetFreeID();
1847 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1853 //=======================================================================
1854 //function : FindFace
1855 //purpose :quadratic triangle
1856 //=======================================================================
1858 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1859 int idnode3, int idnode4,
1860 int idnode5, int idnode6) const
1862 const SMDS_MeshNode * node1 = FindNode(idnode1);
1863 const SMDS_MeshNode * node2 = FindNode(idnode2);
1864 const SMDS_MeshNode * node3 = FindNode(idnode3);
1865 const SMDS_MeshNode * node4 = FindNode(idnode4);
1866 const SMDS_MeshNode * node5 = FindNode(idnode5);
1867 const SMDS_MeshNode * node6 = FindNode(idnode6);
1868 return FindFace(node1, node2, node3, node4, node5, node6);
1871 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1872 const SMDS_MeshNode *node2,
1873 const SMDS_MeshNode *node3,
1874 const SMDS_MeshNode *node4,
1875 const SMDS_MeshNode *node5,
1876 const SMDS_MeshNode *node6)
1878 if ( !node1 ) return 0;
1879 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1880 while(it1->more()) {
1881 const SMDS_MeshElement * e = it1->next();
1882 if ( e->NbNodes() == 6 ) {
1883 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1884 while(it2->more()) {
1885 const SMDS_MeshElement* n = it2->next();
1898 return static_cast<const SMDS_MeshFace *> (e);
1905 //=======================================================================
1906 //function : FindFace
1907 //purpose : quadratic quadrangle
1908 //=======================================================================
1910 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1911 int idnode3, int idnode4,
1912 int idnode5, int idnode6,
1913 int idnode7, int idnode8) const
1915 const SMDS_MeshNode * node1 = FindNode(idnode1);
1916 const SMDS_MeshNode * node2 = FindNode(idnode2);
1917 const SMDS_MeshNode * node3 = FindNode(idnode3);
1918 const SMDS_MeshNode * node4 = FindNode(idnode4);
1919 const SMDS_MeshNode * node5 = FindNode(idnode5);
1920 const SMDS_MeshNode * node6 = FindNode(idnode6);
1921 const SMDS_MeshNode * node7 = FindNode(idnode7);
1922 const SMDS_MeshNode * node8 = FindNode(idnode8);
1923 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1926 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1927 const SMDS_MeshNode *node2,
1928 const SMDS_MeshNode *node3,
1929 const SMDS_MeshNode *node4,
1930 const SMDS_MeshNode *node5,
1931 const SMDS_MeshNode *node6,
1932 const SMDS_MeshNode *node7,
1933 const SMDS_MeshNode *node8)
1935 if ( !node1 ) return 0;
1936 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1937 while(it1->more()) {
1938 const SMDS_MeshElement * e = it1->next();
1939 if ( e->NbNodes() == 8 ) {
1940 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1941 while(it2->more()) {
1942 const SMDS_MeshElement* n = it2->next();
1957 return static_cast<const SMDS_MeshFace *> (e);
1964 //=======================================================================
1965 //function : FindElement
1967 //=======================================================================
1969 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1971 if ((IDelem < 0) || IDelem >= myCells.size())
1973 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
1976 return myCells[IDelem];
1979 //=======================================================================
1980 //function : FindFace
1981 //purpose : find polygon
1982 //=======================================================================
1984 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1986 int nbnodes = nodes_ids.size();
1987 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1988 for (int inode = 0; inode < nbnodes; inode++) {
1989 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1990 if (node == NULL) return NULL;
1991 poly_nodes[inode] = node;
1993 return FindFace(poly_nodes);
1996 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1998 if ( nodes.size() > 2 && nodes[0] ) {
1999 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
2000 while (itF->more()) {
2001 const SMDS_MeshElement* f = itF->next();
2002 if ( f->NbNodes() == nodes.size() ) {
2003 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
2004 while(it2->more()) {
2005 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
2011 return static_cast<const SMDS_MeshFace *> (f);
2018 //=======================================================================
2019 //function : DumpNodes
2021 //=======================================================================
2023 void SMDS_Mesh::DumpNodes() const
2025 MESSAGE("dump nodes of mesh : ");
2026 SMDS_NodeIteratorPtr itnode=nodesIterator();
2027 while(itnode->more()) ; //MESSAGE(itnode->next());
2030 //=======================================================================
2031 //function : Dump0DElements
2033 //=======================================================================
2034 void SMDS_Mesh::Dump0DElements() const
2036 MESSAGE("dump 0D elements of mesh : ");
2037 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2038 while(it0d->more()) ; //MESSAGE(it0d->next());
2041 //=======================================================================
2042 //function : DumpEdges
2044 //=======================================================================
2046 void SMDS_Mesh::DumpEdges() const
2048 MESSAGE("dump edges of mesh : ");
2049 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2050 while(itedge->more()) ; //MESSAGE(itedge->next());
2053 //=======================================================================
2054 //function : DumpFaces
2056 //=======================================================================
2058 void SMDS_Mesh::DumpFaces() const
2060 MESSAGE("dump faces of mesh : ");
2061 SMDS_FaceIteratorPtr itface=facesIterator();
2062 while(itface->more()) ; //MESSAGE(itface->next());
2065 //=======================================================================
2066 //function : DumpVolumes
2068 //=======================================================================
2070 void SMDS_Mesh::DumpVolumes() const
2072 MESSAGE("dump volumes of mesh : ");
2073 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2074 while(itvol->more()) ; //MESSAGE(itvol->next());
2077 //=======================================================================
2078 //function : DebugStats
2080 //=======================================================================
2082 void SMDS_Mesh::DebugStats() const
2084 MESSAGE("Debug stats of mesh : ");
2086 MESSAGE("===== NODES ====="<<NbNodes());
2087 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2088 MESSAGE("===== EDGES ====="<<NbEdges());
2089 MESSAGE("===== FACES ====="<<NbFaces());
2090 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2092 MESSAGE("End Debug stats of mesh ");
2096 SMDS_NodeIteratorPtr itnode=nodesIterator();
2097 int sizeofnodes = 0;
2098 int sizeoffaces = 0;
2100 while(itnode->more())
2102 const SMDS_MeshNode *node = itnode->next();
2104 sizeofnodes += sizeof(*node);
2106 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2109 const SMDS_MeshElement *me = it->next();
2110 sizeofnodes += sizeof(me);
2114 SMDS_FaceIteratorPtr itface=facesIterator();
2115 while(itface->more())
2117 const SMDS_MeshElement *face = itface->next();
2118 sizeoffaces += sizeof(*face);
2121 MESSAGE("total size of node elements = " << sizeofnodes);;
2122 MESSAGE("total size of face elements = " << sizeoffaces);;
2127 ///////////////////////////////////////////////////////////////////////////////
2128 /// Return the number of nodes
2129 ///////////////////////////////////////////////////////////////////////////////
2130 int SMDS_Mesh::NbNodes() const
2132 return myNodes.size();
2135 ///////////////////////////////////////////////////////////////////////////////
2136 /// Return the number of 0D elements
2137 ///////////////////////////////////////////////////////////////////////////////
2138 int SMDS_Mesh::Nb0DElements() const
2140 return myInfo.Nb0DElements(); // -PR- a verfier
2143 ///////////////////////////////////////////////////////////////////////////////
2144 /// Return the number of edges (including construction edges)
2145 ///////////////////////////////////////////////////////////////////////////////
2146 int SMDS_Mesh::NbEdges() const
2148 return myInfo.NbEdges(); // -PR- a verfier
2151 ///////////////////////////////////////////////////////////////////////////////
2152 /// Return the number of faces (including construction faces)
2153 ///////////////////////////////////////////////////////////////////////////////
2154 int SMDS_Mesh::NbFaces() const
2156 return myInfo.NbFaces(); // -PR- a verfier
2159 ///////////////////////////////////////////////////////////////////////////////
2160 /// Return the number of volumes
2161 ///////////////////////////////////////////////////////////////////////////////
2162 int SMDS_Mesh::NbVolumes() const
2164 return myInfo.NbVolumes(); // -PR- a verfier
2167 ///////////////////////////////////////////////////////////////////////////////
2168 /// Return the number of child mesh of this mesh.
2169 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2170 /// (2003-09-08) of SMESH
2171 ///////////////////////////////////////////////////////////////////////////////
2172 int SMDS_Mesh::NbSubMesh() const
2174 return myChildren.size();
2177 ///////////////////////////////////////////////////////////////////////////////
2178 /// Destroy the mesh and all its elements
2179 /// All pointer on elements owned by this mesh become illegals.
2180 ///////////////////////////////////////////////////////////////////////////////
2181 SMDS_Mesh::~SMDS_Mesh()
2183 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2184 while(itc!=myChildren.end())
2192 delete myNodeIDFactory;
2193 delete myElementIDFactory;
2197 SMDS_ElemIteratorPtr eIt = elementsIterator();
2198 while ( eIt->more() )
2199 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2200 SMDS_NodeIteratorPtr itn = nodesIterator();
2202 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2205 // SetOfNodes::Iterator itn(myNodes);
2206 // for (; itn.More(); itn.Next())
2207 // delete itn.Value();
2209 // SetOf0DElements::Iterator it0d (my0DElements);
2210 // for (; it0d.More(); it0d.Next())
2212 // SMDS_MeshElement* elem = it0d.Value();
2216 // SetOfEdges::Iterator ite(myEdges);
2217 // for (; ite.More(); ite.Next())
2219 // SMDS_MeshElement* elem = ite.Value();
2223 // SetOfFaces::Iterator itf(myFaces);
2224 // for (; itf.More(); itf.Next())
2226 // SMDS_MeshElement* elem = itf.Value();
2230 // SetOfVolumes::Iterator itv(myVolumes);
2231 // for (; itv.More(); itv.Next())
2233 // SMDS_MeshElement* elem = itv.Value();
2238 //================================================================================
2240 * \brief Clear all data
2242 //================================================================================
2244 void SMDS_Mesh::Clear()
2246 if (myParent!=NULL) {
2247 SMDS_ElemIteratorPtr eIt = elementsIterator();
2248 while ( eIt->more() )
2249 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2250 SMDS_NodeIteratorPtr itn = nodesIterator();
2252 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2255 myNodeIDFactory->Clear();
2256 myElementIDFactory->Clear();
2259 SMDS_ElemIteratorPtr itv = elementsIterator();
2264 // SMDS_VolumeIteratorPtr itv = volumesIterator();
2265 // while (itv->more())
2266 // delete itv->next();
2267 // myVolumes.Clear();
2269 // SMDS_FaceIteratorPtr itf = facesIterator();
2270 // while (itf->more())
2271 // delete itf->next();
2274 // SMDS_EdgeIteratorPtr ite = edgesIterator();
2275 // while (ite->more())
2276 // delete ite->next();
2279 // SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2280 // while (it0d->more())
2281 // delete it0d->next();
2282 // my0DElements.Clear();
2284 SMDS_NodeIteratorPtr itn = nodesIterator();
2289 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2290 while(itc!=myChildren.end())
2296 ///////////////////////////////////////////////////////////////////////////////
2297 /// Return true if this mesh create faces with edges.
2298 /// A false returned value mean that faces are created with nodes. A concequence
2299 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2300 ///////////////////////////////////////////////////////////////////////////////
2301 bool SMDS_Mesh::hasConstructionEdges()
2303 return myHasConstructionEdges;
2306 ///////////////////////////////////////////////////////////////////////////////
2307 /// Return true if this mesh create volumes with faces
2308 /// A false returned value mean that volumes are created with nodes or edges.
2309 /// (see hasConstructionEdges)
2310 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2312 ///////////////////////////////////////////////////////////////////////////////
2313 bool SMDS_Mesh::hasConstructionFaces()
2315 return myHasConstructionFaces;
2318 ///////////////////////////////////////////////////////////////////////////////
2319 /// Return true if nodes are linked to the finit elements, they are belonging to.
2320 /// Currently, It always return true.
2321 ///////////////////////////////////////////////////////////////////////////////
2322 bool SMDS_Mesh::hasInverseElements()
2324 return myHasInverseElements;
2327 ///////////////////////////////////////////////////////////////////////////////
2328 /// Make this mesh creating construction edges (see hasConstructionEdges)
2329 /// @param b true to have construction edges, else false.
2330 ///////////////////////////////////////////////////////////////////////////////
2331 void SMDS_Mesh::setConstructionEdges(bool b)
2333 myHasConstructionEdges=b;
2336 ///////////////////////////////////////////////////////////////////////////////
2337 /// Make this mesh creating construction faces (see hasConstructionFaces)
2338 /// @param b true to have construction faces, else false.
2339 ///////////////////////////////////////////////////////////////////////////////
2340 void SMDS_Mesh::setConstructionFaces(bool b)
2342 myHasConstructionFaces=b;
2345 ///////////////////////////////////////////////////////////////////////////////
2346 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2347 /// @param b true to link nodes to elements, else false.
2348 ///////////////////////////////////////////////////////////////////////////////
2349 void SMDS_Mesh::setInverseElements(bool b)
2351 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2352 myHasInverseElements=b;
2355 ///////////////////////////////////////////////////////////////////////////////
2356 ///Iterator on NCollection_Map
2357 ///////////////////////////////////////////////////////////////////////////////
2358 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2359 struct MYNode_Map_Iterator: public FATHER
2363 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2370 while (_ctr < _map.size())
2381 ELEM current = _map[_ctr];
2387 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2388 struct MYElem_Map_Iterator: public FATHER
2393 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2401 while (_ctr < _map.size())
2404 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2413 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2419 ///////////////////////////////////////////////////////////////////////////////
2420 /// Return an iterator on nodes of the current mesh factory
2421 ///////////////////////////////////////////////////////////////////////////////
2423 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2425 //return SMDS_NodeIteratorPtr
2426 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2427 typedef MYNode_Map_Iterator
2428 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2429 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2432 ///////////////////////////////////////////////////////////////////////////////
2433 ///Return an iterator on 0D elements of the current mesh.
2434 ///////////////////////////////////////////////////////////////////////////////
2436 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2438 typedef MYElem_Map_Iterator
2439 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2440 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2443 ///////////////////////////////////////////////////////////////////////////////
2444 ///Return an iterator on edges of the current mesh.
2445 ///////////////////////////////////////////////////////////////////////////////
2447 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2449 typedef MYElem_Map_Iterator
2450 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2451 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2454 ///////////////////////////////////////////////////////////////////////////////
2455 ///Return an iterator on faces of the current mesh.
2456 ///////////////////////////////////////////////////////////////////////////////
2458 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2460 typedef MYElem_Map_Iterator
2461 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2462 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2465 ///////////////////////////////////////////////////////////////////////////////
2466 ///Return an iterator on volumes of the current mesh.
2467 ///////////////////////////////////////////////////////////////////////////////
2469 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2471 typedef MYElem_Map_Iterator
2472 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2473 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2476 ///////////////////////////////////////////////////////////////////////////////
2477 /// Return an iterator on elements of the current mesh factory
2478 ///////////////////////////////////////////////////////////////////////////////
2479 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2483 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2485 case SMDSAbs_Volume:
2486 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2488 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2490 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2491 case SMDSAbs_0DElement:
2492 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2494 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2495 //return myNodeIDFactory->elementsIterator();
2498 return myElementIDFactory->elementsIterator();
2501 ///////////////////////////////////////////////////////////////////////////////
2502 /// Do intersection of sets (more than 2)
2503 ///////////////////////////////////////////////////////////////////////////////
2504 static set<const SMDS_MeshElement*> * intersectionOfSets(
2505 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2507 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2508 set<const SMDS_MeshElement*>* rsetB;
2510 for(int i=0; i<numberOfSets-1; i++)
2512 rsetB=new set<const SMDS_MeshElement*>();
2514 rsetA->begin(), rsetA->end(),
2515 vs[i+1].begin(), vs[i+1].end(),
2516 inserter(*rsetB, rsetB->begin()));
2523 ///////////////////////////////////////////////////////////////////////////////
2524 /// Return the list of finite elements owning the given element: elements
2525 /// containing all the nodes of the given element, for instance faces and
2526 /// volumes containing a given edge.
2527 ///////////////////////////////////////////////////////////////////////////////
2528 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2530 int numberOfSets=element->NbNodes();
2531 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2533 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2536 while(itNodes->more())
2538 const SMDS_MeshElement* node = itNodes->next();
2540 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2541 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2543 //initSet[i]=set<const SMDS_MeshElement*>();
2546 const SMDS_MeshElement* elem = itFe->next();
2548 initSet[i].insert(elem);
2554 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2555 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2560 ///////////////////////////////////////////////////////////////////////////////
2561 /// Return the list of nodes used only by the given elements
2562 ///////////////////////////////////////////////////////////////////////////////
2563 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2564 set<const SMDS_MeshElement*>& elements)
2566 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2567 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2569 while(itElements!=elements.end())
2571 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2574 while(itNodes->more())
2576 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2577 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2578 set<const SMDS_MeshElement*> s;
2580 s.insert(itFe->next());
2581 if(s==elements) toReturn->insert(n);
2587 ///////////////////////////////////////////////////////////////////////////////
2588 ///Find the children of an element that are made of given nodes
2589 ///@param setOfChildren The set in which matching children will be inserted
2590 ///@param element The element were to search matching children
2591 ///@param nodes The nodes that the children must have to be selected
2592 ///////////////////////////////////////////////////////////////////////////////
2593 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2594 const SMDS_MeshElement * element,
2595 set<const SMDS_MeshElement*>& nodes)
2597 switch(element->GetType())
2600 MESSAGE("Internal Error: This should not happend");
2602 case SMDSAbs_0DElement:
2608 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2611 const SMDS_MeshElement * e=itn->next();
2612 if(nodes.find(e)!=nodes.end())
2614 setOfChildren.insert(element);
2621 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2624 const SMDS_MeshElement * e=itn->next();
2625 if(nodes.find(e)!=nodes.end())
2627 setOfChildren.insert(element);
2631 if(hasConstructionEdges())
2633 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2635 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2638 case SMDSAbs_Volume:
2640 if(hasConstructionFaces())
2642 SMDS_ElemIteratorPtr ite=element->facesIterator();
2644 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2646 else if(hasConstructionEdges())
2648 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2650 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2656 ///////////////////////////////////////////////////////////////////////////////
2657 ///@param elem The element to delete
2658 ///@param removenodes if true remaining nodes will be removed
2659 ///////////////////////////////////////////////////////////////////////////////
2660 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2661 const bool removenodes)
2663 list<const SMDS_MeshElement *> removedElems;
2664 list<const SMDS_MeshElement *> removedNodes;
2665 RemoveElement( elem, removedElems, removedNodes, removenodes );
2668 ///////////////////////////////////////////////////////////////////////////////
2669 ///@param elem The element to delete
2670 ///@param removedElems to be filled with all removed elements
2671 ///@param removedNodes to be filled with all removed nodes
2672 ///@param removenodes if true remaining nodes will be removed
2673 ///////////////////////////////////////////////////////////////////////////////
2674 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2675 list<const SMDS_MeshElement *>& removedElems,
2676 list<const SMDS_MeshElement *>& removedNodes,
2679 MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2680 // get finite elements built on elem
2681 set<const SMDS_MeshElement*> * s1;
2682 if (elem->GetType() == SMDSAbs_0DElement ||
2683 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2684 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2685 elem->GetType() == SMDSAbs_Volume)
2687 s1 = new set<const SMDS_MeshElement*>();
2691 s1 = getFinitElements(elem);
2693 // get exclusive nodes (which would become free afterwards)
2694 set<const SMDS_MeshElement*> * s2;
2695 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2697 // do not remove nodes except elem
2698 s2 = new set<const SMDS_MeshElement*>();
2703 s2 = getExclusiveNodes(*s1);
2705 // form the set of finite and construction elements to remove
2706 set<const SMDS_MeshElement*> s3;
2707 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2708 while(it!=s1->end())
2710 addChildrenWithNodes(s3, *it ,*s2);
2714 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2716 // remove finite and construction elements
2720 // Remove element from <InverseElements> of its nodes
2721 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2724 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2725 (const_cast<SMDS_MeshElement *>(itn->next()));
2726 n->RemoveInverseElement( (*it) );
2729 switch((*it)->GetType())
2732 MYASSERT("Internal Error: This should not happen");
2734 case SMDSAbs_0DElement:
2735 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2739 myCells[(*it)->GetID()] = 0;
2740 myInfo.RemoveEdge(*it);
2743 myCells[(*it)->GetID()] = 0;
2744 myInfo.RemoveFace(*it);
2746 case SMDSAbs_Volume:
2747 myCells[(*it)->GetID()] = 0;
2748 myInfo.RemoveVolume(*it);
2751 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2752 removedElems.push_back( (*it) );
2753 myElementIDFactory->ReleaseID((*it)->GetID());
2754 MYASSERT("problem delete elem")
2759 // remove exclusive (free) nodes
2763 while(it!=s2->end())
2765 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2766 myNodes[(*it)->GetID()] = 0;
2768 myNodeIDFactory->ReleaseID((*it)->GetID());
2769 removedNodes.push_back( (*it) );
2770 MYASSERT("problem delete node")
2781 ///////////////////////////////////////////////////////////////////////////////
2782 ///@param elem The element to delete
2783 ///////////////////////////////////////////////////////////////////////////////
2784 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2786 int elemId = elem->GetID();
2787 MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2788 SMDSAbs_ElementType aType = elem->GetType();
2789 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2790 if (aType == SMDSAbs_Node) {
2791 // only free node can be removed by this method
2792 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2793 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2794 if (!itFe->more()) { // free node
2795 myNodes[elemId] = 0;
2797 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2798 myNodeIDFactory->ReleaseID(elemId);
2801 if (hasConstructionEdges() || hasConstructionFaces())
2802 // this methods is only for meshes without descendants
2805 int vtkid = this->fromSmdsToVtk(elemId);
2807 // Remove element from <InverseElements> of its nodes
2808 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2809 while (itn->more()) {
2810 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2811 (const_cast<SMDS_MeshElement *>(itn->next()));
2812 n->RemoveInverseElement(elem);
2815 // in meshes without descendants elements are always free
2817 case SMDSAbs_0DElement:
2818 myCells[elemId] = 0;
2819 myInfo.remove(elem);
2823 myCells[elemId] = 0;
2824 myInfo.RemoveEdge(elem);
2825 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2828 myCells[elemId] = 0;
2829 myInfo.RemoveFace(elem);
2830 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2832 case SMDSAbs_Volume:
2833 myCells[elemId] = 0;
2834 myInfo.RemoveVolume(elem);
2835 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2840 myElementIDFactory->ReleaseID(elemId);
2842 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2843 // --- to do: keep vtkid in a list of reusable cells
2848 * Checks if the element is present in mesh.
2849 * Useful to determine dead pointers.
2851 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2853 // we should not imply on validity of *elem, so iterate on containers
2854 // of all types in the hope of finding <elem> somewhere there
2855 SMDS_NodeIteratorPtr itn = nodesIterator();
2857 if (elem == itn->next())
2859 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2860 while (it0d->more())
2861 if (elem == it0d->next())
2863 SMDS_EdgeIteratorPtr ite = edgesIterator();
2865 if (elem == ite->next())
2867 SMDS_FaceIteratorPtr itf = facesIterator();
2869 if (elem == itf->next())
2871 SMDS_VolumeIteratorPtr itv = volumesIterator();
2873 if (elem == itv->next())
2878 //=======================================================================
2879 //function : MaxNodeID
2881 //=======================================================================
2883 int SMDS_Mesh::MaxNodeID() const
2888 //=======================================================================
2889 //function : MinNodeID
2891 //=======================================================================
2893 int SMDS_Mesh::MinNodeID() const
2898 //=======================================================================
2899 //function : MaxElementID
2901 //=======================================================================
2903 int SMDS_Mesh::MaxElementID() const
2905 return myElementIDFactory->GetMaxID();
2908 //=======================================================================
2909 //function : MinElementID
2911 //=======================================================================
2913 int SMDS_Mesh::MinElementID() const
2915 return myElementIDFactory->GetMinID();
2918 //=======================================================================
2919 //function : Renumber
2920 //purpose : Renumber all nodes or elements.
2921 //=======================================================================
2923 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2925 MESSAGE("Renumber");
2929 SMDS_MeshNodeIDFactory * idFactory =
2930 isNodes ? myNodeIDFactory : myElementIDFactory;
2932 // get existing elements in the order of ID increasing
2933 map<int,SMDS_MeshElement*> elemMap;
2934 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2935 while ( idElemIt->more() ) {
2936 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2937 int id = elem->GetID();
2938 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2940 // release their ids
2941 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2943 // for ( ; elemIt != elemMap.end(); elemIt++ )
2945 // int id = (*elemIt).first;
2946 // idFactory->ReleaseID( id );
2950 elemIt = elemMap.begin();
2951 for ( ; elemIt != elemMap.end(); elemIt++ )
2953 idFactory->BindID( ID, (*elemIt).second );
2958 //=======================================================================
2959 //function : GetElementType
2960 //purpose : Return type of element or node with id
2961 //=======================================================================
2963 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2965 SMDS_MeshElement* elem = 0;
2967 elem = myElementIDFactory->MeshElement( id );
2969 elem = myNodeIDFactory->MeshElement( id );
2973 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2977 return elem->GetType();
2982 //********************************************************************
2983 //********************************************************************
2984 //******** *********
2985 //***** Methods for addition of quadratic elements ******
2986 //******** *********
2987 //********************************************************************
2988 //********************************************************************
2990 //=======================================================================
2991 //function : AddEdgeWithID
2993 //=======================================================================
2994 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2996 return SMDS_Mesh::AddEdgeWithID
2997 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2999 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3003 //=======================================================================
3004 //function : AddEdge
3006 //=======================================================================
3007 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3008 const SMDS_MeshNode* n2,
3009 const SMDS_MeshNode* n12)
3011 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3014 //=======================================================================
3015 //function : AddEdgeWithID
3017 //=======================================================================
3018 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3019 const SMDS_MeshNode * n2,
3020 const SMDS_MeshNode * n12,
3023 if ( !n1 || !n2 || !n12 ) return 0;
3024 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
3025 if(myElementIDFactory->BindID(ID, edge)) {
3026 SMDS_MeshNode *node1,*node2, *node12;
3027 //node1 = const_cast<SMDS_MeshNode*>(n1);
3028 //node2 = const_cast<SMDS_MeshNode*>(n2);
3029 //node12 = const_cast<SMDS_MeshNode*>(n12);
3030 //node1->AddInverseElement(edge); // --- fait avec BindID
3031 //node2->AddInverseElement(edge);
3032 //node12->AddInverseElement(edge);
3033 adjustmyCellsCapacity(ID);
3035 myInfo.myNbQuadEdges++;
3045 //=======================================================================
3046 //function : AddFace
3048 //=======================================================================
3049 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3050 const SMDS_MeshNode * n2,
3051 const SMDS_MeshNode * n3,
3052 const SMDS_MeshNode * n12,
3053 const SMDS_MeshNode * n23,
3054 const SMDS_MeshNode * n31)
3056 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3057 myElementIDFactory->GetFreeID());
3060 //=======================================================================
3061 //function : AddFaceWithID
3063 //=======================================================================
3064 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3065 int n12,int n23,int n31, int ID)
3067 return SMDS_Mesh::AddFaceWithID
3068 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3069 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3070 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3071 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3072 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3073 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3077 //=======================================================================
3078 //function : AddFaceWithID
3080 //=======================================================================
3081 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3082 const SMDS_MeshNode * n2,
3083 const SMDS_MeshNode * n3,
3084 const SMDS_MeshNode * n12,
3085 const SMDS_MeshNode * n23,
3086 const SMDS_MeshNode * n31,
3089 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3090 if(hasConstructionEdges()) {
3091 // creation quadratic edges - not implemented
3094 SMDS_QuadraticFaceOfNodes* face =
3095 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
3096 adjustmyCellsCapacity(ID);
3098 myInfo.myNbQuadTriangles++;
3100 if (!registerElement(ID, face)) {
3101 RemoveElement(face, false);
3108 //=======================================================================
3109 //function : AddFace
3111 //=======================================================================
3112 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3113 const SMDS_MeshNode * n2,
3114 const SMDS_MeshNode * n3,
3115 const SMDS_MeshNode * n4,
3116 const SMDS_MeshNode * n12,
3117 const SMDS_MeshNode * n23,
3118 const SMDS_MeshNode * n34,
3119 const SMDS_MeshNode * n41)
3121 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3122 myElementIDFactory->GetFreeID());
3125 //=======================================================================
3126 //function : AddFaceWithID
3128 //=======================================================================
3129 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3130 int n12,int n23,int n34,int n41, int ID)
3132 return SMDS_Mesh::AddFaceWithID
3133 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3134 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3135 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3136 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3137 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3138 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3139 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3140 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3144 //=======================================================================
3145 //function : AddFaceWithID
3147 //=======================================================================
3148 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3149 const SMDS_MeshNode * n2,
3150 const SMDS_MeshNode * n3,
3151 const SMDS_MeshNode * n4,
3152 const SMDS_MeshNode * n12,
3153 const SMDS_MeshNode * n23,
3154 const SMDS_MeshNode * n34,
3155 const SMDS_MeshNode * n41,
3158 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3159 if(hasConstructionEdges()) {
3160 // creation quadratic edges - not implemented
3162 SMDS_QuadraticFaceOfNodes* face =
3163 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
3164 adjustmyCellsCapacity(ID);
3166 myInfo.myNbQuadQuadrangles++;
3168 if (!registerElement(ID, face)) {
3169 RemoveElement(face, false);
3176 //=======================================================================
3177 //function : AddVolume
3179 //=======================================================================
3180 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3181 const SMDS_MeshNode * n2,
3182 const SMDS_MeshNode * n3,
3183 const SMDS_MeshNode * n4,
3184 const SMDS_MeshNode * n12,
3185 const SMDS_MeshNode * n23,
3186 const SMDS_MeshNode * n31,
3187 const SMDS_MeshNode * n14,
3188 const SMDS_MeshNode * n24,
3189 const SMDS_MeshNode * n34)
3191 int ID = myElementIDFactory->GetFreeID();
3192 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3193 n31, n14, n24, n34, ID);
3194 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3198 //=======================================================================
3199 //function : AddVolumeWithID
3201 //=======================================================================
3202 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3203 int n12,int n23,int n31,
3204 int n14,int n24,int n34, int ID)
3206 return SMDS_Mesh::AddVolumeWithID
3207 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3208 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3209 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3210 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3211 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3212 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3213 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3214 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3215 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3216 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3220 //=======================================================================
3221 //function : AddVolumeWithID
3222 //purpose : 2d order tetrahedron of 10 nodes
3223 //=======================================================================
3224 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3225 const SMDS_MeshNode * n2,
3226 const SMDS_MeshNode * n3,
3227 const SMDS_MeshNode * n4,
3228 const SMDS_MeshNode * n12,
3229 const SMDS_MeshNode * n23,
3230 const SMDS_MeshNode * n31,
3231 const SMDS_MeshNode * n14,
3232 const SMDS_MeshNode * n24,
3233 const SMDS_MeshNode * n34,
3236 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3238 if(hasConstructionFaces()) {
3239 // creation quadratic faces - not implemented
3242 SMDS_QuadraticVolumeOfNodes * volume =
3243 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3244 adjustmyCellsCapacity(ID);
3245 myCells[ID] = volume;
3246 myInfo.myNbQuadTetras++;
3248 if (!registerElement(ID, volume)) {
3249 RemoveElement(volume, false);
3256 //=======================================================================
3257 //function : AddVolume
3259 //=======================================================================
3260 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3261 const SMDS_MeshNode * n2,
3262 const SMDS_MeshNode * n3,
3263 const SMDS_MeshNode * n4,
3264 const SMDS_MeshNode * n5,
3265 const SMDS_MeshNode * n12,
3266 const SMDS_MeshNode * n23,
3267 const SMDS_MeshNode * n34,
3268 const SMDS_MeshNode * n41,
3269 const SMDS_MeshNode * n15,
3270 const SMDS_MeshNode * n25,
3271 const SMDS_MeshNode * n35,
3272 const SMDS_MeshNode * n45)
3274 int ID = myElementIDFactory->GetFreeID();
3275 SMDS_MeshVolume * v =
3276 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3277 n15, n25, n35, n45, ID);
3278 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3282 //=======================================================================
3283 //function : AddVolumeWithID
3285 //=======================================================================
3286 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3287 int n12,int n23,int n34,int n41,
3288 int n15,int n25,int n35,int n45, int ID)
3290 return SMDS_Mesh::AddVolumeWithID
3291 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3292 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3293 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3294 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3295 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3296 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3297 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3298 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3299 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3300 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3301 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3302 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3303 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3307 //=======================================================================
3308 //function : AddVolumeWithID
3309 //purpose : 2d order pyramid of 13 nodes
3310 //=======================================================================
3311 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3312 const SMDS_MeshNode * n2,
3313 const SMDS_MeshNode * n3,
3314 const SMDS_MeshNode * n4,
3315 const SMDS_MeshNode * n5,
3316 const SMDS_MeshNode * n12,
3317 const SMDS_MeshNode * n23,
3318 const SMDS_MeshNode * n34,
3319 const SMDS_MeshNode * n41,
3320 const SMDS_MeshNode * n15,
3321 const SMDS_MeshNode * n25,
3322 const SMDS_MeshNode * n35,
3323 const SMDS_MeshNode * n45,
3326 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3327 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3329 if(hasConstructionFaces()) {
3330 // creation quadratic faces - not implemented
3333 SMDS_QuadraticVolumeOfNodes * volume =
3334 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3335 n34,n41,n15,n25,n35,n45);
3336 adjustmyCellsCapacity(ID);
3337 myCells[ID] = volume;
3338 myInfo.myNbQuadPyramids++;
3340 if (!registerElement(ID, volume)) {
3341 RemoveElement(volume, false);
3348 //=======================================================================
3349 //function : AddVolume
3351 //=======================================================================
3352 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3353 const SMDS_MeshNode * n2,
3354 const SMDS_MeshNode * n3,
3355 const SMDS_MeshNode * n4,
3356 const SMDS_MeshNode * n5,
3357 const SMDS_MeshNode * n6,
3358 const SMDS_MeshNode * n12,
3359 const SMDS_MeshNode * n23,
3360 const SMDS_MeshNode * n31,
3361 const SMDS_MeshNode * n45,
3362 const SMDS_MeshNode * n56,
3363 const SMDS_MeshNode * n64,
3364 const SMDS_MeshNode * n14,
3365 const SMDS_MeshNode * n25,
3366 const SMDS_MeshNode * n36)
3368 int ID = myElementIDFactory->GetFreeID();
3369 SMDS_MeshVolume * v =
3370 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3371 n45, n56, n64, n14, n25, n36, ID);
3372 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3376 //=======================================================================
3377 //function : AddVolumeWithID
3379 //=======================================================================
3380 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3381 int n4, int n5, int n6,
3382 int n12,int n23,int n31,
3383 int n45,int n56,int n64,
3384 int n14,int n25,int n36, int ID)
3386 return SMDS_Mesh::AddVolumeWithID
3387 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3388 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3389 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3390 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3391 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3392 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3393 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3394 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3395 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3396 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3397 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3398 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3399 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3400 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3401 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3405 //=======================================================================
3406 //function : AddVolumeWithID
3407 //purpose : 2d order Pentahedron with 15 nodes
3408 //=======================================================================
3409 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3410 const SMDS_MeshNode * n2,
3411 const SMDS_MeshNode * n3,
3412 const SMDS_MeshNode * n4,
3413 const SMDS_MeshNode * n5,
3414 const SMDS_MeshNode * n6,
3415 const SMDS_MeshNode * n12,
3416 const SMDS_MeshNode * n23,
3417 const SMDS_MeshNode * n31,
3418 const SMDS_MeshNode * n45,
3419 const SMDS_MeshNode * n56,
3420 const SMDS_MeshNode * n64,
3421 const SMDS_MeshNode * n14,
3422 const SMDS_MeshNode * n25,
3423 const SMDS_MeshNode * n36,
3426 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3427 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3429 if(hasConstructionFaces()) {
3430 // creation quadratic faces - not implemented
3433 SMDS_QuadraticVolumeOfNodes * volume =
3434 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3435 n45,n56,n64,n14,n25,n36);
3436 adjustmyCellsCapacity(ID);
3437 myCells[ID] = volume;
3438 myInfo.myNbQuadPrisms++;
3440 if (!registerElement(ID, volume)) {
3441 RemoveElement(volume, false);
3448 //=======================================================================
3449 //function : AddVolume
3451 //=======================================================================
3452 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3453 const SMDS_MeshNode * n2,
3454 const SMDS_MeshNode * n3,
3455 const SMDS_MeshNode * n4,
3456 const SMDS_MeshNode * n5,
3457 const SMDS_MeshNode * n6,
3458 const SMDS_MeshNode * n7,
3459 const SMDS_MeshNode * n8,
3460 const SMDS_MeshNode * n12,
3461 const SMDS_MeshNode * n23,
3462 const SMDS_MeshNode * n34,
3463 const SMDS_MeshNode * n41,
3464 const SMDS_MeshNode * n56,
3465 const SMDS_MeshNode * n67,
3466 const SMDS_MeshNode * n78,
3467 const SMDS_MeshNode * n85,
3468 const SMDS_MeshNode * n15,
3469 const SMDS_MeshNode * n26,
3470 const SMDS_MeshNode * n37,
3471 const SMDS_MeshNode * n48)
3473 int ID = myElementIDFactory->GetFreeID();
3474 SMDS_MeshVolume * v =
3475 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3476 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3477 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3481 //=======================================================================
3482 //function : AddVolumeWithID
3484 //=======================================================================
3485 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3486 int n5, int n6, int n7, int n8,
3487 int n12,int n23,int n34,int n41,
3488 int n56,int n67,int n78,int n85,
3489 int n15,int n26,int n37,int n48, int ID)
3491 return SMDS_Mesh::AddVolumeWithID
3492 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3493 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3494 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3495 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3496 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3497 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3498 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3499 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3500 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3501 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3502 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3503 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3504 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3505 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3506 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3507 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3508 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3509 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3510 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3511 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3515 //=======================================================================
3516 //function : AddVolumeWithID
3517 //purpose : 2d order Hexahedrons with 20 nodes
3518 //=======================================================================
3519 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3520 const SMDS_MeshNode * n2,
3521 const SMDS_MeshNode * n3,
3522 const SMDS_MeshNode * n4,
3523 const SMDS_MeshNode * n5,
3524 const SMDS_MeshNode * n6,
3525 const SMDS_MeshNode * n7,
3526 const SMDS_MeshNode * n8,
3527 const SMDS_MeshNode * n12,
3528 const SMDS_MeshNode * n23,
3529 const SMDS_MeshNode * n34,
3530 const SMDS_MeshNode * n41,
3531 const SMDS_MeshNode * n56,
3532 const SMDS_MeshNode * n67,
3533 const SMDS_MeshNode * n78,
3534 const SMDS_MeshNode * n85,
3535 const SMDS_MeshNode * n15,
3536 const SMDS_MeshNode * n26,
3537 const SMDS_MeshNode * n37,
3538 const SMDS_MeshNode * n48,
3541 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3542 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3544 if(hasConstructionFaces()) {
3546 // creation quadratic faces - not implemented
3548 SMDS_QuadraticVolumeOfNodes * volume =
3549 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3550 n56,n67,n78,n85,n15,n26,n37,n48);
3551 adjustmyCellsCapacity(ID);
3552 myCells[ID] = volume;
3553 myInfo.myNbQuadHexas++;
3555 if (!registerElement(ID, volume)) {
3556 RemoveElement(volume, false);
3562 void SMDS_Mesh::updateNodeMinMax()
3565 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3567 myNodeMax=myNodes.size()-1;
3568 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3572 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3574 int val = myIDElements.size();
3575 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3576 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3577 val = myNodes.size();
3578 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3579 myNodes.resize(val +nbNodes, 0);
3582 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3584 int val = myVtkIndex.size();
3585 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3586 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3587 val = myCells.size();
3588 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3589 myNodes.resize(val +nbCells, 0);
3592 void SMDS_Mesh::adjustStructure()
3594 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);