1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "SMDS_FaceOfEdges.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_PolygonalFaceOfNodes.hxx"
33 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_SpacePosition.hxx"
39 #include "SMDS_UnstructuredGrid.hxx"
40 #include "SMDS_VolumeOfFaces.hxx"
41 #include "SMDS_VolumeOfNodes.hxx"
43 #include "utilities.h"
45 #include <vtkUnstructuredGrid.h>
46 #include <vtkUnstructuredGridWriter.h>
47 #include <vtkUnsignedCharArray.h>
49 #include <vtkCellLinks.h>
50 #include <vtkIdList.h>
59 #if !defined WIN32 && !defined __APPLE__
60 #include <sys/sysinfo.h>
63 // number of added entities to check memory after
64 #define CHECKMEMORY_INTERVAL 100000
66 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
67 int SMDS_Mesh::chunkSize = 1024;
70 //================================================================================
72 * \brief Raise an exception if free memory (ram+swap) too low
73 * \param doNotRaise - if true, suppres exception, just return free memory size
74 * \retval int - amount of available memory in MB or negative number in failure case
76 //================================================================================
78 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
80 #if !defined WIN32 && !defined __APPLE__
82 int err = sysinfo( &si );
86 const unsigned long Mbyte = 1024 * 1024;
88 static int limit = -1;
90 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
92 limit = WEXITSTATUS(status);
95 double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
96 limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
101 limit = int ( limit * 1.5 );
102 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
105 // compute separately to avoid overflow
107 ( si.freeram * si.mem_unit ) / Mbyte +
108 ( si.freeswap * si.mem_unit ) / Mbyte;
109 //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
111 if ( freeMb > limit )
112 return freeMb - limit;
117 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
118 throw std::bad_alloc();
124 ///////////////////////////////////////////////////////////////////////////////
125 /// Create a new mesh object
126 ///////////////////////////////////////////////////////////////////////////////
127 SMDS_Mesh::SMDS_Mesh():
128 myNodePool(0), myVolumePool(0), myFacePool(0), myEdgePool(0), myBallPool(0),
130 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
131 myElementIDFactory(new SMDS_MeshElementIDFactory()),
132 myModified(false), myModifTime(0), myCompactTime(0),
133 myHasConstructionEdges(false), myHasConstructionFaces(false),
134 myHasInverseElements(true),
135 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
137 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
138 myNodeIDFactory->SetMesh(this);
139 myElementIDFactory->SetMesh(this);
140 _meshList.push_back(this);
141 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
142 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
143 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
144 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
145 myBallPool = new ObjectPool<SMDS_BallElement>(SMDS_Mesh::chunkSize);
149 //myCellIdSmdsToVtk.clear();
150 myCellIdVtkToSmds.clear();
151 myGrid = SMDS_UnstructuredGrid::New();
152 myGrid->setSMDS_mesh(this);
153 myGrid->Initialize();
155 vtkPoints* points = vtkPoints::New();
156 // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
157 // Use double type for storing coordinates of nodes instead of float.
158 points->SetDataType(VTK_DOUBLE);
159 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
160 myGrid->SetPoints( points );
162 //myGrid->BuildLinks();
165 // initialize static maps in SMDS_MeshCell, to be thread-safe
168 SMDS_MeshCell::toVtkType( SMDSEntity_Node );
169 SMDS_MeshCell::toVtkOrder( SMDSEntity_Node );
170 SMDS_MeshCell::reverseSmdsOrder( SMDSEntity_Node );
171 SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Node );
172 SMDS_MeshCell::toSmdsType( VTK_VERTEX );
173 SMDS_MeshCell::fromVtkOrder( SMDSEntity_Node );
177 ///////////////////////////////////////////////////////////////////////////////
178 /// Create a new child mesh
179 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
180 /// (2003-09-08) of SMESH
181 ///////////////////////////////////////////////////////////////////////////////
182 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
183 myNodePool(parent->myNodePool),
184 myVolumePool(parent->myVolumePool),
185 myFacePool(parent->myFacePool),
186 myEdgePool(parent->myEdgePool),
187 myBallPool(parent->myBallPool),
188 myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
189 myElementIDFactory(parent->myElementIDFactory),
190 myHasConstructionEdges(false), myHasConstructionFaces(false),
191 myHasInverseElements(true)
195 ///////////////////////////////////////////////////////////////////////////////
196 ///Create a submesh and add it to the current mesh
197 ///////////////////////////////////////////////////////////////////////////////
199 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
201 SMDS_Mesh *submesh = new SMDS_Mesh(this);
202 myChildren.insert(myChildren.end(), submesh);
206 ///////////////////////////////////////////////////////////////////////////////
207 ///create a MeshNode and add it to the current Mesh
208 ///An ID is automatically assigned to the node.
209 ///@return : The created node
210 ///////////////////////////////////////////////////////////////////////////////
212 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
214 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
217 ///////////////////////////////////////////////////////////////////////////////
218 ///create a MeshNode and add it to the current Mesh
219 ///@param ID : The ID of the MeshNode to create
220 ///@return : The created node or NULL if a node with this ID already exists
221 ///////////////////////////////////////////////////////////////////////////////
222 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
224 // find the MeshNode corresponding to ID
225 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
229 MESSAGE("=============> Bad Node Id: " << ID);
230 ID = myNodeIDFactory->GetFreeID();
232 myNodeIDFactory->adjustMaxId(ID);
233 SMDS_MeshNode * node = myNodePool->getNew();
234 node->init(ID, myMeshId, 0, x, y, z);
236 if (ID >= (int)myNodes.size())
238 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
239 // MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
242 myNodeIDFactory->BindID(ID,node);
245 this->adjustBoundingBox(x, y, z);
251 ///////////////////////////////////////////////////////////////////////////////
252 /// create a Mesh0DElement and add it to the current Mesh
253 /// @return : The created Mesh0DElement
254 ///////////////////////////////////////////////////////////////////////////////
255 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
257 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
258 if (!node) return NULL;
259 return SMDS_Mesh::Add0DElementWithID(node, ID);
262 ///////////////////////////////////////////////////////////////////////////////
263 /// create a Mesh0DElement and add it to the current Mesh
264 /// @return : The created Mesh0DElement
265 ///////////////////////////////////////////////////////////////////////////////
266 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
268 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
271 ///////////////////////////////////////////////////////////////////////////////
272 /// Create a new Mesh0DElement and at it to the mesh
273 /// @param idnode ID of the node
274 /// @param ID ID of the 0D element to create
275 /// @return The created 0D element or NULL if an element with this
276 /// ID already exists or if input node is not found.
277 ///////////////////////////////////////////////////////////////////////////////
278 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
282 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
283 //MESSAGE("Add0DElementWithID" << ID)
284 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
285 if (myElementIDFactory->BindID(ID, el0d)) {
286 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
287 //node->AddInverseElement(el0d);// --- fait avec BindID
288 adjustmyCellsCapacity(ID);
290 myInfo.myNb0DElements++;
298 ///////////////////////////////////////////////////////////////////////////////
299 /// create a Ball and add it to the current Mesh
300 /// @return : The created Ball
301 ///////////////////////////////////////////////////////////////////////////////
302 SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID)
304 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
305 if (!node) return NULL;
306 return SMDS_Mesh::AddBallWithID(node, diameter, ID);
309 ///////////////////////////////////////////////////////////////////////////////
310 /// create a Ball and add it to the current Mesh
311 /// @return : The created Ball
312 ///////////////////////////////////////////////////////////////////////////////
313 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
315 return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID());
318 ///////////////////////////////////////////////////////////////////////////////
319 /// Create a new Ball and at it to the mesh
320 /// @param idnode ID of the node
321 // @param diameter ball diameter
322 /// @param ID ID of the 0D element to create
323 /// @return The created 0D element or NULL if an element with this
324 /// ID already exists or if input node is not found.
325 ///////////////////////////////////////////////////////////////////////////////
326 SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
330 if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
332 SMDS_BallElement *ball = myBallPool->getNew();
333 ball->init(n->getVtkId(), diameter, this);
334 if (!this->registerElement(ID,ball))
336 this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
337 myBallPool->destroy(ball);
340 adjustmyCellsCapacity(ID);
346 ///////////////////////////////////////////////////////////////////////////////
347 /// create a MeshEdge and add it to the current Mesh
348 /// @return : The created MeshEdge
349 ///////////////////////////////////////////////////////////////////////////////
351 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
353 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
354 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
355 if(!node1 || !node2) return NULL;
356 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
359 ///////////////////////////////////////////////////////////////////////////////
360 /// create a MeshEdge and add it to the current Mesh
361 /// @return : The created MeshEdge
362 ///////////////////////////////////////////////////////////////////////////////
364 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
365 const SMDS_MeshNode * node2)
367 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
370 ///////////////////////////////////////////////////////////////////////////////
371 /// Create a new edge and at it to the mesh
372 /// @param idnode1 ID of the first node
373 /// @param idnode2 ID of the second node
374 /// @param ID ID of the edge to create
375 /// @return The created edge or NULL if an element with this ID already exists or
376 /// if input nodes are not found.
377 ///////////////////////////////////////////////////////////////////////////////
379 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
380 const SMDS_MeshNode * n2,
383 if ( !n1 || !n2 ) return 0;
384 SMDS_MeshEdge * edge = 0;
386 // --- retrieve nodes ID
387 vector<vtkIdType> nodeIds;
389 nodeIds.push_back(n1->getVtkId());
390 nodeIds.push_back(n2->getVtkId());
392 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
393 edgevtk->init(nodeIds, this);
394 if (!this->registerElement(ID,edgevtk))
396 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
397 myEdgePool->destroy(edgevtk);
401 adjustmyCellsCapacity(ID);
405 // if (edge && !registerElement(ID, edge))
407 // RemoveElement(edge, false);
413 ///////////////////////////////////////////////////////////////////////////////
414 /// Add a triangle defined by its nodes. An ID is automatically affected to the
416 ///////////////////////////////////////////////////////////////////////////////
418 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
419 const SMDS_MeshNode * n2,
420 const SMDS_MeshNode * n3)
422 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
425 ///////////////////////////////////////////////////////////////////////////////
426 /// Add a triangle defined by its nodes IDs
427 ///////////////////////////////////////////////////////////////////////////////
429 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
431 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
432 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
433 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
434 if(!node1 || !node2 || !node3) return NULL;
435 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
438 ///////////////////////////////////////////////////////////////////////////////
439 /// Add a triangle defined by its nodes
440 ///////////////////////////////////////////////////////////////////////////////
442 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
443 const SMDS_MeshNode * n2,
444 const SMDS_MeshNode * n3,
447 //MESSAGE("AddFaceWithID " << ID)
448 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
450 // if (face && !registerElement(ID, face)) {
451 // RemoveElement(face, false);
457 ///////////////////////////////////////////////////////////////////////////////
458 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
460 ///////////////////////////////////////////////////////////////////////////////
462 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
463 const SMDS_MeshNode * n2,
464 const SMDS_MeshNode * n3,
465 const SMDS_MeshNode * n4)
467 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
470 ///////////////////////////////////////////////////////////////////////////////
471 /// Add a quadrangle defined by its nodes IDs
472 ///////////////////////////////////////////////////////////////////////////////
474 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
480 SMDS_MeshNode *node1, *node2, *node3, *node4;
481 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
482 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
483 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
484 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
485 if(!node1 || !node2 || !node3 || !node4) return NULL;
486 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
489 ///////////////////////////////////////////////////////////////////////////////
490 /// Add a quadrangle defined by its nodes
491 ///////////////////////////////////////////////////////////////////////////////
493 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
494 const SMDS_MeshNode * n2,
495 const SMDS_MeshNode * n3,
496 const SMDS_MeshNode * n4,
499 //MESSAGE("AddFaceWithID " << ID);
500 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
502 // if (face && !registerElement(ID, face)) {
503 // RemoveElement(face, false);
509 ///////////////////////////////////////////////////////////////////////////////
510 /// Add a triangle defined by its edges. An ID is automatically assigned to the
512 ///////////////////////////////////////////////////////////////////////////////
514 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
515 const SMDS_MeshEdge * e2,
516 const SMDS_MeshEdge * e3)
518 if (!hasConstructionEdges())
520 //MESSAGE("AddFaceWithID");
521 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
524 ///////////////////////////////////////////////////////////////////////////////
525 /// Add a triangle defined by its edges
526 ///////////////////////////////////////////////////////////////////////////////
528 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
529 const SMDS_MeshEdge * e2,
530 const SMDS_MeshEdge * e3,
533 if (!hasConstructionEdges())
535 if ( !e1 || !e2 || !e3 ) return 0;
537 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
539 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
540 adjustmyCellsCapacity(ID);
542 myInfo.myNbTriangles++;
544 if (!registerElement(ID, face)) {
545 registerElement(myElementIDFactory->GetFreeID(), face);
546 //RemoveElement(face, false);
552 ///////////////////////////////////////////////////////////////////////////////
553 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
555 ///////////////////////////////////////////////////////////////////////////////
557 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
558 const SMDS_MeshEdge * e2,
559 const SMDS_MeshEdge * e3,
560 const SMDS_MeshEdge * e4)
562 if (!hasConstructionEdges())
564 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
567 ///////////////////////////////////////////////////////////////////////////////
568 /// Add a quadrangle defined by its edges
569 ///////////////////////////////////////////////////////////////////////////////
571 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
572 const SMDS_MeshEdge * e2,
573 const SMDS_MeshEdge * e3,
574 const SMDS_MeshEdge * e4,
577 if (!hasConstructionEdges())
579 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
580 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
581 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
582 adjustmyCellsCapacity(ID);
584 myInfo.myNbQuadrangles++;
586 if (!registerElement(ID, face))
588 registerElement(myElementIDFactory->GetFreeID(), face);
589 //RemoveElement(face, false);
595 ///////////////////////////////////////////////////////////////////////////////
596 ///Create a new tetrahedron and add it to the mesh.
597 ///@return The created tetrahedron
598 ///////////////////////////////////////////////////////////////////////////////
600 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
601 const SMDS_MeshNode * n2,
602 const SMDS_MeshNode * n3,
603 const SMDS_MeshNode * n4)
605 int ID = myElementIDFactory->GetFreeID();
606 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
607 if(v==NULL) myElementIDFactory->ReleaseID(ID);
611 ///////////////////////////////////////////////////////////////////////////////
612 ///Create a new tetrahedron and add it to the mesh.
613 ///@param ID The ID of the new volume
614 ///@return The created tetrahedron or NULL if an element with this ID already exists
615 ///or if input nodes are not found.
616 ///////////////////////////////////////////////////////////////////////////////
618 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
624 SMDS_MeshNode *node1, *node2, *node3, *node4;
625 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
626 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
627 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
628 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
629 if(!node1 || !node2 || !node3 || !node4) return NULL;
630 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
633 ///////////////////////////////////////////////////////////////////////////////
634 ///Create a new tetrahedron and add it to the mesh.
635 ///@param ID The ID of the new volume
636 ///@return The created tetrahedron
637 ///////////////////////////////////////////////////////////////////////////////
639 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
640 const SMDS_MeshNode * n2,
641 const SMDS_MeshNode * n3,
642 const SMDS_MeshNode * n4,
645 SMDS_MeshVolume* volume = 0;
646 if ( !n1 || !n2 || !n3 || !n4) return volume;
647 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
648 if(hasConstructionFaces()) {
649 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
650 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
651 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
652 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
653 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
654 adjustmyCellsCapacity(ID);
655 myCells[ID] = volume;
658 else if(hasConstructionEdges()) {
662 // --- retrieve nodes ID
664 myNodeIds[0] = n1->getVtkId();
665 myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK
666 myNodeIds[2] = n2->getVtkId();
667 myNodeIds[3] = n4->getVtkId();
669 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
670 volvtk->init(myNodeIds, this);
671 if (!this->registerElement(ID,volvtk))
673 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
674 myVolumePool->destroy(volvtk);
678 adjustmyCellsCapacity(ID);
679 myCells[ID] = volume;
683 // if (!registerElement(ID, volume)) {
684 // RemoveElement(volume, false);
690 ///////////////////////////////////////////////////////////////////////////////
691 ///Create a new pyramid and add it to the mesh.
692 ///Nodes 1,2,3 and 4 define the base of the pyramid
693 ///@return The created pyramid
694 ///////////////////////////////////////////////////////////////////////////////
696 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
697 const SMDS_MeshNode * n2,
698 const SMDS_MeshNode * n3,
699 const SMDS_MeshNode * n4,
700 const SMDS_MeshNode * n5)
702 int ID = myElementIDFactory->GetFreeID();
703 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
704 if(v==NULL) myElementIDFactory->ReleaseID(ID);
708 ///////////////////////////////////////////////////////////////////////////////
709 ///Create a new pyramid and add it to the mesh.
710 ///Nodes 1,2,3 and 4 define the base of the pyramid
711 ///@param ID The ID of the new volume
712 ///@return The created pyramid or NULL if an element with this ID already exists
713 ///or if input nodes are not found.
714 ///////////////////////////////////////////////////////////////////////////////
716 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
723 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
724 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
725 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
726 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
727 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
728 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
729 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
730 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
733 ///////////////////////////////////////////////////////////////////////////////
734 ///Create a new pyramid and add it to the mesh.
735 ///Nodes 1,2,3 and 4 define the base of the pyramid
736 ///@param ID The ID of the new volume
737 ///@return The created pyramid
738 ///////////////////////////////////////////////////////////////////////////////
740 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
741 const SMDS_MeshNode * n2,
742 const SMDS_MeshNode * n3,
743 const SMDS_MeshNode * n4,
744 const SMDS_MeshNode * n5,
747 SMDS_MeshVolume* volume = 0;
748 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
749 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
750 if(hasConstructionFaces()) {
751 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
752 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
753 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
754 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
755 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
756 adjustmyCellsCapacity(ID);
757 myCells[ID] = volume;
758 myInfo.myNbPyramids++;
760 else if(hasConstructionEdges()) {
764 // --- retrieve nodes ID
766 myNodeIds[0] = n1->getVtkId();
767 myNodeIds[1] = n4->getVtkId();
768 myNodeIds[2] = n3->getVtkId();
769 myNodeIds[3] = n2->getVtkId();
770 myNodeIds[4] = n5->getVtkId();
772 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
773 volvtk->init(myNodeIds, this);
774 if (!this->registerElement(ID,volvtk))
776 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
777 myVolumePool->destroy(volvtk);
781 adjustmyCellsCapacity(ID);
782 myCells[ID] = volume;
783 myInfo.myNbPyramids++;
786 // if (!registerElement(ID, volume)) {
787 // RemoveElement(volume, false);
793 ///////////////////////////////////////////////////////////////////////////////
794 ///Create a new prism and add it to the mesh.
795 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
796 ///@return The created prism
797 ///////////////////////////////////////////////////////////////////////////////
799 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
800 const SMDS_MeshNode * n2,
801 const SMDS_MeshNode * n3,
802 const SMDS_MeshNode * n4,
803 const SMDS_MeshNode * n5,
804 const SMDS_MeshNode * n6)
806 int ID = myElementIDFactory->GetFreeID();
807 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
808 if(v==NULL) myElementIDFactory->ReleaseID(ID);
812 ///////////////////////////////////////////////////////////////////////////////
813 ///Create a new prism and add it to the mesh.
814 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
815 ///@param ID The ID of the new volume
816 ///@return The created prism or NULL if an element with this ID already exists
817 ///or if input nodes are not found.
818 ///////////////////////////////////////////////////////////////////////////////
820 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
828 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
829 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
830 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
831 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
832 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
833 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
834 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
835 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
836 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
839 ///////////////////////////////////////////////////////////////////////////////
840 ///Create a new prism and add it to the mesh.
841 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
842 ///@param ID The ID of the new volume
843 ///@return The created prism
844 ///////////////////////////////////////////////////////////////////////////////
846 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
847 const SMDS_MeshNode * n2,
848 const SMDS_MeshNode * n3,
849 const SMDS_MeshNode * n4,
850 const SMDS_MeshNode * n5,
851 const SMDS_MeshNode * n6,
854 SMDS_MeshVolume* volume = 0;
855 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
856 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
857 if(hasConstructionFaces()) {
858 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
859 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
860 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
861 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
862 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
863 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
864 adjustmyCellsCapacity(ID);
865 myCells[ID] = volume;
868 else if(hasConstructionEdges()) {
872 // --- retrieve nodes ID
874 myNodeIds[0] = n1->getVtkId();
875 myNodeIds[1] = n2->getVtkId();
876 myNodeIds[2] = n3->getVtkId();
877 myNodeIds[3] = n4->getVtkId();
878 myNodeIds[4] = n5->getVtkId();
879 myNodeIds[5] = n6->getVtkId();
881 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
882 volvtk->init(myNodeIds, this);
883 if (!this->registerElement(ID,volvtk))
885 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
886 myVolumePool->destroy(volvtk);
890 adjustmyCellsCapacity(ID);
891 myCells[ID] = volume;
895 // if (!registerElement(ID, volume)) {
896 // RemoveElement(volume, false);
902 ///////////////////////////////////////////////////////////////////////////////
903 ///Create a new hexagonal prism and add it to the mesh.
904 ///@return The created prism
905 ///////////////////////////////////////////////////////////////////////////////
907 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
908 const SMDS_MeshNode * n2,
909 const SMDS_MeshNode * n3,
910 const SMDS_MeshNode * n4,
911 const SMDS_MeshNode * n5,
912 const SMDS_MeshNode * n6,
913 const SMDS_MeshNode * n7,
914 const SMDS_MeshNode * n8,
915 const SMDS_MeshNode * n9,
916 const SMDS_MeshNode * n10,
917 const SMDS_MeshNode * n11,
918 const SMDS_MeshNode * n12)
920 int ID = myElementIDFactory->GetFreeID();
921 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
922 n7, n8, n9, n10, n11, n12,
924 if(v==NULL) myElementIDFactory->ReleaseID(ID);
928 ///////////////////////////////////////////////////////////////////////////////
929 ///Create a new hexagonal prism and add it to the mesh.
930 ///@param ID The ID of the new volume
931 ///@return The created prism or NULL if an element with this ID already exists
932 ///or if input nodes are not found.
933 ///////////////////////////////////////////////////////////////////////////////
935 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
949 SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
950 SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
951 SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
952 SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
953 SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
954 SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
955 SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
956 SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
957 SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
958 SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
959 SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
960 SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
961 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
962 node7, node8, node9, node10, node11, node12,
966 ///////////////////////////////////////////////////////////////////////////////
967 ///Create a new hexagonal prism and add it to the mesh.
968 ///@param ID The ID of the new volume
969 ///@return The created prism
970 ///////////////////////////////////////////////////////////////////////////////
972 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
973 const SMDS_MeshNode * n2,
974 const SMDS_MeshNode * n3,
975 const SMDS_MeshNode * n4,
976 const SMDS_MeshNode * n5,
977 const SMDS_MeshNode * n6,
978 const SMDS_MeshNode * n7,
979 const SMDS_MeshNode * n8,
980 const SMDS_MeshNode * n9,
981 const SMDS_MeshNode * n10,
982 const SMDS_MeshNode * n11,
983 const SMDS_MeshNode * n12,
986 SMDS_MeshVolume* volume = 0;
987 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
988 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
990 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
991 if(hasConstructionFaces()) {
994 else if(hasConstructionEdges()) {
998 // --- retrieve nodes ID
999 myNodeIds.resize(12);
1000 myNodeIds[0] = n1->getVtkId();
1001 myNodeIds[1] = n6->getVtkId();
1002 myNodeIds[2] = n5->getVtkId();
1003 myNodeIds[3] = n4->getVtkId();
1004 myNodeIds[4] = n3->getVtkId();
1005 myNodeIds[5] = n2->getVtkId();
1007 myNodeIds[6] = n7->getVtkId();
1008 myNodeIds[7] = n12->getVtkId();
1009 myNodeIds[8] = n11->getVtkId();
1010 myNodeIds[9] = n10->getVtkId();
1011 myNodeIds[10] = n9->getVtkId();
1012 myNodeIds[11] = n8->getVtkId();
1014 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1015 volvtk->init(myNodeIds, this);
1016 if (!this->registerElement(ID,volvtk))
1018 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1019 myVolumePool->destroy(volvtk);
1023 adjustmyCellsCapacity(ID);
1024 myCells[ID] = volume;
1025 myInfo.myNbHexPrism++;
1031 ///////////////////////////////////////////////////////////////////////////////
1032 ///Create a new hexahedron and add it to the mesh.
1033 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1034 ///@return The created hexahedron
1035 ///////////////////////////////////////////////////////////////////////////////
1037 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1038 const SMDS_MeshNode * n2,
1039 const SMDS_MeshNode * n3,
1040 const SMDS_MeshNode * n4,
1041 const SMDS_MeshNode * n5,
1042 const SMDS_MeshNode * n6,
1043 const SMDS_MeshNode * n7,
1044 const SMDS_MeshNode * n8)
1046 int ID = myElementIDFactory->GetFreeID();
1047 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
1048 if(v==NULL) myElementIDFactory->ReleaseID(ID);
1052 ///////////////////////////////////////////////////////////////////////////////
1053 ///Create a new hexahedron and add it to the mesh.
1054 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1055 ///@param ID The ID of the new volume
1056 ///@return The created hexahedron or NULL if an element with this ID already
1057 ///exists or if input nodes are not found.
1058 ///////////////////////////////////////////////////////////////////////////////
1060 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
1070 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
1071 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
1072 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
1073 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
1074 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
1075 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
1076 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
1077 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
1078 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
1079 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
1081 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
1085 ///////////////////////////////////////////////////////////////////////////////
1086 ///Create a new hexahedron and add it to the mesh.
1087 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1088 ///@param ID The ID of the new volume
1089 ///@return The created prism or NULL if an element with this ID already exists
1090 ///or if input nodes are not found.
1091 ///////////////////////////////////////////////////////////////////////////////
1093 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1094 const SMDS_MeshNode * n2,
1095 const SMDS_MeshNode * n3,
1096 const SMDS_MeshNode * n4,
1097 const SMDS_MeshNode * n5,
1098 const SMDS_MeshNode * n6,
1099 const SMDS_MeshNode * n7,
1100 const SMDS_MeshNode * n8,
1103 SMDS_MeshVolume* volume = 0;
1104 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
1105 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1106 if(hasConstructionFaces()) {
1107 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
1108 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
1109 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
1110 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
1111 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
1112 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
1113 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1114 adjustmyCellsCapacity(ID);
1115 myCells[ID] = volume;
1118 else if(hasConstructionEdges()) {
1122 // --- retrieve nodes ID
1123 myNodeIds.resize(8);
1124 myNodeIds[0] = n1->getVtkId();
1125 myNodeIds[1] = n4->getVtkId();
1126 myNodeIds[2] = n3->getVtkId();
1127 myNodeIds[3] = n2->getVtkId();
1128 myNodeIds[4] = n5->getVtkId();
1129 myNodeIds[5] = n8->getVtkId();
1130 myNodeIds[6] = n7->getVtkId();
1131 myNodeIds[7] = n6->getVtkId();
1133 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1134 volvtk->init(myNodeIds, this);
1135 if (!this->registerElement(ID,volvtk))
1137 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1138 myVolumePool->destroy(volvtk);
1142 adjustmyCellsCapacity(ID);
1143 myCells[ID] = volume;
1147 // if (!registerElement(ID, volume)) {
1148 // RemoveElement(volume, false);
1154 ///////////////////////////////////////////////////////////////////////////////
1155 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1156 ///@return The created tetrahedron
1157 ///////////////////////////////////////////////////////////////////////////////
1159 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1160 const SMDS_MeshFace * f2,
1161 const SMDS_MeshFace * f3,
1162 const SMDS_MeshFace * f4)
1164 if (!hasConstructionFaces())
1166 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1169 ///////////////////////////////////////////////////////////////////////////////
1170 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1171 ///@param ID The ID of the new volume
1172 ///@return The created tetrahedron
1173 ///////////////////////////////////////////////////////////////////////////////
1175 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1176 const SMDS_MeshFace * f2,
1177 const SMDS_MeshFace * f3,
1178 const SMDS_MeshFace * f4,
1181 if (!hasConstructionFaces())
1183 if ( !f1 || !f2 || !f3 || !f4) return 0;
1184 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1185 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1186 adjustmyCellsCapacity(ID);
1187 myCells[ID] = volume;
1188 myInfo.myNbTetras++;
1190 if (!registerElement(ID, volume)) {
1191 registerElement(myElementIDFactory->GetFreeID(), volume);
1192 //RemoveElement(volume, false);
1198 ///////////////////////////////////////////////////////////////////////////////
1199 ///Create a new pyramid defined by its faces and add it to the mesh.
1200 ///@return The created pyramid
1201 ///////////////////////////////////////////////////////////////////////////////
1203 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1204 const SMDS_MeshFace * f2,
1205 const SMDS_MeshFace * f3,
1206 const SMDS_MeshFace * f4,
1207 const SMDS_MeshFace * f5)
1209 if (!hasConstructionFaces())
1211 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1214 ///////////////////////////////////////////////////////////////////////////////
1215 ///Create a new pyramid defined by its faces and add it to the mesh.
1216 ///@param ID The ID of the new volume
1217 ///@return The created pyramid
1218 ///////////////////////////////////////////////////////////////////////////////
1220 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1221 const SMDS_MeshFace * f2,
1222 const SMDS_MeshFace * f3,
1223 const SMDS_MeshFace * f4,
1224 const SMDS_MeshFace * f5,
1227 if (!hasConstructionFaces())
1229 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1230 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1231 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1232 adjustmyCellsCapacity(ID);
1233 myCells[ID] = volume;
1234 myInfo.myNbPyramids++;
1236 if (!registerElement(ID, volume)) {
1237 registerElement(myElementIDFactory->GetFreeID(), volume);
1238 //RemoveElement(volume, false);
1244 ///////////////////////////////////////////////////////////////////////////////
1245 ///Create a new prism defined by its faces and add it to the mesh.
1246 ///@return The created prism
1247 ///////////////////////////////////////////////////////////////////////////////
1249 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1250 const SMDS_MeshFace * f2,
1251 const SMDS_MeshFace * f3,
1252 const SMDS_MeshFace * f4,
1253 const SMDS_MeshFace * f5,
1254 const SMDS_MeshFace * f6)
1256 if (!hasConstructionFaces())
1258 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1261 ///////////////////////////////////////////////////////////////////////////////
1262 ///Create a new prism defined by its faces and add it to the mesh.
1263 ///@param ID The ID of the new volume
1264 ///@return The created prism
1265 ///////////////////////////////////////////////////////////////////////////////
1267 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1268 const SMDS_MeshFace * f2,
1269 const SMDS_MeshFace * f3,
1270 const SMDS_MeshFace * f4,
1271 const SMDS_MeshFace * f5,
1272 const SMDS_MeshFace * f6,
1275 if (!hasConstructionFaces())
1277 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1278 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1279 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1280 adjustmyCellsCapacity(ID);
1281 myCells[ID] = volume;
1282 myInfo.myNbPrisms++;
1284 if (!registerElement(ID, volume)) {
1285 registerElement(myElementIDFactory->GetFreeID(), volume);
1286 //RemoveElement(volume, false);
1292 ///////////////////////////////////////////////////////////////////////////////
1293 /// Add a polygon defined by its nodes IDs
1294 ///////////////////////////////////////////////////////////////////////////////
1296 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
1299 int nbNodes = nodes_ids.size();
1300 vector<const SMDS_MeshNode*> nodes (nbNodes);
1301 for (int i = 0; i < nbNodes; i++) {
1302 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1303 if (!nodes[i]) return NULL;
1305 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1308 ///////////////////////////////////////////////////////////////////////////////
1309 /// Add a polygon defined by its nodes
1310 ///////////////////////////////////////////////////////////////////////////////
1313 SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1316 SMDS_MeshFace * face;
1318 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1319 if (hasConstructionEdges())
1325 myNodeIds.resize( nodes.size() );
1326 for ( size_t i = 0; i < nodes.size(); ++i )
1327 myNodeIds[i] = nodes[i]->getVtkId();
1329 SMDS_VtkFace *facevtk = myFacePool->getNew();
1330 facevtk->initPoly(myNodeIds, this);
1331 if (!this->registerElement(ID,facevtk))
1333 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1334 myFacePool->destroy(facevtk);
1339 adjustmyCellsCapacity(ID);
1341 myInfo.myNbPolygons++;
1347 ///////////////////////////////////////////////////////////////////////////////
1348 /// Add a polygon defined by its nodes.
1349 /// An ID is automatically affected to the created face.
1350 ///////////////////////////////////////////////////////////////////////////////
1352 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1354 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1357 ///////////////////////////////////////////////////////////////////////////////
1358 /// Add a quadratic polygon defined by its nodes IDs
1359 ///////////////////////////////////////////////////////////////////////////////
1361 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
1364 vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
1365 for ( size_t i = 0; i < nodes.size(); i++) {
1366 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1367 if (!nodes[i]) return NULL;
1369 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
1372 ///////////////////////////////////////////////////////////////////////////////
1373 /// Add a quadratic polygon defined by its nodes
1374 ///////////////////////////////////////////////////////////////////////////////
1377 SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1380 SMDS_MeshFace * face;
1382 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1383 if (hasConstructionEdges())
1389 myNodeIds.resize( nodes.size() );
1390 for ( size_t i = 0; i < nodes.size(); ++i )
1391 myNodeIds[i] = nodes[i]->getVtkId();
1393 SMDS_VtkFace *facevtk = myFacePool->getNew();
1394 facevtk->initQuadPoly(myNodeIds, this);
1395 if (!this->registerElement(ID,facevtk))
1397 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1398 myFacePool->destroy(facevtk);
1402 adjustmyCellsCapacity(ID);
1404 myInfo.myNbQuadPolygons++;
1409 ///////////////////////////////////////////////////////////////////////////////
1410 /// Add a quadratic polygon defined by its nodes.
1411 /// An ID is automatically affected to the created face.
1412 ///////////////////////////////////////////////////////////////////////////////
1414 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1416 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1419 ///////////////////////////////////////////////////////////////////////////////
1420 /// Create a new polyhedral volume and add it to the mesh.
1421 /// @param ID The ID of the new volume
1422 /// @return The created volume or NULL if an element with this ID already exists
1423 /// or if input nodes are not found.
1424 ///////////////////////////////////////////////////////////////////////////////
1426 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1427 (const vector<int> & nodes_ids,
1428 const vector<int> & quantities,
1431 int nbNodes = nodes_ids.size();
1432 vector<const SMDS_MeshNode*> nodes (nbNodes);
1433 for (int i = 0; i < nbNodes; i++) {
1434 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1435 if (!nodes[i]) return NULL;
1437 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1440 ///////////////////////////////////////////////////////////////////////////////
1441 /// Create a new polyhedral volume and add it to the mesh.
1442 /// @param ID The ID of the new volume
1443 /// @return The created volume
1444 ///////////////////////////////////////////////////////////////////////////////
1447 SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
1448 const vector<int> & quantities,
1451 SMDS_MeshVolume* volume = 0;
1452 if ( nodes.empty() || quantities.empty() )
1454 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1455 if (hasConstructionFaces())
1459 else if (hasConstructionEdges())
1465 //#ifdef VTK_HAVE_POLYHEDRON
1466 myNodeIds.resize( nodes.size() );
1467 for ( size_t i = 0; i < nodes.size(); ++i )
1468 myNodeIds[i] = nodes[i]->getVtkId();
1470 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1471 volvtk->initPoly(myNodeIds, quantities, this);
1472 if (!this->registerElement(ID, volvtk))
1474 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1475 myVolumePool->destroy(volvtk);
1480 // for ( int i = 0; i < nodes.size(); ++i )
1481 // if ( !nodes[ i ] ) return 0;
1482 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1484 adjustmyCellsCapacity(ID);
1485 myCells[ID] = volume;
1486 myInfo.myNbPolyhedrons++;
1489 //#ifndef VTK_HAVE_POLYHEDRON
1490 // if (!registerElement(ID, volume))
1492 // registerElement(myElementIDFactory->GetFreeID(), volume);
1493 // //RemoveElement(volume, false);
1500 ///////////////////////////////////////////////////////////////////////////////
1501 /// Create a new polyhedral volume and add it to the mesh.
1502 /// @return The created volume
1503 ///////////////////////////////////////////////////////////////////////////////
1505 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1506 (const vector<const SMDS_MeshNode*> & nodes,
1507 const vector<int> & quantities)
1509 int ID = myElementIDFactory->GetFreeID();
1510 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1511 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1515 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1517 int ID = myElementIDFactory->GetFreeID();
1518 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1519 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1523 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1525 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1526 volvtk->init(vtkNodeIds, this);
1527 if (!this->registerElement(ID,volvtk))
1529 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1530 myVolumePool->destroy(volvtk);
1533 adjustmyCellsCapacity(ID);
1534 myCells[ID] = volvtk;
1535 vtkIdType aVtkType = volvtk->GetVtkType();
1539 myInfo.myNbTetras++;
1542 myInfo.myNbPyramids++;
1545 myInfo.myNbPrisms++;
1547 case VTK_HEXAHEDRON:
1550 case VTK_QUADRATIC_TETRA:
1551 myInfo.myNbQuadTetras++;
1553 case VTK_QUADRATIC_PYRAMID:
1554 myInfo.myNbQuadPyramids++;
1556 case VTK_QUADRATIC_WEDGE:
1557 myInfo.myNbQuadPrisms++;
1559 case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
1560 myInfo.myNbBiQuadPrisms++;
1562 case VTK_QUADRATIC_HEXAHEDRON:
1563 myInfo.myNbQuadHexas++;
1565 case VTK_TRIQUADRATIC_HEXAHEDRON:
1566 myInfo.myNbTriQuadHexas++;
1568 //#ifdef VTK_HAVE_POLYHEDRON
1569 case VTK_POLYHEDRON:
1570 myInfo.myNbPolyhedrons++;
1574 myInfo.myNbPolyhedrons++;
1580 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1582 int ID = myElementIDFactory->GetFreeID();
1583 SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
1584 if (f == NULL) myElementIDFactory->ReleaseID(ID);
1588 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1590 SMDS_VtkFace *facevtk = myFacePool->getNew();
1591 facevtk->init(vtkNodeIds, this);
1592 if (!this->registerElement(ID,facevtk))
1594 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1595 myFacePool->destroy(facevtk);
1598 adjustmyCellsCapacity(ID);
1599 myCells[ID] = facevtk;
1600 vtkIdType aVtkType = facevtk->GetVtkType();
1604 myInfo.myNbTriangles++;
1607 myInfo.myNbQuadrangles++;
1609 case VTK_QUADRATIC_TRIANGLE:
1610 myInfo.myNbQuadTriangles++;
1612 case VTK_QUADRATIC_QUAD:
1613 myInfo.myNbQuadQuadrangles++;
1615 case VTK_BIQUADRATIC_QUAD:
1616 myInfo.myNbBiQuadQuadrangles++;
1618 case VTK_BIQUADRATIC_TRIANGLE:
1619 myInfo.myNbBiQuadTriangles++;
1622 myInfo.myNbPolygons++;
1625 myInfo.myNbPolygons++;
1630 ///////////////////////////////////////////////////////////////////////////////
1631 /// Registers element with the given ID, maintains inverse connections
1632 ///////////////////////////////////////////////////////////////////////////////
1633 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1635 if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound
1637 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1642 element->myMeshId = myMeshId;
1644 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1646 int vtkId = cell->getVtkId();
1648 vtkId = myElementIDFactory->SetInVtkGrid(element);
1650 if (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector
1652 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1654 myCellIdVtkToSmds[vtkId] = ID;
1656 myElementIDFactory->updateMinMax(ID);
1660 //=======================================================================
1661 //function : MoveNode
1663 //=======================================================================
1665 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
1667 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
1668 node->setXYZ(x,y,z);
1671 ///////////////////////////////////////////////////////////////////////////////
1672 /// Return the node whose SMDS ID is 'ID'.
1673 ///////////////////////////////////////////////////////////////////////////////
1674 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1676 if (ID < 1 || ID >= (int)myNodes.size())
1680 return (const SMDS_MeshNode *)myNodes[ID];
1683 ///////////////////////////////////////////////////////////////////////////////
1684 /// Return the node whose VTK ID is 'vtkId'.
1685 ///////////////////////////////////////////////////////////////////////////////
1686 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1688 // TODO if needed use mesh->nodeIdFromVtkToSmds
1689 if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() )
1691 MESSAGE("------------------------------------------------------------------------- ");
1692 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1693 MESSAGE("------------------------------------------------------------------------- ");
1696 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1699 //////////////////////////////////////////////////////////////////////////////
1700 ///Create a triangle and add it to the current mesh. This method does not bind
1701 ///an ID to the create triangle.
1702 //////////////////////////////////////////////////////////////////////////////
1703 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1704 const SMDS_MeshNode * node2,
1705 const SMDS_MeshNode * node3,
1708 if ( !node1 || !node2 || !node3) return 0;
1709 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1710 if(hasConstructionEdges())
1712 SMDS_MeshEdge *edge1, *edge2, *edge3;
1713 edge1=FindEdgeOrCreate(node1,node2);
1714 edge2=FindEdgeOrCreate(node2,node3);
1715 edge3=FindEdgeOrCreate(node3,node1);
1717 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1718 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1719 adjustmyCellsCapacity(ID);
1721 myInfo.myNbTriangles++;
1726 // --- retrieve nodes ID
1727 myNodeIds.resize(3);
1728 myNodeIds[0] = node1->getVtkId();
1729 myNodeIds[1] = node2->getVtkId();
1730 myNodeIds[2] = node3->getVtkId();
1732 SMDS_MeshFace * face = 0;
1733 SMDS_VtkFace *facevtk = myFacePool->getNew();
1734 facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid
1735 if (!this->registerElement(ID,facevtk))
1737 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1738 myFacePool->destroy(facevtk);
1742 adjustmyCellsCapacity(ID);
1744 myInfo.myNbTriangles++;
1749 ////////////////////////////////////////////////////////////////////////////////
1750 ///Create a quadrangle and add it to the current mesh. This method does not bind
1751 ///an ID to the create triangle.
1752 ////////////////////////////////////////////////////////////////////////////////
1753 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1754 const SMDS_MeshNode * node2,
1755 const SMDS_MeshNode * node3,
1756 const SMDS_MeshNode * node4,
1759 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1760 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1761 if(hasConstructionEdges())
1763 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1764 edge1=FindEdgeOrCreate(node1,node2);
1765 edge2=FindEdgeOrCreate(node2,node3);
1766 edge3=FindEdgeOrCreate(node3,node4);
1767 edge4=FindEdgeOrCreate(node4,node1);
1769 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1770 adjustmyCellsCapacity(ID);
1772 myInfo.myNbQuadrangles++;
1777 // --- retrieve nodes ID
1778 myNodeIds.resize(4);
1779 myNodeIds[0] = node1->getVtkId();
1780 myNodeIds[1] = node2->getVtkId();
1781 myNodeIds[2] = node3->getVtkId();
1782 myNodeIds[3] = node4->getVtkId();
1784 SMDS_MeshFace * face = 0;
1785 SMDS_VtkFace *facevtk = myFacePool->getNew();
1786 facevtk->init(myNodeIds, this);
1787 if (!this->registerElement(ID,facevtk))
1789 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1790 myFacePool->destroy(facevtk);
1794 adjustmyCellsCapacity(ID);
1796 myInfo.myNbQuadrangles++;
1801 ///////////////////////////////////////////////////////////////////////////////
1802 /// Remove a node and all the elements which own this node
1803 ///////////////////////////////////////////////////////////////////////////////
1805 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1807 RemoveElement(node, true);
1810 ///////////////////////////////////////////////////////////////////////////////
1811 /// Remove an edge and all the elements which own this edge
1812 ///////////////////////////////////////////////////////////////////////////////
1814 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1816 RemoveElement(elem0d,true);
1819 ///////////////////////////////////////////////////////////////////////////////
1820 /// Remove an edge and all the elements which own this edge
1821 ///////////////////////////////////////////////////////////////////////////////
1823 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1825 RemoveElement(edge,true);
1828 ///////////////////////////////////////////////////////////////////////////////
1829 /// Remove an face and all the elements which own this face
1830 ///////////////////////////////////////////////////////////////////////////////
1832 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1834 RemoveElement(face, true);
1837 ///////////////////////////////////////////////////////////////////////////////
1839 ///////////////////////////////////////////////////////////////////////////////
1841 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1843 RemoveElement(volume, true);
1846 //=======================================================================
1847 //function : RemoveFromParent
1849 //=======================================================================
1851 bool SMDS_Mesh::RemoveFromParent()
1853 if (myParent==NULL) return false;
1854 else return (myParent->RemoveSubMesh(this));
1857 //=======================================================================
1858 //function : RemoveSubMesh
1860 //=======================================================================
1862 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1866 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1867 for (; itmsh!=myChildren.end() && !found; itmsh++)
1869 SMDS_Mesh * submesh = *itmsh;
1870 if (submesh == aMesh)
1873 myChildren.erase(itmsh);
1880 //=======================================================================
1881 //function : ChangeElementNodes
1883 //=======================================================================
1885 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1886 const SMDS_MeshNode * nodes[],
1889 // keep current nodes of elem
1890 set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1894 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1897 Ok = cell->vtkOrder(nodes, nbnodes);
1898 Ok = cell->ChangeNodes(nodes, nbnodes);
1901 if ( Ok ) { // update InverseElements
1903 set<const SMDS_MeshNode*>::iterator it;
1905 // AddInverseElement to new nodes
1906 for ( int i = 0; i < nbnodes; i++ ) {
1907 it = oldNodes.find( nodes[i] );
1908 if ( it == oldNodes.end() )
1910 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1912 // remove from oldNodes a node that remains in elem
1913 oldNodes.erase( it );
1915 // RemoveInverseElement from the nodes removed from elem
1916 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1918 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1919 n->RemoveInverseElement( cell );
1926 //=======================================================================
1927 //function : ChangePolyhedronNodes
1928 //purpose : to change nodes of polyhedral volume
1929 //=======================================================================
1930 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1931 const vector<const SMDS_MeshNode*>& nodes,
1932 const vector<int> & quantities)
1934 if (elem->GetType() != SMDSAbs_Volume) {
1935 MESSAGE("WRONG ELEM TYPE");
1939 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1944 // keep current nodes of elem
1945 set<const SMDS_MeshElement*> oldNodes;
1946 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1947 while (itn->more()) {
1948 oldNodes.insert(itn->next());
1952 // TODO remove this function
1953 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1959 // update InverseElements
1961 // AddInverseElement to new nodes
1962 int nbnodes = nodes.size();
1963 set<const SMDS_MeshElement*>::iterator it;
1964 for (int i = 0; i < nbnodes; i++) {
1965 it = oldNodes.find(nodes[i]);
1966 if (it == oldNodes.end()) {
1968 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1970 // remove from oldNodes a node that remains in elem
1975 // RemoveInverseElement from the nodes removed from elem
1976 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1977 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1978 (const_cast<SMDS_MeshElement *>( *it ));
1979 n->RemoveInverseElement(elem);
1986 //=======================================================================
1987 //function : Find0DElement
1989 //=======================================================================
1990 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1992 const SMDS_MeshNode * node = FindNode(idnode);
1993 if(node == NULL) return NULL;
1994 return Find0DElement(node);
1997 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1999 if (!node) return 0;
2000 const SMDS_Mesh0DElement* toReturn = NULL;
2001 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
2002 while (it1->more() && (toReturn == NULL)) {
2003 const SMDS_MeshElement* e = it1->next();
2004 if (e->NbNodes() == 1) {
2005 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
2011 //=======================================================================
2012 //function : FindBall
2014 //=======================================================================
2016 const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const
2018 const SMDS_MeshNode * node = FindNode(idnode);
2019 if(node == NULL) return NULL;
2020 return FindBall(node);
2023 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
2025 if (!node) return 0;
2026 const SMDS_BallElement* toReturn = NULL;
2027 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
2028 while (it1->more() && (toReturn == NULL)) {
2029 const SMDS_MeshElement* e = it1->next();
2030 if (e->GetGeomType() == SMDSGeom_BALL)
2031 toReturn = static_cast<const SMDS_BallElement*>(e);
2036 //=======================================================================
2037 //function : Find0DElementOrCreate
2039 //=======================================================================
2040 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
2042 // if (!node) return 0;
2043 // SMDS_Mesh0DElement * toReturn = NULL;
2044 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
2045 // if (toReturn == NULL) {
2046 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
2047 // toReturn = new SMDS_Mesh0DElement(node);
2048 // my0DElements.Add(toReturn);
2049 // myInfo.myNb0DElements++;
2055 //=======================================================================
2056 //function : FindEdge
2058 //=======================================================================
2060 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
2062 const SMDS_MeshNode * node1=FindNode(idnode1);
2063 const SMDS_MeshNode * node2=FindNode(idnode2);
2064 if((node1==NULL)||(node2==NULL)) return NULL;
2065 return FindEdge(node1,node2);
2068 //#include "Profiler.h"
2069 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2070 const SMDS_MeshNode * node2)
2072 if ( !node1 ) return 0;
2073 const SMDS_MeshEdge * toReturn=NULL;
2076 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
2079 while(it1->more()) {
2080 const SMDS_MeshElement * e = it1->next();
2081 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
2082 toReturn = static_cast<const SMDS_MeshEdge*>( e );
2091 //=======================================================================
2092 //function : FindEdgeOrCreate
2094 //=======================================================================
2096 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
2097 const SMDS_MeshNode * node2)
2099 if ( !node1 || !node2) return 0;
2100 SMDS_MeshEdge * toReturn=NULL;
2101 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
2102 if(toReturn==NULL) {
2103 if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2104 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
2105 adjustmyCellsCapacity(ID);
2106 myNodeIds.resize(2);
2107 myNodeIds[0] = node1->getVtkId();
2108 myNodeIds[1] = node2->getVtkId();
2110 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
2111 edgevtk->init(myNodeIds, this);
2112 if (!this->registerElement(ID,edgevtk))
2114 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
2115 myEdgePool->destroy(edgevtk);
2119 myCells[ID] = toReturn;
2126 //=======================================================================
2127 //function : FindEdge
2129 //=======================================================================
2131 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
2134 const SMDS_MeshNode * node1=FindNode(idnode1);
2135 const SMDS_MeshNode * node2=FindNode(idnode2);
2136 const SMDS_MeshNode * node3=FindNode(idnode3);
2137 return FindEdge(node1,node2,node3);
2140 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2141 const SMDS_MeshNode * node2,
2142 const SMDS_MeshNode * node3)
2144 if ( !node1 ) return 0;
2145 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
2146 while(it1->more()) {
2147 const SMDS_MeshElement * e = it1->next();
2148 if ( e->NbNodes() == 3 ) {
2149 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2150 while(it2->more()) {
2151 const SMDS_MeshElement* n = it2->next();
2161 return static_cast<const SMDS_MeshEdge *> (e);
2168 //=======================================================================
2169 //function : FindFace
2171 //=======================================================================
2173 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2176 const SMDS_MeshNode * node1=FindNode(idnode1);
2177 const SMDS_MeshNode * node2=FindNode(idnode2);
2178 const SMDS_MeshNode * node3=FindNode(idnode3);
2179 return FindFace(node1, node2, node3);
2182 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2183 const SMDS_MeshNode *node2,
2184 const SMDS_MeshNode *node3)
2186 if ( !node1 ) return 0;
2187 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2188 while(it1->more()) {
2189 const SMDS_MeshElement * e = it1->next();
2190 if ( e->NbNodes() == 3 ) {
2191 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2192 while(it2->more()) {
2193 const SMDS_MeshElement* n = it2->next();
2203 return static_cast<const SMDS_MeshFace *> (e);
2209 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2210 const SMDS_MeshNode *node2,
2211 const SMDS_MeshNode *node3)
2213 SMDS_MeshFace * toReturn=NULL;
2214 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
2215 if(toReturn==NULL) {
2216 int ID = myElementIDFactory->GetFreeID();
2217 toReturn = createTriangle(node1,node2,node3, ID);
2223 //=======================================================================
2224 //function : FindFace
2226 //=======================================================================
2228 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2229 int idnode3, int idnode4) const
2231 const SMDS_MeshNode * node1=FindNode(idnode1);
2232 const SMDS_MeshNode * node2=FindNode(idnode2);
2233 const SMDS_MeshNode * node3=FindNode(idnode3);
2234 const SMDS_MeshNode * node4=FindNode(idnode4);
2235 return FindFace(node1, node2, node3, node4);
2238 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2239 const SMDS_MeshNode *node2,
2240 const SMDS_MeshNode *node3,
2241 const SMDS_MeshNode *node4)
2243 if ( !node1 ) return 0;
2244 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2245 while(it1->more()) {
2246 const SMDS_MeshElement * e = it1->next();
2247 if ( e->NbNodes() == 4 ) {
2248 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2249 while(it2->more()) {
2250 const SMDS_MeshElement* n = it2->next();
2261 return static_cast<const SMDS_MeshFace *> (e);
2267 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2268 const SMDS_MeshNode *node2,
2269 const SMDS_MeshNode *node3,
2270 const SMDS_MeshNode *node4)
2272 SMDS_MeshFace * toReturn=NULL;
2273 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2274 if(toReturn==NULL) {
2275 int ID = myElementIDFactory->GetFreeID();
2276 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2282 //=======================================================================
2283 //function : FindFace
2284 //purpose :quadratic triangle
2285 //=======================================================================
2287 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2288 int idnode3, int idnode4,
2289 int idnode5, int idnode6) const
2291 const SMDS_MeshNode * node1 = FindNode(idnode1);
2292 const SMDS_MeshNode * node2 = FindNode(idnode2);
2293 const SMDS_MeshNode * node3 = FindNode(idnode3);
2294 const SMDS_MeshNode * node4 = FindNode(idnode4);
2295 const SMDS_MeshNode * node5 = FindNode(idnode5);
2296 const SMDS_MeshNode * node6 = FindNode(idnode6);
2297 return FindFace(node1, node2, node3, node4, node5, node6);
2300 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2301 const SMDS_MeshNode *node2,
2302 const SMDS_MeshNode *node3,
2303 const SMDS_MeshNode *node4,
2304 const SMDS_MeshNode *node5,
2305 const SMDS_MeshNode *node6)
2307 if ( !node1 ) return 0;
2308 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2309 while(it1->more()) {
2310 const SMDS_MeshElement * e = it1->next();
2311 if ( e->NbNodes() == 6 ) {
2312 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2313 while(it2->more()) {
2314 const SMDS_MeshElement* n = it2->next();
2327 return static_cast<const SMDS_MeshFace *> (e);
2334 //=======================================================================
2335 //function : FindFace
2336 //purpose : quadratic quadrangle
2337 //=======================================================================
2339 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2340 int idnode3, int idnode4,
2341 int idnode5, int idnode6,
2342 int idnode7, int idnode8) const
2344 const SMDS_MeshNode * node1 = FindNode(idnode1);
2345 const SMDS_MeshNode * node2 = FindNode(idnode2);
2346 const SMDS_MeshNode * node3 = FindNode(idnode3);
2347 const SMDS_MeshNode * node4 = FindNode(idnode4);
2348 const SMDS_MeshNode * node5 = FindNode(idnode5);
2349 const SMDS_MeshNode * node6 = FindNode(idnode6);
2350 const SMDS_MeshNode * node7 = FindNode(idnode7);
2351 const SMDS_MeshNode * node8 = FindNode(idnode8);
2352 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2355 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2356 const SMDS_MeshNode *node2,
2357 const SMDS_MeshNode *node3,
2358 const SMDS_MeshNode *node4,
2359 const SMDS_MeshNode *node5,
2360 const SMDS_MeshNode *node6,
2361 const SMDS_MeshNode *node7,
2362 const SMDS_MeshNode *node8)
2364 if ( !node1 ) return 0;
2365 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2366 while(it1->more()) {
2367 const SMDS_MeshElement * e = it1->next();
2368 if ( e->NbNodes() == 8 ) {
2369 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2370 while(it2->more()) {
2371 const SMDS_MeshElement* n = it2->next();
2386 return static_cast<const SMDS_MeshFace *> (e);
2393 //=======================================================================
2394 //function : FindElement
2396 //=======================================================================
2398 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2400 if ( IDelem <= 0 || IDelem >= (int)myCells.size() )
2404 return myCells[IDelem];
2407 //=======================================================================
2408 //function : FindFace
2409 //purpose : find polygon
2410 //=======================================================================
2412 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2414 int nbnodes = nodes_ids.size();
2415 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2416 for (int inode = 0; inode < nbnodes; inode++) {
2417 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2418 if (node == NULL) return NULL;
2419 poly_nodes[inode] = node;
2421 return FindFace(poly_nodes);
2424 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2426 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2430 //================================================================================
2432 * \brief Return element based on all given nodes
2433 * \param nodes - node of element
2434 * \param type - type of element
2435 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2436 * \retval const SMDS_MeshElement* - found element or NULL
2438 //================================================================================
2440 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2441 const SMDSAbs_ElementType type,
2442 const bool noMedium)
2444 if ( nodes.size() > 0 && nodes[0] )
2446 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2449 const SMDS_MeshElement* e = itF->next();
2450 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2451 if ( nbNodesToCheck == (int)nodes.size() )
2453 for ( size_t i = 1; e && i < nodes.size(); ++i )
2455 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2456 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2467 //================================================================================
2469 * \brief Return elements including all given nodes
2470 * \param [in] nodes - nodes to find elements around
2471 * \param [out] foundElems - the found elements
2472 * \param [in] type - type of elements to find
2473 * \return int - a number of found elements
2475 //================================================================================
2477 int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
2478 std::vector<const SMDS_MeshElement *>& foundElems,
2479 const SMDSAbs_ElementType type)
2481 // chose a node with minimal number of inverse elements
2482 const SMDS_MeshNode* n0 = nodes[0];
2483 int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
2484 for ( size_t i = 1; i < nodes.size(); ++i )
2485 if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
2488 minNbInverse = n0->NbInverseElements( type );
2494 foundElems.reserve( minNbInverse );
2495 SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
2496 while ( eIt->more() )
2498 const SMDS_MeshElement* e = eIt->next();
2499 bool includeAll = true;
2500 for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
2501 if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
2504 foundElems.push_back( e );
2507 return foundElems.size();
2510 //=======================================================================
2511 //function : DumpNodes
2513 //=======================================================================
2515 void SMDS_Mesh::DumpNodes() const
2517 SMDS_NodeIteratorPtr itnode=nodesIterator();
2518 while(itnode->more()) ; //MESSAGE(itnode->next());
2521 //=======================================================================
2522 //function : Dump0DElements
2524 //=======================================================================
2525 void SMDS_Mesh::Dump0DElements() const
2527 SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement);
2528 while(it0d->more()) ; //MESSAGE(it0d->next());
2531 //=======================================================================
2532 //function : DumpEdges
2534 //=======================================================================
2536 void SMDS_Mesh::DumpEdges() const
2538 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2539 while(itedge->more()) ; //MESSAGE(itedge->next());
2542 //=======================================================================
2543 //function : DumpFaces
2545 //=======================================================================
2547 void SMDS_Mesh::DumpFaces() const
2549 SMDS_FaceIteratorPtr itface=facesIterator();
2550 while(itface->more()) ; //MESSAGE(itface->next());
2553 //=======================================================================
2554 //function : DumpVolumes
2556 //=======================================================================
2558 void SMDS_Mesh::DumpVolumes() const
2560 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2561 while(itvol->more()) ; //MESSAGE(itvol->next());
2564 //=======================================================================
2565 //function : DebugStats
2567 //=======================================================================
2569 void SMDS_Mesh::DebugStats() const
2571 MESSAGE("Debug stats of mesh : ");
2573 MESSAGE("===== NODES ====="<<NbNodes());
2574 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2575 MESSAGE("===== EDGES ====="<<NbEdges());
2576 MESSAGE("===== FACES ====="<<NbFaces());
2577 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2579 MESSAGE("End Debug stats of mesh ");
2583 SMDS_NodeIteratorPtr itnode=nodesIterator();
2584 int sizeofnodes = 0;
2585 int sizeoffaces = 0;
2587 while(itnode->more())
2589 const SMDS_MeshNode *node = itnode->next();
2591 sizeofnodes += sizeof(*node);
2593 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2596 const SMDS_MeshElement *me = it->next();
2597 sizeofnodes += sizeof(me);
2601 SMDS_FaceIteratorPtr itface=facesIterator();
2602 while(itface->more())
2604 const SMDS_MeshElement *face = itface->next();
2605 sizeoffaces += sizeof(*face);
2608 MESSAGE("total size of node elements = " << sizeofnodes);;
2609 MESSAGE("total size of face elements = " << sizeoffaces);;
2614 ///////////////////////////////////////////////////////////////////////////////
2615 /// Return the number of nodes
2616 ///////////////////////////////////////////////////////////////////////////////
2617 int SMDS_Mesh::NbNodes() const
2619 return myInfo.NbNodes();
2622 ///////////////////////////////////////////////////////////////////////////////
2623 /// Return the number of elements
2624 ///////////////////////////////////////////////////////////////////////////////
2625 int SMDS_Mesh::NbElements() const
2627 return myInfo.NbElements();
2629 ///////////////////////////////////////////////////////////////////////////////
2630 /// Return the number of 0D elements
2631 ///////////////////////////////////////////////////////////////////////////////
2632 int SMDS_Mesh::Nb0DElements() const
2634 return myInfo.Nb0DElements();
2637 ///////////////////////////////////////////////////////////////////////////////
2638 /// Return the number of 0D elements
2639 ///////////////////////////////////////////////////////////////////////////////
2640 int SMDS_Mesh::NbBalls() const
2642 return myInfo.NbBalls();
2645 ///////////////////////////////////////////////////////////////////////////////
2646 /// Return the number of edges (including construction edges)
2647 ///////////////////////////////////////////////////////////////////////////////
2648 int SMDS_Mesh::NbEdges() const
2650 return myInfo.NbEdges();
2653 ///////////////////////////////////////////////////////////////////////////////
2654 /// Return the number of faces (including construction faces)
2655 ///////////////////////////////////////////////////////////////////////////////
2656 int SMDS_Mesh::NbFaces() const
2658 return myInfo.NbFaces();
2661 ///////////////////////////////////////////////////////////////////////////////
2662 /// Return the number of volumes
2663 ///////////////////////////////////////////////////////////////////////////////
2664 int SMDS_Mesh::NbVolumes() const
2666 return myInfo.NbVolumes();
2669 ///////////////////////////////////////////////////////////////////////////////
2670 /// Return the number of child mesh of this mesh.
2671 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
2672 ///////////////////////////////////////////////////////////////////////////////
2673 int SMDS_Mesh::NbSubMesh() const
2675 return myChildren.size();
2678 ///////////////////////////////////////////////////////////////////////////////
2679 /// Destroy the mesh and all its elements
2680 /// All pointer on elements owned by this mesh become illegals.
2681 ///////////////////////////////////////////////////////////////////////////////
2682 SMDS_Mesh::~SMDS_Mesh()
2684 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2685 while(itc!=myChildren.end())
2693 delete myNodeIDFactory;
2694 delete myElementIDFactory;
2698 SMDS_ElemIteratorPtr eIt = elementsIterator();
2699 while ( eIt->more() )
2701 const SMDS_MeshElement *elem = eIt->next();
2702 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2704 SMDS_NodeIteratorPtr itn = nodesIterator();
2707 const SMDS_MeshNode *node = itn->next();
2708 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2709 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2715 delete myVolumePool;
2721 //================================================================================
2723 * \brief Clear all data
2725 //================================================================================
2727 void SMDS_Mesh::Clear()
2731 SMDS_ElemIteratorPtr eIt = elementsIterator();
2732 while ( eIt->more() )
2734 const SMDS_MeshElement *elem = eIt->next();
2735 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2737 SMDS_NodeIteratorPtr itn = nodesIterator();
2740 const SMDS_MeshNode *node = itn->next();
2741 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2746 myNodeIDFactory->Clear();
2747 myElementIDFactory->Clear();
2750 myVolumePool->clear();
2751 myFacePool->clear();
2752 myEdgePool->clear();
2753 myBallPool->clear();
2755 clearVector( myCells );
2756 clearVector( myCellIdVtkToSmds );
2758 SMDS_NodeIteratorPtr itn = nodesIterator();
2761 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2762 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2763 //myNodePool->destroy(node);
2765 myNodePool->clear();
2766 clearVector( myNodes );
2768 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2769 while(itc!=myChildren.end())
2780 myGrid->Initialize();
2782 vtkPoints* points = vtkPoints::New();
2783 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2784 // using double type for storing coordinates of nodes instead float.
2785 points->SetDataType(VTK_DOUBLE);
2786 points->SetNumberOfPoints( 0 );
2787 myGrid->SetPoints( points );
2789 myGrid->DeleteLinks();
2792 ///////////////////////////////////////////////////////////////////////////////
2793 /// Return true if this mesh create faces with edges.
2794 /// A false returned value mean that faces are created with nodes. A concequence
2795 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2796 ///////////////////////////////////////////////////////////////////////////////
2797 bool SMDS_Mesh::hasConstructionEdges()
2799 return myHasConstructionEdges;
2802 ///////////////////////////////////////////////////////////////////////////////
2803 /// Return true if this mesh create volumes with faces
2804 /// A false returned value mean that volumes are created with nodes or edges.
2805 /// (see hasConstructionEdges)
2806 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2808 ///////////////////////////////////////////////////////////////////////////////
2809 bool SMDS_Mesh::hasConstructionFaces()
2811 return myHasConstructionFaces;
2814 ///////////////////////////////////////////////////////////////////////////////
2815 /// Return true if nodes are linked to the finit elements, they are belonging to.
2816 /// Currently, It always return true.
2817 ///////////////////////////////////////////////////////////////////////////////
2818 bool SMDS_Mesh::hasInverseElements()
2820 return myHasInverseElements;
2823 ///////////////////////////////////////////////////////////////////////////////
2824 /// Make this mesh creating construction edges (see hasConstructionEdges)
2825 /// @param b true to have construction edges, else false.
2826 ///////////////////////////////////////////////////////////////////////////////
2827 void SMDS_Mesh::setConstructionEdges(bool b)
2829 myHasConstructionEdges=b;
2832 ///////////////////////////////////////////////////////////////////////////////
2833 /// Make this mesh creating construction faces (see hasConstructionFaces)
2834 /// @param b true to have construction faces, else false.
2835 ///////////////////////////////////////////////////////////////////////////////
2836 void SMDS_Mesh::setConstructionFaces(bool b)
2838 myHasConstructionFaces=b;
2841 ///////////////////////////////////////////////////////////////////////////////
2842 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2843 /// @param b true to link nodes to elements, else false.
2844 ///////////////////////////////////////////////////////////////////////////////
2845 void SMDS_Mesh::setInverseElements(bool b)
2847 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2848 myHasInverseElements=b;
2853 //================================================================================
2855 * \brief Iterator on elements in id increasing order
2857 //================================================================================
2859 template <typename ELEM=const SMDS_MeshElement*>
2860 class IdSortedIterator : public SMDS_Iterator<ELEM>
2862 SMDS_MeshElementIDFactory& myIDFact;
2863 int myID, myMaxID, myNbFound, myTotalNb;
2864 SMDSAbs_ElementType myType;
2868 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2869 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2871 :myIDFact( const_cast<SMDS_MeshElementIDFactory&>(fact) ),
2872 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2884 ELEM current = myElem;
2886 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2887 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2888 && myElem->GetType() != myType )
2891 myNbFound += bool(myElem);
2897 //================================================================================
2899 * \brief Iterator on vector of elements, possibly being resized while iteration
2901 //================================================================================
2903 template<typename RETURN_VALUE,
2904 typename VECTOR_VALUE=SMDS_MeshCell*,
2905 typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
2906 class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
2908 const std::vector<VECTOR_VALUE>& _vector;
2911 VALUE_FILTER _filter;
2913 ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
2914 const VALUE_FILTER& filter=VALUE_FILTER() )
2915 :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
2917 if ( _more && !_filter( _vector[ _index ]))
2924 virtual RETURN_VALUE next()
2926 if ( !_more ) return NULL;
2927 VECTOR_VALUE current = _vector[ _index ];
2929 while ( !_more && ++_index < _vector.size() )
2930 _more = _filter( _vector[ _index ]);
2931 return (RETURN_VALUE) current;
2936 ///////////////////////////////////////////////////////////////////////////////
2937 /// Return an iterator on nodes of the current mesh factory
2938 ///////////////////////////////////////////////////////////////////////////////
2940 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2942 // naturally always sorted by ID
2943 typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
2944 return SMDS_NodeIteratorPtr( new TIterator(myNodes));
2947 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
2949 // naturally always sorted by ID
2950 typedef ElemVecIterator
2951 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
2952 return SMDS_ElemIteratorPtr
2953 (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
2956 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
2958 if ( type == SMDSEntity_Node )
2960 typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
2961 return SMDS_ElemIteratorPtr( new TIterator(myNodes));
2963 // naturally always sorted by ID
2964 typedef ElemVecIterator
2965 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
2966 return SMDS_ElemIteratorPtr
2967 (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
2970 ///////////////////////////////////////////////////////////////////////////////
2971 /// Return an iterator on elements of the current mesh factory
2972 ///////////////////////////////////////////////////////////////////////////////
2973 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2975 // naturally always sorted by ID
2979 return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
2982 return SMDS_ElemIteratorPtr
2983 ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
2986 typedef ElemVecIterator
2987 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
2988 return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
2990 return SMDS_ElemIteratorPtr();
2993 ///////////////////////////////////////////////////////////////////////////////
2994 ///Return an iterator on edges of the current mesh.
2995 ///////////////////////////////////////////////////////////////////////////////
2997 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2999 // naturally always sorted by ID
3000 typedef ElemVecIterator
3001 < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3002 return SMDS_EdgeIteratorPtr
3003 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
3006 ///////////////////////////////////////////////////////////////////////////////
3007 ///Return an iterator on faces of the current mesh.
3008 ///////////////////////////////////////////////////////////////////////////////
3010 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
3012 // naturally always sorted by ID
3013 typedef ElemVecIterator
3014 < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3015 return SMDS_FaceIteratorPtr
3016 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
3019 ///////////////////////////////////////////////////////////////////////////////
3020 ///Return an iterator on volumes of the current mesh.
3021 ///////////////////////////////////////////////////////////////////////////////
3023 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
3025 // naturally always sorted by ID
3026 typedef ElemVecIterator
3027 < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3028 return SMDS_VolumeIteratorPtr
3029 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
3032 ///////////////////////////////////////////////////////////////////////////////
3033 /// Do intersection of sets (more than 2)
3034 ///////////////////////////////////////////////////////////////////////////////
3035 static set<const SMDS_MeshElement*> * intersectionOfSets(
3036 set<const SMDS_MeshElement*> vs[], int numberOfSets)
3038 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
3039 set<const SMDS_MeshElement*>* rsetB;
3041 for(int i=0; i<numberOfSets-1; i++)
3043 rsetB=new set<const SMDS_MeshElement*>();
3045 rsetA->begin(), rsetA->end(),
3046 vs[i+1].begin(), vs[i+1].end(),
3047 inserter(*rsetB, rsetB->begin()));
3054 ///////////////////////////////////////////////////////////////////////////////
3055 /// Return the list of finite elements owning the given element: elements
3056 /// containing all the nodes of the given element, for instance faces and
3057 /// volumes containing a given edge.
3058 ///////////////////////////////////////////////////////////////////////////////
3059 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
3061 int numberOfSets=element->NbNodes();
3062 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
3064 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
3067 while ( itNodes->more() )
3069 const SMDS_MeshElement* node = itNodes->next();
3071 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
3072 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3074 while ( itFe->more() )
3076 const SMDS_MeshElement* elem = itFe->next();
3078 initSet[i].insert(elem);
3083 set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
3088 ///////////////////////////////////////////////////////////////////////////////
3089 /// Return the list of nodes used only by the given elements
3090 ///////////////////////////////////////////////////////////////////////////////
3091 static set<const SMDS_MeshElement*> * getExclusiveNodes(set<const SMDS_MeshElement*>& elements)
3093 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
3094 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
3096 while(itElements!=elements.end())
3098 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
3101 while(itNodes->more())
3103 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
3104 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3105 set<const SMDS_MeshElement*> s;
3107 s.insert(itFe->next());
3108 if(s==elements) toReturn->insert(n);
3114 ///////////////////////////////////////////////////////////////////////////////
3115 ///Find the children of an element that are made of given nodes
3116 ///@param setOfChildren The set in which matching children will be inserted
3117 ///@param element The element were to search matching children
3118 ///@param nodes The nodes that the children must have to be selected
3119 ///////////////////////////////////////////////////////////////////////////////
3120 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
3121 const SMDS_MeshElement * element,
3122 set<const SMDS_MeshElement*>& nodes)
3124 switch(element->GetType())
3127 MESSAGE("Internal Error: This should not happen");
3129 case SMDSAbs_0DElement:
3136 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3139 const SMDS_MeshElement * e=itn->next();
3140 if(nodes.find(e)!=nodes.end())
3142 setOfChildren.insert(element);
3149 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3152 const SMDS_MeshElement * e=itn->next();
3153 if(nodes.find(e)!=nodes.end())
3155 setOfChildren.insert(element);
3159 if(hasConstructionEdges())
3161 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3163 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3166 case SMDSAbs_Volume:
3168 if(hasConstructionFaces())
3170 SMDS_ElemIteratorPtr ite=element->facesIterator();
3172 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3174 else if(hasConstructionEdges())
3176 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3178 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3181 case SMDSAbs_NbElementTypes:
3182 case SMDSAbs_All: break;
3186 ///////////////////////////////////////////////////////////////////////////////
3187 ///@param elem The element to delete
3188 ///@param removenodes if true remaining nodes will be removed
3189 ///////////////////////////////////////////////////////////////////////////////
3190 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3191 const bool removenodes)
3193 list<const SMDS_MeshElement *> removedElems;
3194 list<const SMDS_MeshElement *> removedNodes;
3195 RemoveElement( elem, removedElems, removedNodes, removenodes );
3198 ///////////////////////////////////////////////////////////////////////////////
3199 ///@param elem The element to delete
3200 ///@param removedElems to be filled with all removed elements
3201 ///@param removedNodes to be filled with all removed nodes
3202 ///@param removenodes if true remaining nodes will be removed
3203 ///////////////////////////////////////////////////////////////////////////////
3204 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3205 list<const SMDS_MeshElement *>& removedElems,
3206 list<const SMDS_MeshElement *>& removedNodes,
3209 // get finite elements built on elem
3210 set<const SMDS_MeshElement*> * s1;
3211 if ( (elem->GetType() == SMDSAbs_0DElement)
3212 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3213 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3214 || (elem->GetType() == SMDSAbs_Volume) )
3216 s1 = new set<const SMDS_MeshElement*> ();
3220 s1 = getFinitElements(elem);
3222 // get exclusive nodes (which would become free afterwards)
3223 set<const SMDS_MeshElement*> * s2;
3224 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3226 // do not remove nodes except elem
3227 s2 = new set<const SMDS_MeshElement*> ();
3232 s2 = getExclusiveNodes(*s1);
3234 // form the set of finite and construction elements to remove
3235 set<const SMDS_MeshElement*> s3;
3236 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3237 while (it != s1->end())
3239 addChildrenWithNodes(s3, *it, *s2);
3243 if (elem->GetType() != SMDSAbs_Node)
3246 // remove finite and construction elements
3248 while (it != s3.end())
3250 // Remove element from <InverseElements> of its nodes
3251 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3254 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3255 n->RemoveInverseElement((*it));
3257 int IdToRemove = (*it)->GetID();
3258 int vtkid = (*it)->getVtkId();
3259 switch ((*it)->GetType())
3262 MYASSERT("Internal Error: This should not happen");
3264 case SMDSAbs_0DElement:
3265 if (IdToRemove >= 0)
3267 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3270 removedElems.push_back((*it));
3271 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3275 if (IdToRemove >= 0)
3277 myCells[IdToRemove] = 0;
3278 myInfo.RemoveEdge(*it);
3280 removedElems.push_back((*it));
3281 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3282 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3283 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3285 ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
3290 if (IdToRemove >= 0)
3292 myCells[IdToRemove] = 0;
3293 myInfo.RemoveFace(*it);
3295 removedElems.push_back((*it));
3296 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3297 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3298 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3300 ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
3304 case SMDSAbs_Volume:
3305 if (IdToRemove >= 0)
3307 myCells[IdToRemove] = 0;
3308 myInfo.RemoveVolume(*it);
3310 removedElems.push_back((*it));
3311 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3312 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3313 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3315 ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
3320 if (IdToRemove >= 0)
3322 myCells[IdToRemove] = 0;
3325 removedElems.push_back((*it));
3326 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3327 if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
3328 myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
3330 ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
3335 case SMDSAbs_All: // avoid compilation warning
3336 case SMDSAbs_NbElementTypes: break;
3340 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3345 // remove exclusive (free) nodes
3349 while (it != s2->end())
3351 int IdToRemove = (*it)->GetID();
3352 if (IdToRemove >= 0)
3354 myNodes[IdToRemove] = 0;
3357 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3358 removedNodes.push_back((*it));
3359 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3361 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3362 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3375 ///////////////////////////////////////////////////////////////////////////////
3376 ///@param elem The element to delete
3377 ///////////////////////////////////////////////////////////////////////////////
3378 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3380 int elemId = elem->GetID();
3381 int vtkId = elem->getVtkId();
3382 SMDSAbs_ElementType aType = elem->GetType();
3383 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3384 if ( aType == SMDSAbs_Node )
3386 // only free node can be removed by this method
3387 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3388 if ( n->NbInverseElements() == 0 ) { // free node
3389 myNodes[elemId] = 0;
3391 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3392 ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( 0, -1, -1 ); // avoid reuse
3393 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3394 myNodeIDFactory->ReleaseID(elemId, vtkId);
3399 if (hasConstructionEdges() || hasConstructionFaces())
3400 // this methods is only for meshes without descendants
3403 // Remove element from <InverseElements> of its nodes
3404 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3405 while (itn->more()) {
3406 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3407 (const_cast<SMDS_MeshElement *>(itn->next()));
3408 n->RemoveInverseElement(elem);
3411 // in meshes without descendants elements are always free
3413 case SMDSAbs_0DElement:
3414 myCells[elemId] = 0;
3415 myInfo.remove(elem);
3420 myCells[elemId] = 0;
3421 myInfo.RemoveEdge(elem);
3422 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3425 myCells[elemId] = 0;
3426 myInfo.RemoveFace(elem);
3427 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3429 case SMDSAbs_Volume:
3430 myCells[elemId] = 0;
3431 myInfo.RemoveVolume(elem);
3432 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3435 myCells[elemId] = 0;
3436 myInfo.remove(elem);
3437 myBallPool->destroy(static_cast<SMDS_BallElement*>(todest));
3442 myElementIDFactory->ReleaseID(elemId, vtkId);
3444 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3445 // --- to do: keep vtkid in a list of reusable cells
3448 ((SMDS_MeshElement*) elem)->init( 0, -1, -1 ); // avoid reuse
3453 * Checks if the element is present in mesh.
3454 * Useful to determine dead pointers.
3456 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3458 // we should not rely on validity of *elem, so iterate on containers
3459 // of all types in the hope of finding <elem> somewhere there
3460 SMDS_NodeIteratorPtr itn = nodesIterator();
3462 if (elem == itn->next())
3464 SMDS_ElemIteratorPtr ite = elementsIterator();
3466 if (elem == ite->next())
3471 //=======================================================================
3472 //function : MaxNodeID
3474 //=======================================================================
3476 int SMDS_Mesh::MaxNodeID() const
3478 return myNodeIDFactory->GetMaxID();
3481 //=======================================================================
3482 //function : MinNodeID
3484 //=======================================================================
3486 int SMDS_Mesh::MinNodeID() const
3488 return myNodeIDFactory->GetMinID();
3491 //=======================================================================
3492 //function : MaxElementID
3494 //=======================================================================
3496 int SMDS_Mesh::MaxElementID() const
3498 return myElementIDFactory->GetMaxID();
3501 //=======================================================================
3502 //function : MinElementID
3504 //=======================================================================
3506 int SMDS_Mesh::MinElementID() const
3508 return myElementIDFactory->GetMinID();
3511 //=======================================================================
3512 //function : Renumber
3513 //purpose : Renumber all nodes or elements.
3514 //=======================================================================
3516 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3521 SMDS_MeshNodeIDFactory * idFactory =
3522 isNodes ? myNodeIDFactory : myElementIDFactory;
3524 // get existing elements in the order of ID increasing
3525 map<int,SMDS_MeshElement*> elemMap;
3526 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3527 while ( idElemIt->more() ) {
3528 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3529 int id = elem->GetID();
3530 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3532 // release their ids
3533 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3535 // for ( ; elemIt != elemMap.end(); elemIt++ )
3537 // int id = (*elemIt).first;
3538 // idFactory->ReleaseID( id );
3542 elemIt = elemMap.begin();
3543 for ( ; elemIt != elemMap.end(); elemIt++ )
3545 idFactory->BindID( ID, (*elemIt).second );
3550 //=======================================================================
3551 //function : GetElementType
3552 //purpose : Return type of element or node with id
3553 //=======================================================================
3555 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3557 SMDS_MeshElement* elem = 0;
3559 elem = myElementIDFactory->MeshElement( id );
3561 elem = myNodeIDFactory->MeshElement( id );
3565 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3569 return elem->GetType();
3574 //********************************************************************
3575 //********************************************************************
3576 //******** *********
3577 //***** Methods for addition of quadratic elements ******
3578 //******** *********
3579 //********************************************************************
3580 //********************************************************************
3582 //=======================================================================
3583 //function : AddEdgeWithID
3585 //=======================================================================
3586 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3588 return SMDS_Mesh::AddEdgeWithID
3589 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3590 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3591 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3595 //=======================================================================
3596 //function : AddEdge
3598 //=======================================================================
3599 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3600 const SMDS_MeshNode* n2,
3601 const SMDS_MeshNode* n12)
3603 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3606 //=======================================================================
3607 //function : AddEdgeWithID
3609 //=======================================================================
3610 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3611 const SMDS_MeshNode * n2,
3612 const SMDS_MeshNode * n12,
3615 if ( !n1 || !n2 || !n12 ) return 0;
3617 // --- retrieve nodes ID
3618 myNodeIds.resize(3);
3619 myNodeIds[0] = n1->getVtkId();
3620 myNodeIds[1] = n2->getVtkId();
3621 myNodeIds[2] = n12->getVtkId();
3623 SMDS_MeshEdge * edge = 0;
3624 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3625 edgevtk->init(myNodeIds, this);
3626 if (!this->registerElement(ID,edgevtk))
3628 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3629 myEdgePool->destroy(edgevtk);
3633 adjustmyCellsCapacity(ID);
3635 myInfo.myNbQuadEdges++;
3637 // if (!registerElement(ID, edge)) {
3638 // RemoveElement(edge, false);
3646 //=======================================================================
3647 //function : AddFace
3649 //=======================================================================
3650 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3651 const SMDS_MeshNode * n2,
3652 const SMDS_MeshNode * n3,
3653 const SMDS_MeshNode * n12,
3654 const SMDS_MeshNode * n23,
3655 const SMDS_MeshNode * n31)
3657 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3658 myElementIDFactory->GetFreeID());
3661 //=======================================================================
3662 //function : AddFaceWithID
3664 //=======================================================================
3665 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3666 int n12,int n23,int n31, int ID)
3668 return SMDS_Mesh::AddFaceWithID
3669 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3670 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3671 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3672 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3673 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3674 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3678 //=======================================================================
3679 //function : AddFaceWithID
3681 //=======================================================================
3682 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3683 const SMDS_MeshNode * n2,
3684 const SMDS_MeshNode * n3,
3685 const SMDS_MeshNode * n12,
3686 const SMDS_MeshNode * n23,
3687 const SMDS_MeshNode * n31,
3690 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3691 if(hasConstructionEdges()) {
3692 // creation quadratic edges - not implemented
3697 // --- retrieve nodes ID
3698 myNodeIds.resize(6);
3699 myNodeIds[0] = n1->getVtkId();
3700 myNodeIds[1] = n2->getVtkId();
3701 myNodeIds[2] = n3->getVtkId();
3702 myNodeIds[3] = n12->getVtkId();
3703 myNodeIds[4] = n23->getVtkId();
3704 myNodeIds[5] = n31->getVtkId();
3706 SMDS_MeshFace * face = 0;
3707 SMDS_VtkFace *facevtk = myFacePool->getNew();
3708 facevtk->init(myNodeIds, this);
3709 if (!this->registerElement(ID,facevtk))
3711 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3712 myFacePool->destroy(facevtk);
3716 adjustmyCellsCapacity(ID);
3718 myInfo.myNbQuadTriangles++;
3720 // if (!registerElement(ID, face)) {
3721 // RemoveElement(face, false);
3729 //=======================================================================
3730 //function : AddFace
3732 //=======================================================================
3733 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3734 const SMDS_MeshNode * n2,
3735 const SMDS_MeshNode * n3,
3736 const SMDS_MeshNode * n12,
3737 const SMDS_MeshNode * n23,
3738 const SMDS_MeshNode * n31,
3739 const SMDS_MeshNode * nCenter)
3741 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
3742 myElementIDFactory->GetFreeID());
3745 //=======================================================================
3746 //function : AddFaceWithID
3748 //=======================================================================
3749 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3750 int n12,int n23,int n31, int nCenter, int ID)
3752 return SMDS_Mesh::AddFaceWithID
3753 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3754 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3755 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3756 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3757 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3758 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3759 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3763 //=======================================================================
3764 //function : AddFaceWithID
3766 //=======================================================================
3767 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3768 const SMDS_MeshNode * n2,
3769 const SMDS_MeshNode * n3,
3770 const SMDS_MeshNode * n12,
3771 const SMDS_MeshNode * n23,
3772 const SMDS_MeshNode * n31,
3773 const SMDS_MeshNode * nCenter,
3776 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
3777 if(hasConstructionEdges()) {
3778 // creation quadratic edges - not implemented
3783 // --- retrieve nodes ID
3784 myNodeIds.resize(7);
3785 myNodeIds[0] = n1->getVtkId();
3786 myNodeIds[1] = n2->getVtkId();
3787 myNodeIds[2] = n3->getVtkId();
3788 myNodeIds[3] = n12->getVtkId();
3789 myNodeIds[4] = n23->getVtkId();
3790 myNodeIds[5] = n31->getVtkId();
3791 myNodeIds[6] = nCenter->getVtkId();
3793 SMDS_MeshFace * face = 0;
3794 SMDS_VtkFace *facevtk = myFacePool->getNew();
3795 facevtk->init(myNodeIds, this);
3796 if (!this->registerElement(ID,facevtk))
3798 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3799 myFacePool->destroy(facevtk);
3803 adjustmyCellsCapacity(ID);
3805 myInfo.myNbBiQuadTriangles++;
3807 // if (!registerElement(ID, face)) {
3808 // RemoveElement(face, false);
3816 //=======================================================================
3817 //function : AddFace
3819 //=======================================================================
3820 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3821 const SMDS_MeshNode * n2,
3822 const SMDS_MeshNode * n3,
3823 const SMDS_MeshNode * n4,
3824 const SMDS_MeshNode * n12,
3825 const SMDS_MeshNode * n23,
3826 const SMDS_MeshNode * n34,
3827 const SMDS_MeshNode * n41)
3829 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3830 myElementIDFactory->GetFreeID());
3833 //=======================================================================
3834 //function : AddFaceWithID
3836 //=======================================================================
3837 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3838 int n12,int n23,int n34,int n41, int ID)
3840 return SMDS_Mesh::AddFaceWithID
3841 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3842 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3843 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3844 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3845 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3846 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3847 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3848 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3852 //=======================================================================
3853 //function : AddFaceWithID
3855 //=======================================================================
3856 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3857 const SMDS_MeshNode * n2,
3858 const SMDS_MeshNode * n3,
3859 const SMDS_MeshNode * n4,
3860 const SMDS_MeshNode * n12,
3861 const SMDS_MeshNode * n23,
3862 const SMDS_MeshNode * n34,
3863 const SMDS_MeshNode * n41,
3866 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3867 if(hasConstructionEdges()) {
3868 // creation quadratic edges - not implemented
3873 // --- retrieve nodes ID
3874 myNodeIds.resize(8);
3875 myNodeIds[0] = n1->getVtkId();
3876 myNodeIds[1] = n2->getVtkId();
3877 myNodeIds[2] = n3->getVtkId();
3878 myNodeIds[3] = n4->getVtkId();
3879 myNodeIds[4] = n12->getVtkId();
3880 myNodeIds[5] = n23->getVtkId();
3881 myNodeIds[6] = n34->getVtkId();
3882 myNodeIds[7] = n41->getVtkId();
3884 SMDS_MeshFace * face = 0;
3885 SMDS_VtkFace *facevtk = myFacePool->getNew();
3886 facevtk->init(myNodeIds, this);
3887 if (!this->registerElement(ID,facevtk))
3889 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3890 myFacePool->destroy(facevtk);
3894 adjustmyCellsCapacity(ID);
3896 myInfo.myNbQuadQuadrangles++;
3898 // if (!registerElement(ID, face)) {
3899 // RemoveElement(face, false);
3906 //=======================================================================
3907 //function : AddFace
3909 //=======================================================================
3910 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3911 const SMDS_MeshNode * n2,
3912 const SMDS_MeshNode * n3,
3913 const SMDS_MeshNode * n4,
3914 const SMDS_MeshNode * n12,
3915 const SMDS_MeshNode * n23,
3916 const SMDS_MeshNode * n34,
3917 const SMDS_MeshNode * n41,
3918 const SMDS_MeshNode * nCenter)
3920 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
3921 myElementIDFactory->GetFreeID());
3924 //=======================================================================
3925 //function : AddFaceWithID
3927 //=======================================================================
3928 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3929 int n12,int n23,int n34,int n41, int nCenter, int ID)
3931 return SMDS_Mesh::AddFaceWithID
3932 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3933 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3934 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3935 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3936 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3937 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3938 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3939 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3940 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3944 //=======================================================================
3945 //function : AddFaceWithID
3947 //=======================================================================
3948 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3949 const SMDS_MeshNode * n2,
3950 const SMDS_MeshNode * n3,
3951 const SMDS_MeshNode * n4,
3952 const SMDS_MeshNode * n12,
3953 const SMDS_MeshNode * n23,
3954 const SMDS_MeshNode * n34,
3955 const SMDS_MeshNode * n41,
3956 const SMDS_MeshNode * nCenter,
3959 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
3960 if(hasConstructionEdges()) {
3961 // creation quadratic edges - not implemented
3966 // --- retrieve nodes ID
3967 myNodeIds.resize(9);
3968 myNodeIds[0] = n1->getVtkId();
3969 myNodeIds[1] = n2->getVtkId();
3970 myNodeIds[2] = n3->getVtkId();
3971 myNodeIds[3] = n4->getVtkId();
3972 myNodeIds[4] = n12->getVtkId();
3973 myNodeIds[5] = n23->getVtkId();
3974 myNodeIds[6] = n34->getVtkId();
3975 myNodeIds[7] = n41->getVtkId();
3976 myNodeIds[8] = nCenter->getVtkId();
3978 SMDS_MeshFace * face = 0;
3979 SMDS_VtkFace *facevtk = myFacePool->getNew();
3980 facevtk->init(myNodeIds, this);
3981 if (!this->registerElement(ID,facevtk))
3983 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3984 myFacePool->destroy(facevtk);
3988 adjustmyCellsCapacity(ID);
3990 myInfo.myNbBiQuadQuadrangles++;
3992 // if (!registerElement(ID, face)) {
3993 // RemoveElement(face, false);
4001 //=======================================================================
4002 //function : AddVolume
4004 //=======================================================================
4005 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4006 const SMDS_MeshNode * n2,
4007 const SMDS_MeshNode * n3,
4008 const SMDS_MeshNode * n4,
4009 const SMDS_MeshNode * n12,
4010 const SMDS_MeshNode * n23,
4011 const SMDS_MeshNode * n31,
4012 const SMDS_MeshNode * n14,
4013 const SMDS_MeshNode * n24,
4014 const SMDS_MeshNode * n34)
4016 int ID = myElementIDFactory->GetFreeID();
4017 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
4018 n31, n14, n24, n34, ID);
4019 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4023 //=======================================================================
4024 //function : AddVolumeWithID
4026 //=======================================================================
4027 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4028 int n12,int n23,int n31,
4029 int n14,int n24,int n34, int ID)
4031 return SMDS_Mesh::AddVolumeWithID
4032 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4033 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4034 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4035 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4036 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4037 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4038 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4039 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4040 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
4041 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4045 //=======================================================================
4046 //function : AddVolumeWithID
4047 //purpose : 2d order tetrahedron of 10 nodes
4048 //=======================================================================
4049 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4050 const SMDS_MeshNode * n2,
4051 const SMDS_MeshNode * n3,
4052 const SMDS_MeshNode * n4,
4053 const SMDS_MeshNode * n12,
4054 const SMDS_MeshNode * n23,
4055 const SMDS_MeshNode * n31,
4056 const SMDS_MeshNode * n14,
4057 const SMDS_MeshNode * n24,
4058 const SMDS_MeshNode * n34,
4061 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
4063 if(hasConstructionFaces()) {
4064 // creation quadratic faces - not implemented
4067 // --- retrieve nodes ID
4068 myNodeIds.resize(10);
4069 myNodeIds[0] = n1->getVtkId();
4070 myNodeIds[1] = n3->getVtkId();
4071 myNodeIds[2] = n2->getVtkId();
4072 myNodeIds[3] = n4->getVtkId();
4074 myNodeIds[4] = n31->getVtkId();
4075 myNodeIds[5] = n23->getVtkId();
4076 myNodeIds[6] = n12->getVtkId();
4078 myNodeIds[7] = n14->getVtkId();
4079 myNodeIds[8] = n34->getVtkId();
4080 myNodeIds[9] = n24->getVtkId();
4082 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4083 volvtk->init(myNodeIds, this);
4084 if (!this->registerElement(ID,volvtk))
4086 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4087 myVolumePool->destroy(volvtk);
4090 adjustmyCellsCapacity(ID);
4091 myCells[ID] = volvtk;
4092 myInfo.myNbQuadTetras++;
4094 // if (!registerElement(ID, volvtk)) {
4095 // RemoveElement(volvtk, false);
4102 //=======================================================================
4103 //function : AddVolume
4105 //=======================================================================
4106 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4107 const SMDS_MeshNode * n2,
4108 const SMDS_MeshNode * n3,
4109 const SMDS_MeshNode * n4,
4110 const SMDS_MeshNode * n5,
4111 const SMDS_MeshNode * n12,
4112 const SMDS_MeshNode * n23,
4113 const SMDS_MeshNode * n34,
4114 const SMDS_MeshNode * n41,
4115 const SMDS_MeshNode * n15,
4116 const SMDS_MeshNode * n25,
4117 const SMDS_MeshNode * n35,
4118 const SMDS_MeshNode * n45)
4120 int ID = myElementIDFactory->GetFreeID();
4121 SMDS_MeshVolume * v =
4122 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
4123 n15, n25, n35, n45, ID);
4124 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4128 //=======================================================================
4129 //function : AddVolumeWithID
4131 //=======================================================================
4132 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
4133 int n12,int n23,int n34,int n41,
4134 int n15,int n25,int n35,int n45, int ID)
4136 return SMDS_Mesh::AddVolumeWithID
4137 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4138 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4139 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4140 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4141 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4142 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4143 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4144 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4145 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4146 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4147 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4148 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
4149 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4153 //=======================================================================
4154 //function : AddVolumeWithID
4155 //purpose : 2d order pyramid of 13 nodes
4156 //=======================================================================
4157 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4158 const SMDS_MeshNode * n2,
4159 const SMDS_MeshNode * n3,
4160 const SMDS_MeshNode * n4,
4161 const SMDS_MeshNode * n5,
4162 const SMDS_MeshNode * n12,
4163 const SMDS_MeshNode * n23,
4164 const SMDS_MeshNode * n34,
4165 const SMDS_MeshNode * n41,
4166 const SMDS_MeshNode * n15,
4167 const SMDS_MeshNode * n25,
4168 const SMDS_MeshNode * n35,
4169 const SMDS_MeshNode * n45,
4172 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
4173 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
4175 if(hasConstructionFaces()) {
4176 // creation quadratic faces - not implemented
4179 // --- retrieve nodes ID
4180 myNodeIds.resize(13);
4181 myNodeIds[0] = n1->getVtkId();
4182 myNodeIds[1] = n4->getVtkId();
4183 myNodeIds[2] = n3->getVtkId();
4184 myNodeIds[3] = n2->getVtkId();
4185 myNodeIds[4] = n5->getVtkId();
4187 myNodeIds[5] = n41->getVtkId();
4188 myNodeIds[6] = n34->getVtkId();
4189 myNodeIds[7] = n23->getVtkId();
4190 myNodeIds[8] = n12->getVtkId();
4192 myNodeIds[9] = n15->getVtkId();
4193 myNodeIds[10] = n45->getVtkId();
4194 myNodeIds[11] = n35->getVtkId();
4195 myNodeIds[12] = n25->getVtkId();
4197 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4198 volvtk->init(myNodeIds, this);
4199 if (!this->registerElement(ID,volvtk))
4201 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4202 myVolumePool->destroy(volvtk);
4205 adjustmyCellsCapacity(ID);
4206 myCells[ID] = volvtk;
4207 myInfo.myNbQuadPyramids++;
4209 // if (!registerElement(ID, volvtk)) {
4210 // RemoveElement(volvtk, false);
4217 //=======================================================================
4218 //function : AddVolume
4219 //purpose : 2d order Pentahedron (prism) with 15 nodes
4220 //=======================================================================
4221 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4222 const SMDS_MeshNode * n2,
4223 const SMDS_MeshNode * n3,
4224 const SMDS_MeshNode * n4,
4225 const SMDS_MeshNode * n5,
4226 const SMDS_MeshNode * n6,
4227 const SMDS_MeshNode * n12,
4228 const SMDS_MeshNode * n23,
4229 const SMDS_MeshNode * n31,
4230 const SMDS_MeshNode * n45,
4231 const SMDS_MeshNode * n56,
4232 const SMDS_MeshNode * n64,
4233 const SMDS_MeshNode * n14,
4234 const SMDS_MeshNode * n25,
4235 const SMDS_MeshNode * n36)
4237 int ID = myElementIDFactory->GetFreeID();
4238 SMDS_MeshVolume * v =
4239 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4240 n45, n56, n64, n14, n25, n36, ID);
4241 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4245 //=======================================================================
4246 //function : AddVolumeWithID
4247 //purpose : 2d order Pentahedron (prism) with 15 nodes
4248 //=======================================================================
4249 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4250 int n4, int n5, int n6,
4251 int n12,int n23,int n31,
4252 int n45,int n56,int n64,
4253 int n14,int n25,int n36, int ID)
4255 return SMDS_Mesh::AddVolumeWithID
4256 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4257 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4258 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4259 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4260 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4261 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4262 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4263 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4264 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4265 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4266 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4267 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4268 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4269 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4270 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4274 //=======================================================================
4275 //function : AddVolumeWithID
4276 //purpose : 2d order Pentahedron (prism) with 15 nodes
4277 //=======================================================================
4278 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4279 const SMDS_MeshNode * n2,
4280 const SMDS_MeshNode * n3,
4281 const SMDS_MeshNode * n4,
4282 const SMDS_MeshNode * n5,
4283 const SMDS_MeshNode * n6,
4284 const SMDS_MeshNode * n12,
4285 const SMDS_MeshNode * n23,
4286 const SMDS_MeshNode * n31,
4287 const SMDS_MeshNode * n45,
4288 const SMDS_MeshNode * n56,
4289 const SMDS_MeshNode * n64,
4290 const SMDS_MeshNode * n14,
4291 const SMDS_MeshNode * n25,
4292 const SMDS_MeshNode * n36,
4295 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4296 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
4298 if(hasConstructionFaces()) {
4299 // creation quadratic faces - not implemented
4302 // --- retrieve nodes ID
4303 myNodeIds.resize(15);
4304 myNodeIds[0] = n1->getVtkId();
4305 myNodeIds[1] = n2->getVtkId();
4306 myNodeIds[2] = n3->getVtkId();
4308 myNodeIds[3] = n4->getVtkId();
4309 myNodeIds[4] = n5->getVtkId();
4310 myNodeIds[5] = n6->getVtkId();
4312 myNodeIds[6] = n12->getVtkId();
4313 myNodeIds[7] = n23->getVtkId();
4314 myNodeIds[8] = n31->getVtkId();
4316 myNodeIds[9] = n45->getVtkId();
4317 myNodeIds[10] = n56->getVtkId();
4318 myNodeIds[11] = n64->getVtkId();
4320 myNodeIds[12] = n14->getVtkId();
4321 myNodeIds[13] = n25->getVtkId();
4322 myNodeIds[14] = n36->getVtkId();
4324 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4325 volvtk->init(myNodeIds, this);
4326 if (!this->registerElement(ID,volvtk))
4328 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4329 myVolumePool->destroy(volvtk);
4332 adjustmyCellsCapacity(ID);
4333 myCells[ID] = volvtk;
4334 myInfo.myNbQuadPrisms++;
4336 // if (!registerElement(ID, volvtk)) {
4337 // RemoveElement(volvtk, false);
4343 //=======================================================================
4344 //function : AddVolume
4345 //purpose : 2d order Pentahedron (prism) with 18 nodes
4346 //=======================================================================
4347 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4348 const SMDS_MeshNode * n2,
4349 const SMDS_MeshNode * n3,
4350 const SMDS_MeshNode * n4,
4351 const SMDS_MeshNode * n5,
4352 const SMDS_MeshNode * n6,
4353 const SMDS_MeshNode * n12,
4354 const SMDS_MeshNode * n23,
4355 const SMDS_MeshNode * n31,
4356 const SMDS_MeshNode * n45,
4357 const SMDS_MeshNode * n56,
4358 const SMDS_MeshNode * n64,
4359 const SMDS_MeshNode * n14,
4360 const SMDS_MeshNode * n25,
4361 const SMDS_MeshNode * n36,
4362 const SMDS_MeshNode * n1245,
4363 const SMDS_MeshNode * n2356,
4364 const SMDS_MeshNode * n1346)
4366 //MESSAGE("AddVolume penta18");
4367 int ID = myElementIDFactory->GetFreeID();
4368 SMDS_MeshVolume * v =
4369 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4370 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346, ID);
4371 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4375 //=======================================================================
4376 //function : AddVolumeWithID
4377 //purpose : 2d order Pentahedron (prism) with 18 nodes
4378 //=======================================================================
4379 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4380 int n4, int n5, int n6,
4381 int n12,int n23,int n31,
4382 int n45,int n56,int n64,
4383 int n14,int n25,int n36,
4384 int n1245, int n2356, int n1346, int ID)
4386 //MESSAGE("AddVolumeWithID penta18 " << ID);
4387 return SMDS_Mesh::AddVolumeWithID
4388 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4389 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4390 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4391 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4392 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4393 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4394 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4395 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4396 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4397 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4398 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4399 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4400 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4401 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4402 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4403 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1245),
4404 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2356),
4405 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1346),
4409 //=======================================================================
4410 //function : AddVolumeWithID
4411 //purpose : 2d order Pentahedron (prism) with 18 nodes
4412 //=======================================================================
4413 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4414 const SMDS_MeshNode * n2,
4415 const SMDS_MeshNode * n3,
4416 const SMDS_MeshNode * n4,
4417 const SMDS_MeshNode * n5,
4418 const SMDS_MeshNode * n6,
4419 const SMDS_MeshNode * n12,
4420 const SMDS_MeshNode * n23,
4421 const SMDS_MeshNode * n31,
4422 const SMDS_MeshNode * n45,
4423 const SMDS_MeshNode * n56,
4424 const SMDS_MeshNode * n64,
4425 const SMDS_MeshNode * n14,
4426 const SMDS_MeshNode * n25,
4427 const SMDS_MeshNode * n36,
4428 const SMDS_MeshNode * n1245,
4429 const SMDS_MeshNode * n2356,
4430 const SMDS_MeshNode * n1346,
4433 //MESSAGE("AddVolumeWithID penta18 "<< ID);
4434 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4435 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
4437 if(hasConstructionFaces()) {
4438 // creation quadratic faces - not implemented
4441 // --- retrieve nodes ID
4442 myNodeIds.resize(18);
4443 myNodeIds[0] = n1->getVtkId();
4444 myNodeIds[1] = n2->getVtkId();
4445 myNodeIds[2] = n3->getVtkId();
4447 myNodeIds[3] = n4->getVtkId();
4448 myNodeIds[4] = n5->getVtkId();
4449 myNodeIds[5] = n6->getVtkId();
4451 myNodeIds[6] = n12->getVtkId();
4452 myNodeIds[7] = n23->getVtkId();
4453 myNodeIds[8] = n31->getVtkId();
4455 myNodeIds[9] = n45->getVtkId();
4456 myNodeIds[10] = n56->getVtkId();
4457 myNodeIds[11] = n64->getVtkId();
4459 myNodeIds[12] = n14->getVtkId();
4460 myNodeIds[13] = n25->getVtkId();
4461 myNodeIds[14] = n36->getVtkId();
4463 myNodeIds[15] = n1245->getVtkId();
4464 myNodeIds[16] = n2356->getVtkId();
4465 myNodeIds[17] = n1346->getVtkId();
4467 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4468 volvtk->init(myNodeIds, this);
4469 if (!this->registerElement(ID,volvtk))
4471 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4472 myVolumePool->destroy(volvtk);
4475 adjustmyCellsCapacity(ID);
4476 myCells[ID] = volvtk;
4477 myInfo.myNbBiQuadPrisms++;
4479 // if (!registerElement(ID, volvtk)) {
4480 // RemoveElement(volvtk, false);
4487 //=======================================================================
4488 //function : AddVolume
4490 //=======================================================================
4491 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4492 const SMDS_MeshNode * n2,
4493 const SMDS_MeshNode * n3,
4494 const SMDS_MeshNode * n4,
4495 const SMDS_MeshNode * n5,
4496 const SMDS_MeshNode * n6,
4497 const SMDS_MeshNode * n7,
4498 const SMDS_MeshNode * n8,
4499 const SMDS_MeshNode * n12,
4500 const SMDS_MeshNode * n23,
4501 const SMDS_MeshNode * n34,
4502 const SMDS_MeshNode * n41,
4503 const SMDS_MeshNode * n56,
4504 const SMDS_MeshNode * n67,
4505 const SMDS_MeshNode * n78,
4506 const SMDS_MeshNode * n85,
4507 const SMDS_MeshNode * n15,
4508 const SMDS_MeshNode * n26,
4509 const SMDS_MeshNode * n37,
4510 const SMDS_MeshNode * n48)
4512 int ID = myElementIDFactory->GetFreeID();
4513 SMDS_MeshVolume * v =
4514 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4515 n56, n67, n78, n85, n15, n26, n37, n48, ID);
4516 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4520 //=======================================================================
4521 //function : AddVolumeWithID
4523 //=======================================================================
4524 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4525 int n5, int n6, int n7, int n8,
4526 int n12,int n23,int n34,int n41,
4527 int n56,int n67,int n78,int n85,
4528 int n15,int n26,int n37,int n48, int ID)
4530 return SMDS_Mesh::AddVolumeWithID
4531 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4532 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4533 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4534 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4535 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4536 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4537 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4538 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4539 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4540 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4541 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4542 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4543 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4544 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4545 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4546 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4547 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4548 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4549 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4550 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4554 //=======================================================================
4555 //function : AddVolumeWithID
4556 //purpose : 2d order Hexahedrons with 20 nodes
4557 //=======================================================================
4558 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4559 const SMDS_MeshNode * n2,
4560 const SMDS_MeshNode * n3,
4561 const SMDS_MeshNode * n4,
4562 const SMDS_MeshNode * n5,
4563 const SMDS_MeshNode * n6,
4564 const SMDS_MeshNode * n7,
4565 const SMDS_MeshNode * n8,
4566 const SMDS_MeshNode * n12,
4567 const SMDS_MeshNode * n23,
4568 const SMDS_MeshNode * n34,
4569 const SMDS_MeshNode * n41,
4570 const SMDS_MeshNode * n56,
4571 const SMDS_MeshNode * n67,
4572 const SMDS_MeshNode * n78,
4573 const SMDS_MeshNode * n85,
4574 const SMDS_MeshNode * n15,
4575 const SMDS_MeshNode * n26,
4576 const SMDS_MeshNode * n37,
4577 const SMDS_MeshNode * n48,
4580 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4581 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4583 if(hasConstructionFaces()) {
4585 // creation quadratic faces - not implemented
4587 // --- retrieve nodes ID
4588 myNodeIds.resize(20);
4589 myNodeIds[0] = n1->getVtkId();
4590 myNodeIds[1] = n4->getVtkId();
4591 myNodeIds[2] = n3->getVtkId();
4592 myNodeIds[3] = n2->getVtkId();
4594 myNodeIds[4] = n5->getVtkId();
4595 myNodeIds[5] = n8->getVtkId();
4596 myNodeIds[6] = n7->getVtkId();
4597 myNodeIds[7] = n6->getVtkId();
4599 myNodeIds[8] = n41->getVtkId();
4600 myNodeIds[9] = n34->getVtkId();
4601 myNodeIds[10] = n23->getVtkId();
4602 myNodeIds[11] = n12->getVtkId();
4604 myNodeIds[12] = n85->getVtkId();
4605 myNodeIds[13] = n78->getVtkId();
4606 myNodeIds[14] = n67->getVtkId();
4607 myNodeIds[15] = n56->getVtkId();
4609 myNodeIds[16] = n15->getVtkId();
4610 myNodeIds[17] = n48->getVtkId();
4611 myNodeIds[18] = n37->getVtkId();
4612 myNodeIds[19] = n26->getVtkId();
4614 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4615 volvtk->init(myNodeIds, this);
4616 if (!this->registerElement(ID,volvtk))
4618 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4619 myVolumePool->destroy(volvtk);
4622 adjustmyCellsCapacity(ID);
4623 myCells[ID] = volvtk;
4624 myInfo.myNbQuadHexas++;
4626 // if (!registerElement(ID, volvtk)) {
4627 // RemoveElement(volvtk, false);
4633 //=======================================================================
4634 //function : AddVolume
4636 //=======================================================================
4637 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4638 const SMDS_MeshNode * n2,
4639 const SMDS_MeshNode * n3,
4640 const SMDS_MeshNode * n4,
4641 const SMDS_MeshNode * n5,
4642 const SMDS_MeshNode * n6,
4643 const SMDS_MeshNode * n7,
4644 const SMDS_MeshNode * n8,
4645 const SMDS_MeshNode * n12,
4646 const SMDS_MeshNode * n23,
4647 const SMDS_MeshNode * n34,
4648 const SMDS_MeshNode * n41,
4649 const SMDS_MeshNode * n56,
4650 const SMDS_MeshNode * n67,
4651 const SMDS_MeshNode * n78,
4652 const SMDS_MeshNode * n85,
4653 const SMDS_MeshNode * n15,
4654 const SMDS_MeshNode * n26,
4655 const SMDS_MeshNode * n37,
4656 const SMDS_MeshNode * n48,
4657 const SMDS_MeshNode * n1234,
4658 const SMDS_MeshNode * n1256,
4659 const SMDS_MeshNode * n2367,
4660 const SMDS_MeshNode * n3478,
4661 const SMDS_MeshNode * n1458,
4662 const SMDS_MeshNode * n5678,
4663 const SMDS_MeshNode * nCenter)
4665 int ID = myElementIDFactory->GetFreeID();
4666 SMDS_MeshVolume * v =
4667 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4668 n56, n67, n78, n85, n15, n26, n37, n48,
4669 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
4671 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4675 //=======================================================================
4676 //function : AddVolumeWithID
4678 //=======================================================================
4679 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4680 int n5, int n6, int n7, int n8,
4681 int n12,int n23,int n34,int n41,
4682 int n56,int n67,int n78,int n85,
4683 int n15,int n26,int n37,int n48,
4684 int n1234,int n1256,int n2367,int n3478,
4685 int n1458,int n5678,int nCenter, int ID)
4687 return SMDS_Mesh::AddVolumeWithID
4688 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4689 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4690 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4691 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4692 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4693 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4694 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4695 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4696 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4697 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4698 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4699 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4700 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4701 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4702 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4703 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4704 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4705 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4706 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4707 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4708 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
4709 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
4710 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
4711 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
4712 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
4713 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
4714 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
4718 //=======================================================================
4719 //function : AddVolumeWithID
4720 //purpose : 2d order Hexahedrons with 20 nodes
4721 //=======================================================================
4722 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4723 const SMDS_MeshNode * n2,
4724 const SMDS_MeshNode * n3,
4725 const SMDS_MeshNode * n4,
4726 const SMDS_MeshNode * n5,
4727 const SMDS_MeshNode * n6,
4728 const SMDS_MeshNode * n7,
4729 const SMDS_MeshNode * n8,
4730 const SMDS_MeshNode * n12,
4731 const SMDS_MeshNode * n23,
4732 const SMDS_MeshNode * n34,
4733 const SMDS_MeshNode * n41,
4734 const SMDS_MeshNode * n56,
4735 const SMDS_MeshNode * n67,
4736 const SMDS_MeshNode * n78,
4737 const SMDS_MeshNode * n85,
4738 const SMDS_MeshNode * n15,
4739 const SMDS_MeshNode * n26,
4740 const SMDS_MeshNode * n37,
4741 const SMDS_MeshNode * n48,
4742 const SMDS_MeshNode * n1234,
4743 const SMDS_MeshNode * n1256,
4744 const SMDS_MeshNode * n2367,
4745 const SMDS_MeshNode * n3478,
4746 const SMDS_MeshNode * n1458,
4747 const SMDS_MeshNode * n5678,
4748 const SMDS_MeshNode * nCenter,
4751 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4752 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
4753 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
4755 if(hasConstructionFaces()) {
4757 // creation quadratic faces - not implemented
4759 // --- retrieve nodes ID
4760 myNodeIds.resize(27);
4761 myNodeIds[0] = n1->getVtkId();
4762 myNodeIds[1] = n4->getVtkId();
4763 myNodeIds[2] = n3->getVtkId();
4764 myNodeIds[3] = n2->getVtkId();
4766 myNodeIds[4] = n5->getVtkId();
4767 myNodeIds[5] = n8->getVtkId();
4768 myNodeIds[6] = n7->getVtkId();
4769 myNodeIds[7] = n6->getVtkId();
4771 myNodeIds[8] = n41->getVtkId();
4772 myNodeIds[9] = n34->getVtkId();
4773 myNodeIds[10] = n23->getVtkId();
4774 myNodeIds[11] = n12->getVtkId();
4776 myNodeIds[12] = n85->getVtkId();
4777 myNodeIds[13] = n78->getVtkId();
4778 myNodeIds[14] = n67->getVtkId();
4779 myNodeIds[15] = n56->getVtkId();
4781 myNodeIds[16] = n15->getVtkId();
4782 myNodeIds[17] = n48->getVtkId();
4783 myNodeIds[18] = n37->getVtkId();
4784 myNodeIds[19] = n26->getVtkId();
4786 myNodeIds[20] = n1256->getVtkId();
4787 myNodeIds[21] = n3478->getVtkId();
4788 myNodeIds[22] = n1458->getVtkId();
4789 myNodeIds[23] = n2367->getVtkId();
4790 myNodeIds[24] = n1234->getVtkId();
4791 myNodeIds[25] = n5678->getVtkId();
4792 myNodeIds[26] = nCenter->getVtkId();
4794 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4795 volvtk->init(myNodeIds, this);
4796 if (!this->registerElement(ID,volvtk))
4798 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4799 myVolumePool->destroy(volvtk);
4802 adjustmyCellsCapacity(ID);
4803 myCells[ID] = volvtk;
4804 myInfo.myNbTriQuadHexas++;
4809 void SMDS_Mesh::dumpGrid(string ficdump)
4811 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4812 // aWriter->SetFileName(ficdump.c_str());
4813 // aWriter->SetInput(myGrid);
4814 // if(myGrid->GetNumberOfCells())
4816 // aWriter->Write();
4818 // aWriter->Delete();
4819 ficdump = ficdump + "_connectivity";
4820 ofstream ficcon(ficdump.c_str(), ios::out);
4821 int nbPoints = myGrid->GetNumberOfPoints();
4822 ficcon << "-------------------------------- points " << nbPoints << endl;
4823 for (int i=0; i<nbPoints; i++)
4825 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4827 int nbCells = myGrid->GetNumberOfCells();
4828 ficcon << "-------------------------------- cells " << nbCells << endl;
4829 for (int i=0; i<nbCells; i++)
4831 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4832 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4833 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4834 for (int j=0; j<nbptcell; j++)
4836 ficcon << " " << listid->GetId(j);
4840 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4841 vtkCellLinks *links = myGrid->GetLinks();
4842 for (int i=0; i<nbPoints; i++)
4844 int ncells = links->GetNcells(i);
4845 vtkIdType *cells = links->GetCells(i);
4846 ficcon << i << " - " << ncells << " -";
4847 for (int j=0; j<ncells; j++)
4849 ficcon << " " << cells[j];
4857 void SMDS_Mesh::compactMesh()
4859 this->myCompactTime = this->myModifTime;
4862 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4864 if (vtkid >= 0 && vtkid < (int)myCellIdVtkToSmds.size())
4865 return myCellIdVtkToSmds[vtkid];
4866 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4869 // void SMDS_Mesh::updateBoundingBox()
4871 // xmin = 0; xmax = 0;
4872 // ymin = 0; ymax = 0;
4873 // zmin = 0; zmax = 0;
4874 // vtkPoints *points = myGrid->GetPoints();
4875 // int myNodesSize = this->myNodes.size();
4876 // for (int i = 0; i < myNodesSize; i++)
4878 // if (SMDS_MeshNode *n = myNodes[i])
4880 // double coords[3];
4881 // points->GetPoint(n->myVtkID, coords);
4882 // if (coords[0] < xmin) xmin = coords[0];
4883 // else if (coords[0] > xmax) xmax = coords[0];
4884 // if (coords[1] < ymin) ymin = coords[1];
4885 // else if (coords[1] > ymax) ymax = coords[1];
4886 // if (coords[2] < zmin) zmin = coords[2];
4887 // else if (coords[2] > zmax) zmax = coords[2];
4892 double SMDS_Mesh::getMaxDim()
4894 double dmax = 1.e-3;
4895 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4896 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4897 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4901 //! modification that needs compact structure and redraw
4902 void SMDS_Mesh::Modified()
4904 if (this->myModified)
4906 this->myModifTime++;
4911 //! get last modification timeStamp
4912 vtkMTimeType SMDS_Mesh::GetMTime() const
4914 return this->myModifTime;
4917 bool SMDS_Mesh::isCompacted()
4919 return this->myCompactTime == this->myModifTime;