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()
2260 SMDS_ElemIteratorPtr eIt = elementsIterator();
2261 while ( eIt->more() )
2262 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2263 SMDS_NodeIteratorPtr itn = nodesIterator();
2265 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2269 myNodeIDFactory->Clear();
2270 myElementIDFactory->Clear();
2273 SMDS_ElemIteratorPtr itv = elementsIterator();
2276 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2277 SMDSAbs_ElementType aType = elem->GetType();
2280 case SMDSAbs_0DElement:
2284 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2287 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2289 case SMDSAbs_Volume:
2290 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2298 SMDS_NodeIteratorPtr itn = nodesIterator();
2301 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2302 myNodePool->destroy(node);
2306 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2307 while(itc!=myChildren.end())
2312 myGrid->Initialize();
2314 vtkPoints* points = vtkPoints::New();
2315 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
2316 myGrid->SetPoints( points );
2318 myGrid->BuildLinks();
2321 ///////////////////////////////////////////////////////////////////////////////
2322 /// Return true if this mesh create faces with edges.
2323 /// A false returned value mean that faces are created with nodes. A concequence
2324 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2325 ///////////////////////////////////////////////////////////////////////////////
2326 bool SMDS_Mesh::hasConstructionEdges()
2328 return myHasConstructionEdges;
2331 ///////////////////////////////////////////////////////////////////////////////
2332 /// Return true if this mesh create volumes with faces
2333 /// A false returned value mean that volumes are created with nodes or edges.
2334 /// (see hasConstructionEdges)
2335 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2337 ///////////////////////////////////////////////////////////////////////////////
2338 bool SMDS_Mesh::hasConstructionFaces()
2340 return myHasConstructionFaces;
2343 ///////////////////////////////////////////////////////////////////////////////
2344 /// Return true if nodes are linked to the finit elements, they are belonging to.
2345 /// Currently, It always return true.
2346 ///////////////////////////////////////////////////////////////////////////////
2347 bool SMDS_Mesh::hasInverseElements()
2349 return myHasInverseElements;
2352 ///////////////////////////////////////////////////////////////////////////////
2353 /// Make this mesh creating construction edges (see hasConstructionEdges)
2354 /// @param b true to have construction edges, else false.
2355 ///////////////////////////////////////////////////////////////////////////////
2356 void SMDS_Mesh::setConstructionEdges(bool b)
2358 myHasConstructionEdges=b;
2361 ///////////////////////////////////////////////////////////////////////////////
2362 /// Make this mesh creating construction faces (see hasConstructionFaces)
2363 /// @param b true to have construction faces, else false.
2364 ///////////////////////////////////////////////////////////////////////////////
2365 void SMDS_Mesh::setConstructionFaces(bool b)
2367 myHasConstructionFaces=b;
2370 ///////////////////////////////////////////////////////////////////////////////
2371 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2372 /// @param b true to link nodes to elements, else false.
2373 ///////////////////////////////////////////////////////////////////////////////
2374 void SMDS_Mesh::setInverseElements(bool b)
2376 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2377 myHasInverseElements=b;
2380 ///////////////////////////////////////////////////////////////////////////////
2381 ///Iterator on NCollection_Map
2382 ///////////////////////////////////////////////////////////////////////////////
2383 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2384 struct MYNode_Map_Iterator: public FATHER
2388 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2395 while (_ctr < _map.size())
2406 ELEM current = _map[_ctr];
2412 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2413 struct MYElem_Map_Iterator: public FATHER
2418 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2426 while (_ctr < _map.size())
2429 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2438 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2444 ///////////////////////////////////////////////////////////////////////////////
2445 /// Return an iterator on nodes of the current mesh factory
2446 ///////////////////////////////////////////////////////////////////////////////
2448 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2450 //return SMDS_NodeIteratorPtr
2451 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2452 typedef MYNode_Map_Iterator
2453 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2454 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2457 ///////////////////////////////////////////////////////////////////////////////
2458 ///Return an iterator on 0D elements of the current mesh.
2459 ///////////////////////////////////////////////////////////////////////////////
2461 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2463 typedef MYElem_Map_Iterator
2464 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2465 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2468 ///////////////////////////////////////////////////////////////////////////////
2469 ///Return an iterator on edges of the current mesh.
2470 ///////////////////////////////////////////////////////////////////////////////
2472 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2474 typedef MYElem_Map_Iterator
2475 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2476 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2479 ///////////////////////////////////////////////////////////////////////////////
2480 ///Return an iterator on faces of the current mesh.
2481 ///////////////////////////////////////////////////////////////////////////////
2483 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2485 typedef MYElem_Map_Iterator
2486 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2487 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2490 ///////////////////////////////////////////////////////////////////////////////
2491 ///Return an iterator on volumes of the current mesh.
2492 ///////////////////////////////////////////////////////////////////////////////
2494 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2496 typedef MYElem_Map_Iterator
2497 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2498 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2501 ///////////////////////////////////////////////////////////////////////////////
2502 /// Return an iterator on elements of the current mesh factory
2503 ///////////////////////////////////////////////////////////////////////////////
2504 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2508 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2510 case SMDSAbs_Volume:
2511 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2513 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2515 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2516 case SMDSAbs_0DElement:
2517 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2519 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2520 //return myNodeIDFactory->elementsIterator();
2523 return myElementIDFactory->elementsIterator();
2526 ///////////////////////////////////////////////////////////////////////////////
2527 /// Do intersection of sets (more than 2)
2528 ///////////////////////////////////////////////////////////////////////////////
2529 static set<const SMDS_MeshElement*> * intersectionOfSets(
2530 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2532 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2533 set<const SMDS_MeshElement*>* rsetB;
2535 for(int i=0; i<numberOfSets-1; i++)
2537 rsetB=new set<const SMDS_MeshElement*>();
2539 rsetA->begin(), rsetA->end(),
2540 vs[i+1].begin(), vs[i+1].end(),
2541 inserter(*rsetB, rsetB->begin()));
2548 ///////////////////////////////////////////////////////////////////////////////
2549 /// Return the list of finite elements owning the given element: elements
2550 /// containing all the nodes of the given element, for instance faces and
2551 /// volumes containing a given edge.
2552 ///////////////////////////////////////////////////////////////////////////////
2553 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2555 int numberOfSets=element->NbNodes();
2556 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2558 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2561 while(itNodes->more())
2563 const SMDS_MeshElement* node = itNodes->next();
2565 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2566 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2568 //initSet[i]=set<const SMDS_MeshElement*>();
2571 const SMDS_MeshElement* elem = itFe->next();
2573 initSet[i].insert(elem);
2579 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2580 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2585 ///////////////////////////////////////////////////////////////////////////////
2586 /// Return the list of nodes used only by the given elements
2587 ///////////////////////////////////////////////////////////////////////////////
2588 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2589 set<const SMDS_MeshElement*>& elements)
2591 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2592 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2594 while(itElements!=elements.end())
2596 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2599 while(itNodes->more())
2601 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2602 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2603 set<const SMDS_MeshElement*> s;
2605 s.insert(itFe->next());
2606 if(s==elements) toReturn->insert(n);
2612 ///////////////////////////////////////////////////////////////////////////////
2613 ///Find the children of an element that are made of given nodes
2614 ///@param setOfChildren The set in which matching children will be inserted
2615 ///@param element The element were to search matching children
2616 ///@param nodes The nodes that the children must have to be selected
2617 ///////////////////////////////////////////////////////////////////////////////
2618 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2619 const SMDS_MeshElement * element,
2620 set<const SMDS_MeshElement*>& nodes)
2622 switch(element->GetType())
2625 MESSAGE("Internal Error: This should not happend");
2627 case SMDSAbs_0DElement:
2633 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2636 const SMDS_MeshElement * e=itn->next();
2637 if(nodes.find(e)!=nodes.end())
2639 setOfChildren.insert(element);
2646 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2649 const SMDS_MeshElement * e=itn->next();
2650 if(nodes.find(e)!=nodes.end())
2652 setOfChildren.insert(element);
2656 if(hasConstructionEdges())
2658 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2660 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2663 case SMDSAbs_Volume:
2665 if(hasConstructionFaces())
2667 SMDS_ElemIteratorPtr ite=element->facesIterator();
2669 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2671 else if(hasConstructionEdges())
2673 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2675 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2681 ///////////////////////////////////////////////////////////////////////////////
2682 ///@param elem The element to delete
2683 ///@param removenodes if true remaining nodes will be removed
2684 ///////////////////////////////////////////////////////////////////////////////
2685 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2686 const bool removenodes)
2688 list<const SMDS_MeshElement *> removedElems;
2689 list<const SMDS_MeshElement *> removedNodes;
2690 RemoveElement( elem, removedElems, removedNodes, removenodes );
2693 ///////////////////////////////////////////////////////////////////////////////
2694 ///@param elem The element to delete
2695 ///@param removedElems to be filled with all removed elements
2696 ///@param removedNodes to be filled with all removed nodes
2697 ///@param removenodes if true remaining nodes will be removed
2698 ///////////////////////////////////////////////////////////////////////////////
2699 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2700 list<const SMDS_MeshElement *>& removedElems,
2701 list<const SMDS_MeshElement *>& removedNodes,
2704 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2705 // get finite elements built on elem
2706 set<const SMDS_MeshElement*> * s1;
2707 if (elem->GetType() == SMDSAbs_0DElement ||
2708 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2709 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2710 elem->GetType() == SMDSAbs_Volume)
2712 s1 = new set<const SMDS_MeshElement*>();
2716 s1 = getFinitElements(elem);
2718 // get exclusive nodes (which would become free afterwards)
2719 set<const SMDS_MeshElement*> * s2;
2720 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2722 // do not remove nodes except elem
2723 s2 = new set<const SMDS_MeshElement*>();
2728 s2 = getExclusiveNodes(*s1);
2730 // form the set of finite and construction elements to remove
2731 set<const SMDS_MeshElement*> s3;
2732 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2733 while(it!=s1->end())
2735 addChildrenWithNodes(s3, *it ,*s2);
2739 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2741 // remove finite and construction elements
2745 // Remove element from <InverseElements> of its nodes
2746 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2749 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2750 (const_cast<SMDS_MeshElement *>(itn->next()));
2751 n->RemoveInverseElement( (*it) );
2754 switch((*it)->GetType())
2757 MYASSERT("Internal Error: This should not happen");
2759 case SMDSAbs_0DElement:
2760 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2762 removedElems.push_back( (*it) );
2763 myElementIDFactory->ReleaseID((*it)->GetID());
2767 myCells[(*it)->GetID()] = 0;
2768 myInfo.RemoveEdge(*it);
2769 removedElems.push_back( (*it) );
2770 myElementIDFactory->ReleaseID((*it)->GetID());
2771 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
2772 myEdgePool->destroy((SMDS_VtkEdge*)vtkElem);
2776 myCells[(*it)->GetID()] = 0;
2777 myInfo.RemoveFace(*it);
2778 removedElems.push_back( (*it) );
2779 myElementIDFactory->ReleaseID((*it)->GetID());
2780 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
2781 myFacePool->destroy((SMDS_VtkFace*)vtkElem);
2784 case SMDSAbs_Volume:
2785 myCells[(*it)->GetID()] = 0;
2786 myInfo.RemoveVolume(*it);
2787 removedElems.push_back( (*it) );
2788 myElementIDFactory->ReleaseID((*it)->GetID());
2789 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
2790 myVolumePool->destroy((SMDS_VtkVolume*)vtkElem);
2797 // remove exclusive (free) nodes
2801 while(it!=s2->end())
2803 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2804 myNodes[(*it)->GetID()] = 0;
2806 myNodeIDFactory->ReleaseID((*it)->GetID());
2807 removedNodes.push_back( (*it) );
2808 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
2809 myNodePool->destroy((SMDS_MeshNode*)vtkElem);
2820 ///////////////////////////////////////////////////////////////////////////////
2821 ///@param elem The element to delete
2822 ///////////////////////////////////////////////////////////////////////////////
2823 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2825 int elemId = elem->GetID();
2826 //MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2827 SMDSAbs_ElementType aType = elem->GetType();
2828 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2829 if (aType == SMDSAbs_Node) {
2830 // only free node can be removed by this method
2831 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2832 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2833 if (!itFe->more()) { // free node
2834 myNodes[elemId] = 0;
2836 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2837 myNodeIDFactory->ReleaseID(elemId);
2840 if (hasConstructionEdges() || hasConstructionFaces())
2841 // this methods is only for meshes without descendants
2844 int vtkid = this->fromSmdsToVtk(elemId);
2846 // Remove element from <InverseElements> of its nodes
2847 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2848 while (itn->more()) {
2849 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2850 (const_cast<SMDS_MeshElement *>(itn->next()));
2851 n->RemoveInverseElement(elem);
2854 // in meshes without descendants elements are always free
2856 case SMDSAbs_0DElement:
2857 myCells[elemId] = 0;
2858 myInfo.remove(elem);
2862 myCells[elemId] = 0;
2863 myInfo.RemoveEdge(elem);
2864 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2867 myCells[elemId] = 0;
2868 myInfo.RemoveFace(elem);
2869 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2871 case SMDSAbs_Volume:
2872 myCells[elemId] = 0;
2873 myInfo.RemoveVolume(elem);
2874 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2879 myElementIDFactory->ReleaseID(elemId);
2881 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2882 // --- to do: keep vtkid in a list of reusable cells
2887 * Checks if the element is present in mesh.
2888 * Useful to determine dead pointers.
2890 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2892 // we should not imply on validity of *elem, so iterate on containers
2893 // of all types in the hope of finding <elem> somewhere there
2894 SMDS_NodeIteratorPtr itn = nodesIterator();
2896 if (elem == itn->next())
2898 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2899 while (it0d->more())
2900 if (elem == it0d->next())
2902 SMDS_EdgeIteratorPtr ite = edgesIterator();
2904 if (elem == ite->next())
2906 SMDS_FaceIteratorPtr itf = facesIterator();
2908 if (elem == itf->next())
2910 SMDS_VolumeIteratorPtr itv = volumesIterator();
2912 if (elem == itv->next())
2917 //=======================================================================
2918 //function : MaxNodeID
2920 //=======================================================================
2922 int SMDS_Mesh::MaxNodeID() const
2927 //=======================================================================
2928 //function : MinNodeID
2930 //=======================================================================
2932 int SMDS_Mesh::MinNodeID() const
2937 //=======================================================================
2938 //function : MaxElementID
2940 //=======================================================================
2942 int SMDS_Mesh::MaxElementID() const
2944 return myElementIDFactory->GetMaxID();
2947 //=======================================================================
2948 //function : MinElementID
2950 //=======================================================================
2952 int SMDS_Mesh::MinElementID() const
2954 return myElementIDFactory->GetMinID();
2957 //=======================================================================
2958 //function : Renumber
2959 //purpose : Renumber all nodes or elements.
2960 //=======================================================================
2962 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2964 MESSAGE("Renumber");
2968 SMDS_MeshNodeIDFactory * idFactory =
2969 isNodes ? myNodeIDFactory : myElementIDFactory;
2971 // get existing elements in the order of ID increasing
2972 map<int,SMDS_MeshElement*> elemMap;
2973 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2974 while ( idElemIt->more() ) {
2975 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2976 int id = elem->GetID();
2977 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2979 // release their ids
2980 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2982 // for ( ; elemIt != elemMap.end(); elemIt++ )
2984 // int id = (*elemIt).first;
2985 // idFactory->ReleaseID( id );
2989 elemIt = elemMap.begin();
2990 for ( ; elemIt != elemMap.end(); elemIt++ )
2992 idFactory->BindID( ID, (*elemIt).second );
2997 //=======================================================================
2998 //function : GetElementType
2999 //purpose : Return type of element or node with id
3000 //=======================================================================
3002 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3004 SMDS_MeshElement* elem = 0;
3006 elem = myElementIDFactory->MeshElement( id );
3008 elem = myNodeIDFactory->MeshElement( id );
3012 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3016 return elem->GetType();
3021 //********************************************************************
3022 //********************************************************************
3023 //******** *********
3024 //***** Methods for addition of quadratic elements ******
3025 //******** *********
3026 //********************************************************************
3027 //********************************************************************
3029 //=======================================================================
3030 //function : AddEdgeWithID
3032 //=======================================================================
3033 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3035 return SMDS_Mesh::AddEdgeWithID
3036 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3037 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3038 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3042 //=======================================================================
3043 //function : AddEdge
3045 //=======================================================================
3046 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3047 const SMDS_MeshNode* n2,
3048 const SMDS_MeshNode* n12)
3050 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3053 //=======================================================================
3054 //function : AddEdgeWithID
3056 //=======================================================================
3057 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3058 const SMDS_MeshNode * n2,
3059 const SMDS_MeshNode * n12,
3062 if ( !n1 || !n2 || !n12 ) return 0;
3064 // --- retrieve nodes ID
3065 vector<vtkIdType> nodeIds;
3067 nodeIds.push_back(n1->getId());
3068 nodeIds.push_back(n2->getId());
3069 nodeIds.push_back(n12->getId());
3071 SMDS_MeshEdge * edge = 0;
3072 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3073 edgevtk->init(nodeIds, this);
3075 adjustmyCellsCapacity(ID);
3077 myInfo.myNbQuadEdges++;
3079 if (!registerElement(ID, edge)) {
3080 RemoveElement(edge, false);
3088 //=======================================================================
3089 //function : AddFace
3091 //=======================================================================
3092 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3093 const SMDS_MeshNode * n2,
3094 const SMDS_MeshNode * n3,
3095 const SMDS_MeshNode * n12,
3096 const SMDS_MeshNode * n23,
3097 const SMDS_MeshNode * n31)
3099 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3100 myElementIDFactory->GetFreeID());
3103 //=======================================================================
3104 //function : AddFaceWithID
3106 //=======================================================================
3107 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3108 int n12,int n23,int n31, int ID)
3110 return SMDS_Mesh::AddFaceWithID
3111 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3112 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3113 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3114 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3115 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3116 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3120 //=======================================================================
3121 //function : AddFaceWithID
3123 //=======================================================================
3124 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3125 const SMDS_MeshNode * n2,
3126 const SMDS_MeshNode * n3,
3127 const SMDS_MeshNode * n12,
3128 const SMDS_MeshNode * n23,
3129 const SMDS_MeshNode * n31,
3132 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3133 if(hasConstructionEdges()) {
3134 // creation quadratic edges - not implemented
3139 // --- retrieve nodes ID
3140 vector<vtkIdType> nodeIds;
3142 nodeIds.push_back(n1->getId());
3143 nodeIds.push_back(n2->getId());
3144 nodeIds.push_back(n3->getId());
3145 nodeIds.push_back(n12->getId());
3146 nodeIds.push_back(n23->getId());
3147 nodeIds.push_back(n31->getId());
3149 SMDS_MeshFace * face = 0;
3150 SMDS_VtkFace *facevtk = myFacePool->getNew();
3151 facevtk->init(nodeIds, this);
3153 adjustmyCellsCapacity(ID);
3155 myInfo.myNbQuadTriangles++;
3157 if (!registerElement(ID, face)) {
3158 RemoveElement(face, false);
3166 //=======================================================================
3167 //function : AddFace
3169 //=======================================================================
3170 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3171 const SMDS_MeshNode * n2,
3172 const SMDS_MeshNode * n3,
3173 const SMDS_MeshNode * n4,
3174 const SMDS_MeshNode * n12,
3175 const SMDS_MeshNode * n23,
3176 const SMDS_MeshNode * n34,
3177 const SMDS_MeshNode * n41)
3179 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3180 myElementIDFactory->GetFreeID());
3183 //=======================================================================
3184 //function : AddFaceWithID
3186 //=======================================================================
3187 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3188 int n12,int n23,int n34,int n41, int ID)
3190 return SMDS_Mesh::AddFaceWithID
3191 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3192 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3193 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3194 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3195 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3196 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3197 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3198 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3202 //=======================================================================
3203 //function : AddFaceWithID
3205 //=======================================================================
3206 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3207 const SMDS_MeshNode * n2,
3208 const SMDS_MeshNode * n3,
3209 const SMDS_MeshNode * n4,
3210 const SMDS_MeshNode * n12,
3211 const SMDS_MeshNode * n23,
3212 const SMDS_MeshNode * n34,
3213 const SMDS_MeshNode * n41,
3216 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3217 if(hasConstructionEdges()) {
3218 // creation quadratic edges - not implemented
3223 // --- retrieve nodes ID
3224 vector<vtkIdType> nodeIds;
3226 nodeIds.push_back(n1->getId());
3227 nodeIds.push_back(n2->getId());
3228 nodeIds.push_back(n3->getId());
3229 nodeIds.push_back(n4->getId());
3230 nodeIds.push_back(n12->getId());
3231 nodeIds.push_back(n23->getId());
3232 nodeIds.push_back(n34->getId());
3233 nodeIds.push_back(n41->getId());
3235 SMDS_MeshFace * face = 0;
3236 SMDS_VtkFace *facevtk = myFacePool->getNew();
3237 facevtk->init(nodeIds, this);
3239 adjustmyCellsCapacity(ID);
3241 myInfo.myNbQuadQuadrangles++;
3243 if (!registerElement(ID, face)) {
3244 RemoveElement(face, false);
3252 //=======================================================================
3253 //function : AddVolume
3255 //=======================================================================
3256 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3257 const SMDS_MeshNode * n2,
3258 const SMDS_MeshNode * n3,
3259 const SMDS_MeshNode * n4,
3260 const SMDS_MeshNode * n12,
3261 const SMDS_MeshNode * n23,
3262 const SMDS_MeshNode * n31,
3263 const SMDS_MeshNode * n14,
3264 const SMDS_MeshNode * n24,
3265 const SMDS_MeshNode * n34)
3267 int ID = myElementIDFactory->GetFreeID();
3268 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3269 n31, n14, n24, n34, ID);
3270 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3274 //=======================================================================
3275 //function : AddVolumeWithID
3277 //=======================================================================
3278 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3279 int n12,int n23,int n31,
3280 int n14,int n24,int n34, int ID)
3282 return SMDS_Mesh::AddVolumeWithID
3283 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3288 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3289 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3290 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3291 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3292 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3296 //=======================================================================
3297 //function : AddVolumeWithID
3298 //purpose : 2d order tetrahedron of 10 nodes
3299 //=======================================================================
3300 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3301 const SMDS_MeshNode * n2,
3302 const SMDS_MeshNode * n3,
3303 const SMDS_MeshNode * n4,
3304 const SMDS_MeshNode * n12,
3305 const SMDS_MeshNode * n23,
3306 const SMDS_MeshNode * n31,
3307 const SMDS_MeshNode * n14,
3308 const SMDS_MeshNode * n24,
3309 const SMDS_MeshNode * n34,
3312 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3314 if(hasConstructionFaces()) {
3315 // creation quadratic faces - not implemented
3318 // --- retrieve nodes ID
3319 vector<vtkIdType> nodeIds;
3321 nodeIds.push_back(n1->getId());
3322 nodeIds.push_back(n3->getId());
3323 nodeIds.push_back(n2->getId());
3324 nodeIds.push_back(n4->getId());
3326 nodeIds.push_back(n31->getId());
3327 nodeIds.push_back(n23->getId());
3328 nodeIds.push_back(n12->getId());
3330 nodeIds.push_back(n14->getId());
3331 nodeIds.push_back(n34->getId());
3332 nodeIds.push_back(n24->getId());
3334 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3335 volvtk->init(nodeIds, this);
3336 adjustmyCellsCapacity(ID);
3337 myCells[ID] = volvtk;
3338 myInfo.myNbQuadTetras++;
3340 if (!registerElement(ID, volvtk)) {
3341 RemoveElement(volvtk, false);
3348 //=======================================================================
3349 //function : AddVolume
3351 //=======================================================================
3352 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3353 const SMDS_MeshNode * n2,
3354 const SMDS_MeshNode * n3,
3355 const SMDS_MeshNode * n4,
3356 const SMDS_MeshNode * n5,
3357 const SMDS_MeshNode * n12,
3358 const SMDS_MeshNode * n23,
3359 const SMDS_MeshNode * n34,
3360 const SMDS_MeshNode * n41,
3361 const SMDS_MeshNode * n15,
3362 const SMDS_MeshNode * n25,
3363 const SMDS_MeshNode * n35,
3364 const SMDS_MeshNode * n45)
3366 int ID = myElementIDFactory->GetFreeID();
3367 SMDS_MeshVolume * v =
3368 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3369 n15, n25, n35, n45, ID);
3370 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3374 //=======================================================================
3375 //function : AddVolumeWithID
3377 //=======================================================================
3378 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3379 int n12,int n23,int n34,int n41,
3380 int n15,int n25,int n35,int n45, int ID)
3382 return SMDS_Mesh::AddVolumeWithID
3383 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3384 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3385 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3386 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3387 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3388 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3389 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3390 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3391 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3392 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3393 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3394 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3395 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3399 //=======================================================================
3400 //function : AddVolumeWithID
3401 //purpose : 2d order pyramid of 13 nodes
3402 //=======================================================================
3403 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3404 const SMDS_MeshNode * n2,
3405 const SMDS_MeshNode * n3,
3406 const SMDS_MeshNode * n4,
3407 const SMDS_MeshNode * n5,
3408 const SMDS_MeshNode * n12,
3409 const SMDS_MeshNode * n23,
3410 const SMDS_MeshNode * n34,
3411 const SMDS_MeshNode * n41,
3412 const SMDS_MeshNode * n15,
3413 const SMDS_MeshNode * n25,
3414 const SMDS_MeshNode * n35,
3415 const SMDS_MeshNode * n45,
3418 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3419 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3421 if(hasConstructionFaces()) {
3422 // creation quadratic faces - not implemented
3425 // --- retrieve nodes ID
3426 vector<vtkIdType> nodeIds;
3428 nodeIds.push_back(n1->getId());
3429 nodeIds.push_back(n4->getId());
3430 nodeIds.push_back(n3->getId());
3431 nodeIds.push_back(n2->getId());
3432 nodeIds.push_back(n5->getId());
3434 nodeIds.push_back(n41->getId());
3435 nodeIds.push_back(n34->getId());
3436 nodeIds.push_back(n23->getId());
3437 nodeIds.push_back(n12->getId());
3439 nodeIds.push_back(n15->getId());
3440 nodeIds.push_back(n45->getId());
3441 nodeIds.push_back(n35->getId());
3442 nodeIds.push_back(n25->getId());
3444 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3445 volvtk->init(nodeIds, this);
3446 adjustmyCellsCapacity(ID);
3447 myCells[ID] = volvtk;
3448 myInfo.myNbQuadPyramids++;
3450 if (!registerElement(ID, volvtk)) {
3451 RemoveElement(volvtk, false);
3458 //=======================================================================
3459 //function : AddVolume
3461 //=======================================================================
3462 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3463 const SMDS_MeshNode * n2,
3464 const SMDS_MeshNode * n3,
3465 const SMDS_MeshNode * n4,
3466 const SMDS_MeshNode * n5,
3467 const SMDS_MeshNode * n6,
3468 const SMDS_MeshNode * n12,
3469 const SMDS_MeshNode * n23,
3470 const SMDS_MeshNode * n31,
3471 const SMDS_MeshNode * n45,
3472 const SMDS_MeshNode * n56,
3473 const SMDS_MeshNode * n64,
3474 const SMDS_MeshNode * n14,
3475 const SMDS_MeshNode * n25,
3476 const SMDS_MeshNode * n36)
3478 int ID = myElementIDFactory->GetFreeID();
3479 SMDS_MeshVolume * v =
3480 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3481 n45, n56, n64, n14, n25, n36, ID);
3482 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3486 //=======================================================================
3487 //function : AddVolumeWithID
3489 //=======================================================================
3490 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3491 int n4, int n5, int n6,
3492 int n12,int n23,int n31,
3493 int n45,int n56,int n64,
3494 int n14,int n25,int n36, int ID)
3496 return SMDS_Mesh::AddVolumeWithID
3497 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3498 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3499 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3500 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3501 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3502 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3503 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3504 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3505 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3506 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3507 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3508 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3509 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3510 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3511 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3515 //=======================================================================
3516 //function : AddVolumeWithID
3517 //purpose : 2d order Pentahedron with 15 nodes
3518 //=======================================================================
3519 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3520 const SMDS_MeshNode * n2,
3521 const SMDS_MeshNode * n3,
3522 const SMDS_MeshNode * n4,
3523 const SMDS_MeshNode * n5,
3524 const SMDS_MeshNode * n6,
3525 const SMDS_MeshNode * n12,
3526 const SMDS_MeshNode * n23,
3527 const SMDS_MeshNode * n31,
3528 const SMDS_MeshNode * n45,
3529 const SMDS_MeshNode * n56,
3530 const SMDS_MeshNode * n64,
3531 const SMDS_MeshNode * n14,
3532 const SMDS_MeshNode * n25,
3533 const SMDS_MeshNode * n36,
3536 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3537 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3539 if(hasConstructionFaces()) {
3540 // creation quadratic faces - not implemented
3543 // --- retrieve nodes ID
3544 vector<vtkIdType> nodeIds;
3546 nodeIds.push_back(n1->getId());
3547 nodeIds.push_back(n2->getId());
3548 nodeIds.push_back(n3->getId());
3550 nodeIds.push_back(n4->getId());
3551 nodeIds.push_back(n5->getId());
3552 nodeIds.push_back(n6->getId());
3554 nodeIds.push_back(n12->getId());
3555 nodeIds.push_back(n23->getId());
3556 nodeIds.push_back(n31->getId());
3558 nodeIds.push_back(n45->getId());
3559 nodeIds.push_back(n56->getId());
3560 nodeIds.push_back(n64->getId());
3562 nodeIds.push_back(n14->getId());
3563 nodeIds.push_back(n25->getId());
3564 nodeIds.push_back(n36->getId());
3566 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3567 volvtk->init(nodeIds, this);
3568 adjustmyCellsCapacity(ID);
3569 myCells[ID] = volvtk;
3570 myInfo.myNbQuadPrisms++;
3572 if (!registerElement(ID, volvtk)) {
3573 RemoveElement(volvtk, false);
3580 //=======================================================================
3581 //function : AddVolume
3583 //=======================================================================
3584 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3585 const SMDS_MeshNode * n2,
3586 const SMDS_MeshNode * n3,
3587 const SMDS_MeshNode * n4,
3588 const SMDS_MeshNode * n5,
3589 const SMDS_MeshNode * n6,
3590 const SMDS_MeshNode * n7,
3591 const SMDS_MeshNode * n8,
3592 const SMDS_MeshNode * n12,
3593 const SMDS_MeshNode * n23,
3594 const SMDS_MeshNode * n34,
3595 const SMDS_MeshNode * n41,
3596 const SMDS_MeshNode * n56,
3597 const SMDS_MeshNode * n67,
3598 const SMDS_MeshNode * n78,
3599 const SMDS_MeshNode * n85,
3600 const SMDS_MeshNode * n15,
3601 const SMDS_MeshNode * n26,
3602 const SMDS_MeshNode * n37,
3603 const SMDS_MeshNode * n48)
3605 int ID = myElementIDFactory->GetFreeID();
3606 SMDS_MeshVolume * v =
3607 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3608 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3609 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3613 //=======================================================================
3614 //function : AddVolumeWithID
3616 //=======================================================================
3617 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3618 int n5, int n6, int n7, int n8,
3619 int n12,int n23,int n34,int n41,
3620 int n56,int n67,int n78,int n85,
3621 int n15,int n26,int n37,int n48, int ID)
3623 return SMDS_Mesh::AddVolumeWithID
3624 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3625 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3626 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3627 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3628 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3629 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3630 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3631 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3632 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3633 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3634 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3635 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3636 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3637 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3638 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3639 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3640 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3641 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3642 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3643 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3647 //=======================================================================
3648 //function : AddVolumeWithID
3649 //purpose : 2d order Hexahedrons with 20 nodes
3650 //=======================================================================
3651 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3652 const SMDS_MeshNode * n2,
3653 const SMDS_MeshNode * n3,
3654 const SMDS_MeshNode * n4,
3655 const SMDS_MeshNode * n5,
3656 const SMDS_MeshNode * n6,
3657 const SMDS_MeshNode * n7,
3658 const SMDS_MeshNode * n8,
3659 const SMDS_MeshNode * n12,
3660 const SMDS_MeshNode * n23,
3661 const SMDS_MeshNode * n34,
3662 const SMDS_MeshNode * n41,
3663 const SMDS_MeshNode * n56,
3664 const SMDS_MeshNode * n67,
3665 const SMDS_MeshNode * n78,
3666 const SMDS_MeshNode * n85,
3667 const SMDS_MeshNode * n15,
3668 const SMDS_MeshNode * n26,
3669 const SMDS_MeshNode * n37,
3670 const SMDS_MeshNode * n48,
3673 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3674 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3676 if(hasConstructionFaces()) {
3678 // creation quadratic faces - not implemented
3680 // --- retrieve nodes ID
3681 vector<vtkIdType> nodeIds;
3683 nodeIds.push_back(n1->getId());
3684 nodeIds.push_back(n4->getId());
3685 nodeIds.push_back(n3->getId());
3686 nodeIds.push_back(n2->getId());
3688 nodeIds.push_back(n5->getId());
3689 nodeIds.push_back(n8->getId());
3690 nodeIds.push_back(n7->getId());
3691 nodeIds.push_back(n6->getId());
3693 nodeIds.push_back(n41->getId());
3694 nodeIds.push_back(n34->getId());
3695 nodeIds.push_back(n23->getId());
3696 nodeIds.push_back(n12->getId());
3698 nodeIds.push_back(n85->getId());
3699 nodeIds.push_back(n78->getId());
3700 nodeIds.push_back(n67->getId());
3701 nodeIds.push_back(n56->getId());
3703 nodeIds.push_back(n15->getId());
3704 nodeIds.push_back(n48->getId());
3705 nodeIds.push_back(n37->getId());
3706 nodeIds.push_back(n26->getId());
3708 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3709 volvtk->init(nodeIds, this);
3710 adjustmyCellsCapacity(ID);
3711 myCells[ID] = volvtk;
3712 myInfo.myNbQuadHexas++;
3714 if (!registerElement(ID, volvtk)) {
3715 RemoveElement(volvtk, false);
3721 void SMDS_Mesh::updateNodeMinMax()
3724 if (myNodes.size() == 0)
3729 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3731 myNodeMax=myNodes.size()-1;
3732 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3736 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3738 int val = myIDElements.size();
3739 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3740 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3741 val = myNodes.size();
3742 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3743 myNodes.resize(val +nbNodes, 0);
3746 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3748 int val = myVtkIndex.size();
3749 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3750 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3751 val = myCells.size();
3752 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3753 myNodes.resize(val +nbCells, 0);
3756 void SMDS_Mesh::adjustStructure()
3758 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3761 void SMDS_Mesh::dumpGrid(string ficdump)
3763 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
3764 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
3765 // aWriter->SetFileName(ficdump.c_str());
3766 // aWriter->SetInput(myGrid);
3767 // if(myGrid->GetNumberOfCells())
3769 // aWriter->Write();
3771 // aWriter->Delete();
3772 ficdump = ficdump + "_connectivity";
3773 ofstream ficcon(ficdump.c_str(), ios::out);
3774 int nbPoints = myGrid->GetNumberOfPoints();
3775 ficcon << "-------------------------------- points " << nbPoints << endl;
3776 for (int i=0; i<nbPoints; i++)
3778 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
3780 int nbCells = myGrid->GetNumberOfCells();
3781 ficcon << "-------------------------------- cells " << nbCells << endl;
3782 for (int i=0; i<nbCells; i++)
3784 // MESSAGE(i << " " << myGrid->GetCell(i));
3785 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
3786 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
3787 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
3788 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
3789 for (int j=0; j<nbptcell; j++)
3791 ficcon << " " << listid->GetId(j);
3795 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
3796 vtkCellLinks *links = myGrid->GetCellLinks();
3797 for (int i=0; i<nbPoints; i++)
3799 int ncells = links->GetNcells(i);
3800 vtkIdType *cells = links->GetCells(i);
3801 ficcon << i << " - " << ncells << " -";
3802 for (int j=0; j<ncells; j++)
3804 ficcon << " " << cells[j];