1 // Copyright (C) 2007-2015 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>
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)
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 myNodeMin(0), myNodeMax(0),
134 myHasConstructionEdges(false), myHasConstructionFaces(false),
135 myHasInverseElements(true),
136 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
138 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
139 myNodeIDFactory->SetMesh(this);
140 myElementIDFactory->SetMesh(this);
141 _meshList.push_back(this);
142 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
143 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
144 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
145 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
146 myBallPool = new ObjectPool<SMDS_BallElement>(SMDS_Mesh::chunkSize);
150 //myCellIdSmdsToVtk.clear();
151 myCellIdVtkToSmds.clear();
152 myGrid = SMDS_UnstructuredGrid::New();
153 myGrid->setSMDS_mesh(this);
154 myGrid->Initialize();
156 vtkPoints* points = vtkPoints::New();
157 // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
158 // Use double type for storing coordinates of nodes instead of float.
159 points->SetDataType(VTK_DOUBLE);
160 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
161 myGrid->SetPoints( points );
163 myGrid->BuildLinks();
167 ///////////////////////////////////////////////////////////////////////////////
168 /// Create a new child mesh
169 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
170 /// (2003-09-08) of SMESH
171 ///////////////////////////////////////////////////////////////////////////////
172 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
173 myNodePool(parent->myNodePool),
174 myVolumePool(parent->myVolumePool),
175 myFacePool(parent->myFacePool),
176 myEdgePool(parent->myEdgePool),
177 myBallPool(parent->myBallPool),
178 myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
179 myElementIDFactory(parent->myElementIDFactory),
180 myHasConstructionEdges(false), myHasConstructionFaces(false),
181 myHasInverseElements(true)
185 ///////////////////////////////////////////////////////////////////////////////
186 ///Create a submesh and add it to the current mesh
187 ///////////////////////////////////////////////////////////////////////////////
189 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
191 SMDS_Mesh *submesh = new SMDS_Mesh(this);
192 myChildren.insert(myChildren.end(), submesh);
196 ///////////////////////////////////////////////////////////////////////////////
197 ///create a MeshNode and add it to the current Mesh
198 ///An ID is automatically assigned to the node.
199 ///@return : The created node
200 ///////////////////////////////////////////////////////////////////////////////
202 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
204 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
207 ///////////////////////////////////////////////////////////////////////////////
208 ///create a MeshNode and add it to the current Mesh
209 ///@param ID : The ID of the MeshNode to create
210 ///@return : The created node or NULL if a node with this ID already exists
211 ///////////////////////////////////////////////////////////////////////////////
212 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
214 // find the MeshNode corresponding to ID
215 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
219 MESSAGE("=============> Bad Node Id: " << ID);
220 ID = myNodeIDFactory->GetFreeID();
222 myNodeIDFactory->adjustMaxId(ID);
223 SMDS_MeshNode * node = myNodePool->getNew();
224 node->init(ID, myMeshId, 0, x, y, z);
226 if (ID >= (int)myNodes.size())
228 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
229 // MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
232 myNodeIDFactory->BindID(ID,node);
235 this->adjustBoundingBox(x, y, z);
241 ///////////////////////////////////////////////////////////////////////////////
242 /// create a Mesh0DElement and add it to the current Mesh
243 /// @return : The created Mesh0DElement
244 ///////////////////////////////////////////////////////////////////////////////
245 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
247 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
248 if (!node) return NULL;
249 return SMDS_Mesh::Add0DElementWithID(node, ID);
252 ///////////////////////////////////////////////////////////////////////////////
253 /// create a Mesh0DElement and add it to the current Mesh
254 /// @return : The created Mesh0DElement
255 ///////////////////////////////////////////////////////////////////////////////
256 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
258 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
261 ///////////////////////////////////////////////////////////////////////////////
262 /// Create a new Mesh0DElement and at it to the mesh
263 /// @param idnode ID of the node
264 /// @param ID ID of the 0D element to create
265 /// @return The created 0D element or NULL if an element with this
266 /// ID already exists or if input node is not found.
267 ///////////////////////////////////////////////////////////////////////////////
268 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
272 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
273 //MESSAGE("Add0DElementWithID" << ID)
274 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
275 if (myElementIDFactory->BindID(ID, el0d)) {
276 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
277 //node->AddInverseElement(el0d);// --- fait avec BindID
278 adjustmyCellsCapacity(ID);
280 myInfo.myNb0DElements++;
288 ///////////////////////////////////////////////////////////////////////////////
289 /// create a Ball and add it to the current Mesh
290 /// @return : The created Ball
291 ///////////////////////////////////////////////////////////////////////////////
292 SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID)
294 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
295 if (!node) return NULL;
296 return SMDS_Mesh::AddBallWithID(node, diameter, ID);
299 ///////////////////////////////////////////////////////////////////////////////
300 /// create a Ball and add it to the current Mesh
301 /// @return : The created Ball
302 ///////////////////////////////////////////////////////////////////////////////
303 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
305 return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID());
308 ///////////////////////////////////////////////////////////////////////////////
309 /// Create a new Ball and at it to the mesh
310 /// @param idnode ID of the node
311 // @param diameter ball diameter
312 /// @param ID ID of the 0D element to create
313 /// @return The created 0D element or NULL if an element with this
314 /// ID already exists or if input node is not found.
315 ///////////////////////////////////////////////////////////////////////////////
316 SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
320 if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
322 SMDS_BallElement *ball = myBallPool->getNew();
323 ball->init(n->getVtkId(), diameter, this);
324 if (!this->registerElement(ID,ball))
326 this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
327 myBallPool->destroy(ball);
330 adjustmyCellsCapacity(ID);
336 ///////////////////////////////////////////////////////////////////////////////
337 /// create a MeshEdge and add it to the current Mesh
338 /// @return : The created MeshEdge
339 ///////////////////////////////////////////////////////////////////////////////
341 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
343 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
344 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
345 if(!node1 || !node2) return NULL;
346 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
349 ///////////////////////////////////////////////////////////////////////////////
350 /// create a MeshEdge and add it to the current Mesh
351 /// @return : The created MeshEdge
352 ///////////////////////////////////////////////////////////////////////////////
354 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
355 const SMDS_MeshNode * node2)
357 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
360 ///////////////////////////////////////////////////////////////////////////////
361 /// Create a new edge and at it to the mesh
362 /// @param idnode1 ID of the first node
363 /// @param idnode2 ID of the second node
364 /// @param ID ID of the edge to create
365 /// @return The created edge or NULL if an element with this ID already exists or
366 /// if input nodes are not found.
367 ///////////////////////////////////////////////////////////////////////////////
369 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
370 const SMDS_MeshNode * n2,
373 if ( !n1 || !n2 ) return 0;
374 SMDS_MeshEdge * edge = 0;
376 // --- retreive nodes ID
377 vector<vtkIdType> nodeIds;
379 nodeIds.push_back(n1->getVtkId());
380 nodeIds.push_back(n2->getVtkId());
382 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
383 edgevtk->init(nodeIds, this);
384 if (!this->registerElement(ID,edgevtk))
386 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
387 myEdgePool->destroy(edgevtk);
391 adjustmyCellsCapacity(ID);
395 // if (edge && !registerElement(ID, edge))
397 // RemoveElement(edge, false);
403 ///////////////////////////////////////////////////////////////////////////////
404 /// Add a triangle defined by its nodes. An ID is automatically affected to the
406 ///////////////////////////////////////////////////////////////////////////////
408 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
409 const SMDS_MeshNode * n2,
410 const SMDS_MeshNode * n3)
412 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
415 ///////////////////////////////////////////////////////////////////////////////
416 /// Add a triangle defined by its nodes IDs
417 ///////////////////////////////////////////////////////////////////////////////
419 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
421 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
422 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
423 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
424 if(!node1 || !node2 || !node3) return NULL;
425 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
428 ///////////////////////////////////////////////////////////////////////////////
429 /// Add a triangle defined by its nodes
430 ///////////////////////////////////////////////////////////////////////////////
432 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
433 const SMDS_MeshNode * n2,
434 const SMDS_MeshNode * n3,
437 //MESSAGE("AddFaceWithID " << ID)
438 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
440 // if (face && !registerElement(ID, face)) {
441 // RemoveElement(face, false);
447 ///////////////////////////////////////////////////////////////////////////////
448 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
450 ///////////////////////////////////////////////////////////////////////////////
452 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
453 const SMDS_MeshNode * n2,
454 const SMDS_MeshNode * n3,
455 const SMDS_MeshNode * n4)
457 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
460 ///////////////////////////////////////////////////////////////////////////////
461 /// Add a quadrangle defined by its nodes IDs
462 ///////////////////////////////////////////////////////////////////////////////
464 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
470 SMDS_MeshNode *node1, *node2, *node3, *node4;
471 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
472 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
473 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
474 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
475 if(!node1 || !node2 || !node3 || !node4) return NULL;
476 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
479 ///////////////////////////////////////////////////////////////////////////////
480 /// Add a quadrangle defined by its nodes
481 ///////////////////////////////////////////////////////////////////////////////
483 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
484 const SMDS_MeshNode * n2,
485 const SMDS_MeshNode * n3,
486 const SMDS_MeshNode * n4,
489 //MESSAGE("AddFaceWithID " << ID);
490 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
492 // if (face && !registerElement(ID, face)) {
493 // RemoveElement(face, false);
499 ///////////////////////////////////////////////////////////////////////////////
500 /// Add a triangle defined by its edges. An ID is automatically assigned to the
502 ///////////////////////////////////////////////////////////////////////////////
504 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
505 const SMDS_MeshEdge * e2,
506 const SMDS_MeshEdge * e3)
508 if (!hasConstructionEdges())
510 //MESSAGE("AddFaceWithID");
511 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
514 ///////////////////////////////////////////////////////////////////////////////
515 /// Add a triangle defined by its edges
516 ///////////////////////////////////////////////////////////////////////////////
518 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
519 const SMDS_MeshEdge * e2,
520 const SMDS_MeshEdge * e3,
523 if (!hasConstructionEdges())
525 if ( !e1 || !e2 || !e3 ) return 0;
527 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
528 MESSAGE("AddFaceWithID" << ID);
530 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
531 adjustmyCellsCapacity(ID);
533 myInfo.myNbTriangles++;
535 if (!registerElement(ID, face)) {
536 registerElement(myElementIDFactory->GetFreeID(), face);
537 //RemoveElement(face, false);
543 ///////////////////////////////////////////////////////////////////////////////
544 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
546 ///////////////////////////////////////////////////////////////////////////////
548 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
549 const SMDS_MeshEdge * e2,
550 const SMDS_MeshEdge * e3,
551 const SMDS_MeshEdge * e4)
553 if (!hasConstructionEdges())
555 //MESSAGE("AddFaceWithID" );
556 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
559 ///////////////////////////////////////////////////////////////////////////////
560 /// Add a quadrangle defined by its edges
561 ///////////////////////////////////////////////////////////////////////////////
563 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
564 const SMDS_MeshEdge * e2,
565 const SMDS_MeshEdge * e3,
566 const SMDS_MeshEdge * e4,
569 if (!hasConstructionEdges())
571 MESSAGE("AddFaceWithID" << ID);
572 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
573 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
574 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
575 adjustmyCellsCapacity(ID);
577 myInfo.myNbQuadrangles++;
579 if (!registerElement(ID, face))
581 registerElement(myElementIDFactory->GetFreeID(), face);
582 //RemoveElement(face, false);
588 ///////////////////////////////////////////////////////////////////////////////
589 ///Create a new tetrahedron and add it to the mesh.
590 ///@return The created tetrahedron
591 ///////////////////////////////////////////////////////////////////////////////
593 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
594 const SMDS_MeshNode * n2,
595 const SMDS_MeshNode * n3,
596 const SMDS_MeshNode * n4)
598 int ID = myElementIDFactory->GetFreeID();
599 //MESSAGE("AddVolumeWithID " << ID);
600 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
601 if(v==NULL) myElementIDFactory->ReleaseID(ID);
605 ///////////////////////////////////////////////////////////////////////////////
606 ///Create a new tetrahedron and add it to the mesh.
607 ///@param ID The ID of the new volume
608 ///@return The created tetrahedron or NULL if an element with this ID already exists
609 ///or if input nodes are not found.
610 ///////////////////////////////////////////////////////////////////////////////
612 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
618 //MESSAGE("AddVolumeWithID" << ID);
619 SMDS_MeshNode *node1, *node2, *node3, *node4;
620 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
621 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
622 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
623 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
624 if(!node1 || !node2 || !node3 || !node4) return NULL;
625 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
628 ///////////////////////////////////////////////////////////////////////////////
629 ///Create a new tetrahedron and add it to the mesh.
630 ///@param ID The ID of the new volume
631 ///@return The created tetrahedron
632 ///////////////////////////////////////////////////////////////////////////////
634 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
635 const SMDS_MeshNode * n2,
636 const SMDS_MeshNode * n3,
637 const SMDS_MeshNode * n4,
640 //MESSAGE("AddVolumeWithID " << ID);
641 SMDS_MeshVolume* volume = 0;
642 if ( !n1 || !n2 || !n3 || !n4) return volume;
643 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
644 if(hasConstructionFaces()) {
645 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
646 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
647 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
648 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
649 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
650 adjustmyCellsCapacity(ID);
651 myCells[ID] = volume;
654 else if(hasConstructionEdges()) {
655 MESSAGE("Error : Not implemented");
659 // --- retrieve nodes ID
661 myNodeIds[0] = n1->getVtkId();
662 myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK
663 myNodeIds[2] = n2->getVtkId();
664 myNodeIds[3] = n4->getVtkId();
666 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
667 volvtk->init(myNodeIds, this);
668 if (!this->registerElement(ID,volvtk))
670 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
671 myVolumePool->destroy(volvtk);
675 adjustmyCellsCapacity(ID);
676 myCells[ID] = volume;
680 // if (!registerElement(ID, volume)) {
681 // RemoveElement(volume, false);
687 ///////////////////////////////////////////////////////////////////////////////
688 ///Create a new pyramid and add it to the mesh.
689 ///Nodes 1,2,3 and 4 define the base of the pyramid
690 ///@return The created pyramid
691 ///////////////////////////////////////////////////////////////////////////////
693 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
694 const SMDS_MeshNode * n2,
695 const SMDS_MeshNode * n3,
696 const SMDS_MeshNode * n4,
697 const SMDS_MeshNode * n5)
699 int ID = myElementIDFactory->GetFreeID();
700 //MESSAGE("AddVolumeWithID " << ID);
701 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
702 if(v==NULL) myElementIDFactory->ReleaseID(ID);
706 ///////////////////////////////////////////////////////////////////////////////
707 ///Create a new pyramid and add it to the mesh.
708 ///Nodes 1,2,3 and 4 define the base of the pyramid
709 ///@param ID The ID of the new volume
710 ///@return The created pyramid or NULL if an element with this ID already exists
711 ///or if input nodes are not found.
712 ///////////////////////////////////////////////////////////////////////////////
714 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
721 //MESSAGE("AddVolumeWithID " << ID);
722 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
723 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
724 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
725 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
726 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
727 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
728 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
729 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
732 ///////////////////////////////////////////////////////////////////////////////
733 ///Create a new pyramid and add it to the mesh.
734 ///Nodes 1,2,3 and 4 define the base of the pyramid
735 ///@param ID The ID of the new volume
736 ///@return The created pyramid
737 ///////////////////////////////////////////////////////////////////////////////
739 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
740 const SMDS_MeshNode * n2,
741 const SMDS_MeshNode * n3,
742 const SMDS_MeshNode * n4,
743 const SMDS_MeshNode * n5,
746 //MESSAGE("AddVolumeWithID " << ID);
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()) {
761 MESSAGE("Error : Not implemented");
765 // --- retrieve nodes ID
767 myNodeIds[0] = n1->getVtkId();
768 myNodeIds[1] = n4->getVtkId();
769 myNodeIds[2] = n3->getVtkId();
770 myNodeIds[3] = n2->getVtkId();
771 myNodeIds[4] = n5->getVtkId();
773 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
774 volvtk->init(myNodeIds, this);
775 if (!this->registerElement(ID,volvtk))
777 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
778 myVolumePool->destroy(volvtk);
782 adjustmyCellsCapacity(ID);
783 myCells[ID] = volume;
784 myInfo.myNbPyramids++;
787 // if (!registerElement(ID, volume)) {
788 // RemoveElement(volume, false);
794 ///////////////////////////////////////////////////////////////////////////////
795 ///Create a new prism and add it to the mesh.
796 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
797 ///@return The created prism
798 ///////////////////////////////////////////////////////////////////////////////
800 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
801 const SMDS_MeshNode * n2,
802 const SMDS_MeshNode * n3,
803 const SMDS_MeshNode * n4,
804 const SMDS_MeshNode * n5,
805 const SMDS_MeshNode * n6)
807 int ID = myElementIDFactory->GetFreeID();
808 //MESSAGE("AddVolumeWithID " << ID);
809 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
810 if(v==NULL) myElementIDFactory->ReleaseID(ID);
814 ///////////////////////////////////////////////////////////////////////////////
815 ///Create a new prism and add it to the mesh.
816 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
817 ///@param ID The ID of the new volume
818 ///@return The created prism or NULL if an element with this ID already exists
819 ///or if input nodes are not found.
820 ///////////////////////////////////////////////////////////////////////////////
822 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
830 //MESSAGE("AddVolumeWithID " << ID);
831 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
832 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
833 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
834 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
835 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
836 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
837 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
838 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
839 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
842 ///////////////////////////////////////////////////////////////////////////////
843 ///Create a new prism and add it to the mesh.
844 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
845 ///@param ID The ID of the new volume
846 ///@return The created prism
847 ///////////////////////////////////////////////////////////////////////////////
849 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
850 const SMDS_MeshNode * n2,
851 const SMDS_MeshNode * n3,
852 const SMDS_MeshNode * n4,
853 const SMDS_MeshNode * n5,
854 const SMDS_MeshNode * n6,
857 //MESSAGE("AddVolumeWithID " << ID);
858 SMDS_MeshVolume* volume = 0;
859 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
860 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
861 if(hasConstructionFaces()) {
862 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
863 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
864 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
865 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
866 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
867 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
868 adjustmyCellsCapacity(ID);
869 myCells[ID] = volume;
872 else if(hasConstructionEdges()) {
873 MESSAGE("Error : Not implemented");
877 // --- retrieve nodes ID
879 myNodeIds[0] = n1->getVtkId();
880 myNodeIds[1] = n2->getVtkId();
881 myNodeIds[2] = n3->getVtkId();
882 myNodeIds[3] = n4->getVtkId();
883 myNodeIds[4] = n5->getVtkId();
884 myNodeIds[5] = n6->getVtkId();
886 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
887 volvtk->init(myNodeIds, this);
888 if (!this->registerElement(ID,volvtk))
890 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
891 myVolumePool->destroy(volvtk);
895 adjustmyCellsCapacity(ID);
896 myCells[ID] = volume;
900 // if (!registerElement(ID, volume)) {
901 // RemoveElement(volume, false);
907 ///////////////////////////////////////////////////////////////////////////////
908 ///Create a new hexagonal prism and add it to the mesh.
909 ///@return The created prism
910 ///////////////////////////////////////////////////////////////////////////////
912 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
913 const SMDS_MeshNode * n2,
914 const SMDS_MeshNode * n3,
915 const SMDS_MeshNode * n4,
916 const SMDS_MeshNode * n5,
917 const SMDS_MeshNode * n6,
918 const SMDS_MeshNode * n7,
919 const SMDS_MeshNode * n8,
920 const SMDS_MeshNode * n9,
921 const SMDS_MeshNode * n10,
922 const SMDS_MeshNode * n11,
923 const SMDS_MeshNode * n12)
925 int ID = myElementIDFactory->GetFreeID();
926 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
927 n7, n8, n9, n10, n11, n12,
929 if(v==NULL) myElementIDFactory->ReleaseID(ID);
933 ///////////////////////////////////////////////////////////////////////////////
934 ///Create a new hexagonal prism and add it to the mesh.
935 ///@param ID The ID of the new volume
936 ///@return The created prism or NULL if an element with this ID already exists
937 ///or if input nodes are not found.
938 ///////////////////////////////////////////////////////////////////////////////
940 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
954 SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
955 SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
956 SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
957 SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
958 SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
959 SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
960 SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
961 SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
962 SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
963 SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
964 SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
965 SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
966 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
967 node7, node8, node9, node10, node11, node12,
971 ///////////////////////////////////////////////////////////////////////////////
972 ///Create a new hexagonal prism and add it to the mesh.
973 ///@param ID The ID of the new volume
974 ///@return The created prism
975 ///////////////////////////////////////////////////////////////////////////////
977 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
978 const SMDS_MeshNode * n2,
979 const SMDS_MeshNode * n3,
980 const SMDS_MeshNode * n4,
981 const SMDS_MeshNode * n5,
982 const SMDS_MeshNode * n6,
983 const SMDS_MeshNode * n7,
984 const SMDS_MeshNode * n8,
985 const SMDS_MeshNode * n9,
986 const SMDS_MeshNode * n10,
987 const SMDS_MeshNode * n11,
988 const SMDS_MeshNode * n12,
991 SMDS_MeshVolume* volume = 0;
992 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
993 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
995 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
996 if(hasConstructionFaces()) {
997 MESSAGE("Error : Not implemented");
1000 else if(hasConstructionEdges()) {
1001 MESSAGE("Error : Not implemented");
1005 // --- retrieve nodes ID
1006 myNodeIds.resize(12);
1007 myNodeIds[0] = n1->getVtkId();
1008 myNodeIds[1] = n6->getVtkId();
1009 myNodeIds[2] = n5->getVtkId();
1010 myNodeIds[3] = n4->getVtkId();
1011 myNodeIds[4] = n3->getVtkId();
1012 myNodeIds[5] = n2->getVtkId();
1014 myNodeIds[6] = n7->getVtkId();
1015 myNodeIds[7] = n12->getVtkId();
1016 myNodeIds[8] = n11->getVtkId();
1017 myNodeIds[9] = n10->getVtkId();
1018 myNodeIds[10] = n9->getVtkId();
1019 myNodeIds[11] = n8->getVtkId();
1021 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1022 volvtk->init(myNodeIds, this);
1023 if (!this->registerElement(ID,volvtk))
1025 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1026 myVolumePool->destroy(volvtk);
1030 adjustmyCellsCapacity(ID);
1031 myCells[ID] = volume;
1032 myInfo.myNbHexPrism++;
1038 ///////////////////////////////////////////////////////////////////////////////
1039 ///Create a new hexahedron and add it to the mesh.
1040 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1041 ///@return The created hexahedron
1042 ///////////////////////////////////////////////////////////////////////////////
1044 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1045 const SMDS_MeshNode * n2,
1046 const SMDS_MeshNode * n3,
1047 const SMDS_MeshNode * n4,
1048 const SMDS_MeshNode * n5,
1049 const SMDS_MeshNode * n6,
1050 const SMDS_MeshNode * n7,
1051 const SMDS_MeshNode * n8)
1053 int ID = myElementIDFactory->GetFreeID();
1054 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
1055 if(v==NULL) myElementIDFactory->ReleaseID(ID);
1059 ///////////////////////////////////////////////////////////////////////////////
1060 ///Create a new hexahedron and add it to the mesh.
1061 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1062 ///@param ID The ID of the new volume
1063 ///@return The created hexahedron or NULL if an element with this ID already
1064 ///exists or if input nodes are not found.
1065 ///////////////////////////////////////////////////////////////////////////////
1067 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
1077 //MESSAGE("AddVolumeWithID " << ID);
1078 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
1079 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
1080 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
1081 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
1082 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
1083 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
1084 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
1085 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
1086 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
1087 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
1089 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
1093 ///////////////////////////////////////////////////////////////////////////////
1094 ///Create a new hexahedron and add it to the mesh.
1095 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1096 ///@param ID The ID of the new volume
1097 ///@return The created prism or NULL if an element with this ID already exists
1098 ///or if input nodes are not found.
1099 ///////////////////////////////////////////////////////////////////////////////
1101 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1102 const SMDS_MeshNode * n2,
1103 const SMDS_MeshNode * n3,
1104 const SMDS_MeshNode * n4,
1105 const SMDS_MeshNode * n5,
1106 const SMDS_MeshNode * n6,
1107 const SMDS_MeshNode * n7,
1108 const SMDS_MeshNode * n8,
1111 //MESSAGE("AddVolumeWithID " << ID);
1112 SMDS_MeshVolume* volume = 0;
1113 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
1114 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1115 if(hasConstructionFaces()) {
1116 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
1117 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
1118 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
1119 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
1120 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
1121 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
1122 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1123 adjustmyCellsCapacity(ID);
1124 myCells[ID] = volume;
1127 else if(hasConstructionEdges()) {
1128 MESSAGE("Error : Not implemented");
1132 // --- retrieve nodes ID
1133 myNodeIds.resize(8);
1134 myNodeIds[0] = n1->getVtkId();
1135 myNodeIds[1] = n4->getVtkId();
1136 myNodeIds[2] = n3->getVtkId();
1137 myNodeIds[3] = n2->getVtkId();
1138 myNodeIds[4] = n5->getVtkId();
1139 myNodeIds[5] = n8->getVtkId();
1140 myNodeIds[6] = n7->getVtkId();
1141 myNodeIds[7] = n6->getVtkId();
1143 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1144 volvtk->init(myNodeIds, this);
1145 if (!this->registerElement(ID,volvtk))
1147 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1148 myVolumePool->destroy(volvtk);
1152 adjustmyCellsCapacity(ID);
1153 myCells[ID] = volume;
1157 // if (!registerElement(ID, volume)) {
1158 // RemoveElement(volume, false);
1164 ///////////////////////////////////////////////////////////////////////////////
1165 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1166 ///@return The created tetrahedron
1167 ///////////////////////////////////////////////////////////////////////////////
1169 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1170 const SMDS_MeshFace * f2,
1171 const SMDS_MeshFace * f3,
1172 const SMDS_MeshFace * f4)
1174 //MESSAGE("AddVolumeWithID");
1175 if (!hasConstructionFaces())
1177 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1180 ///////////////////////////////////////////////////////////////////////////////
1181 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1182 ///@param ID The ID of the new volume
1183 ///@return The created tetrahedron
1184 ///////////////////////////////////////////////////////////////////////////////
1186 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1187 const SMDS_MeshFace * f2,
1188 const SMDS_MeshFace * f3,
1189 const SMDS_MeshFace * f4,
1192 MESSAGE("AddVolumeWithID" << ID);
1193 if (!hasConstructionFaces())
1195 if ( !f1 || !f2 || !f3 || !f4) return 0;
1196 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1197 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1198 adjustmyCellsCapacity(ID);
1199 myCells[ID] = volume;
1200 myInfo.myNbTetras++;
1202 if (!registerElement(ID, volume)) {
1203 registerElement(myElementIDFactory->GetFreeID(), volume);
1204 //RemoveElement(volume, false);
1210 ///////////////////////////////////////////////////////////////////////////////
1211 ///Create a new pyramid defined by its faces and add it to the mesh.
1212 ///@return The created pyramid
1213 ///////////////////////////////////////////////////////////////////////////////
1215 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1216 const SMDS_MeshFace * f2,
1217 const SMDS_MeshFace * f3,
1218 const SMDS_MeshFace * f4,
1219 const SMDS_MeshFace * f5)
1221 //MESSAGE("AddVolumeWithID");
1222 if (!hasConstructionFaces())
1224 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1227 ///////////////////////////////////////////////////////////////////////////////
1228 ///Create a new pyramid defined by its faces and add it to the mesh.
1229 ///@param ID The ID of the new volume
1230 ///@return The created pyramid
1231 ///////////////////////////////////////////////////////////////////////////////
1233 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1234 const SMDS_MeshFace * f2,
1235 const SMDS_MeshFace * f3,
1236 const SMDS_MeshFace * f4,
1237 const SMDS_MeshFace * f5,
1240 MESSAGE("AddVolumeWithID" << ID);
1241 if (!hasConstructionFaces())
1243 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1244 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1245 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1246 adjustmyCellsCapacity(ID);
1247 myCells[ID] = volume;
1248 myInfo.myNbPyramids++;
1250 if (!registerElement(ID, volume)) {
1251 registerElement(myElementIDFactory->GetFreeID(), volume);
1252 //RemoveElement(volume, false);
1258 ///////////////////////////////////////////////////////////////////////////////
1259 ///Create a new prism defined by its faces and add it to the mesh.
1260 ///@return The created prism
1261 ///////////////////////////////////////////////////////////////////////////////
1263 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1264 const SMDS_MeshFace * f2,
1265 const SMDS_MeshFace * f3,
1266 const SMDS_MeshFace * f4,
1267 const SMDS_MeshFace * f5,
1268 const SMDS_MeshFace * f6)
1270 //MESSAGE("AddVolumeWithID" );
1271 if (!hasConstructionFaces())
1273 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1276 ///////////////////////////////////////////////////////////////////////////////
1277 ///Create a new prism defined by its faces and add it to the mesh.
1278 ///@param ID The ID of the new volume
1279 ///@return The created prism
1280 ///////////////////////////////////////////////////////////////////////////////
1282 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1283 const SMDS_MeshFace * f2,
1284 const SMDS_MeshFace * f3,
1285 const SMDS_MeshFace * f4,
1286 const SMDS_MeshFace * f5,
1287 const SMDS_MeshFace * f6,
1290 MESSAGE("AddVolumeWithID" << ID);
1291 if (!hasConstructionFaces())
1293 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1294 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1295 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1296 adjustmyCellsCapacity(ID);
1297 myCells[ID] = volume;
1298 myInfo.myNbPrisms++;
1300 if (!registerElement(ID, volume)) {
1301 registerElement(myElementIDFactory->GetFreeID(), volume);
1302 //RemoveElement(volume, false);
1308 ///////////////////////////////////////////////////////////////////////////////
1309 /// Add a polygon defined by its nodes IDs
1310 ///////////////////////////////////////////////////////////////////////////////
1312 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
1315 int nbNodes = nodes_ids.size();
1316 vector<const SMDS_MeshNode*> nodes (nbNodes);
1317 for (int i = 0; i < nbNodes; i++) {
1318 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1319 if (!nodes[i]) return NULL;
1321 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1324 ///////////////////////////////////////////////////////////////////////////////
1325 /// Add a polygon defined by its nodes
1326 ///////////////////////////////////////////////////////////////////////////////
1329 SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1332 SMDS_MeshFace * face;
1334 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1335 if (hasConstructionEdges())
1337 MESSAGE("Error : Not implemented");
1342 myNodeIds.resize( nodes.size() );
1343 for ( size_t i = 0; i < nodes.size(); ++i )
1344 myNodeIds[i] = nodes[i]->getVtkId();
1346 SMDS_VtkFace *facevtk = myFacePool->getNew();
1347 facevtk->initPoly(myNodeIds, this);
1348 if (!this->registerElement(ID,facevtk))
1350 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1351 myFacePool->destroy(facevtk);
1356 adjustmyCellsCapacity(ID);
1358 myInfo.myNbPolygons++;
1364 ///////////////////////////////////////////////////////////////////////////////
1365 /// Add a polygon defined by its nodes.
1366 /// An ID is automatically affected to the created face.
1367 ///////////////////////////////////////////////////////////////////////////////
1369 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1371 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1374 ///////////////////////////////////////////////////////////////////////////////
1375 /// Add a quadratic polygon defined by its nodes IDs
1376 ///////////////////////////////////////////////////////////////////////////////
1378 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
1381 vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
1382 for ( size_t i = 0; i < nodes.size(); i++) {
1383 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1384 if (!nodes[i]) return NULL;
1386 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
1389 ///////////////////////////////////////////////////////////////////////////////
1390 /// Add a quadratic polygon defined by its nodes
1391 ///////////////////////////////////////////////////////////////////////////////
1394 SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1397 SMDS_MeshFace * face;
1399 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1400 if (hasConstructionEdges())
1402 MESSAGE("Error : Not implemented");
1407 myNodeIds.resize( nodes.size() );
1408 for ( size_t i = 0; i < nodes.size(); ++i )
1409 myNodeIds[i] = nodes[i]->getVtkId();
1411 SMDS_VtkFace *facevtk = myFacePool->getNew();
1412 facevtk->initQuadPoly(myNodeIds, this);
1413 if (!this->registerElement(ID,facevtk))
1415 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1416 myFacePool->destroy(facevtk);
1420 adjustmyCellsCapacity(ID);
1422 myInfo.myNbQuadPolygons++;
1427 ///////////////////////////////////////////////////////////////////////////////
1428 /// Add a quadratic polygon defined by its nodes.
1429 /// An ID is automatically affected to the created face.
1430 ///////////////////////////////////////////////////////////////////////////////
1432 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1434 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1437 ///////////////////////////////////////////////////////////////////////////////
1438 /// Create a new polyhedral volume and add it to the mesh.
1439 /// @param ID The ID of the new volume
1440 /// @return The created volume or NULL if an element with this ID already exists
1441 /// or if input nodes are not found.
1442 ///////////////////////////////////////////////////////////////////////////////
1444 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1445 (const vector<int> & nodes_ids,
1446 const vector<int> & quantities,
1449 int nbNodes = nodes_ids.size();
1450 vector<const SMDS_MeshNode*> nodes (nbNodes);
1451 for (int i = 0; i < nbNodes; i++) {
1452 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1453 if (!nodes[i]) return NULL;
1455 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1458 ///////////////////////////////////////////////////////////////////////////////
1459 /// Create a new polyhedral volume and add it to the mesh.
1460 /// @param ID The ID of the new volume
1461 /// @return The created volume
1462 ///////////////////////////////////////////////////////////////////////////////
1465 SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
1466 const vector<int> & quantities,
1469 SMDS_MeshVolume* volume = 0;
1470 if ( nodes.empty() || quantities.empty() )
1472 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1473 if (hasConstructionFaces())
1475 MESSAGE("Error : Not implemented");
1478 else if (hasConstructionEdges())
1480 MESSAGE("Error : Not implemented");
1485 //#ifdef VTK_HAVE_POLYHEDRON
1486 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1487 myNodeIds.resize( nodes.size() );
1488 for ( size_t i = 0; i < nodes.size(); ++i )
1489 myNodeIds[i] = nodes[i]->getVtkId();
1491 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1492 volvtk->initPoly(myNodeIds, quantities, this);
1493 if (!this->registerElement(ID, volvtk))
1495 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1496 myVolumePool->destroy(volvtk);
1501 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1502 // for ( int i = 0; i < nodes.size(); ++i )
1503 // if ( !nodes[ i ] ) return 0;
1504 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1506 adjustmyCellsCapacity(ID);
1507 myCells[ID] = volume;
1508 myInfo.myNbPolyhedrons++;
1511 //#ifndef VTK_HAVE_POLYHEDRON
1512 // if (!registerElement(ID, volume))
1514 // registerElement(myElementIDFactory->GetFreeID(), volume);
1515 // //RemoveElement(volume, false);
1522 ///////////////////////////////////////////////////////////////////////////////
1523 /// Create a new polyhedral volume and add it to the mesh.
1524 /// @return The created volume
1525 ///////////////////////////////////////////////////////////////////////////////
1527 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1528 (const vector<const SMDS_MeshNode*> & nodes,
1529 const vector<int> & quantities)
1531 int ID = myElementIDFactory->GetFreeID();
1532 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1533 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1537 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1539 int ID = myElementIDFactory->GetFreeID();
1540 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1541 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1545 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1547 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1548 volvtk->init(vtkNodeIds, this);
1549 if (!this->registerElement(ID,volvtk))
1551 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1552 myVolumePool->destroy(volvtk);
1555 adjustmyCellsCapacity(ID);
1556 myCells[ID] = volvtk;
1557 vtkIdType aVtkType = volvtk->GetVtkType();
1561 myInfo.myNbTetras++;
1564 myInfo.myNbPyramids++;
1567 myInfo.myNbPrisms++;
1569 case VTK_HEXAHEDRON:
1572 case VTK_QUADRATIC_TETRA:
1573 myInfo.myNbQuadTetras++;
1575 case VTK_QUADRATIC_PYRAMID:
1576 myInfo.myNbQuadPyramids++;
1578 case VTK_QUADRATIC_WEDGE:
1579 myInfo.myNbQuadPrisms++;
1581 case VTK_QUADRATIC_HEXAHEDRON:
1582 myInfo.myNbQuadHexas++;
1584 //#ifdef VTK_HAVE_POLYHEDRON
1585 case VTK_POLYHEDRON:
1586 myInfo.myNbPolyhedrons++;
1590 myInfo.myNbPolyhedrons++;
1596 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1598 int ID = myElementIDFactory->GetFreeID();
1599 SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
1600 if (f == NULL) myElementIDFactory->ReleaseID(ID);
1604 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1606 SMDS_VtkFace *facevtk = myFacePool->getNew();
1607 facevtk->init(vtkNodeIds, this);
1608 if (!this->registerElement(ID,facevtk))
1610 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1611 myFacePool->destroy(facevtk);
1614 adjustmyCellsCapacity(ID);
1615 myCells[ID] = facevtk;
1616 vtkIdType aVtkType = facevtk->GetVtkType();
1620 myInfo.myNbTriangles++;
1623 myInfo.myNbQuadrangles++;
1625 case VTK_QUADRATIC_TRIANGLE:
1626 myInfo.myNbQuadTriangles++;
1628 case VTK_QUADRATIC_QUAD:
1629 myInfo.myNbQuadQuadrangles++;
1631 case VTK_BIQUADRATIC_QUAD:
1632 myInfo.myNbBiQuadQuadrangles++;
1634 case VTK_BIQUADRATIC_TRIANGLE:
1635 myInfo.myNbBiQuadTriangles++;
1638 myInfo.myNbPolygons++;
1641 myInfo.myNbPolygons++;
1646 ///////////////////////////////////////////////////////////////////////////////
1647 /// Registers element with the given ID, maintains inverse connections
1648 ///////////////////////////////////////////////////////////////////////////////
1649 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1651 //MESSAGE("registerElement " << ID);
1652 if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound
1654 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1659 element->myMeshId = myMeshId;
1661 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1663 int vtkId = cell->getVtkId();
1665 vtkId = myElementIDFactory->SetInVtkGrid(element);
1667 if (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector
1669 // MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1670 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1672 myCellIdVtkToSmds[vtkId] = ID;
1674 myElementIDFactory->updateMinMax(ID);
1678 //=======================================================================
1679 //function : MoveNode
1681 //=======================================================================
1683 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
1685 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
1686 node->setXYZ(x,y,z);
1689 ///////////////////////////////////////////////////////////////////////////////
1690 /// Return the node whose SMDS ID is 'ID'.
1691 ///////////////////////////////////////////////////////////////////////////////
1692 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1694 if (ID < 1 || ID >= (int)myNodes.size())
1696 // MESSAGE("------------------------------------------------------------------------- ");
1697 // MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1698 // MESSAGE("------------------------------------------------------------------------- ");
1701 return (const SMDS_MeshNode *)myNodes[ID];
1704 ///////////////////////////////////////////////////////////////////////////////
1705 /// Return the node whose VTK ID is 'vtkId'.
1706 ///////////////////////////////////////////////////////////////////////////////
1707 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1709 // TODO if needed use mesh->nodeIdFromVtkToSmds
1710 if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() )
1712 MESSAGE("------------------------------------------------------------------------- ");
1713 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1714 MESSAGE("------------------------------------------------------------------------- ");
1717 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1720 ///////////////////////////////////////////////////////////////////////////////
1721 ///Create a triangle and add it to the current mesh. This method do not bind an
1722 ///ID to the create triangle.
1723 ///////////////////////////////////////////////////////////////////////////////
1724 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1725 const SMDS_MeshNode * node2,
1726 const SMDS_MeshNode * node3,
1729 if ( !node1 || !node2 || !node3) return 0;
1730 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1731 if(hasConstructionEdges())
1733 SMDS_MeshEdge *edge1, *edge2, *edge3;
1734 edge1=FindEdgeOrCreate(node1,node2);
1735 edge2=FindEdgeOrCreate(node2,node3);
1736 edge3=FindEdgeOrCreate(node3,node1);
1738 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1739 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1740 adjustmyCellsCapacity(ID);
1742 myInfo.myNbTriangles++;
1747 // --- retrieve nodes ID
1748 myNodeIds.resize(3);
1749 myNodeIds[0] = node1->getVtkId();
1750 myNodeIds[1] = node2->getVtkId();
1751 myNodeIds[2] = node3->getVtkId();
1753 SMDS_MeshFace * face = 0;
1754 SMDS_VtkFace *facevtk = myFacePool->getNew();
1755 facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid
1756 if (!this->registerElement(ID,facevtk))
1758 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1759 myFacePool->destroy(facevtk);
1763 adjustmyCellsCapacity(ID);
1765 //MESSAGE("createTriangle " << ID << " " << face);
1766 myInfo.myNbTriangles++;
1771 ///////////////////////////////////////////////////////////////////////////////
1772 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1773 ///a ID to the create triangle.
1774 ///////////////////////////////////////////////////////////////////////////////
1775 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1776 const SMDS_MeshNode * node2,
1777 const SMDS_MeshNode * node3,
1778 const SMDS_MeshNode * node4,
1781 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1782 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1783 if(hasConstructionEdges())
1785 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1786 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1787 edge1=FindEdgeOrCreate(node1,node2);
1788 edge2=FindEdgeOrCreate(node2,node3);
1789 edge3=FindEdgeOrCreate(node3,node4);
1790 edge4=FindEdgeOrCreate(node4,node1);
1792 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1793 adjustmyCellsCapacity(ID);
1795 myInfo.myNbQuadrangles++;
1800 // --- retrieve nodes ID
1801 myNodeIds.resize(4);
1802 myNodeIds[0] = node1->getVtkId();
1803 myNodeIds[1] = node2->getVtkId();
1804 myNodeIds[2] = node3->getVtkId();
1805 myNodeIds[3] = node4->getVtkId();
1807 SMDS_MeshFace * face = 0;
1808 SMDS_VtkFace *facevtk = myFacePool->getNew();
1809 facevtk->init(myNodeIds, this);
1810 if (!this->registerElement(ID,facevtk))
1812 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1813 myFacePool->destroy(facevtk);
1817 adjustmyCellsCapacity(ID);
1819 myInfo.myNbQuadrangles++;
1824 ///////////////////////////////////////////////////////////////////////////////
1825 /// Remove a node and all the elements which own this node
1826 ///////////////////////////////////////////////////////////////////////////////
1828 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1830 MESSAGE("RemoveNode");
1831 RemoveElement(node, true);
1834 ///////////////////////////////////////////////////////////////////////////////
1835 /// Remove an edge and all the elements which own this edge
1836 ///////////////////////////////////////////////////////////////////////////////
1838 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1840 MESSAGE("Remove0DElement");
1841 RemoveElement(elem0d,true);
1844 ///////////////////////////////////////////////////////////////////////////////
1845 /// Remove an edge and all the elements which own this edge
1846 ///////////////////////////////////////////////////////////////////////////////
1848 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1850 MESSAGE("RemoveEdge");
1851 RemoveElement(edge,true);
1854 ///////////////////////////////////////////////////////////////////////////////
1855 /// Remove an face and all the elements which own this face
1856 ///////////////////////////////////////////////////////////////////////////////
1858 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1860 MESSAGE("RemoveFace");
1861 RemoveElement(face, true);
1864 ///////////////////////////////////////////////////////////////////////////////
1866 ///////////////////////////////////////////////////////////////////////////////
1868 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1870 MESSAGE("RemoveVolume");
1871 RemoveElement(volume, true);
1874 //=======================================================================
1875 //function : RemoveFromParent
1877 //=======================================================================
1879 bool SMDS_Mesh::RemoveFromParent()
1881 if (myParent==NULL) return false;
1882 else return (myParent->RemoveSubMesh(this));
1885 //=======================================================================
1886 //function : RemoveSubMesh
1888 //=======================================================================
1890 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1894 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1895 for (; itmsh!=myChildren.end() && !found; itmsh++)
1897 SMDS_Mesh * submesh = *itmsh;
1898 if (submesh == aMesh)
1901 myChildren.erase(itmsh);
1908 //=======================================================================
1909 //function : ChangeElementNodes
1911 //=======================================================================
1913 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1914 const SMDS_MeshNode * nodes[],
1917 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1918 // keep current nodes of elem
1919 set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1923 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1926 Ok = cell->vtkOrder(nodes, nbnodes);
1927 Ok = cell->ChangeNodes(nodes, nbnodes);
1930 if ( Ok ) { // update InverseElements
1932 set<const SMDS_MeshNode*>::iterator it;
1934 // AddInverseElement to new nodes
1935 for ( int i = 0; i < nbnodes; i++ ) {
1936 it = oldNodes.find( nodes[i] );
1937 if ( it == oldNodes.end() )
1939 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1941 // remove from oldNodes a node that remains in elem
1942 oldNodes.erase( it );
1944 // RemoveInverseElement from the nodes removed from elem
1945 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1947 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1948 n->RemoveInverseElement( cell );
1955 //=======================================================================
1956 //function : ChangePolyhedronNodes
1957 //purpose : to change nodes of polyhedral volume
1958 //=======================================================================
1959 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1960 const vector<const SMDS_MeshNode*>& nodes,
1961 const vector<int> & quantities)
1963 if (elem->GetType() != SMDSAbs_Volume) {
1964 MESSAGE("WRONG ELEM TYPE");
1968 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1973 // keep current nodes of elem
1974 set<const SMDS_MeshElement*> oldNodes;
1975 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1976 while (itn->more()) {
1977 oldNodes.insert(itn->next());
1981 // TODO remove this function
1982 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1988 // update InverseElements
1990 // AddInverseElement to new nodes
1991 int nbnodes = nodes.size();
1992 set<const SMDS_MeshElement*>::iterator it;
1993 for (int i = 0; i < nbnodes; i++) {
1994 it = oldNodes.find(nodes[i]);
1995 if (it == oldNodes.end()) {
1997 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1999 // remove from oldNodes a node that remains in elem
2004 // RemoveInverseElement from the nodes removed from elem
2005 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
2006 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2007 (const_cast<SMDS_MeshElement *>( *it ));
2008 n->RemoveInverseElement(elem);
2015 //=======================================================================
2016 //function : Find0DElement
2018 //=======================================================================
2019 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
2021 const SMDS_MeshNode * node = FindNode(idnode);
2022 if(node == NULL) return NULL;
2023 return Find0DElement(node);
2026 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
2028 if (!node) return 0;
2029 const SMDS_Mesh0DElement* toReturn = NULL;
2030 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
2031 while (it1->more() && (toReturn == NULL)) {
2032 const SMDS_MeshElement* e = it1->next();
2033 if (e->NbNodes() == 1) {
2034 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
2040 //=======================================================================
2041 //function : FindBall
2043 //=======================================================================
2045 const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const
2047 const SMDS_MeshNode * node = FindNode(idnode);
2048 if(node == NULL) return NULL;
2049 return FindBall(node);
2052 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
2054 if (!node) return 0;
2055 const SMDS_BallElement* toReturn = NULL;
2056 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
2057 while (it1->more() && (toReturn == NULL)) {
2058 const SMDS_MeshElement* e = it1->next();
2059 if (e->GetGeomType() == SMDSGeom_BALL)
2060 toReturn = static_cast<const SMDS_BallElement*>(e);
2065 //=======================================================================
2066 //function : Find0DElementOrCreate
2068 //=======================================================================
2069 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
2071 // if (!node) return 0;
2072 // SMDS_Mesh0DElement * toReturn = NULL;
2073 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
2074 // if (toReturn == NULL) {
2075 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
2076 // toReturn = new SMDS_Mesh0DElement(node);
2077 // my0DElements.Add(toReturn);
2078 // myInfo.myNb0DElements++;
2084 //=======================================================================
2085 //function : FindEdge
2087 //=======================================================================
2089 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
2091 const SMDS_MeshNode * node1=FindNode(idnode1);
2092 const SMDS_MeshNode * node2=FindNode(idnode2);
2093 if((node1==NULL)||(node2==NULL)) return NULL;
2094 return FindEdge(node1,node2);
2097 //#include "Profiler.h"
2098 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2099 const SMDS_MeshNode * node2)
2101 if ( !node1 ) return 0;
2102 const SMDS_MeshEdge * toReturn=NULL;
2105 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
2108 while(it1->more()) {
2109 const SMDS_MeshElement * e = it1->next();
2110 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
2111 toReturn = static_cast<const SMDS_MeshEdge*>( e );
2120 //=======================================================================
2121 //function : FindEdgeOrCreate
2123 //=======================================================================
2125 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
2126 const SMDS_MeshNode * node2)
2128 if ( !node1 || !node2) return 0;
2129 SMDS_MeshEdge * toReturn=NULL;
2130 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
2131 if(toReturn==NULL) {
2132 if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2133 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
2134 adjustmyCellsCapacity(ID);
2135 myNodeIds.resize(2);
2136 myNodeIds[0] = node1->getVtkId();
2137 myNodeIds[1] = node2->getVtkId();
2139 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
2140 edgevtk->init(myNodeIds, this);
2141 if (!this->registerElement(ID,edgevtk))
2143 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
2144 myEdgePool->destroy(edgevtk);
2148 myCells[ID] = toReturn;
2155 //=======================================================================
2156 //function : FindEdge
2158 //=======================================================================
2160 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
2163 const SMDS_MeshNode * node1=FindNode(idnode1);
2164 const SMDS_MeshNode * node2=FindNode(idnode2);
2165 const SMDS_MeshNode * node3=FindNode(idnode3);
2166 return FindEdge(node1,node2,node3);
2169 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2170 const SMDS_MeshNode * node2,
2171 const SMDS_MeshNode * node3)
2173 if ( !node1 ) return 0;
2174 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
2175 while(it1->more()) {
2176 const SMDS_MeshElement * e = it1->next();
2177 if ( e->NbNodes() == 3 ) {
2178 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2179 while(it2->more()) {
2180 const SMDS_MeshElement* n = it2->next();
2190 return static_cast<const SMDS_MeshEdge *> (e);
2197 //=======================================================================
2198 //function : FindFace
2200 //=======================================================================
2202 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2205 const SMDS_MeshNode * node1=FindNode(idnode1);
2206 const SMDS_MeshNode * node2=FindNode(idnode2);
2207 const SMDS_MeshNode * node3=FindNode(idnode3);
2208 return FindFace(node1, node2, node3);
2211 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2212 const SMDS_MeshNode *node2,
2213 const SMDS_MeshNode *node3)
2215 if ( !node1 ) return 0;
2216 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2217 while(it1->more()) {
2218 const SMDS_MeshElement * e = it1->next();
2219 if ( e->NbNodes() == 3 ) {
2220 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2221 while(it2->more()) {
2222 const SMDS_MeshElement* n = it2->next();
2232 return static_cast<const SMDS_MeshFace *> (e);
2238 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2239 const SMDS_MeshNode *node2,
2240 const SMDS_MeshNode *node3)
2242 SMDS_MeshFace * toReturn=NULL;
2243 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
2244 if(toReturn==NULL) {
2245 int ID = myElementIDFactory->GetFreeID();
2246 toReturn = createTriangle(node1,node2,node3, ID);
2252 //=======================================================================
2253 //function : FindFace
2255 //=======================================================================
2257 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2258 int idnode3, int idnode4) const
2260 const SMDS_MeshNode * node1=FindNode(idnode1);
2261 const SMDS_MeshNode * node2=FindNode(idnode2);
2262 const SMDS_MeshNode * node3=FindNode(idnode3);
2263 const SMDS_MeshNode * node4=FindNode(idnode4);
2264 return FindFace(node1, node2, node3, node4);
2267 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2268 const SMDS_MeshNode *node2,
2269 const SMDS_MeshNode *node3,
2270 const SMDS_MeshNode *node4)
2272 if ( !node1 ) return 0;
2273 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2274 while(it1->more()) {
2275 const SMDS_MeshElement * e = it1->next();
2276 if ( e->NbNodes() == 4 ) {
2277 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2278 while(it2->more()) {
2279 const SMDS_MeshElement* n = it2->next();
2290 return static_cast<const SMDS_MeshFace *> (e);
2296 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2297 const SMDS_MeshNode *node2,
2298 const SMDS_MeshNode *node3,
2299 const SMDS_MeshNode *node4)
2301 SMDS_MeshFace * toReturn=NULL;
2302 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2303 if(toReturn==NULL) {
2304 int ID = myElementIDFactory->GetFreeID();
2305 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2311 //=======================================================================
2312 //function : FindFace
2313 //purpose :quadratic triangle
2314 //=======================================================================
2316 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2317 int idnode3, int idnode4,
2318 int idnode5, int idnode6) const
2320 const SMDS_MeshNode * node1 = FindNode(idnode1);
2321 const SMDS_MeshNode * node2 = FindNode(idnode2);
2322 const SMDS_MeshNode * node3 = FindNode(idnode3);
2323 const SMDS_MeshNode * node4 = FindNode(idnode4);
2324 const SMDS_MeshNode * node5 = FindNode(idnode5);
2325 const SMDS_MeshNode * node6 = FindNode(idnode6);
2326 return FindFace(node1, node2, node3, node4, node5, node6);
2329 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2330 const SMDS_MeshNode *node2,
2331 const SMDS_MeshNode *node3,
2332 const SMDS_MeshNode *node4,
2333 const SMDS_MeshNode *node5,
2334 const SMDS_MeshNode *node6)
2336 if ( !node1 ) return 0;
2337 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2338 while(it1->more()) {
2339 const SMDS_MeshElement * e = it1->next();
2340 if ( e->NbNodes() == 6 ) {
2341 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2342 while(it2->more()) {
2343 const SMDS_MeshElement* n = it2->next();
2356 return static_cast<const SMDS_MeshFace *> (e);
2363 //=======================================================================
2364 //function : FindFace
2365 //purpose : quadratic quadrangle
2366 //=======================================================================
2368 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2369 int idnode3, int idnode4,
2370 int idnode5, int idnode6,
2371 int idnode7, int idnode8) const
2373 const SMDS_MeshNode * node1 = FindNode(idnode1);
2374 const SMDS_MeshNode * node2 = FindNode(idnode2);
2375 const SMDS_MeshNode * node3 = FindNode(idnode3);
2376 const SMDS_MeshNode * node4 = FindNode(idnode4);
2377 const SMDS_MeshNode * node5 = FindNode(idnode5);
2378 const SMDS_MeshNode * node6 = FindNode(idnode6);
2379 const SMDS_MeshNode * node7 = FindNode(idnode7);
2380 const SMDS_MeshNode * node8 = FindNode(idnode8);
2381 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2384 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2385 const SMDS_MeshNode *node2,
2386 const SMDS_MeshNode *node3,
2387 const SMDS_MeshNode *node4,
2388 const SMDS_MeshNode *node5,
2389 const SMDS_MeshNode *node6,
2390 const SMDS_MeshNode *node7,
2391 const SMDS_MeshNode *node8)
2393 if ( !node1 ) return 0;
2394 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2395 while(it1->more()) {
2396 const SMDS_MeshElement * e = it1->next();
2397 if ( e->NbNodes() == 8 ) {
2398 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2399 while(it2->more()) {
2400 const SMDS_MeshElement* n = it2->next();
2415 return static_cast<const SMDS_MeshFace *> (e);
2422 //=======================================================================
2423 //function : FindElement
2425 //=======================================================================
2427 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2429 if ( IDelem <= 0 || IDelem >= (int)myCells.size() )
2431 MESSAGE("--------------------------------------------------------------------------------- ");
2432 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2433 MESSAGE("--------------------------------------------------------------------------------- ");
2434 // TODO raise an exception
2438 return myCells[IDelem];
2441 //=======================================================================
2442 //function : FindFace
2443 //purpose : find polygon
2444 //=======================================================================
2446 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2448 int nbnodes = nodes_ids.size();
2449 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2450 for (int inode = 0; inode < nbnodes; inode++) {
2451 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2452 if (node == NULL) return NULL;
2453 poly_nodes[inode] = node;
2455 return FindFace(poly_nodes);
2458 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2460 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2464 //================================================================================
2466 * \brief Return element based on all given nodes
2467 * \param nodes - node of element
2468 * \param type - type of element
2469 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2470 * \retval const SMDS_MeshElement* - found element or NULL
2472 //================================================================================
2474 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2475 const SMDSAbs_ElementType type,
2476 const bool noMedium)
2478 if ( nodes.size() > 0 && nodes[0] )
2480 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2483 const SMDS_MeshElement* e = itF->next();
2484 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2485 if ( nbNodesToCheck == (int)nodes.size() )
2487 for ( size_t i = 1; e && i < nodes.size(); ++i )
2489 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2490 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2501 //=======================================================================
2502 //function : DumpNodes
2504 //=======================================================================
2506 void SMDS_Mesh::DumpNodes() const
2508 MESSAGE("dump nodes of mesh : ");
2509 SMDS_NodeIteratorPtr itnode=nodesIterator();
2510 while(itnode->more()) ; //MESSAGE(itnode->next());
2513 //=======================================================================
2514 //function : Dump0DElements
2516 //=======================================================================
2517 void SMDS_Mesh::Dump0DElements() const
2519 MESSAGE("dump 0D elements of mesh : ");
2520 SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement);
2521 while(it0d->more()) ; //MESSAGE(it0d->next());
2524 //=======================================================================
2525 //function : DumpEdges
2527 //=======================================================================
2529 void SMDS_Mesh::DumpEdges() const
2531 MESSAGE("dump edges of mesh : ");
2532 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2533 while(itedge->more()) ; //MESSAGE(itedge->next());
2536 //=======================================================================
2537 //function : DumpFaces
2539 //=======================================================================
2541 void SMDS_Mesh::DumpFaces() const
2543 MESSAGE("dump faces of mesh : ");
2544 SMDS_FaceIteratorPtr itface=facesIterator();
2545 while(itface->more()) ; //MESSAGE(itface->next());
2548 //=======================================================================
2549 //function : DumpVolumes
2551 //=======================================================================
2553 void SMDS_Mesh::DumpVolumes() const
2555 MESSAGE("dump volumes of mesh : ");
2556 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2557 while(itvol->more()) ; //MESSAGE(itvol->next());
2560 //=======================================================================
2561 //function : DebugStats
2563 //=======================================================================
2565 void SMDS_Mesh::DebugStats() const
2567 MESSAGE("Debug stats of mesh : ");
2569 MESSAGE("===== NODES ====="<<NbNodes());
2570 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2571 MESSAGE("===== EDGES ====="<<NbEdges());
2572 MESSAGE("===== FACES ====="<<NbFaces());
2573 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2575 MESSAGE("End Debug stats of mesh ");
2579 SMDS_NodeIteratorPtr itnode=nodesIterator();
2580 int sizeofnodes = 0;
2581 int sizeoffaces = 0;
2583 while(itnode->more())
2585 const SMDS_MeshNode *node = itnode->next();
2587 sizeofnodes += sizeof(*node);
2589 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2592 const SMDS_MeshElement *me = it->next();
2593 sizeofnodes += sizeof(me);
2597 SMDS_FaceIteratorPtr itface=facesIterator();
2598 while(itface->more())
2600 const SMDS_MeshElement *face = itface->next();
2601 sizeoffaces += sizeof(*face);
2604 MESSAGE("total size of node elements = " << sizeofnodes);;
2605 MESSAGE("total size of face elements = " << sizeoffaces);;
2610 ///////////////////////////////////////////////////////////////////////////////
2611 /// Return the number of nodes
2612 ///////////////////////////////////////////////////////////////////////////////
2613 int SMDS_Mesh::NbNodes() const
2615 //MESSAGE(myGrid->GetNumberOfPoints());
2616 //MESSAGE(myInfo.NbNodes());
2617 //MESSAGE(myNodeMax);
2618 return myInfo.NbNodes();
2621 ///////////////////////////////////////////////////////////////////////////////
2622 /// Return the number of 0D elements
2623 ///////////////////////////////////////////////////////////////////////////////
2624 int SMDS_Mesh::Nb0DElements() const
2626 return myInfo.Nb0DElements();
2629 ///////////////////////////////////////////////////////////////////////////////
2630 /// Return the number of 0D elements
2631 ///////////////////////////////////////////////////////////////////////////////
2632 int SMDS_Mesh::NbBalls() const
2634 return myInfo.NbBalls();
2637 ///////////////////////////////////////////////////////////////////////////////
2638 /// Return the number of edges (including construction edges)
2639 ///////////////////////////////////////////////////////////////////////////////
2640 int SMDS_Mesh::NbEdges() const
2642 return myInfo.NbEdges();
2645 ///////////////////////////////////////////////////////////////////////////////
2646 /// Return the number of faces (including construction faces)
2647 ///////////////////////////////////////////////////////////////////////////////
2648 int SMDS_Mesh::NbFaces() const
2650 return myInfo.NbFaces();
2653 ///////////////////////////////////////////////////////////////////////////////
2654 /// Return the number of volumes
2655 ///////////////////////////////////////////////////////////////////////////////
2656 int SMDS_Mesh::NbVolumes() const
2658 return myInfo.NbVolumes();
2661 ///////////////////////////////////////////////////////////////////////////////
2662 /// Return the number of child mesh of this mesh.
2663 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
2664 ///////////////////////////////////////////////////////////////////////////////
2665 int SMDS_Mesh::NbSubMesh() const
2667 return myChildren.size();
2670 ///////////////////////////////////////////////////////////////////////////////
2671 /// Destroy the mesh and all its elements
2672 /// All pointer on elements owned by this mesh become illegals.
2673 ///////////////////////////////////////////////////////////////////////////////
2674 SMDS_Mesh::~SMDS_Mesh()
2676 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2677 while(itc!=myChildren.end())
2685 delete myNodeIDFactory;
2686 delete myElementIDFactory;
2690 SMDS_ElemIteratorPtr eIt = elementsIterator();
2691 while ( eIt->more() )
2693 const SMDS_MeshElement *elem = eIt->next();
2694 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2696 SMDS_NodeIteratorPtr itn = nodesIterator();
2699 const SMDS_MeshNode *node = itn->next();
2700 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2701 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2707 delete myVolumePool;
2713 //================================================================================
2715 * \brief Clear all data
2717 //================================================================================
2719 void SMDS_Mesh::Clear()
2721 MESSAGE("SMDS_Mesh::Clear");
2724 SMDS_ElemIteratorPtr eIt = elementsIterator();
2725 while ( eIt->more() )
2727 const SMDS_MeshElement *elem = eIt->next();
2728 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2730 SMDS_NodeIteratorPtr itn = nodesIterator();
2733 const SMDS_MeshNode *node = itn->next();
2734 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2739 myNodeIDFactory->Clear();
2740 myElementIDFactory->Clear();
2743 // SMDS_ElemIteratorPtr itv = elementsIterator();
2744 // while (itv->more())
2746 // SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2747 // SMDSAbs_ElementType aType = elem->GetType();
2750 // case SMDSAbs_0DElement:
2753 // case SMDSAbs_Edge:
2754 // myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2756 // case SMDSAbs_Face:
2757 // myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2759 // case SMDSAbs_Volume:
2760 // myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2762 // case SMDSAbs_Ball:
2763 // myBallPool->destroy(static_cast<SMDS_BallElement*>(elem));
2769 myVolumePool->clear();
2770 myFacePool->clear();
2771 myEdgePool->clear();
2772 myBallPool->clear();
2774 clearVector( myCells );
2775 clearVector( myCellIdVtkToSmds );
2777 SMDS_NodeIteratorPtr itn = nodesIterator();
2780 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2781 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2782 //myNodePool->destroy(node);
2784 myNodePool->clear();
2785 clearVector( myNodes );
2787 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2788 while(itc!=myChildren.end())
2799 myGrid->Initialize();
2801 vtkPoints* points = vtkPoints::New();
2802 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2803 // using double type for storing coordinates of nodes instead float.
2804 points->SetDataType(VTK_DOUBLE);
2805 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2806 myGrid->SetPoints( points );
2808 myGrid->BuildLinks();
2811 ///////////////////////////////////////////////////////////////////////////////
2812 /// Return true if this mesh create faces with edges.
2813 /// A false returned value mean that faces are created with nodes. A concequence
2814 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2815 ///////////////////////////////////////////////////////////////////////////////
2816 bool SMDS_Mesh::hasConstructionEdges()
2818 return myHasConstructionEdges;
2821 ///////////////////////////////////////////////////////////////////////////////
2822 /// Return true if this mesh create volumes with faces
2823 /// A false returned value mean that volumes are created with nodes or edges.
2824 /// (see hasConstructionEdges)
2825 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2827 ///////////////////////////////////////////////////////////////////////////////
2828 bool SMDS_Mesh::hasConstructionFaces()
2830 return myHasConstructionFaces;
2833 ///////////////////////////////////////////////////////////////////////////////
2834 /// Return true if nodes are linked to the finit elements, they are belonging to.
2835 /// Currently, It always return true.
2836 ///////////////////////////////////////////////////////////////////////////////
2837 bool SMDS_Mesh::hasInverseElements()
2839 return myHasInverseElements;
2842 ///////////////////////////////////////////////////////////////////////////////
2843 /// Make this mesh creating construction edges (see hasConstructionEdges)
2844 /// @param b true to have construction edges, else false.
2845 ///////////////////////////////////////////////////////////////////////////////
2846 void SMDS_Mesh::setConstructionEdges(bool b)
2848 myHasConstructionEdges=b;
2851 ///////////////////////////////////////////////////////////////////////////////
2852 /// Make this mesh creating construction faces (see hasConstructionFaces)
2853 /// @param b true to have construction faces, else false.
2854 ///////////////////////////////////////////////////////////////////////////////
2855 void SMDS_Mesh::setConstructionFaces(bool b)
2857 myHasConstructionFaces=b;
2860 ///////////////////////////////////////////////////////////////////////////////
2861 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2862 /// @param b true to link nodes to elements, else false.
2863 ///////////////////////////////////////////////////////////////////////////////
2864 void SMDS_Mesh::setInverseElements(bool b)
2866 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2867 myHasInverseElements=b;
2872 //================================================================================
2874 * \brief Iterator on elements in id increasing order
2876 //================================================================================
2878 template <typename ELEM=const SMDS_MeshElement*>
2879 class IdSortedIterator : public SMDS_Iterator<ELEM>
2881 SMDS_MeshElementIDFactory& myIDFact;
2882 int myID, myMaxID, myNbFound, myTotalNb;
2883 SMDSAbs_ElementType myType;
2887 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2888 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2891 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2903 ELEM current = myElem;
2905 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2906 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2907 && myElem->GetType() != myType )
2910 myNbFound += bool(myElem);
2916 //================================================================================
2918 * \brief Iterator on vector of elements, possibly being resized while iteration
2920 //================================================================================
2922 template<typename RETURN_VALUE,
2923 typename VECTOR_VALUE=SMDS_MeshCell*,
2924 typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
2925 class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
2927 const std::vector<VECTOR_VALUE>& _vector;
2930 VALUE_FILTER _filter;
2932 ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
2933 const VALUE_FILTER& filter=VALUE_FILTER() )
2934 :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
2936 if ( _more && !_filter( _vector[ _index ]))
2943 virtual RETURN_VALUE next()
2945 if ( !_more ) return NULL;
2946 VECTOR_VALUE current = _vector[ _index ];
2948 while ( !_more && ++_index < _vector.size() )
2949 _more = _filter( _vector[ _index ]);
2950 return (RETURN_VALUE) current;
2955 ///////////////////////////////////////////////////////////////////////////////
2956 /// Return an iterator on nodes of the current mesh factory
2957 ///////////////////////////////////////////////////////////////////////////////
2959 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2961 // naturally always sorted by ID
2962 typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
2963 return SMDS_NodeIteratorPtr( new TIterator(myNodes));
2966 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
2968 // naturally always sorted by ID
2969 typedef ElemVecIterator
2970 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
2971 return SMDS_ElemIteratorPtr
2972 (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
2975 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
2977 if ( type == SMDSEntity_Node )
2979 typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
2980 return SMDS_ElemIteratorPtr( new TIterator(myNodes));
2982 // naturally always sorted by ID
2983 typedef ElemVecIterator
2984 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
2985 return SMDS_ElemIteratorPtr
2986 (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
2989 ///////////////////////////////////////////////////////////////////////////////
2990 /// Return an iterator on elements of the current mesh factory
2991 ///////////////////////////////////////////////////////////////////////////////
2992 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2994 // naturally always sorted by ID
2998 return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
3001 return SMDS_ElemIteratorPtr
3002 ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
3005 typedef ElemVecIterator
3006 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3007 return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
3009 return SMDS_ElemIteratorPtr();
3012 ///////////////////////////////////////////////////////////////////////////////
3013 ///Return an iterator on edges of the current mesh.
3014 ///////////////////////////////////////////////////////////////////////////////
3016 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
3018 // naturally always sorted by ID
3019 typedef ElemVecIterator
3020 < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3021 return SMDS_EdgeIteratorPtr
3022 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
3025 ///////////////////////////////////////////////////////////////////////////////
3026 ///Return an iterator on faces of the current mesh.
3027 ///////////////////////////////////////////////////////////////////////////////
3029 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
3031 // naturally always sorted by ID
3032 typedef ElemVecIterator
3033 < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3034 return SMDS_FaceIteratorPtr
3035 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
3038 ///////////////////////////////////////////////////////////////////////////////
3039 ///Return an iterator on volumes of the current mesh.
3040 ///////////////////////////////////////////////////////////////////////////////
3042 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
3044 // naturally always sorted by ID
3045 typedef ElemVecIterator
3046 < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3047 return SMDS_VolumeIteratorPtr
3048 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
3051 ///////////////////////////////////////////////////////////////////////////////
3052 /// Do intersection of sets (more than 2)
3053 ///////////////////////////////////////////////////////////////////////////////
3054 static set<const SMDS_MeshElement*> * intersectionOfSets(
3055 set<const SMDS_MeshElement*> vs[], int numberOfSets)
3057 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
3058 set<const SMDS_MeshElement*>* rsetB;
3060 for(int i=0; i<numberOfSets-1; i++)
3062 rsetB=new set<const SMDS_MeshElement*>();
3064 rsetA->begin(), rsetA->end(),
3065 vs[i+1].begin(), vs[i+1].end(),
3066 inserter(*rsetB, rsetB->begin()));
3073 ///////////////////////////////////////////////////////////////////////////////
3074 /// Return the list of finite elements owning the given element: elements
3075 /// containing all the nodes of the given element, for instance faces and
3076 /// volumes containing a given edge.
3077 ///////////////////////////////////////////////////////////////////////////////
3078 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
3080 int numberOfSets=element->NbNodes();
3081 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
3083 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
3086 while(itNodes->more())
3088 const SMDS_MeshElement* node = itNodes->next();
3090 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
3091 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3093 //initSet[i]=set<const SMDS_MeshElement*>();
3096 const SMDS_MeshElement* elem = itFe->next();
3098 initSet[i].insert(elem);
3104 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
3105 // MESSAGE("nb elems " << i << " intersection " << retSet->size());
3110 ///////////////////////////////////////////////////////////////////////////////
3111 /// Return the list of nodes used only by the given elements
3112 ///////////////////////////////////////////////////////////////////////////////
3113 static set<const SMDS_MeshElement*> * getExclusiveNodes(set<const SMDS_MeshElement*>& elements)
3115 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
3116 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
3118 while(itElements!=elements.end())
3120 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
3123 while(itNodes->more())
3125 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
3126 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3127 set<const SMDS_MeshElement*> s;
3129 s.insert(itFe->next());
3130 if(s==elements) toReturn->insert(n);
3136 ///////////////////////////////////////////////////////////////////////////////
3137 ///Find the children of an element that are made of given nodes
3138 ///@param setOfChildren The set in which matching children will be inserted
3139 ///@param element The element were to search matching children
3140 ///@param nodes The nodes that the children must have to be selected
3141 ///////////////////////////////////////////////////////////////////////////////
3142 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
3143 const SMDS_MeshElement * element,
3144 set<const SMDS_MeshElement*>& nodes)
3146 switch(element->GetType())
3149 MESSAGE("Internal Error: This should not happen");
3151 case SMDSAbs_0DElement:
3158 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3161 const SMDS_MeshElement * e=itn->next();
3162 if(nodes.find(e)!=nodes.end())
3164 setOfChildren.insert(element);
3171 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3174 const SMDS_MeshElement * e=itn->next();
3175 if(nodes.find(e)!=nodes.end())
3177 setOfChildren.insert(element);
3181 if(hasConstructionEdges())
3183 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3185 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3188 case SMDSAbs_Volume:
3190 if(hasConstructionFaces())
3192 SMDS_ElemIteratorPtr ite=element->facesIterator();
3194 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3196 else if(hasConstructionEdges())
3198 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3200 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3203 case SMDSAbs_NbElementTypes:
3204 case SMDSAbs_All: break;
3208 ///////////////////////////////////////////////////////////////////////////////
3209 ///@param elem The element to delete
3210 ///@param removenodes if true remaining nodes will be removed
3211 ///////////////////////////////////////////////////////////////////////////////
3212 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3213 const bool removenodes)
3215 list<const SMDS_MeshElement *> removedElems;
3216 list<const SMDS_MeshElement *> removedNodes;
3217 RemoveElement( elem, removedElems, removedNodes, removenodes );
3220 ///////////////////////////////////////////////////////////////////////////////
3221 ///@param elem The element to delete
3222 ///@param removedElems to be filled with all removed elements
3223 ///@param removedNodes to be filled with all removed nodes
3224 ///@param removenodes if true remaining nodes will be removed
3225 ///////////////////////////////////////////////////////////////////////////////
3226 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3227 list<const SMDS_MeshElement *>& removedElems,
3228 list<const SMDS_MeshElement *>& removedNodes,
3231 // get finite elements built on elem
3232 set<const SMDS_MeshElement*> * s1;
3233 if ( (elem->GetType() == SMDSAbs_0DElement)
3234 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3235 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3236 || (elem->GetType() == SMDSAbs_Volume) )
3238 s1 = new set<const SMDS_MeshElement*> ();
3242 s1 = getFinitElements(elem);
3244 // get exclusive nodes (which would become free afterwards)
3245 set<const SMDS_MeshElement*> * s2;
3246 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3248 // do not remove nodes except elem
3249 s2 = new set<const SMDS_MeshElement*> ();
3254 s2 = getExclusiveNodes(*s1);
3256 // form the set of finite and construction elements to remove
3257 set<const SMDS_MeshElement*> s3;
3258 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3259 while (it != s1->end())
3261 addChildrenWithNodes(s3, *it, *s2);
3265 if (elem->GetType() != SMDSAbs_Node)
3268 // remove finite and construction elements
3270 while (it != s3.end())
3272 // Remove element from <InverseElements> of its nodes
3273 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3276 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3277 n->RemoveInverseElement((*it));
3279 int IdToRemove = (*it)->GetID();
3280 int vtkid = (*it)->getVtkId();
3281 switch ((*it)->GetType())
3284 MYASSERT("Internal Error: This should not happen");
3286 case SMDSAbs_0DElement:
3287 if (IdToRemove >= 0)
3289 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3292 removedElems.push_back((*it));
3293 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3297 if (IdToRemove >= 0)
3299 myCells[IdToRemove] = 0;
3300 myInfo.RemoveEdge(*it);
3302 removedElems.push_back((*it));
3303 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3304 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it)) {
3305 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3306 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3312 if (IdToRemove >= 0)
3314 myCells[IdToRemove] = 0;
3315 myInfo.RemoveFace(*it);
3317 removedElems.push_back((*it));
3318 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3319 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it)) {
3320 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3321 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3326 case SMDSAbs_Volume:
3327 if (IdToRemove >= 0)
3329 myCells[IdToRemove] = 0;
3330 myInfo.RemoveVolume(*it);
3332 removedElems.push_back((*it));
3333 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3334 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it)) {
3335 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3336 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3342 if (IdToRemove >= 0)
3344 myCells[IdToRemove] = 0;
3347 removedElems.push_back((*it));
3348 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3349 if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it)) {
3350 myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
3351 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3357 case SMDSAbs_All: // avoid compilation warning
3358 case SMDSAbs_NbElementTypes: break;
3362 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3367 // remove exclusive (free) nodes
3371 while (it != s2->end())
3373 int IdToRemove = (*it)->GetID();
3374 if (IdToRemove >= 0)
3376 myNodes[IdToRemove] = 0;
3379 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3380 removedNodes.push_back((*it));
3381 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3383 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3384 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3397 ///////////////////////////////////////////////////////////////////////////////
3398 ///@param elem The element to delete
3399 ///////////////////////////////////////////////////////////////////////////////
3400 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3402 int elemId = elem->GetID();
3403 int vtkId = elem->getVtkId();
3404 //MESSAGE("RemoveFreeElement " << elemId);
3405 SMDSAbs_ElementType aType = elem->GetType();
3406 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3407 if (aType == SMDSAbs_Node) {
3408 //MESSAGE("Remove free node " << elemId);
3409 // only free node can be removed by this method
3410 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3411 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3412 if (!itFe->more()) { // free node
3413 myNodes[elemId] = 0;
3415 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3416 ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( -1, -1, -1 ); // avoid reuse
3417 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3418 myNodeIDFactory->ReleaseID(elemId, vtkId);
3421 if (hasConstructionEdges() || hasConstructionFaces())
3422 // this methods is only for meshes without descendants
3425 //MESSAGE("Remove free element " << elemId);
3426 // Remove element from <InverseElements> of its nodes
3427 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3428 while (itn->more()) {
3429 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3430 (const_cast<SMDS_MeshElement *>(itn->next()));
3431 n->RemoveInverseElement(elem);
3434 // in meshes without descendants elements are always free
3436 case SMDSAbs_0DElement:
3437 myCells[elemId] = 0;
3438 myInfo.remove(elem);
3443 myCells[elemId] = 0;
3444 myInfo.RemoveEdge(elem);
3445 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3448 myCells[elemId] = 0;
3449 myInfo.RemoveFace(elem);
3450 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3452 case SMDSAbs_Volume:
3453 myCells[elemId] = 0;
3454 myInfo.RemoveVolume(elem);
3455 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3458 myCells[elemId] = 0;
3459 myInfo.remove(elem);
3460 myBallPool->destroy(static_cast<SMDS_BallElement*>(todest));
3465 myElementIDFactory->ReleaseID(elemId, vtkId);
3467 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3468 // --- to do: keep vtkid in a list of reusable cells
3471 ((SMDS_MeshElement*) elem)->init( -1, -1, -1 ); // avoid reuse
3476 * Checks if the element is present in mesh.
3477 * Useful to determine dead pointers.
3479 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3481 // we should not imply on validity of *elem, so iterate on containers
3482 // of all types in the hope of finding <elem> somewhere there
3483 SMDS_NodeIteratorPtr itn = nodesIterator();
3485 if (elem == itn->next())
3487 SMDS_ElemIteratorPtr ite = elementsIterator();
3489 if (elem == ite->next())
3494 //=======================================================================
3495 //function : MaxNodeID
3497 //=======================================================================
3499 int SMDS_Mesh::MaxNodeID() const
3504 //=======================================================================
3505 //function : MinNodeID
3507 //=======================================================================
3509 int SMDS_Mesh::MinNodeID() const
3514 //=======================================================================
3515 //function : MaxElementID
3517 //=======================================================================
3519 int SMDS_Mesh::MaxElementID() const
3521 return myElementIDFactory->GetMaxID();
3524 //=======================================================================
3525 //function : MinElementID
3527 //=======================================================================
3529 int SMDS_Mesh::MinElementID() const
3531 return myElementIDFactory->GetMinID();
3534 //=======================================================================
3535 //function : Renumber
3536 //purpose : Renumber all nodes or elements.
3537 //=======================================================================
3539 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3541 MESSAGE("Renumber");
3545 SMDS_MeshNodeIDFactory * idFactory =
3546 isNodes ? myNodeIDFactory : myElementIDFactory;
3548 // get existing elements in the order of ID increasing
3549 map<int,SMDS_MeshElement*> elemMap;
3550 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3551 while ( idElemIt->more() ) {
3552 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3553 int id = elem->GetID();
3554 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3556 // release their ids
3557 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3559 // for ( ; elemIt != elemMap.end(); elemIt++ )
3561 // int id = (*elemIt).first;
3562 // idFactory->ReleaseID( id );
3566 elemIt = elemMap.begin();
3567 for ( ; elemIt != elemMap.end(); elemIt++ )
3569 idFactory->BindID( ID, (*elemIt).second );
3574 //=======================================================================
3575 //function : GetElementType
3576 //purpose : Return type of element or node with id
3577 //=======================================================================
3579 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3581 SMDS_MeshElement* elem = 0;
3583 elem = myElementIDFactory->MeshElement( id );
3585 elem = myNodeIDFactory->MeshElement( id );
3589 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3593 return elem->GetType();
3598 //********************************************************************
3599 //********************************************************************
3600 //******** *********
3601 //***** Methods for addition of quadratic elements ******
3602 //******** *********
3603 //********************************************************************
3604 //********************************************************************
3606 //=======================================================================
3607 //function : AddEdgeWithID
3609 //=======================================================================
3610 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3612 return SMDS_Mesh::AddEdgeWithID
3613 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3614 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3615 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3619 //=======================================================================
3620 //function : AddEdge
3622 //=======================================================================
3623 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3624 const SMDS_MeshNode* n2,
3625 const SMDS_MeshNode* n12)
3627 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3630 //=======================================================================
3631 //function : AddEdgeWithID
3633 //=======================================================================
3634 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3635 const SMDS_MeshNode * n2,
3636 const SMDS_MeshNode * n12,
3639 if ( !n1 || !n2 || !n12 ) return 0;
3641 // --- retrieve nodes ID
3642 myNodeIds.resize(3);
3643 myNodeIds[0] = n1->getVtkId();
3644 myNodeIds[1] = n2->getVtkId();
3645 myNodeIds[2] = n12->getVtkId();
3647 SMDS_MeshEdge * edge = 0;
3648 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3649 edgevtk->init(myNodeIds, this);
3650 if (!this->registerElement(ID,edgevtk))
3652 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3653 myEdgePool->destroy(edgevtk);
3657 adjustmyCellsCapacity(ID);
3659 myInfo.myNbQuadEdges++;
3661 // if (!registerElement(ID, edge)) {
3662 // RemoveElement(edge, false);
3670 //=======================================================================
3671 //function : AddFace
3673 //=======================================================================
3674 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3675 const SMDS_MeshNode * n2,
3676 const SMDS_MeshNode * n3,
3677 const SMDS_MeshNode * n12,
3678 const SMDS_MeshNode * n23,
3679 const SMDS_MeshNode * n31)
3681 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3682 myElementIDFactory->GetFreeID());
3685 //=======================================================================
3686 //function : AddFaceWithID
3688 //=======================================================================
3689 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3690 int n12,int n23,int n31, int ID)
3692 return SMDS_Mesh::AddFaceWithID
3693 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3694 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3695 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3696 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3697 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3698 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3702 //=======================================================================
3703 //function : AddFaceWithID
3705 //=======================================================================
3706 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3707 const SMDS_MeshNode * n2,
3708 const SMDS_MeshNode * n3,
3709 const SMDS_MeshNode * n12,