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"
40 #include "SMDS_UnstructuredGrid.hxx"
42 #include <vtkUnstructuredGrid.h>
43 #include <vtkUnstructuredGridWriter.h>
44 #include <vtkUnsignedCharArray.h>
46 #include <vtkCellLinks.h>
47 #include <vtkIdList.h>
56 #include <sys/sysinfo.h>
59 // number of added entities to check memory after
60 #define CHECKMEMORY_INTERVAL 1000
62 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
63 int SMDS_Mesh::chunkSize = 1024;
66 //================================================================================
68 * \brief Raise an exception if free memory (ram+swap) too low
69 * \param doNotRaise - if true, suppres exception, just return free memory size
70 * \retval int - amount of available memory in MB or negative number in failure case
72 //================================================================================
74 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
78 int err = sysinfo( &si );
82 static int limit = -1;
84 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
86 limit = WEXITSTATUS(status);
91 limit = int( limit * 1.5 );
93 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
97 const unsigned long Mbyte = 1024 * 1024;
98 // compute separately to avoid overflow
100 ( si.freeram * si.mem_unit ) / Mbyte +
101 ( si.freeswap * si.mem_unit ) / Mbyte;
103 if ( freeMb > limit )
104 return freeMb - limit;
109 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
111 throw std::bad_alloc();
117 ///////////////////////////////////////////////////////////////////////////////
118 /// Create a new mesh object
119 ///////////////////////////////////////////////////////////////////////////////
120 SMDS_Mesh::SMDS_Mesh()
122 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
123 myElementIDFactory(new SMDS_MeshElementIDFactory()),
124 myHasConstructionEdges(false), myHasConstructionFaces(false),
125 myHasInverseElements(true),
126 myNodeMin(0), myNodeMax(0),
127 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
129 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
130 MESSAGE("myMeshId=" << myMeshId);
131 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
132 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
133 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
134 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
135 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
136 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
137 myNodeIDFactory->SetMesh(this);
138 myElementIDFactory->SetMesh(this);
139 _meshList.push_back(this);
140 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
141 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
142 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
143 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
147 myIDElements.clear();
149 myGrid = SMDS_UnstructuredGrid::New();
150 myGrid->Initialize();
152 vtkPoints* points = vtkPoints::New();
153 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
154 myGrid->SetPoints( points );
156 myGrid->BuildLinks();
159 ///////////////////////////////////////////////////////////////////////////////
160 /// Create a new child mesh
161 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
162 /// (2003-09-08) of SMESH
163 ///////////////////////////////////////////////////////////////////////////////
164 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
165 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
166 myElementIDFactory(parent->myElementIDFactory),
167 myHasConstructionEdges(false), myHasConstructionFaces(false),
168 myHasInverseElements(true),
169 myNodePool(parent->myNodePool),
170 myEdgePool(parent->myEdgePool),
171 myFacePool(parent->myFacePool),
172 myVolumePool(parent->myVolumePool)
176 ///////////////////////////////////////////////////////////////////////////////
177 ///Create a submesh and add it to the current mesh
178 ///////////////////////////////////////////////////////////////////////////////
180 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
182 SMDS_Mesh *submesh = new SMDS_Mesh(this);
183 myChildren.insert(myChildren.end(), submesh);
187 ///////////////////////////////////////////////////////////////////////////////
188 ///create a MeshNode and add it to the current Mesh
189 ///An ID is automatically assigned to the node.
190 ///@return : The created node
191 ///////////////////////////////////////////////////////////////////////////////
193 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
195 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
198 ///////////////////////////////////////////////////////////////////////////////
199 ///create a MeshNode and add it to the current Mesh
200 ///@param ID : The ID of the MeshNode to create
201 ///@return : The created node or NULL if a node with this ID already exists
202 ///////////////////////////////////////////////////////////////////////////////
203 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
205 // find the MeshNode corresponding to ID
206 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
208 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
209 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
210 SMDS_MeshNode * node = myNodePool->getNew();
211 node->init(ID, myMeshId, -1, x, y, z);
212 if (ID >= myNodes.size())
214 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
215 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
218 myNodeIDFactory->BindID(ID,node);
225 ///////////////////////////////////////////////////////////////////////////////
226 /// create a Mesh0DElement and add it to the current Mesh
227 /// @return : The created Mesh0DElement
228 ///////////////////////////////////////////////////////////////////////////////
229 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
231 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
232 if (!node) return NULL;
233 return SMDS_Mesh::Add0DElementWithID(node, ID);
236 ///////////////////////////////////////////////////////////////////////////////
237 /// create a Mesh0DElement and add it to the current Mesh
238 /// @return : The created Mesh0DElement
239 ///////////////////////////////////////////////////////////////////////////////
240 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
242 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
245 ///////////////////////////////////////////////////////////////////////////////
246 /// Create a new Mesh0DElement and at it to the mesh
247 /// @param idnode ID of the node
248 /// @param ID ID of the 0D element to create
249 /// @return The created 0D element or NULL if an element with this
250 /// ID already exists or if input node is not found.
251 ///////////////////////////////////////////////////////////////////////////////
252 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
256 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
257 //MESSAGE("Add0DElementWithID" << ID)
258 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
259 if (myElementIDFactory->BindID(ID, el0d)) {
260 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
261 //node->AddInverseElement(el0d);// --- fait avec BindID
262 adjustmyCellsCapacity(ID);
264 myInfo.myNb0DElements++;
272 ///////////////////////////////////////////////////////////////////////////////
273 /// create a MeshEdge and add it to the current Mesh
274 /// @return : The created MeshEdge
275 ///////////////////////////////////////////////////////////////////////////////
277 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
279 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
280 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
281 if(!node1 || !node2) return NULL;
282 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
285 ///////////////////////////////////////////////////////////////////////////////
286 /// create a MeshEdge and add it to the current Mesh
287 /// @return : The created MeshEdge
288 ///////////////////////////////////////////////////////////////////////////////
290 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
291 const SMDS_MeshNode * node2)
293 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
296 ///////////////////////////////////////////////////////////////////////////////
297 /// Create a new edge and at it to the mesh
298 /// @param idnode1 ID of the first node
299 /// @param idnode2 ID of the second node
300 /// @param ID ID of the edge to create
301 /// @return The created edge or NULL if an element with this ID already exists or
302 /// if input nodes are not found.
303 ///////////////////////////////////////////////////////////////////////////////
305 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
306 const SMDS_MeshNode * n2,
309 if ( !n1 || !n2 ) return 0;
310 SMDS_MeshEdge * edge = 0;
312 // --- retreive nodes ID
313 vector<vtkIdType> nodeIds;
315 nodeIds.push_back(n1->getId());
316 nodeIds.push_back(n2->getId());
318 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
319 edgevtk->init(nodeIds, this);
321 adjustmyCellsCapacity(ID);
325 if (edge && !registerElement(ID, edge))
327 RemoveElement(edge, false);
333 ///////////////////////////////////////////////////////////////////////////////
334 /// Add a triangle defined by its nodes. An ID is automatically affected to the
336 ///////////////////////////////////////////////////////////////////////////////
338 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
339 const SMDS_MeshNode * n2,
340 const SMDS_MeshNode * n3)
342 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
345 ///////////////////////////////////////////////////////////////////////////////
346 /// Add a triangle defined by its nodes IDs
347 ///////////////////////////////////////////////////////////////////////////////
349 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
351 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
352 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
353 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
354 if(!node1 || !node2 || !node3) return NULL;
355 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
358 ///////////////////////////////////////////////////////////////////////////////
359 /// Add a triangle defined by its nodes
360 ///////////////////////////////////////////////////////////////////////////////
362 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
363 const SMDS_MeshNode * n2,
364 const SMDS_MeshNode * n3,
367 //MESSAGE("AddFaceWithID " << ID)
368 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
370 if (face && !registerElement(ID, face)) {
371 RemoveElement(face, false);
377 ///////////////////////////////////////////////////////////////////////////////
378 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
380 ///////////////////////////////////////////////////////////////////////////////
382 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
383 const SMDS_MeshNode * n2,
384 const SMDS_MeshNode * n3,
385 const SMDS_MeshNode * n4)
387 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
390 ///////////////////////////////////////////////////////////////////////////////
391 /// Add a quadrangle defined by its nodes IDs
392 ///////////////////////////////////////////////////////////////////////////////
394 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
400 SMDS_MeshNode *node1, *node2, *node3, *node4;
401 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
402 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
403 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
404 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
405 if(!node1 || !node2 || !node3 || !node4) return NULL;
406 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
409 ///////////////////////////////////////////////////////////////////////////////
410 /// Add a quadrangle defined by its nodes
411 ///////////////////////////////////////////////////////////////////////////////
413 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
414 const SMDS_MeshNode * n2,
415 const SMDS_MeshNode * n3,
416 const SMDS_MeshNode * n4,
419 //MESSAGE("AddFaceWithID " << ID);
420 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
422 if (face && !registerElement(ID, face)) {
423 RemoveElement(face, false);
429 ///////////////////////////////////////////////////////////////////////////////
430 /// Add a triangle defined by its edges. An ID is automatically assigned to the
432 ///////////////////////////////////////////////////////////////////////////////
434 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
435 const SMDS_MeshEdge * e2,
436 const SMDS_MeshEdge * e3)
438 if (!hasConstructionEdges())
440 //MESSAGE("AddFaceWithID");
441 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
444 ///////////////////////////////////////////////////////////////////////////////
445 /// Add a triangle defined by its edges
446 ///////////////////////////////////////////////////////////////////////////////
448 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
449 const SMDS_MeshEdge * e2,
450 const SMDS_MeshEdge * e3,
453 if (!hasConstructionEdges())
455 if ( !e1 || !e2 || !e3 ) return 0;
457 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
458 //MESSAGE("AddFaceWithID" << ID);
460 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
461 adjustmyCellsCapacity(ID);
463 myInfo.myNbTriangles++;
465 if (!registerElement(ID, face)) {
466 RemoveElement(face, false);
472 ///////////////////////////////////////////////////////////////////////////////
473 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
475 ///////////////////////////////////////////////////////////////////////////////
477 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
478 const SMDS_MeshEdge * e2,
479 const SMDS_MeshEdge * e3,
480 const SMDS_MeshEdge * e4)
482 if (!hasConstructionEdges())
484 //MESSAGE("AddFaceWithID" );
485 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
488 ///////////////////////////////////////////////////////////////////////////////
489 /// Add a quadrangle defined by its edges
490 ///////////////////////////////////////////////////////////////////////////////
492 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
493 const SMDS_MeshEdge * e2,
494 const SMDS_MeshEdge * e3,
495 const SMDS_MeshEdge * e4,
498 if (!hasConstructionEdges())
500 //MESSAGE("AddFaceWithID" << ID);
501 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
502 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
503 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
504 adjustmyCellsCapacity(ID);
506 myInfo.myNbQuadrangles++;
508 if (!registerElement(ID, face))
510 RemoveElement(face, false);
516 ///////////////////////////////////////////////////////////////////////////////
517 ///Create a new tetrahedron and add it to the mesh.
518 ///@return The created tetrahedron
519 ///////////////////////////////////////////////////////////////////////////////
521 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
522 const SMDS_MeshNode * n2,
523 const SMDS_MeshNode * n3,
524 const SMDS_MeshNode * n4)
526 int ID = myElementIDFactory->GetFreeID();
527 //MESSAGE("AddVolumeWithID " << ID);
528 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
529 if(v==NULL) myElementIDFactory->ReleaseID(ID);
533 ///////////////////////////////////////////////////////////////////////////////
534 ///Create a new tetrahedron and add it to the mesh.
535 ///@param ID The ID of the new volume
536 ///@return The created tetrahedron or NULL if an element with this ID already exists
537 ///or if input nodes are not found.
538 ///////////////////////////////////////////////////////////////////////////////
540 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
546 //MESSAGE("AddVolumeWithID" << ID);
547 SMDS_MeshNode *node1, *node2, *node3, *node4;
548 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
549 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
550 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
551 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
552 if(!node1 || !node2 || !node3 || !node4) return NULL;
553 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
556 ///////////////////////////////////////////////////////////////////////////////
557 ///Create a new tetrahedron and add it to the mesh.
558 ///@param ID The ID of the new volume
559 ///@return The created tetrahedron
560 ///////////////////////////////////////////////////////////////////////////////
562 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
563 const SMDS_MeshNode * n2,
564 const SMDS_MeshNode * n3,
565 const SMDS_MeshNode * n4,
568 //MESSAGE("AddVolumeWithID " << ID);
569 SMDS_MeshVolume* volume = 0;
570 if ( !n1 || !n2 || !n3 || !n4) return volume;
571 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
572 if(hasConstructionFaces()) {
573 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
574 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
575 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
576 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
577 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
578 adjustmyCellsCapacity(ID);
579 myCells[ID] = volume;
582 else if(hasConstructionEdges()) {
583 MESSAGE("Error : Not implemented");
587 // --- retrieve nodes ID
588 vector<vtkIdType> nodeIds;
590 nodeIds.push_back(n1->getId());
591 nodeIds.push_back(n3->getId()); // order SMDS-->VTK
592 nodeIds.push_back(n2->getId());
593 nodeIds.push_back(n4->getId());
595 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
596 volvtk->init(nodeIds, this);
598 adjustmyCellsCapacity(ID);
599 myCells[ID] = volume;
603 if (!registerElement(ID, volume)) {
604 RemoveElement(volume, false);
610 ///////////////////////////////////////////////////////////////////////////////
611 ///Create a new pyramid and add it to the mesh.
612 ///Nodes 1,2,3 and 4 define the base of the pyramid
613 ///@return The created pyramid
614 ///////////////////////////////////////////////////////////////////////////////
616 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
617 const SMDS_MeshNode * n2,
618 const SMDS_MeshNode * n3,
619 const SMDS_MeshNode * n4,
620 const SMDS_MeshNode * n5)
622 int ID = myElementIDFactory->GetFreeID();
623 //MESSAGE("AddVolumeWithID " << ID);
624 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
625 if(v==NULL) myElementIDFactory->ReleaseID(ID);
629 ///////////////////////////////////////////////////////////////////////////////
630 ///Create a new pyramid and add it to the mesh.
631 ///Nodes 1,2,3 and 4 define the base of the pyramid
632 ///@param ID The ID of the new volume
633 ///@return The created pyramid or NULL if an element with this ID already exists
634 ///or if input nodes are not found.
635 ///////////////////////////////////////////////////////////////////////////////
637 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
644 //MESSAGE("AddVolumeWithID " << ID);
645 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
646 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
647 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
648 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
649 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
650 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
651 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
652 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
655 ///////////////////////////////////////////////////////////////////////////////
656 ///Create a new pyramid and add it to the mesh.
657 ///Nodes 1,2,3 and 4 define the base of the pyramid
658 ///@param ID The ID of the new volume
659 ///@return The created pyramid
660 ///////////////////////////////////////////////////////////////////////////////
662 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
663 const SMDS_MeshNode * n2,
664 const SMDS_MeshNode * n3,
665 const SMDS_MeshNode * n4,
666 const SMDS_MeshNode * n5,
669 //MESSAGE("AddVolumeWithID " << ID);
670 SMDS_MeshVolume* volume = 0;
671 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
672 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
673 if(hasConstructionFaces()) {
674 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
675 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
676 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
677 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
678 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
679 adjustmyCellsCapacity(ID);
680 myCells[ID] = volume;
681 myInfo.myNbPyramids++;
683 else if(hasConstructionEdges()) {
684 MESSAGE("Error : Not implemented");
688 // --- retrieve nodes ID
689 vector<vtkIdType> nodeIds;
691 nodeIds.push_back(n1->getId());
692 nodeIds.push_back(n4->getId());
693 nodeIds.push_back(n3->getId());
694 nodeIds.push_back(n2->getId());
695 nodeIds.push_back(n5->getId());
697 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
698 volvtk->init(nodeIds, this);
700 adjustmyCellsCapacity(ID);
701 myCells[ID] = volume;
702 myInfo.myNbPyramids++;
705 if (!registerElement(ID, volume)) {
706 RemoveElement(volume, false);
712 ///////////////////////////////////////////////////////////////////////////////
713 ///Create a new prism and add it to the mesh.
714 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
715 ///@return The created prism
716 ///////////////////////////////////////////////////////////////////////////////
718 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
719 const SMDS_MeshNode * n2,
720 const SMDS_MeshNode * n3,
721 const SMDS_MeshNode * n4,
722 const SMDS_MeshNode * n5,
723 const SMDS_MeshNode * n6)
725 int ID = myElementIDFactory->GetFreeID();
726 //MESSAGE("AddVolumeWithID " << ID);
727 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
728 if(v==NULL) myElementIDFactory->ReleaseID(ID);
732 ///////////////////////////////////////////////////////////////////////////////
733 ///Create a new prism and add it to the mesh.
734 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
735 ///@param ID The ID of the new volume
736 ///@return The created prism or NULL if an element with this ID already exists
737 ///or if input nodes are not found.
738 ///////////////////////////////////////////////////////////////////////////////
740 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
748 //MESSAGE("AddVolumeWithID " << ID);
749 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
750 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
751 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
752 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
753 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
754 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
755 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
756 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
757 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
760 ///////////////////////////////////////////////////////////////////////////////
761 ///Create a new prism and add it to the mesh.
762 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
763 ///@param ID The ID of the new volume
764 ///@return The created prism
765 ///////////////////////////////////////////////////////////////////////////////
767 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
768 const SMDS_MeshNode * n2,
769 const SMDS_MeshNode * n3,
770 const SMDS_MeshNode * n4,
771 const SMDS_MeshNode * n5,
772 const SMDS_MeshNode * n6,
775 //MESSAGE("AddVolumeWithID " << ID);
776 SMDS_MeshVolume* volume = 0;
777 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
778 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
779 if(hasConstructionFaces()) {
780 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
781 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
782 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
783 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
784 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
785 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
786 adjustmyCellsCapacity(ID);
787 myCells[ID] = volume;
790 else if(hasConstructionEdges()) {
791 MESSAGE("Error : Not implemented");
795 // --- retrieve nodes ID
796 vector<vtkIdType> nodeIds;
798 nodeIds.push_back(n1->getId());
799 nodeIds.push_back(n2->getId());
800 nodeIds.push_back(n3->getId());
801 nodeIds.push_back(n4->getId());
802 nodeIds.push_back(n5->getId());
803 nodeIds.push_back(n6->getId());
805 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
806 volvtk->init(nodeIds, this);
808 adjustmyCellsCapacity(ID);
809 myCells[ID] = volume;
813 if (!registerElement(ID, volume)) {
814 RemoveElement(volume, false);
820 ///////////////////////////////////////////////////////////////////////////////
821 ///Create a new hexahedron and add it to the mesh.
822 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
823 ///@return The created hexahedron
824 ///////////////////////////////////////////////////////////////////////////////
826 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
827 const SMDS_MeshNode * n2,
828 const SMDS_MeshNode * n3,
829 const SMDS_MeshNode * n4,
830 const SMDS_MeshNode * n5,
831 const SMDS_MeshNode * n6,
832 const SMDS_MeshNode * n7,
833 const SMDS_MeshNode * n8)
835 int ID = myElementIDFactory->GetFreeID();
836 //MESSAGE("AddVolumeWithID " << ID);
837 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
838 if(v==NULL) myElementIDFactory->ReleaseID(ID);
842 ///////////////////////////////////////////////////////////////////////////////
843 ///Create a new hexahedron and add it to the mesh.
844 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
845 ///@param ID The ID of the new volume
846 ///@return The created hexahedron or NULL if an element with this ID already
847 ///exists or if input nodes are not found.
848 ///////////////////////////////////////////////////////////////////////////////
850 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
860 //MESSAGE("AddVolumeWithID " << ID);
861 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
862 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
863 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
864 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
865 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
866 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
867 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
868 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
869 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
870 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
872 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
876 ///////////////////////////////////////////////////////////////////////////////
877 ///Create a new hexahedron and add it to the mesh.
878 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
879 ///@param ID The ID of the new volume
880 ///@return The created prism or NULL if an element with this ID already exists
881 ///or if input nodes are not found.
882 ///////////////////////////////////////////////////////////////////////////////
884 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
885 const SMDS_MeshNode * n2,
886 const SMDS_MeshNode * n3,
887 const SMDS_MeshNode * n4,
888 const SMDS_MeshNode * n5,
889 const SMDS_MeshNode * n6,
890 const SMDS_MeshNode * n7,
891 const SMDS_MeshNode * n8,
894 //MESSAGE("AddVolumeWithID " << ID);
895 SMDS_MeshVolume* volume = 0;
896 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
897 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
898 if(hasConstructionFaces()) {
899 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
900 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
901 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
902 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
903 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
904 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
905 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
906 adjustmyCellsCapacity(ID);
907 myCells[ID] = volume;
910 else if(hasConstructionEdges()) {
911 MESSAGE("Error : Not implemented");
915 // --- retrieve nodes ID
916 vector<vtkIdType> nodeIds;
918 nodeIds.push_back(n1->getId());
919 nodeIds.push_back(n4->getId());
920 nodeIds.push_back(n3->getId());
921 nodeIds.push_back(n2->getId());
922 nodeIds.push_back(n5->getId());
923 nodeIds.push_back(n8->getId());
924 nodeIds.push_back(n7->getId());
925 nodeIds.push_back(n6->getId());
927 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
928 volvtk->init(nodeIds, this);
930 adjustmyCellsCapacity(ID);
931 myCells[ID] = volume;
935 if (!registerElement(ID, volume)) {
936 RemoveElement(volume, false);
942 ///////////////////////////////////////////////////////////////////////////////
943 ///Create a new tetrahedron defined by its faces and add it to the mesh.
944 ///@return The created tetrahedron
945 ///////////////////////////////////////////////////////////////////////////////
947 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
948 const SMDS_MeshFace * f2,
949 const SMDS_MeshFace * f3,
950 const SMDS_MeshFace * f4)
952 //MESSAGE("AddVolumeWithID");
953 if (!hasConstructionFaces())
955 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
958 ///////////////////////////////////////////////////////////////////////////////
959 ///Create a new tetrahedron defined by its faces and add it to the mesh.
960 ///@param ID The ID of the new volume
961 ///@return The created tetrahedron
962 ///////////////////////////////////////////////////////////////////////////////
964 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
965 const SMDS_MeshFace * f2,
966 const SMDS_MeshFace * f3,
967 const SMDS_MeshFace * f4,
970 //MESSAGE("AddVolumeWithID" << ID);
971 if (!hasConstructionFaces())
973 if ( !f1 || !f2 || !f3 || !f4) return 0;
974 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
975 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
976 adjustmyCellsCapacity(ID);
977 myCells[ID] = volume;
980 if (!registerElement(ID, volume)) {
981 RemoveElement(volume, false);
987 ///////////////////////////////////////////////////////////////////////////////
988 ///Create a new pyramid defined by its faces and add it to the mesh.
989 ///@return The created pyramid
990 ///////////////////////////////////////////////////////////////////////////////
992 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
993 const SMDS_MeshFace * f2,
994 const SMDS_MeshFace * f3,
995 const SMDS_MeshFace * f4,
996 const SMDS_MeshFace * f5)
998 //MESSAGE("AddVolumeWithID");
999 if (!hasConstructionFaces())
1001 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1004 ///////////////////////////////////////////////////////////////////////////////
1005 ///Create a new pyramid defined by its faces and add it to the mesh.
1006 ///@param ID The ID of the new volume
1007 ///@return The created pyramid
1008 ///////////////////////////////////////////////////////////////////////////////
1010 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1011 const SMDS_MeshFace * f2,
1012 const SMDS_MeshFace * f3,
1013 const SMDS_MeshFace * f4,
1014 const SMDS_MeshFace * f5,
1017 //MESSAGE("AddVolumeWithID" << ID);
1018 if (!hasConstructionFaces())
1020 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1021 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1022 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1023 adjustmyCellsCapacity(ID);
1024 myCells[ID] = volume;
1025 myInfo.myNbPyramids++;
1027 if (!registerElement(ID, volume)) {
1028 RemoveElement(volume, false);
1034 ///////////////////////////////////////////////////////////////////////////////
1035 ///Create a new prism defined by its faces and add it to the mesh.
1036 ///@return The created prism
1037 ///////////////////////////////////////////////////////////////////////////////
1039 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1040 const SMDS_MeshFace * f2,
1041 const SMDS_MeshFace * f3,
1042 const SMDS_MeshFace * f4,
1043 const SMDS_MeshFace * f5,
1044 const SMDS_MeshFace * f6)
1046 //MESSAGE("AddVolumeWithID" );
1047 if (!hasConstructionFaces())
1049 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1052 ///////////////////////////////////////////////////////////////////////////////
1053 ///Create a new prism defined by its faces and add it to the mesh.
1054 ///@param ID The ID of the new volume
1055 ///@return The created prism
1056 ///////////////////////////////////////////////////////////////////////////////
1058 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1059 const SMDS_MeshFace * f2,
1060 const SMDS_MeshFace * f3,
1061 const SMDS_MeshFace * f4,
1062 const SMDS_MeshFace * f5,
1063 const SMDS_MeshFace * f6,
1066 //MESSAGE("AddVolumeWithID" << ID);
1067 if (!hasConstructionFaces())
1069 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1070 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1071 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1072 adjustmyCellsCapacity(ID);
1073 myCells[ID] = volume;
1074 myInfo.myNbPrisms++;
1076 if (!registerElement(ID, volume)) {
1077 RemoveElement(volume, false);
1083 ///////////////////////////////////////////////////////////////////////////////
1084 /// Add a polygon defined by its nodes IDs
1085 ///////////////////////////////////////////////////////////////////////////////
1087 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1090 int nbNodes = nodes_ids.size();
1091 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1092 for (int i = 0; i < nbNodes; i++) {
1093 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1094 if (!nodes[i]) return NULL;
1096 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1099 ///////////////////////////////////////////////////////////////////////////////
1100 /// Add a polygon defined by its nodes
1101 ///////////////////////////////////////////////////////////////////////////////
1103 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1104 (std::vector<const SMDS_MeshNode*> nodes,
1107 SMDS_MeshFace * face;
1109 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1110 if (hasConstructionEdges())
1112 MESSAGE("Error : Not implemented");
1117 for ( int i = 0; i < nodes.size(); ++i )
1118 if ( !nodes[ i ] ) return 0;
1119 face = new SMDS_PolygonalFaceOfNodes(nodes);
1120 adjustmyCellsCapacity(ID);
1122 myInfo.myNbPolygons++;
1125 if (!registerElement(ID, face)) {
1126 RemoveElement(face, false);
1132 ///////////////////////////////////////////////////////////////////////////////
1133 /// Add a polygon defined by its nodes.
1134 /// An ID is automatically affected to the created face.
1135 ///////////////////////////////////////////////////////////////////////////////
1137 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1139 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1142 ///////////////////////////////////////////////////////////////////////////////
1143 /// Create a new polyhedral volume and add it to the mesh.
1144 /// @param ID The ID of the new volume
1145 /// @return The created volume or NULL if an element with this ID already exists
1146 /// or if input nodes are not found.
1147 ///////////////////////////////////////////////////////////////////////////////
1149 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1150 (std::vector<int> nodes_ids,
1151 std::vector<int> quantities,
1154 int nbNodes = nodes_ids.size();
1155 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1156 for (int i = 0; i < nbNodes; i++) {
1157 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1158 if (!nodes[i]) return NULL;
1160 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1163 ///////////////////////////////////////////////////////////////////////////////
1164 /// Create a new polyhedral volume and add it to the mesh.
1165 /// @param ID The ID of the new volume
1166 /// @return The created volume
1167 ///////////////////////////////////////////////////////////////////////////////
1169 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1170 (std::vector<const SMDS_MeshNode*> nodes,
1171 std::vector<int> quantities,
1174 SMDS_MeshVolume* volume;
1175 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1176 if (hasConstructionFaces()) {
1177 MESSAGE("Error : Not implemented");
1179 } else if (hasConstructionEdges()) {
1180 MESSAGE("Error : Not implemented");
1183 for ( int i = 0; i < nodes.size(); ++i )
1184 if ( !nodes[ i ] ) return 0;
1185 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1186 adjustmyCellsCapacity(ID);
1187 myCells[ID] = volume;
1188 myInfo.myNbPolyhedrons++;
1191 if (!registerElement(ID, volume)) {
1192 RemoveElement(volume, false);
1198 ///////////////////////////////////////////////////////////////////////////////
1199 /// Create a new polyhedral volume and add it to the mesh.
1200 /// @return The created volume
1201 ///////////////////////////////////////////////////////////////////////////////
1203 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1204 (std::vector<const SMDS_MeshNode*> nodes,
1205 std::vector<int> quantities)
1207 int ID = myElementIDFactory->GetFreeID();
1208 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1209 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1213 ///////////////////////////////////////////////////////////////////////////////
1214 /// Registers element with the given ID, maintains inverse connections
1215 ///////////////////////////////////////////////////////////////////////////////
1216 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1218 //MESSAGE("registerElement " << ID);
1219 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1221 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1226 element->myMeshId = myMeshId;
1228 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1230 int vtkId = cell->getVtkId();
1232 vtkId = myElementIDFactory->SetInVtkGrid(element);
1234 if (ID >= myIDElements.size()) // --- resize local vector
1236 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1237 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1240 myIDElements[ID] = vtkId;
1241 //MESSAGE("smds:" << ID << " vtk:" << vtkId );
1243 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1245 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1246 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1248 myVtkIndex[vtkId] = ID;
1250 myElementIDFactory->updateMinMax(ID);
1254 ///////////////////////////////////////////////////////////////////////////////
1255 /// Return the node whose ID is 'ID'.
1256 ///////////////////////////////////////////////////////////////////////////////
1257 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1259 if (ID < 0 || ID >= myNodes.size())
1261 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1264 return (const SMDS_MeshNode *)myNodes[ID];
1267 ///////////////////////////////////////////////////////////////////////////////
1268 ///Create a triangle and add it to the current mesh. This method do not bind an
1269 ///ID to the create triangle.
1270 ///////////////////////////////////////////////////////////////////////////////
1271 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1272 const SMDS_MeshNode * node2,
1273 const SMDS_MeshNode * node3,
1276 if ( !node1 || !node2 || !node3) return 0;
1277 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1278 if(hasConstructionEdges())
1280 SMDS_MeshEdge *edge1, *edge2, *edge3;
1281 edge1=FindEdgeOrCreate(node1,node2);
1282 edge2=FindEdgeOrCreate(node2,node3);
1283 edge3=FindEdgeOrCreate(node3,node1);
1285 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1286 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1287 adjustmyCellsCapacity(ID);
1289 myInfo.myNbTriangles++;
1294 // --- retrieve nodes ID
1295 vector<vtkIdType> nodeIds;
1297 nodeIds.push_back(node1->getId());
1298 nodeIds.push_back(node2->getId());
1299 nodeIds.push_back(node3->getId());
1301 SMDS_MeshFace * face = 0;
1302 SMDS_VtkFace *facevtk = myFacePool->getNew();
1303 facevtk->init(nodeIds, this);
1305 adjustmyCellsCapacity(ID);
1307 //MESSAGE("createTriangle " << ID << " " << face);
1308 myInfo.myNbTriangles++;
1313 ///////////////////////////////////////////////////////////////////////////////
1314 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1315 ///a ID to the create triangle.
1316 ///////////////////////////////////////////////////////////////////////////////
1317 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1318 const SMDS_MeshNode * node2,
1319 const SMDS_MeshNode * node3,
1320 const SMDS_MeshNode * node4,
1323 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1324 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1325 if(hasConstructionEdges())
1327 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1328 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1329 edge1=FindEdgeOrCreate(node1,node2);
1330 edge2=FindEdgeOrCreate(node2,node3);
1331 edge3=FindEdgeOrCreate(node3,node4);
1332 edge4=FindEdgeOrCreate(node4,node1);
1334 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1335 adjustmyCellsCapacity(ID);
1337 myInfo.myNbQuadrangles++;
1342 // --- retrieve nodes ID
1343 vector<vtkIdType> nodeIds;
1345 nodeIds.push_back(node1->getId());
1346 nodeIds.push_back(node2->getId());
1347 nodeIds.push_back(node3->getId());
1348 nodeIds.push_back(node4->getId());
1350 SMDS_MeshFace * face = 0;
1351 SMDS_VtkFace *facevtk = myFacePool->getNew();
1352 facevtk->init(nodeIds, this);
1354 adjustmyCellsCapacity(ID);
1356 myInfo.myNbQuadrangles++;
1361 ///////////////////////////////////////////////////////////////////////////////
1362 /// Remove a node and all the elements which own this node
1363 ///////////////////////////////////////////////////////////////////////////////
1365 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1367 MESSAGE("RemoveNode");
1368 RemoveElement(node, true);
1371 ///////////////////////////////////////////////////////////////////////////////
1372 /// Remove an edge and all the elements which own this edge
1373 ///////////////////////////////////////////////////////////////////////////////
1375 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1377 MESSAGE("Remove0DElement");
1378 RemoveElement(elem0d,true);
1381 ///////////////////////////////////////////////////////////////////////////////
1382 /// Remove an edge and all the elements which own this edge
1383 ///////////////////////////////////////////////////////////////////////////////
1385 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1387 MESSAGE("RemoveEdge");
1388 RemoveElement(edge,true);
1391 ///////////////////////////////////////////////////////////////////////////////
1392 /// Remove an face and all the elements which own this face
1393 ///////////////////////////////////////////////////////////////////////////////
1395 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1397 MESSAGE("RemoveFace");
1398 RemoveElement(face, true);
1401 ///////////////////////////////////////////////////////////////////////////////
1403 ///////////////////////////////////////////////////////////////////////////////
1405 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1407 MESSAGE("RemoveVolume");
1408 RemoveElement(volume, true);
1411 //=======================================================================
1412 //function : RemoveFromParent
1414 //=======================================================================
1416 bool SMDS_Mesh::RemoveFromParent()
1418 if (myParent==NULL) return false;
1419 else return (myParent->RemoveSubMesh(this));
1422 //=======================================================================
1423 //function : RemoveSubMesh
1425 //=======================================================================
1427 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1431 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1432 for (; itmsh!=myChildren.end() && !found; itmsh++)
1434 SMDS_Mesh * submesh = *itmsh;
1435 if (submesh == aMesh)
1438 myChildren.erase(itmsh);
1445 //=======================================================================
1446 //function : ChangeElementNodes
1448 //=======================================================================
1450 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1451 const SMDS_MeshNode * nodes[],
1454 MYASSERT(0); // REVOIR LES TYPES
1455 // keep current nodes of elem
1456 set<const SMDS_MeshElement*> oldNodes;
1457 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1459 oldNodes.insert( itn->next() );
1461 if ( !element->IsPoly() )
1462 myInfo.remove( element ); // element may change type
1466 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1467 switch ( elem->GetType() )
1469 case SMDSAbs_0DElement: {
1470 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1471 Ok = elem0d->ChangeNode( nodes[0] );
1474 case SMDSAbs_Edge: {
1475 if ( nbnodes == 2 ) {
1476 if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
1477 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1479 else if ( nbnodes == 3 ) {
1480 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1481 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1485 case SMDSAbs_Face: {
1486 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1487 Ok = face->ChangeNodes( nodes, nbnodes );
1489 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1490 Ok = QF->ChangeNodes( nodes, nbnodes );
1492 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1493 Ok = face->ChangeNodes(nodes, nbnodes);
1496 case SMDSAbs_Volume: {
1497 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1498 Ok = vol->ChangeNodes( nodes, nbnodes );
1500 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1501 Ok = QV->ChangeNodes( nodes, nbnodes );
1505 MESSAGE ( "WRONG ELEM TYPE");
1508 if ( Ok ) { // update InverseElements
1510 set<const SMDS_MeshElement*>::iterator it;
1512 // AddInverseElement to new nodes
1513 for ( int i = 0; i < nbnodes; i++ ) {
1514 it = oldNodes.find( nodes[i] );
1515 if ( it == oldNodes.end() )
1517 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1519 // remove from oldNodes a node that remains in elem
1520 oldNodes.erase( it );
1522 // RemoveInverseElement from the nodes removed from elem
1523 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1525 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1526 (const_cast<SMDS_MeshElement *>( *it ));
1527 n->RemoveInverseElement( elem );
1531 if ( !element->IsPoly() )
1532 myInfo.add( element ); // element may change type
1537 //=======================================================================
1538 //function : ChangePolyhedronNodes
1539 //purpose : to change nodes of polyhedral volume
1540 //=======================================================================
1541 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1542 const vector<const SMDS_MeshNode*>& nodes,
1543 const vector<int> & quantities)
1545 if (elem->GetType() != SMDSAbs_Volume) {
1546 MESSAGE("WRONG ELEM TYPE");
1550 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1555 // keep current nodes of elem
1556 set<const SMDS_MeshElement*> oldNodes;
1557 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1558 while (itn->more()) {
1559 oldNodes.insert(itn->next());
1563 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1568 // update InverseElements
1570 // AddInverseElement to new nodes
1571 int nbnodes = nodes.size();
1572 set<const SMDS_MeshElement*>::iterator it;
1573 for (int i = 0; i < nbnodes; i++) {
1574 it = oldNodes.find(nodes[i]);
1575 if (it == oldNodes.end()) {
1577 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1579 // remove from oldNodes a node that remains in elem
1584 // RemoveInverseElement from the nodes removed from elem
1585 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1586 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1587 (const_cast<SMDS_MeshElement *>( *it ));
1588 n->RemoveInverseElement(elem);
1595 //=======================================================================
1596 //function : Find0DElement
1598 //=======================================================================
1599 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1601 const SMDS_MeshNode * node = FindNode(idnode);
1602 if(node == NULL) return NULL;
1603 return Find0DElement(node);
1606 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1608 if (!node) return 0;
1609 const SMDS_Mesh0DElement* toReturn = NULL;
1610 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1611 while (it1->more() && (toReturn == NULL)) {
1612 const SMDS_MeshElement* e = it1->next();
1613 if (e->NbNodes() == 1) {
1614 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1620 //=======================================================================
1621 //function : Find0DElementOrCreate
1623 //=======================================================================
1624 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1626 // if (!node) return 0;
1627 // SMDS_Mesh0DElement * toReturn = NULL;
1628 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1629 // if (toReturn == NULL) {
1630 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1631 // toReturn = new SMDS_Mesh0DElement(node);
1632 // my0DElements.Add(toReturn);
1633 // myInfo.myNb0DElements++;
1639 //=======================================================================
1640 //function : FindEdge
1642 //=======================================================================
1644 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1646 const SMDS_MeshNode * node1=FindNode(idnode1);
1647 const SMDS_MeshNode * node2=FindNode(idnode2);
1648 if((node1==NULL)||(node2==NULL)) return NULL;
1649 return FindEdge(node1,node2);
1652 //#include "Profiler.h"
1653 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1654 const SMDS_MeshNode * node2)
1656 if ( !node1 ) return 0;
1657 const SMDS_MeshEdge * toReturn=NULL;
1660 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1663 while(it1->more()) {
1664 const SMDS_MeshElement * e = it1->next();
1665 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1666 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1675 //=======================================================================
1676 //function : FindEdgeOrCreate
1678 //=======================================================================
1680 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1681 const SMDS_MeshNode * node2)
1683 if ( !node1 || !node2) return 0;
1684 SMDS_MeshEdge * toReturn=NULL;
1685 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1686 if(toReturn==NULL) {
1687 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1688 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1689 adjustmyCellsCapacity(ID);
1690 vector<vtkIdType> nodeIds;
1692 nodeIds.push_back(node1->getId());
1693 nodeIds.push_back(node2->getId());
1695 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1696 edgevtk->init(nodeIds, this);
1698 myCells[ID] = toReturn;
1705 //=======================================================================
1706 //function : FindEdge
1708 //=======================================================================
1710 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1713 const SMDS_MeshNode * node1=FindNode(idnode1);
1714 const SMDS_MeshNode * node2=FindNode(idnode2);
1715 const SMDS_MeshNode * node3=FindNode(idnode3);
1716 return FindEdge(node1,node2,node3);
1719 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1720 const SMDS_MeshNode * node2,
1721 const SMDS_MeshNode * node3)
1723 if ( !node1 ) return 0;
1724 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1725 while(it1->more()) {
1726 const SMDS_MeshElement * e = it1->next();
1727 if ( e->NbNodes() == 3 ) {
1728 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1729 while(it2->more()) {
1730 const SMDS_MeshElement* n = it2->next();
1740 return static_cast<const SMDS_MeshEdge *> (e);
1747 //=======================================================================
1748 //function : FindFace
1750 //=======================================================================
1752 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1755 const SMDS_MeshNode * node1=FindNode(idnode1);
1756 const SMDS_MeshNode * node2=FindNode(idnode2);
1757 const SMDS_MeshNode * node3=FindNode(idnode3);
1758 return FindFace(node1, node2, node3);
1761 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1762 const SMDS_MeshNode *node2,
1763 const SMDS_MeshNode *node3)
1765 if ( !node1 ) return 0;
1766 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1767 while(it1->more()) {
1768 const SMDS_MeshElement * e = it1->next();
1769 if ( e->NbNodes() == 3 ) {
1770 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1771 while(it2->more()) {
1772 const SMDS_MeshElement* n = it2->next();
1782 return static_cast<const SMDS_MeshFace *> (e);
1788 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1789 const SMDS_MeshNode *node2,
1790 const SMDS_MeshNode *node3)
1792 SMDS_MeshFace * toReturn=NULL;
1793 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1794 if(toReturn==NULL) {
1795 int ID = myElementIDFactory->GetFreeID();
1796 toReturn = createTriangle(node1,node2,node3, ID);
1802 //=======================================================================
1803 //function : FindFace
1805 //=======================================================================
1807 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1808 int idnode3, int idnode4) const
1810 const SMDS_MeshNode * node1=FindNode(idnode1);
1811 const SMDS_MeshNode * node2=FindNode(idnode2);
1812 const SMDS_MeshNode * node3=FindNode(idnode3);
1813 const SMDS_MeshNode * node4=FindNode(idnode4);
1814 return FindFace(node1, node2, node3, node4);
1817 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1818 const SMDS_MeshNode *node2,
1819 const SMDS_MeshNode *node3,
1820 const SMDS_MeshNode *node4)
1822 if ( !node1 ) return 0;
1823 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1824 while(it1->more()) {
1825 const SMDS_MeshElement * e = it1->next();
1826 if ( e->NbNodes() == 4 ) {
1827 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1828 while(it2->more()) {
1829 const SMDS_MeshElement* n = it2->next();
1840 return static_cast<const SMDS_MeshFace *> (e);
1846 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1847 const SMDS_MeshNode *node2,
1848 const SMDS_MeshNode *node3,
1849 const SMDS_MeshNode *node4)
1851 SMDS_MeshFace * toReturn=NULL;
1852 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1853 if(toReturn==NULL) {
1854 int ID = myElementIDFactory->GetFreeID();
1855 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1861 //=======================================================================
1862 //function : FindFace
1863 //purpose :quadratic triangle
1864 //=======================================================================
1866 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1867 int idnode3, int idnode4,
1868 int idnode5, int idnode6) const
1870 const SMDS_MeshNode * node1 = FindNode(idnode1);
1871 const SMDS_MeshNode * node2 = FindNode(idnode2);
1872 const SMDS_MeshNode * node3 = FindNode(idnode3);
1873 const SMDS_MeshNode * node4 = FindNode(idnode4);
1874 const SMDS_MeshNode * node5 = FindNode(idnode5);
1875 const SMDS_MeshNode * node6 = FindNode(idnode6);
1876 return FindFace(node1, node2, node3, node4, node5, node6);
1879 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1880 const SMDS_MeshNode *node2,
1881 const SMDS_MeshNode *node3,
1882 const SMDS_MeshNode *node4,
1883 const SMDS_MeshNode *node5,
1884 const SMDS_MeshNode *node6)
1886 if ( !node1 ) return 0;
1887 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1888 while(it1->more()) {
1889 const SMDS_MeshElement * e = it1->next();
1890 if ( e->NbNodes() == 6 ) {
1891 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1892 while(it2->more()) {
1893 const SMDS_MeshElement* n = it2->next();
1906 return static_cast<const SMDS_MeshFace *> (e);
1913 //=======================================================================
1914 //function : FindFace
1915 //purpose : quadratic quadrangle
1916 //=======================================================================
1918 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1919 int idnode3, int idnode4,
1920 int idnode5, int idnode6,
1921 int idnode7, int idnode8) const
1923 const SMDS_MeshNode * node1 = FindNode(idnode1);
1924 const SMDS_MeshNode * node2 = FindNode(idnode2);
1925 const SMDS_MeshNode * node3 = FindNode(idnode3);
1926 const SMDS_MeshNode * node4 = FindNode(idnode4);
1927 const SMDS_MeshNode * node5 = FindNode(idnode5);
1928 const SMDS_MeshNode * node6 = FindNode(idnode6);
1929 const SMDS_MeshNode * node7 = FindNode(idnode7);
1930 const SMDS_MeshNode * node8 = FindNode(idnode8);
1931 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1934 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1935 const SMDS_MeshNode *node2,
1936 const SMDS_MeshNode *node3,
1937 const SMDS_MeshNode *node4,
1938 const SMDS_MeshNode *node5,
1939 const SMDS_MeshNode *node6,
1940 const SMDS_MeshNode *node7,
1941 const SMDS_MeshNode *node8)
1943 if ( !node1 ) return 0;
1944 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1945 while(it1->more()) {
1946 const SMDS_MeshElement * e = it1->next();
1947 if ( e->NbNodes() == 8 ) {
1948 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1949 while(it2->more()) {
1950 const SMDS_MeshElement* n = it2->next();
1965 return static_cast<const SMDS_MeshFace *> (e);
1972 //=======================================================================
1973 //function : FindElement
1975 //=======================================================================
1977 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1979 if ((IDelem < 0) || IDelem >= myCells.size())
1981 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
1985 return myCells[IDelem];
1988 //=======================================================================
1989 //function : FindFace
1990 //purpose : find polygon
1991 //=======================================================================
1993 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1995 int nbnodes = nodes_ids.size();
1996 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1997 for (int inode = 0; inode < nbnodes; inode++) {
1998 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1999 if (node == NULL) return NULL;
2000 poly_nodes[inode] = node;
2002 return FindFace(poly_nodes);
2005 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
2007 if ( nodes.size() > 2 && nodes[0] ) {
2008 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
2009 while (itF->more()) {
2010 const SMDS_MeshElement* f = itF->next();
2011 if ( f->NbNodes() == nodes.size() ) {
2012 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
2013 while(it2->more()) {
2014 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
2020 return static_cast<const SMDS_MeshFace *> (f);
2027 //=======================================================================
2028 //function : DumpNodes
2030 //=======================================================================
2032 void SMDS_Mesh::DumpNodes() const
2034 MESSAGE("dump nodes of mesh : ");
2035 SMDS_NodeIteratorPtr itnode=nodesIterator();
2036 while(itnode->more()) ; //MESSAGE(itnode->next());
2039 //=======================================================================
2040 //function : Dump0DElements
2042 //=======================================================================
2043 void SMDS_Mesh::Dump0DElements() const
2045 MESSAGE("dump 0D elements of mesh : ");
2046 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2047 while(it0d->more()) ; //MESSAGE(it0d->next());
2050 //=======================================================================
2051 //function : DumpEdges
2053 //=======================================================================
2055 void SMDS_Mesh::DumpEdges() const
2057 MESSAGE("dump edges of mesh : ");
2058 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2059 while(itedge->more()) ; //MESSAGE(itedge->next());
2062 //=======================================================================
2063 //function : DumpFaces
2065 //=======================================================================
2067 void SMDS_Mesh::DumpFaces() const
2069 MESSAGE("dump faces of mesh : ");
2070 SMDS_FaceIteratorPtr itface=facesIterator();
2071 while(itface->more()) ; //MESSAGE(itface->next());
2074 //=======================================================================
2075 //function : DumpVolumes
2077 //=======================================================================
2079 void SMDS_Mesh::DumpVolumes() const
2081 MESSAGE("dump volumes of mesh : ");
2082 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2083 while(itvol->more()) ; //MESSAGE(itvol->next());
2086 //=======================================================================
2087 //function : DebugStats
2089 //=======================================================================
2091 void SMDS_Mesh::DebugStats() const
2093 MESSAGE("Debug stats of mesh : ");
2095 MESSAGE("===== NODES ====="<<NbNodes());
2096 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2097 MESSAGE("===== EDGES ====="<<NbEdges());
2098 MESSAGE("===== FACES ====="<<NbFaces());
2099 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2101 MESSAGE("End Debug stats of mesh ");
2105 SMDS_NodeIteratorPtr itnode=nodesIterator();
2106 int sizeofnodes = 0;
2107 int sizeoffaces = 0;
2109 while(itnode->more())
2111 const SMDS_MeshNode *node = itnode->next();
2113 sizeofnodes += sizeof(*node);
2115 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2118 const SMDS_MeshElement *me = it->next();
2119 sizeofnodes += sizeof(me);
2123 SMDS_FaceIteratorPtr itface=facesIterator();
2124 while(itface->more())
2126 const SMDS_MeshElement *face = itface->next();
2127 sizeoffaces += sizeof(*face);
2130 MESSAGE("total size of node elements = " << sizeofnodes);;
2131 MESSAGE("total size of face elements = " << sizeoffaces);;
2136 ///////////////////////////////////////////////////////////////////////////////
2137 /// Return the number of nodes
2138 ///////////////////////////////////////////////////////////////////////////////
2139 int SMDS_Mesh::NbNodes() const
2141 //MESSAGE(myGrid->GetNumberOfPoints());
2142 //MESSAGE(myInfo.NbNodes());
2143 //MESSAGE(myNodeMax);
2144 return myInfo.NbNodes();
2147 ///////////////////////////////////////////////////////////////////////////////
2148 /// Return the number of 0D elements
2149 ///////////////////////////////////////////////////////////////////////////////
2150 int SMDS_Mesh::Nb0DElements() const
2152 return myInfo.Nb0DElements(); // -PR- a verfier
2155 ///////////////////////////////////////////////////////////////////////////////
2156 /// Return the number of edges (including construction edges)
2157 ///////////////////////////////////////////////////////////////////////////////
2158 int SMDS_Mesh::NbEdges() const
2160 return myInfo.NbEdges(); // -PR- a verfier
2163 ///////////////////////////////////////////////////////////////////////////////
2164 /// Return the number of faces (including construction faces)
2165 ///////////////////////////////////////////////////////////////////////////////
2166 int SMDS_Mesh::NbFaces() const
2168 return myInfo.NbFaces(); // -PR- a verfier
2171 ///////////////////////////////////////////////////////////////////////////////
2172 /// Return the number of volumes
2173 ///////////////////////////////////////////////////////////////////////////////
2174 int SMDS_Mesh::NbVolumes() const
2176 return myInfo.NbVolumes(); // -PR- a verfier
2179 ///////////////////////////////////////////////////////////////////////////////
2180 /// Return the number of child mesh of this mesh.
2181 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2182 /// (2003-09-08) of SMESH
2183 ///////////////////////////////////////////////////////////////////////////////
2184 int SMDS_Mesh::NbSubMesh() const
2186 return myChildren.size();
2189 ///////////////////////////////////////////////////////////////////////////////
2190 /// Destroy the mesh and all its elements
2191 /// All pointer on elements owned by this mesh become illegals.
2192 ///////////////////////////////////////////////////////////////////////////////
2193 SMDS_Mesh::~SMDS_Mesh()
2195 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2196 while(itc!=myChildren.end())
2204 delete myNodeIDFactory;
2205 delete myElementIDFactory;
2209 SMDS_ElemIteratorPtr eIt = elementsIterator();
2210 while ( eIt->more() )
2211 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2212 SMDS_NodeIteratorPtr itn = nodesIterator();
2214 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2217 // SetOfNodes::Iterator itn(myNodes);
2218 // for (; itn.More(); itn.Next())
2219 // delete itn.Value();
2221 // SetOf0DElements::Iterator it0d (my0DElements);
2222 // for (; it0d.More(); it0d.Next())
2224 // SMDS_MeshElement* elem = it0d.Value();
2228 // SetOfEdges::Iterator ite(myEdges);
2229 // for (; ite.More(); ite.Next())
2231 // SMDS_MeshElement* elem = ite.Value();
2235 // SetOfFaces::Iterator itf(myFaces);
2236 // for (; itf.More(); itf.Next())
2238 // SMDS_MeshElement* elem = itf.Value();
2242 // SetOfVolumes::Iterator itv(myVolumes);
2243 // for (; itv.More(); itv.Next())
2245 // SMDS_MeshElement* elem = itv.Value();
2250 //================================================================================
2252 * \brief Clear all data
2254 //================================================================================
2256 void SMDS_Mesh::Clear()
2258 if (myParent!=NULL) {
2259 SMDS_ElemIteratorPtr eIt = elementsIterator();
2260 while ( eIt->more() )
2261 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2262 SMDS_NodeIteratorPtr itn = nodesIterator();
2264 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2267 myNodeIDFactory->Clear();
2268 myElementIDFactory->Clear();
2271 SMDS_ElemIteratorPtr itv = elementsIterator();
2276 // SMDS_VolumeIteratorPtr itv = volumesIterator();
2277 // while (itv->more())
2278 // delete itv->next();
2279 // myVolumes.Clear();
2281 // SMDS_FaceIteratorPtr itf = facesIterator();
2282 // while (itf->more())
2283 // delete itf->next();
2286 // SMDS_EdgeIteratorPtr ite = edgesIterator();
2287 // while (ite->more())
2288 // delete ite->next();
2291 // SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2292 // while (it0d->more())
2293 // delete it0d->next();
2294 // my0DElements.Clear();
2296 SMDS_NodeIteratorPtr itn = nodesIterator();
2301 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2302 while(itc!=myChildren.end())
2308 ///////////////////////////////////////////////////////////////////////////////
2309 /// Return true if this mesh create faces with edges.
2310 /// A false returned value mean that faces are created with nodes. A concequence
2311 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2312 ///////////////////////////////////////////////////////////////////////////////
2313 bool SMDS_Mesh::hasConstructionEdges()
2315 return myHasConstructionEdges;
2318 ///////////////////////////////////////////////////////////////////////////////
2319 /// Return true if this mesh create volumes with faces
2320 /// A false returned value mean that volumes are created with nodes or edges.
2321 /// (see hasConstructionEdges)
2322 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2324 ///////////////////////////////////////////////////////////////////////////////
2325 bool SMDS_Mesh::hasConstructionFaces()
2327 return myHasConstructionFaces;
2330 ///////////////////////////////////////////////////////////////////////////////
2331 /// Return true if nodes are linked to the finit elements, they are belonging to.
2332 /// Currently, It always return true.
2333 ///////////////////////////////////////////////////////////////////////////////
2334 bool SMDS_Mesh::hasInverseElements()
2336 return myHasInverseElements;
2339 ///////////////////////////////////////////////////////////////////////////////
2340 /// Make this mesh creating construction edges (see hasConstructionEdges)
2341 /// @param b true to have construction edges, else false.
2342 ///////////////////////////////////////////////////////////////////////////////
2343 void SMDS_Mesh::setConstructionEdges(bool b)
2345 myHasConstructionEdges=b;
2348 ///////////////////////////////////////////////////////////////////////////////
2349 /// Make this mesh creating construction faces (see hasConstructionFaces)
2350 /// @param b true to have construction faces, else false.
2351 ///////////////////////////////////////////////////////////////////////////////
2352 void SMDS_Mesh::setConstructionFaces(bool b)
2354 myHasConstructionFaces=b;
2357 ///////////////////////////////////////////////////////////////////////////////
2358 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2359 /// @param b true to link nodes to elements, else false.
2360 ///////////////////////////////////////////////////////////////////////////////
2361 void SMDS_Mesh::setInverseElements(bool b)
2363 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2364 myHasInverseElements=b;
2367 ///////////////////////////////////////////////////////////////////////////////
2368 ///Iterator on NCollection_Map
2369 ///////////////////////////////////////////////////////////////////////////////
2370 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2371 struct MYNode_Map_Iterator: public FATHER
2375 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2382 while (_ctr < _map.size())
2393 ELEM current = _map[_ctr];
2399 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2400 struct MYElem_Map_Iterator: public FATHER
2405 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2413 while (_ctr < _map.size())
2416 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2425 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2431 ///////////////////////////////////////////////////////////////////////////////
2432 /// Return an iterator on nodes of the current mesh factory
2433 ///////////////////////////////////////////////////////////////////////////////
2435 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2437 //return SMDS_NodeIteratorPtr
2438 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2439 typedef MYNode_Map_Iterator
2440 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2441 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2444 ///////////////////////////////////////////////////////////////////////////////
2445 ///Return an iterator on 0D elements of the current mesh.
2446 ///////////////////////////////////////////////////////////////////////////////
2448 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2450 typedef MYElem_Map_Iterator
2451 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2452 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2455 ///////////////////////////////////////////////////////////////////////////////
2456 ///Return an iterator on edges of the current mesh.
2457 ///////////////////////////////////////////////////////////////////////////////
2459 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2461 typedef MYElem_Map_Iterator
2462 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2463 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2466 ///////////////////////////////////////////////////////////////////////////////
2467 ///Return an iterator on faces of the current mesh.
2468 ///////////////////////////////////////////////////////////////////////////////
2470 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2472 typedef MYElem_Map_Iterator
2473 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2474 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2477 ///////////////////////////////////////////////////////////////////////////////
2478 ///Return an iterator on volumes of the current mesh.
2479 ///////////////////////////////////////////////////////////////////////////////
2481 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2483 typedef MYElem_Map_Iterator
2484 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2485 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2488 ///////////////////////////////////////////////////////////////////////////////
2489 /// Return an iterator on elements of the current mesh factory
2490 ///////////////////////////////////////////////////////////////////////////////
2491 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2495 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2497 case SMDSAbs_Volume:
2498 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2500 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2502 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2503 case SMDSAbs_0DElement:
2504 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2506 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2507 //return myNodeIDFactory->elementsIterator();
2510 return myElementIDFactory->elementsIterator();
2513 ///////////////////////////////////////////////////////////////////////////////
2514 /// Do intersection of sets (more than 2)
2515 ///////////////////////////////////////////////////////////////////////////////
2516 static set<const SMDS_MeshElement*> * intersectionOfSets(
2517 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2519 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2520 set<const SMDS_MeshElement*>* rsetB;
2522 for(int i=0; i<numberOfSets-1; i++)
2524 rsetB=new set<const SMDS_MeshElement*>();
2526 rsetA->begin(), rsetA->end(),
2527 vs[i+1].begin(), vs[i+1].end(),
2528 inserter(*rsetB, rsetB->begin()));
2535 ///////////////////////////////////////////////////////////////////////////////
2536 /// Return the list of finite elements owning the given element: elements
2537 /// containing all the nodes of the given element, for instance faces and
2538 /// volumes containing a given edge.
2539 ///////////////////////////////////////////////////////////////////////////////
2540 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2542 int numberOfSets=element->NbNodes();
2543 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2545 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2548 while(itNodes->more())
2550 const SMDS_MeshElement* node = itNodes->next();
2552 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2553 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2555 //initSet[i]=set<const SMDS_MeshElement*>();
2558 const SMDS_MeshElement* elem = itFe->next();
2560 initSet[i].insert(elem);
2566 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2567 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2572 ///////////////////////////////////////////////////////////////////////////////
2573 /// Return the list of nodes used only by the given elements
2574 ///////////////////////////////////////////////////////////////////////////////
2575 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2576 set<const SMDS_MeshElement*>& elements)
2578 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2579 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2581 while(itElements!=elements.end())
2583 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2586 while(itNodes->more())
2588 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2589 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2590 set<const SMDS_MeshElement*> s;
2592 s.insert(itFe->next());
2593 if(s==elements) toReturn->insert(n);
2599 ///////////////////////////////////////////////////////////////////////////////
2600 ///Find the children of an element that are made of given nodes
2601 ///@param setOfChildren The set in which matching children will be inserted
2602 ///@param element The element were to search matching children
2603 ///@param nodes The nodes that the children must have to be selected
2604 ///////////////////////////////////////////////////////////////////////////////
2605 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2606 const SMDS_MeshElement * element,
2607 set<const SMDS_MeshElement*>& nodes)
2609 switch(element->GetType())
2612 MESSAGE("Internal Error: This should not happend");
2614 case SMDSAbs_0DElement:
2620 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2623 const SMDS_MeshElement * e=itn->next();
2624 if(nodes.find(e)!=nodes.end())
2626 setOfChildren.insert(element);
2633 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2636 const SMDS_MeshElement * e=itn->next();
2637 if(nodes.find(e)!=nodes.end())
2639 setOfChildren.insert(element);
2643 if(hasConstructionEdges())
2645 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2647 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2650 case SMDSAbs_Volume:
2652 if(hasConstructionFaces())
2654 SMDS_ElemIteratorPtr ite=element->facesIterator();
2656 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2658 else if(hasConstructionEdges())
2660 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2662 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2668 ///////////////////////////////////////////////////////////////////////////////
2669 ///@param elem The element to delete
2670 ///@param removenodes if true remaining nodes will be removed
2671 ///////////////////////////////////////////////////////////////////////////////
2672 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2673 const bool removenodes)
2675 list<const SMDS_MeshElement *> removedElems;
2676 list<const SMDS_MeshElement *> removedNodes;
2677 RemoveElement( elem, removedElems, removedNodes, removenodes );
2680 ///////////////////////////////////////////////////////////////////////////////
2681 ///@param elem The element to delete
2682 ///@param removedElems to be filled with all removed elements
2683 ///@param removedNodes to be filled with all removed nodes
2684 ///@param removenodes if true remaining nodes will be removed
2685 ///////////////////////////////////////////////////////////////////////////////
2686 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2687 list<const SMDS_MeshElement *>& removedElems,
2688 list<const SMDS_MeshElement *>& removedNodes,
2691 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2692 // get finite elements built on elem
2693 set<const SMDS_MeshElement*> * s1;
2694 if (elem->GetType() == SMDSAbs_0DElement ||
2695 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2696 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2697 elem->GetType() == SMDSAbs_Volume)
2699 s1 = new set<const SMDS_MeshElement*>();
2703 s1 = getFinitElements(elem);
2705 // get exclusive nodes (which would become free afterwards)
2706 set<const SMDS_MeshElement*> * s2;
2707 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2709 // do not remove nodes except elem
2710 s2 = new set<const SMDS_MeshElement*>();
2715 s2 = getExclusiveNodes(*s1);
2717 // form the set of finite and construction elements to remove
2718 set<const SMDS_MeshElement*> s3;
2719 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2720 while(it!=s1->end())
2722 addChildrenWithNodes(s3, *it ,*s2);
2726 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2728 // remove finite and construction elements
2732 // Remove element from <InverseElements> of its nodes
2733 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2736 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2737 (const_cast<SMDS_MeshElement *>(itn->next()));
2738 n->RemoveInverseElement( (*it) );
2741 switch((*it)->GetType())
2744 MYASSERT("Internal Error: This should not happen");
2746 case SMDSAbs_0DElement:
2747 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2749 removedElems.push_back( (*it) );
2750 myElementIDFactory->ReleaseID((*it)->GetID());
2754 myCells[(*it)->GetID()] = 0;
2755 myInfo.RemoveEdge(*it);
2756 removedElems.push_back( (*it) );
2757 myElementIDFactory->ReleaseID((*it)->GetID());
2758 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
2759 myEdgePool->destroy((SMDS_VtkEdge*)vtkElem);
2763 myCells[(*it)->GetID()] = 0;
2764 myInfo.RemoveFace(*it);
2765 removedElems.push_back( (*it) );
2766 myElementIDFactory->ReleaseID((*it)->GetID());
2767 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
2768 myFacePool->destroy((SMDS_VtkFace*)vtkElem);
2771 case SMDSAbs_Volume:
2772 myCells[(*it)->GetID()] = 0;
2773 myInfo.RemoveVolume(*it);
2774 removedElems.push_back( (*it) );
2775 myElementIDFactory->ReleaseID((*it)->GetID());
2776 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
2777 myVolumePool->destroy((SMDS_VtkVolume*)vtkElem);
2784 // remove exclusive (free) nodes
2788 while(it!=s2->end())
2790 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2791 myNodes[(*it)->GetID()] = 0;
2793 myNodeIDFactory->ReleaseID((*it)->GetID());
2794 removedNodes.push_back( (*it) );
2795 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
2796 myNodePool->destroy((SMDS_MeshNode*)vtkElem);
2807 ///////////////////////////////////////////////////////////////////////////////
2808 ///@param elem The element to delete
2809 ///////////////////////////////////////////////////////////////////////////////
2810 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2812 int elemId = elem->GetID();
2813 //MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2814 SMDSAbs_ElementType aType = elem->GetType();
2815 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2816 if (aType == SMDSAbs_Node) {
2817 // only free node can be removed by this method
2818 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2819 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2820 if (!itFe->more()) { // free node
2821 myNodes[elemId] = 0;
2823 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2824 myNodeIDFactory->ReleaseID(elemId);
2827 if (hasConstructionEdges() || hasConstructionFaces())
2828 // this methods is only for meshes without descendants
2831 int vtkid = this->fromSmdsToVtk(elemId);
2833 // Remove element from <InverseElements> of its nodes
2834 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2835 while (itn->more()) {
2836 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2837 (const_cast<SMDS_MeshElement *>(itn->next()));
2838 n->RemoveInverseElement(elem);
2841 // in meshes without descendants elements are always free
2843 case SMDSAbs_0DElement:
2844 myCells[elemId] = 0;
2845 myInfo.remove(elem);
2849 myCells[elemId] = 0;
2850 myInfo.RemoveEdge(elem);
2851 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2854 myCells[elemId] = 0;
2855 myInfo.RemoveFace(elem);
2856 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2858 case SMDSAbs_Volume:
2859 myCells[elemId] = 0;
2860 myInfo.RemoveVolume(elem);
2861 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2866 myElementIDFactory->ReleaseID(elemId);
2868 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2869 // --- to do: keep vtkid in a list of reusable cells
2874 * Checks if the element is present in mesh.
2875 * Useful to determine dead pointers.
2877 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2879 // we should not imply on validity of *elem, so iterate on containers
2880 // of all types in the hope of finding <elem> somewhere there
2881 SMDS_NodeIteratorPtr itn = nodesIterator();
2883 if (elem == itn->next())
2885 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2886 while (it0d->more())
2887 if (elem == it0d->next())
2889 SMDS_EdgeIteratorPtr ite = edgesIterator();
2891 if (elem == ite->next())
2893 SMDS_FaceIteratorPtr itf = facesIterator();
2895 if (elem == itf->next())
2897 SMDS_VolumeIteratorPtr itv = volumesIterator();
2899 if (elem == itv->next())
2904 //=======================================================================
2905 //function : MaxNodeID
2907 //=======================================================================
2909 int SMDS_Mesh::MaxNodeID() const
2914 //=======================================================================
2915 //function : MinNodeID
2917 //=======================================================================
2919 int SMDS_Mesh::MinNodeID() const
2924 //=======================================================================
2925 //function : MaxElementID
2927 //=======================================================================
2929 int SMDS_Mesh::MaxElementID() const
2931 return myElementIDFactory->GetMaxID();
2934 //=======================================================================
2935 //function : MinElementID
2937 //=======================================================================
2939 int SMDS_Mesh::MinElementID() const
2941 return myElementIDFactory->GetMinID();
2944 //=======================================================================
2945 //function : Renumber
2946 //purpose : Renumber all nodes or elements.
2947 //=======================================================================
2949 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2951 MESSAGE("Renumber");
2955 SMDS_MeshNodeIDFactory * idFactory =
2956 isNodes ? myNodeIDFactory : myElementIDFactory;
2958 // get existing elements in the order of ID increasing
2959 map<int,SMDS_MeshElement*> elemMap;
2960 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2961 while ( idElemIt->more() ) {
2962 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2963 int id = elem->GetID();
2964 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2966 // release their ids
2967 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2969 // for ( ; elemIt != elemMap.end(); elemIt++ )
2971 // int id = (*elemIt).first;
2972 // idFactory->ReleaseID( id );
2976 elemIt = elemMap.begin();
2977 for ( ; elemIt != elemMap.end(); elemIt++ )
2979 idFactory->BindID( ID, (*elemIt).second );
2984 //=======================================================================
2985 //function : GetElementType
2986 //purpose : Return type of element or node with id
2987 //=======================================================================
2989 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2991 SMDS_MeshElement* elem = 0;
2993 elem = myElementIDFactory->MeshElement( id );
2995 elem = myNodeIDFactory->MeshElement( id );
2999 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3003 return elem->GetType();
3008 //********************************************************************
3009 //********************************************************************
3010 //******** *********
3011 //***** Methods for addition of quadratic elements ******
3012 //******** *********
3013 //********************************************************************
3014 //********************************************************************
3016 //=======================================================================
3017 //function : AddEdgeWithID
3019 //=======================================================================
3020 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3022 return SMDS_Mesh::AddEdgeWithID
3023 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3024 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3025 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3029 //=======================================================================
3030 //function : AddEdge
3032 //=======================================================================
3033 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3034 const SMDS_MeshNode* n2,
3035 const SMDS_MeshNode* n12)
3037 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3040 //=======================================================================
3041 //function : AddEdgeWithID
3043 //=======================================================================
3044 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3045 const SMDS_MeshNode * n2,
3046 const SMDS_MeshNode * n12,
3049 if ( !n1 || !n2 || !n12 ) return 0;
3051 // --- retrieve nodes ID
3052 vector<vtkIdType> nodeIds;
3054 nodeIds.push_back(n1->getId());
3055 nodeIds.push_back(n2->getId());
3056 nodeIds.push_back(n12->getId());
3058 SMDS_MeshEdge * edge = 0;
3059 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3060 edgevtk->init(nodeIds, this);
3062 adjustmyCellsCapacity(ID);
3064 myInfo.myNbQuadEdges++;
3066 if (!registerElement(ID, edge)) {
3067 RemoveElement(edge, false);
3075 //=======================================================================
3076 //function : AddFace
3078 //=======================================================================
3079 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3080 const SMDS_MeshNode * n2,
3081 const SMDS_MeshNode * n3,
3082 const SMDS_MeshNode * n12,
3083 const SMDS_MeshNode * n23,
3084 const SMDS_MeshNode * n31)
3086 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3087 myElementIDFactory->GetFreeID());
3090 //=======================================================================
3091 //function : AddFaceWithID
3093 //=======================================================================
3094 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3095 int n12,int n23,int n31, int ID)
3097 return SMDS_Mesh::AddFaceWithID
3098 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3099 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3100 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3101 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3102 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3103 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3107 //=======================================================================
3108 //function : AddFaceWithID
3110 //=======================================================================
3111 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3112 const SMDS_MeshNode * n2,
3113 const SMDS_MeshNode * n3,
3114 const SMDS_MeshNode * n12,
3115 const SMDS_MeshNode * n23,
3116 const SMDS_MeshNode * n31,
3119 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3120 if(hasConstructionEdges()) {
3121 // creation quadratic edges - not implemented
3126 // --- retrieve nodes ID
3127 vector<vtkIdType> nodeIds;
3129 nodeIds.push_back(n1->getId());
3130 nodeIds.push_back(n2->getId());
3131 nodeIds.push_back(n3->getId());
3132 nodeIds.push_back(n12->getId());
3133 nodeIds.push_back(n23->getId());
3134 nodeIds.push_back(n31->getId());
3136 SMDS_MeshFace * face = 0;
3137 SMDS_VtkFace *facevtk = myFacePool->getNew();
3138 facevtk->init(nodeIds, this);
3140 adjustmyCellsCapacity(ID);
3142 myInfo.myNbQuadTriangles++;
3144 if (!registerElement(ID, face)) {
3145 RemoveElement(face, false);
3153 //=======================================================================
3154 //function : AddFace
3156 //=======================================================================
3157 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3158 const SMDS_MeshNode * n2,
3159 const SMDS_MeshNode * n3,
3160 const SMDS_MeshNode * n4,
3161 const SMDS_MeshNode * n12,
3162 const SMDS_MeshNode * n23,
3163 const SMDS_MeshNode * n34,
3164 const SMDS_MeshNode * n41)
3166 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3167 myElementIDFactory->GetFreeID());
3170 //=======================================================================
3171 //function : AddFaceWithID
3173 //=======================================================================
3174 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3175 int n12,int n23,int n34,int n41, int ID)
3177 return SMDS_Mesh::AddFaceWithID
3178 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3179 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3180 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3181 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3182 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3183 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3184 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3185 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3189 //=======================================================================
3190 //function : AddFaceWithID
3192 //=======================================================================
3193 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3194 const SMDS_MeshNode * n2,
3195 const SMDS_MeshNode * n3,
3196 const SMDS_MeshNode * n4,
3197 const SMDS_MeshNode * n12,
3198 const SMDS_MeshNode * n23,
3199 const SMDS_MeshNode * n34,
3200 const SMDS_MeshNode * n41,
3203 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3204 if(hasConstructionEdges()) {
3205 // creation quadratic edges - not implemented
3210 // --- retrieve nodes ID
3211 vector<vtkIdType> nodeIds;
3213 nodeIds.push_back(n1->getId());
3214 nodeIds.push_back(n2->getId());
3215 nodeIds.push_back(n3->getId());
3216 nodeIds.push_back(n4->getId());
3217 nodeIds.push_back(n12->getId());
3218 nodeIds.push_back(n23->getId());
3219 nodeIds.push_back(n34->getId());
3220 nodeIds.push_back(n41->getId());
3222 SMDS_MeshFace * face = 0;
3223 SMDS_VtkFace *facevtk = myFacePool->getNew();
3224 facevtk->init(nodeIds, this);
3226 adjustmyCellsCapacity(ID);
3228 myInfo.myNbQuadQuadrangles++;
3230 if (!registerElement(ID, face)) {
3231 RemoveElement(face, false);
3239 //=======================================================================
3240 //function : AddVolume
3242 //=======================================================================
3243 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3244 const SMDS_MeshNode * n2,
3245 const SMDS_MeshNode * n3,
3246 const SMDS_MeshNode * n4,
3247 const SMDS_MeshNode * n12,
3248 const SMDS_MeshNode * n23,
3249 const SMDS_MeshNode * n31,
3250 const SMDS_MeshNode * n14,
3251 const SMDS_MeshNode * n24,
3252 const SMDS_MeshNode * n34)
3254 int ID = myElementIDFactory->GetFreeID();
3255 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3256 n31, n14, n24, n34, ID);
3257 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3261 //=======================================================================
3262 //function : AddVolumeWithID
3264 //=======================================================================
3265 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3266 int n12,int n23,int n31,
3267 int n14,int n24,int n34, int ID)
3269 return SMDS_Mesh::AddVolumeWithID
3270 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3271 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3272 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3273 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3274 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3275 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3276 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3277 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3278 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3279 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3283 //=======================================================================
3284 //function : AddVolumeWithID
3285 //purpose : 2d order tetrahedron of 10 nodes
3286 //=======================================================================
3287 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3288 const SMDS_MeshNode * n2,
3289 const SMDS_MeshNode * n3,
3290 const SMDS_MeshNode * n4,
3291 const SMDS_MeshNode * n12,
3292 const SMDS_MeshNode * n23,
3293 const SMDS_MeshNode * n31,
3294 const SMDS_MeshNode * n14,
3295 const SMDS_MeshNode * n24,
3296 const SMDS_MeshNode * n34,
3299 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3301 if(hasConstructionFaces()) {
3302 // creation quadratic faces - not implemented
3305 // --- retrieve nodes ID
3306 vector<vtkIdType> nodeIds;
3308 nodeIds.push_back(n1->getId());
3309 nodeIds.push_back(n3->getId());
3310 nodeIds.push_back(n2->getId());
3311 nodeIds.push_back(n4->getId());
3313 nodeIds.push_back(n31->getId());
3314 nodeIds.push_back(n23->getId());
3315 nodeIds.push_back(n12->getId());
3317 nodeIds.push_back(n14->getId());
3318 nodeIds.push_back(n34->getId());
3319 nodeIds.push_back(n24->getId());
3321 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3322 volvtk->init(nodeIds, this);
3323 adjustmyCellsCapacity(ID);
3324 myCells[ID] = volvtk;
3325 myInfo.myNbQuadTetras++;
3327 if (!registerElement(ID, volvtk)) {
3328 RemoveElement(volvtk, false);
3335 //=======================================================================
3336 //function : AddVolume
3338 //=======================================================================
3339 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3340 const SMDS_MeshNode * n2,
3341 const SMDS_MeshNode * n3,
3342 const SMDS_MeshNode * n4,
3343 const SMDS_MeshNode * n5,
3344 const SMDS_MeshNode * n12,
3345 const SMDS_MeshNode * n23,
3346 const SMDS_MeshNode * n34,
3347 const SMDS_MeshNode * n41,
3348 const SMDS_MeshNode * n15,
3349 const SMDS_MeshNode * n25,
3350 const SMDS_MeshNode * n35,
3351 const SMDS_MeshNode * n45)
3353 int ID = myElementIDFactory->GetFreeID();
3354 SMDS_MeshVolume * v =
3355 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3356 n15, n25, n35, n45, ID);
3357 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3361 //=======================================================================
3362 //function : AddVolumeWithID
3364 //=======================================================================
3365 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3366 int n12,int n23,int n34,int n41,
3367 int n15,int n25,int n35,int n45, int ID)
3369 return SMDS_Mesh::AddVolumeWithID
3370 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3371 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3372 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3373 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3374 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3375 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3376 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3377 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3378 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3379 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3380 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3381 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3382 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3386 //=======================================================================
3387 //function : AddVolumeWithID
3388 //purpose : 2d order pyramid of 13 nodes
3389 //=======================================================================
3390 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3391 const SMDS_MeshNode * n2,
3392 const SMDS_MeshNode * n3,
3393 const SMDS_MeshNode * n4,
3394 const SMDS_MeshNode * n5,
3395 const SMDS_MeshNode * n12,
3396 const SMDS_MeshNode * n23,
3397 const SMDS_MeshNode * n34,
3398 const SMDS_MeshNode * n41,
3399 const SMDS_MeshNode * n15,
3400 const SMDS_MeshNode * n25,
3401 const SMDS_MeshNode * n35,
3402 const SMDS_MeshNode * n45,
3405 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3406 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3408 if(hasConstructionFaces()) {
3409 // creation quadratic faces - not implemented
3412 // --- retrieve nodes ID
3413 vector<vtkIdType> nodeIds;
3415 nodeIds.push_back(n1->getId());
3416 nodeIds.push_back(n4->getId());
3417 nodeIds.push_back(n3->getId());
3418 nodeIds.push_back(n2->getId());
3419 nodeIds.push_back(n5->getId());
3421 nodeIds.push_back(n41->getId());
3422 nodeIds.push_back(n34->getId());
3423 nodeIds.push_back(n23->getId());
3424 nodeIds.push_back(n12->getId());
3426 nodeIds.push_back(n15->getId());
3427 nodeIds.push_back(n45->getId());
3428 nodeIds.push_back(n35->getId());
3429 nodeIds.push_back(n25->getId());
3431 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3432 volvtk->init(nodeIds, this);
3433 adjustmyCellsCapacity(ID);
3434 myCells[ID] = volvtk;
3435 myInfo.myNbQuadPyramids++;
3437 if (!registerElement(ID, volvtk)) {
3438 RemoveElement(volvtk, false);
3445 //=======================================================================
3446 //function : AddVolume
3448 //=======================================================================
3449 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3450 const SMDS_MeshNode * n2,
3451 const SMDS_MeshNode * n3,
3452 const SMDS_MeshNode * n4,
3453 const SMDS_MeshNode * n5,
3454 const SMDS_MeshNode * n6,
3455 const SMDS_MeshNode * n12,
3456 const SMDS_MeshNode * n23,
3457 const SMDS_MeshNode * n31,
3458 const SMDS_MeshNode * n45,
3459 const SMDS_MeshNode * n56,
3460 const SMDS_MeshNode * n64,
3461 const SMDS_MeshNode * n14,
3462 const SMDS_MeshNode * n25,
3463 const SMDS_MeshNode * n36)
3465 int ID = myElementIDFactory->GetFreeID();
3466 SMDS_MeshVolume * v =
3467 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3468 n45, n56, n64, n14, n25, n36, ID);
3469 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3473 //=======================================================================
3474 //function : AddVolumeWithID
3476 //=======================================================================
3477 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3478 int n4, int n5, int n6,
3479 int n12,int n23,int n31,
3480 int n45,int n56,int n64,
3481 int n14,int n25,int n36, int ID)
3483 return SMDS_Mesh::AddVolumeWithID
3484 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3485 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3486 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3487 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3488 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3489 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3490 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3491 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3492 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3493 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3494 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3495 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3496 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3497 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3498 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3502 //=======================================================================
3503 //function : AddVolumeWithID
3504 //purpose : 2d order Pentahedron with 15 nodes
3505 //=======================================================================
3506 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3507 const SMDS_MeshNode * n2,
3508 const SMDS_MeshNode * n3,
3509 const SMDS_MeshNode * n4,
3510 const SMDS_MeshNode * n5,
3511 const SMDS_MeshNode * n6,
3512 const SMDS_MeshNode * n12,
3513 const SMDS_MeshNode * n23,
3514 const SMDS_MeshNode * n31,
3515 const SMDS_MeshNode * n45,
3516 const SMDS_MeshNode * n56,
3517 const SMDS_MeshNode * n64,
3518 const SMDS_MeshNode * n14,
3519 const SMDS_MeshNode * n25,
3520 const SMDS_MeshNode * n36,
3523 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3524 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3526 if(hasConstructionFaces()) {
3527 // creation quadratic faces - not implemented
3530 // --- retrieve nodes ID
3531 vector<vtkIdType> nodeIds;
3533 nodeIds.push_back(n1->getId());
3534 nodeIds.push_back(n2->getId());
3535 nodeIds.push_back(n3->getId());
3537 nodeIds.push_back(n4->getId());
3538 nodeIds.push_back(n5->getId());
3539 nodeIds.push_back(n6->getId());
3541 nodeIds.push_back(n12->getId());
3542 nodeIds.push_back(n23->getId());
3543 nodeIds.push_back(n31->getId());
3545 nodeIds.push_back(n45->getId());
3546 nodeIds.push_back(n56->getId());
3547 nodeIds.push_back(n64->getId());
3549 nodeIds.push_back(n14->getId());
3550 nodeIds.push_back(n25->getId());
3551 nodeIds.push_back(n36->getId());
3553 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3554 volvtk->init(nodeIds, this);
3555 adjustmyCellsCapacity(ID);
3556 myCells[ID] = volvtk;
3557 myInfo.myNbQuadPrisms++;
3559 if (!registerElement(ID, volvtk)) {
3560 RemoveElement(volvtk, false);
3567 //=======================================================================
3568 //function : AddVolume
3570 //=======================================================================
3571 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3572 const SMDS_MeshNode * n2,
3573 const SMDS_MeshNode * n3,
3574 const SMDS_MeshNode * n4,
3575 const SMDS_MeshNode * n5,
3576 const SMDS_MeshNode * n6,
3577 const SMDS_MeshNode * n7,
3578 const SMDS_MeshNode * n8,
3579 const SMDS_MeshNode * n12,
3580 const SMDS_MeshNode * n23,
3581 const SMDS_MeshNode * n34,
3582 const SMDS_MeshNode * n41,
3583 const SMDS_MeshNode * n56,
3584 const SMDS_MeshNode * n67,
3585 const SMDS_MeshNode * n78,
3586 const SMDS_MeshNode * n85,
3587 const SMDS_MeshNode * n15,
3588 const SMDS_MeshNode * n26,
3589 const SMDS_MeshNode * n37,
3590 const SMDS_MeshNode * n48)
3592 int ID = myElementIDFactory->GetFreeID();
3593 SMDS_MeshVolume * v =
3594 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3595 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3596 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3600 //=======================================================================
3601 //function : AddVolumeWithID
3603 //=======================================================================
3604 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3605 int n5, int n6, int n7, int n8,
3606 int n12,int n23,int n34,int n41,
3607 int n56,int n67,int n78,int n85,
3608 int n15,int n26,int n37,int n48, int ID)
3610 return SMDS_Mesh::AddVolumeWithID
3611 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3612 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3613 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3614 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3615 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3616 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3617 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3618 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3619 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3620 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3621 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3622 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3623 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3624 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3625 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3626 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3627 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3628 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3629 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3630 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3634 //=======================================================================
3635 //function : AddVolumeWithID
3636 //purpose : 2d order Hexahedrons with 20 nodes
3637 //=======================================================================
3638 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3639 const SMDS_MeshNode * n2,
3640 const SMDS_MeshNode * n3,
3641 const SMDS_MeshNode * n4,
3642 const SMDS_MeshNode * n5,
3643 const SMDS_MeshNode * n6,
3644 const SMDS_MeshNode * n7,
3645 const SMDS_MeshNode * n8,
3646 const SMDS_MeshNode * n12,
3647 const SMDS_MeshNode * n23,
3648 const SMDS_MeshNode * n34,
3649 const SMDS_MeshNode * n41,
3650 const SMDS_MeshNode * n56,
3651 const SMDS_MeshNode * n67,
3652 const SMDS_MeshNode * n78,
3653 const SMDS_MeshNode * n85,
3654 const SMDS_MeshNode * n15,
3655 const SMDS_MeshNode * n26,
3656 const SMDS_MeshNode * n37,
3657 const SMDS_MeshNode * n48,
3660 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3661 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3663 if(hasConstructionFaces()) {
3665 // creation quadratic faces - not implemented
3667 // --- retrieve nodes ID
3668 vector<vtkIdType> nodeIds;
3670 nodeIds.push_back(n1->getId());
3671 nodeIds.push_back(n4->getId());
3672 nodeIds.push_back(n3->getId());
3673 nodeIds.push_back(n2->getId());
3675 nodeIds.push_back(n5->getId());
3676 nodeIds.push_back(n8->getId());
3677 nodeIds.push_back(n7->getId());
3678 nodeIds.push_back(n6->getId());
3680 nodeIds.push_back(n41->getId());
3681 nodeIds.push_back(n34->getId());
3682 nodeIds.push_back(n23->getId());
3683 nodeIds.push_back(n12->getId());
3685 nodeIds.push_back(n85->getId());
3686 nodeIds.push_back(n78->getId());
3687 nodeIds.push_back(n67->getId());
3688 nodeIds.push_back(n56->getId());
3690 nodeIds.push_back(n15->getId());
3691 nodeIds.push_back(n48->getId());
3692 nodeIds.push_back(n37->getId());
3693 nodeIds.push_back(n26->getId());
3695 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3696 volvtk->init(nodeIds, this);
3697 adjustmyCellsCapacity(ID);
3698 myCells[ID] = volvtk;
3699 myInfo.myNbQuadHexas++;
3701 if (!registerElement(ID, volvtk)) {
3702 RemoveElement(volvtk, false);
3708 void SMDS_Mesh::updateNodeMinMax()
3711 if (myNodes.size() == 0)
3716 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3718 myNodeMax=myNodes.size()-1;
3719 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3723 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3725 int val = myIDElements.size();
3726 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3727 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3728 val = myNodes.size();
3729 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3730 myNodes.resize(val +nbNodes, 0);
3733 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3735 int val = myVtkIndex.size();
3736 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3737 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3738 val = myCells.size();
3739 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3740 myNodes.resize(val +nbCells, 0);
3743 void SMDS_Mesh::adjustStructure()
3745 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3748 void SMDS_Mesh::dumpGrid(string ficdump)
3750 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
3751 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
3752 // aWriter->SetFileName(ficdump.c_str());
3753 // aWriter->SetInput(myGrid);
3754 // if(myGrid->GetNumberOfCells())
3756 // aWriter->Write();
3758 // aWriter->Delete();
3759 ficdump = ficdump + "_connectivity";
3760 ofstream ficcon(ficdump.c_str(), ios::out);
3761 int nbPoints = myGrid->GetNumberOfPoints();
3762 ficcon << "-------------------------------- points " << nbPoints << endl;
3763 for (int i=0; i<nbPoints; i++)
3765 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
3767 int nbCells = myGrid->GetNumberOfCells();
3768 ficcon << "-------------------------------- cells " << nbCells << endl;
3769 for (int i=0; i<nbCells; i++)
3771 // MESSAGE(i << " " << myGrid->GetCell(i));
3772 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
3773 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
3774 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
3775 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
3776 for (int j=0; j<nbptcell; j++)
3778 ficcon << " " << listid->GetId(j);
3782 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
3783 vtkCellLinks *links = myGrid->GetCellLinks();
3784 for (int i=0; i<nbPoints; i++)
3786 int ncells = links->GetNcells(i);
3787 vtkIdType *cells = links->GetCells(i);
3788 ficcon << i << " - " << ncells << " -";
3789 for (int j=0; j<ncells; j++)
3791 ficcon << " " << cells[j];