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:
3157 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3160 const SMDS_MeshElement * e=itn->next();
3161 if(nodes.find(e)!=nodes.end())
3163 setOfChildren.insert(element);
3170 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3173 const SMDS_MeshElement * e=itn->next();
3174 if(nodes.find(e)!=nodes.end())
3176 setOfChildren.insert(element);
3180 if(hasConstructionEdges())
3182 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3184 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3187 case SMDSAbs_Volume:
3189 if(hasConstructionFaces())
3191 SMDS_ElemIteratorPtr ite=element->facesIterator();
3193 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3195 else if(hasConstructionEdges())
3197 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3199 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3202 case SMDSAbs_All: break;
3206 ///////////////////////////////////////////////////////////////////////////////
3207 ///@param elem The element to delete
3208 ///@param removenodes if true remaining nodes will be removed
3209 ///////////////////////////////////////////////////////////////////////////////
3210 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3211 const bool removenodes)
3213 list<const SMDS_MeshElement *> removedElems;
3214 list<const SMDS_MeshElement *> removedNodes;
3215 RemoveElement( elem, removedElems, removedNodes, removenodes );
3218 ///////////////////////////////////////////////////////////////////////////////
3219 ///@param elem The element to delete
3220 ///@param removedElems to be filled with all removed elements
3221 ///@param removedNodes to be filled with all removed nodes
3222 ///@param removenodes if true remaining nodes will be removed
3223 ///////////////////////////////////////////////////////////////////////////////
3224 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3225 list<const SMDS_MeshElement *>& removedElems,
3226 list<const SMDS_MeshElement *>& removedNodes,
3229 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
3230 // get finite elements built on elem
3231 set<const SMDS_MeshElement*> * s1;
3232 if ( (elem->GetType() == SMDSAbs_0DElement)
3233 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3234 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3235 || (elem->GetType() == SMDSAbs_Volume) )
3237 s1 = new set<const SMDS_MeshElement*> ();
3241 s1 = getFinitElements(elem);
3243 // get exclusive nodes (which would become free afterwards)
3244 set<const SMDS_MeshElement*> * s2;
3245 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3247 // do not remove nodes except elem
3248 s2 = new set<const SMDS_MeshElement*> ();
3253 s2 = getExclusiveNodes(*s1);
3255 // form the set of finite and construction elements to remove
3256 set<const SMDS_MeshElement*> s3;
3257 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3258 while (it != s1->end())
3260 addChildrenWithNodes(s3, *it, *s2);
3264 if (elem->GetType() != SMDSAbs_Node)
3267 // remove finite and construction elements
3269 while (it != s3.end())
3271 // Remove element from <InverseElements> of its nodes
3272 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3275 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3276 n->RemoveInverseElement((*it));
3278 int IdToRemove = (*it)->GetID();
3279 int vtkid = (*it)->getVtkId();
3280 //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3281 // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3282 switch ((*it)->GetType())
3285 MYASSERT("Internal Error: This should not happen")
3288 case SMDSAbs_0DElement:
3289 if (IdToRemove >= 0)
3291 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3294 removedElems.push_back((*it));
3295 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3299 if (IdToRemove >= 0)
3301 myCells[IdToRemove] = 0;
3302 myInfo.RemoveEdge(*it);
3304 removedElems.push_back((*it));
3305 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3306 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3307 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
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);
3324 case SMDSAbs_Volume:
3325 if (IdToRemove >= 0)
3327 myCells[IdToRemove] = 0;
3328 myInfo.RemoveVolume(*it);
3330 removedElems.push_back((*it));
3331 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3332 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3333 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3338 if (IdToRemove >= 0)
3340 myCells[IdToRemove] = 0;
3343 removedElems.push_back((*it));
3344 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3345 if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
3346 myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
3352 case SMDSAbs_NbElementTypes: break;
3356 //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3357 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3362 // remove exclusive (free) nodes
3366 while (it != s2->end())
3368 int IdToRemove = (*it)->GetID();
3369 //MESSAGE( "SMDS: RM node " << IdToRemove);
3370 if (IdToRemove >= 0)
3372 myNodes[IdToRemove] = 0;
3375 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3376 removedNodes.push_back((*it));
3377 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3379 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3380 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3393 ///////////////////////////////////////////////////////////////////////////////
3394 ///@param elem The element to delete
3395 ///////////////////////////////////////////////////////////////////////////////
3396 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3398 int elemId = elem->GetID();
3399 int vtkId = elem->getVtkId();
3400 //MESSAGE("RemoveFreeElement " << elemId);
3401 SMDSAbs_ElementType aType = elem->GetType();
3402 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3403 if (aType == SMDSAbs_Node) {
3404 //MESSAGE("Remove free node " << elemId);
3405 // only free node can be removed by this method
3406 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3407 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3408 if (!itFe->more()) { // free node
3409 myNodes[elemId] = 0;
3411 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3412 ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( -1, -1, -1 ); // avoid reuse
3413 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3414 myNodeIDFactory->ReleaseID(elemId, vtkId);
3417 if (hasConstructionEdges() || hasConstructionFaces())
3418 // this methods is only for meshes without descendants
3421 //MESSAGE("Remove free element " << elemId);
3422 // Remove element from <InverseElements> of its nodes
3423 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3424 while (itn->more()) {
3425 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3426 (const_cast<SMDS_MeshElement *>(itn->next()));
3427 n->RemoveInverseElement(elem);
3430 // in meshes without descendants elements are always free
3432 case SMDSAbs_0DElement:
3433 myCells[elemId] = 0;
3434 myInfo.remove(elem);
3438 myCells[elemId] = 0;
3439 myInfo.RemoveEdge(elem);
3440 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3443 myCells[elemId] = 0;
3444 myInfo.RemoveFace(elem);
3445 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3447 case SMDSAbs_Volume:
3448 myCells[elemId] = 0;
3449 myInfo.RemoveVolume(elem);
3450 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3453 myCells[elemId] = 0;
3454 myInfo.remove(elem);
3455 myBallPool->destroy(static_cast<SMDS_BallElement*>(todest));
3460 myElementIDFactory->ReleaseID(elemId, vtkId);
3462 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3463 // --- to do: keep vtkid in a list of reusable cells
3468 * Checks if the element is present in mesh.
3469 * Useful to determine dead pointers.
3471 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3473 // we should not imply on validity of *elem, so iterate on containers
3474 // of all types in the hope of finding <elem> somewhere there
3475 SMDS_NodeIteratorPtr itn = nodesIterator();
3477 if (elem == itn->next())
3479 SMDS_ElemIteratorPtr ite = elementsIterator();
3481 if (elem == ite->next())
3486 //=======================================================================
3487 //function : MaxNodeID
3489 //=======================================================================
3491 int SMDS_Mesh::MaxNodeID() const
3496 //=======================================================================
3497 //function : MinNodeID
3499 //=======================================================================
3501 int SMDS_Mesh::MinNodeID() const
3506 //=======================================================================
3507 //function : MaxElementID
3509 //=======================================================================
3511 int SMDS_Mesh::MaxElementID() const
3513 return myElementIDFactory->GetMaxID();
3516 //=======================================================================
3517 //function : MinElementID
3519 //=======================================================================
3521 int SMDS_Mesh::MinElementID() const
3523 return myElementIDFactory->GetMinID();
3526 //=======================================================================
3527 //function : Renumber
3528 //purpose : Renumber all nodes or elements.
3529 //=======================================================================
3531 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3533 MESSAGE("Renumber");
3537 SMDS_MeshNodeIDFactory * idFactory =
3538 isNodes ? myNodeIDFactory : myElementIDFactory;
3540 // get existing elements in the order of ID increasing
3541 map<int,SMDS_MeshElement*> elemMap;
3542 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3543 while ( idElemIt->more() ) {
3544 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3545 int id = elem->GetID();
3546 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3548 // release their ids
3549 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3551 // for ( ; elemIt != elemMap.end(); elemIt++ )
3553 // int id = (*elemIt).first;
3554 // idFactory->ReleaseID( id );
3558 elemIt = elemMap.begin();
3559 for ( ; elemIt != elemMap.end(); elemIt++ )
3561 idFactory->BindID( ID, (*elemIt).second );
3566 //=======================================================================
3567 //function : GetElementType
3568 //purpose : Return type of element or node with id
3569 //=======================================================================
3571 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3573 SMDS_MeshElement* elem = 0;
3575 elem = myElementIDFactory->MeshElement( id );
3577 elem = myNodeIDFactory->MeshElement( id );
3581 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3585 return elem->GetType();
3590 //********************************************************************
3591 //********************************************************************
3592 //******** *********
3593 //***** Methods for addition of quadratic elements ******
3594 //******** *********
3595 //********************************************************************
3596 //********************************************************************
3598 //=======================================================================
3599 //function : AddEdgeWithID
3601 //=======================================================================
3602 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3604 return SMDS_Mesh::AddEdgeWithID
3605 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3606 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3607 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3611 //=======================================================================
3612 //function : AddEdge
3614 //=======================================================================
3615 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3616 const SMDS_MeshNode* n2,
3617 const SMDS_MeshNode* n12)
3619 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3622 //=======================================================================
3623 //function : AddEdgeWithID
3625 //=======================================================================
3626 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3627 const SMDS_MeshNode * n2,
3628 const SMDS_MeshNode * n12,
3631 if ( !n1 || !n2 || !n12 ) return 0;
3633 // --- retrieve nodes ID
3634 myNodeIds.resize(3);
3635 myNodeIds[0] = n1->getVtkId();
3636 myNodeIds[1] = n2->getVtkId();
3637 myNodeIds[2] = n12->getVtkId();
3639 SMDS_MeshEdge * edge = 0;
3640 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3641 edgevtk->init(myNodeIds, this);
3642 if (!this->registerElement(ID,edgevtk))
3644 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3645 myEdgePool->destroy(edgevtk);
3649 adjustmyCellsCapacity(ID);
3651 myInfo.myNbQuadEdges++;
3653 // if (!registerElement(ID, edge)) {
3654 // RemoveElement(edge, false);
3662 //=======================================================================
3663 //function : AddFace
3665 //=======================================================================
3666 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3667 const SMDS_MeshNode * n2,
3668 const SMDS_MeshNode * n3,
3669 const SMDS_MeshNode * n12,
3670 const SMDS_MeshNode * n23,
3671 const SMDS_MeshNode * n31)
3673 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3674 myElementIDFactory->GetFreeID());
3677 //=======================================================================
3678 //function : AddFaceWithID
3680 //=======================================================================
3681 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3682 int n12,int n23,int n31, int ID)
3684 return SMDS_Mesh::AddFaceWithID
3685 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3686 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3687 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3688 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3689 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3690 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3694 //=======================================================================
3695 //function : AddFaceWithID
3697 //=======================================================================
3698 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3699 const SMDS_MeshNode * n2,
3700 const SMDS_MeshNode * n3,
3701 const SMDS_MeshNode * n12,
3702 const SMDS_MeshNode * n23,
3703 const SMDS_MeshNode * n31,
3706 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3707 if(hasConstructionEdges()) {
3708 // creation quadratic edges - not implemented
3713 // --- retrieve nodes ID
3714 myNodeIds.resize(6);
3715 myNodeIds[0] = n1->getVtkId();
3716 myNodeIds[1] = n2->getVtkId();
3717 myNodeIds[2] = n3->getVtkId();
3718 myNodeIds[3] = n12->getVtkId();
3719 myNodeIds[4] = n23->getVtkId();
3720 myNodeIds[5] = n31->getVtkId();
3722 SMDS_MeshFace * face = 0;
3723 SMDS_VtkFace *facevtk = myFacePool->getNew();
3724 facevtk->init(myNodeIds, this);
3725 if (!this->registerElement(ID,facevtk))
3727 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3728 myFacePool->destroy(facevtk);
3732 adjustmyCellsCapacity(ID);
3734 myInfo.myNbQuadTriangles++;
3736 // if (!registerElement(ID, face)) {
3737 // RemoveElement(face, false);
3745 //=======================================================================
3746 //function : AddFace
3748 //=======================================================================
3749 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3750 const SMDS_MeshNode * n2,
3751 const SMDS_MeshNode * n3,
3752 const SMDS_MeshNode * n12,
3753 const SMDS_MeshNode * n23,
3754 const SMDS_MeshNode * n31,
3755 const SMDS_MeshNode * nCenter)
3757 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
3758 myElementIDFactory->GetFreeID());
3761 //=======================================================================
3762 //function : AddFaceWithID
3764 //=======================================================================
3765 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3766 int n12,int n23,int n31, int nCenter, int ID)
3768 return SMDS_Mesh::AddFaceWithID
3769 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3770 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3771 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3772 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3773 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3774 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3775 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3779 //=======================================================================
3780 //function : AddFaceWithID
3782 //=======================================================================
3783 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3784 const SMDS_MeshNode * n2,
3785 const SMDS_MeshNode * n3,
3786 const SMDS_MeshNode * n12,
3787 const SMDS_MeshNode * n23,
3788 const SMDS_MeshNode * n31,
3789 const SMDS_MeshNode * nCenter,
3792 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
3793 if(hasConstructionEdges()) {
3794 // creation quadratic edges - not implemented
3799 // --- retrieve nodes ID
3800 myNodeIds.resize(7);
3801 myNodeIds[0] = n1->getVtkId();
3802 myNodeIds[1] = n2->getVtkId();
3803 myNodeIds[2] = n3->getVtkId();
3804 myNodeIds[3] = n12->getVtkId();
3805 myNodeIds[4] = n23->getVtkId();
3806 myNodeIds[5] = n31->getVtkId();
3807 myNodeIds[6] = nCenter->getVtkId();
3809 SMDS_MeshFace * face = 0;
3810 SMDS_VtkFace *facevtk = myFacePool->getNew();
3811 facevtk->init(myNodeIds, this);
3812 if (!this->registerElement(ID,facevtk))
3814 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3815 myFacePool->destroy(facevtk);
3819 adjustmyCellsCapacity(ID);
3821 myInfo.myNbBiQuadTriangles++;
3823 // if (!registerElement(ID, face)) {
3824 // RemoveElement(face, false);
3832 //=======================================================================
3833 //function : AddFace
3835 //=======================================================================
3836 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3837 const SMDS_MeshNode * n2,
3838 const SMDS_MeshNode * n3,
3839 const SMDS_MeshNode * n4,
3840 const SMDS_MeshNode * n12,
3841 const SMDS_MeshNode * n23,
3842 const SMDS_MeshNode * n34,
3843 const SMDS_MeshNode * n41)
3845 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3846 myElementIDFactory->GetFreeID());
3849 //=======================================================================
3850 //function : AddFaceWithID
3852 //=======================================================================
3853 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3854 int n12,int n23,int n34,int n41, int ID)
3856 return SMDS_Mesh::AddFaceWithID
3857 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3858 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3859 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3860 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3861 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3862 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3863 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3864 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3868 //=======================================================================
3869 //function : AddFaceWithID
3871 //=======================================================================
3872 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3873 const SMDS_MeshNode * n2,
3874 const SMDS_MeshNode * n3,
3875 const SMDS_MeshNode * n4,
3876 const SMDS_MeshNode * n12,
3877 const SMDS_MeshNode * n23,
3878 const SMDS_MeshNode * n34,
3879 const SMDS_MeshNode * n41,
3882 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3883 if(hasConstructionEdges()) {
3884 // creation quadratic edges - not implemented
3889 // --- retrieve nodes ID
3890 myNodeIds.resize(8);
3891 myNodeIds[0] = n1->getVtkId();
3892 myNodeIds[1] = n2->getVtkId();
3893 myNodeIds[2] = n3->getVtkId();
3894 myNodeIds[3] = n4->getVtkId();
3895 myNodeIds[4] = n12->getVtkId();
3896 myNodeIds[5] = n23->getVtkId();
3897 myNodeIds[6] = n34->getVtkId();
3898 myNodeIds[7] = n41->getVtkId();
3900 SMDS_MeshFace * face = 0;
3901 SMDS_VtkFace *facevtk = myFacePool->getNew();
3902 facevtk->init(myNodeIds, this);
3903 if (!this->registerElement(ID,facevtk))
3905 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3906 myFacePool->destroy(facevtk);
3910 adjustmyCellsCapacity(ID);
3912 myInfo.myNbQuadQuadrangles++;
3914 // if (!registerElement(ID, face)) {
3915 // RemoveElement(face, false);
3922 //=======================================================================
3923 //function : AddFace
3925 //=======================================================================
3926 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3927 const SMDS_MeshNode * n2,
3928 const SMDS_MeshNode * n3,
3929 const SMDS_MeshNode * n4,
3930 const SMDS_MeshNode * n12,
3931 const SMDS_MeshNode * n23,
3932 const SMDS_MeshNode * n34,
3933 const SMDS_MeshNode * n41,
3934 const SMDS_MeshNode * nCenter)
3936 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
3937 myElementIDFactory->GetFreeID());
3940 //=======================================================================
3941 //function : AddFaceWithID
3943 //=======================================================================
3944 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3945 int n12,int n23,int n34,int n41, int nCenter, int ID)
3947 return SMDS_Mesh::AddFaceWithID
3948 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3949 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3950 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3951 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3952 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3953 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3954 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3955 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3956 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3960 //=======================================================================
3961 //function : AddFaceWithID
3963 //=======================================================================
3964 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3965 const SMDS_MeshNode * n2,
3966 const SMDS_MeshNode * n3,
3967 const SMDS_MeshNode * n4,
3968 const SMDS_MeshNode * n12,
3969 const SMDS_MeshNode * n23,
3970 const SMDS_MeshNode * n34,
3971 const SMDS_MeshNode * n41,
3972 const SMDS_MeshNode * nCenter,
3975 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
3976 if(hasConstructionEdges()) {
3977 // creation quadratic edges - not implemented
3982 // --- retrieve nodes ID
3983 myNodeIds.resize(9);
3984 myNodeIds[0] = n1->getVtkId();
3985 myNodeIds[1] = n2->getVtkId();
3986 myNodeIds[2] = n3->getVtkId();
3987 myNodeIds[3] = n4->getVtkId();
3988 myNodeIds[4] = n12->getVtkId();
3989 myNodeIds[5] = n23->getVtkId();
3990 myNodeIds[6] = n34->getVtkId();
3991 myNodeIds[7] = n41->getVtkId();
3992 myNodeIds[8] = nCenter->getVtkId();
3994 SMDS_MeshFace * face = 0;
3995 SMDS_VtkFace *facevtk = myFacePool->getNew();
3996 facevtk->init(myNodeIds, this);
3997 if (!this->registerElement(ID,facevtk))
3999 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
4000 myFacePool->destroy(facevtk);
4004 adjustmyCellsCapacity(ID);
4006 myInfo.myNbBiQuadQuadrangles++;
4008 // if (!registerElement(ID, face)) {
4009 // RemoveElement(face, false);
4017 //=======================================================================
4018 //function : AddVolume
4020 //=======================================================================
4021 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4022 const SMDS_MeshNode * n2,
4023 const SMDS_MeshNode * n3,
4024 const SMDS_MeshNode * n4,
4025 const SMDS_MeshNode * n12,
4026 const SMDS_MeshNode * n23,
4027 const SMDS_MeshNode * n31,
4028 const SMDS_MeshNode * n14,
4029 const SMDS_MeshNode * n24,
4030 const SMDS_MeshNode * n34)
4032 int ID = myElementIDFactory->GetFreeID();
4033 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
4034 n31, n14, n24, n34, ID);
4035 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4039 //=======================================================================
4040 //function : AddVolumeWithID
4042 //=======================================================================
4043 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4044 int n12,int n23,int n31,
4045 int n14,int n24,int n34, int ID)
4047 return SMDS_Mesh::AddVolumeWithID
4048 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4049 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4050 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4051 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4052 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4053 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4054 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4055 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4056 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
4057 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4061 //=======================================================================
4062 //function : AddVolumeWithID
4063 //purpose : 2d order tetrahedron of 10 nodes
4064 //=======================================================================
4065 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4066 const SMDS_MeshNode * n2,
4067 const SMDS_MeshNode * n3,
4068 const SMDS_MeshNode * n4,
4069 const SMDS_MeshNode * n12,
4070 const SMDS_MeshNode * n23,
4071 const SMDS_MeshNode * n31,
4072 const SMDS_MeshNode * n14,
4073 const SMDS_MeshNode * n24,
4074 const SMDS_MeshNode * n34,
4077 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
4079 if(hasConstructionFaces()) {
4080 // creation quadratic faces - not implemented
4083 // --- retrieve nodes ID
4084 myNodeIds.resize(10);
4085 myNodeIds[0] = n1->getVtkId();
4086 myNodeIds[1] = n3->getVtkId();
4087 myNodeIds[2] = n2->getVtkId();
4088 myNodeIds[3] = n4->getVtkId();
4090 myNodeIds[4] = n31->getVtkId();
4091 myNodeIds[5] = n23->getVtkId();
4092 myNodeIds[6] = n12->getVtkId();
4094 myNodeIds[7] = n14->getVtkId();
4095 myNodeIds[8] = n34->getVtkId();
4096 myNodeIds[9] = n24->getVtkId();
4098 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4099 volvtk->init(myNodeIds, this);
4100 if (!this->registerElement(ID,volvtk))
4102 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4103 myVolumePool->destroy(volvtk);
4106 adjustmyCellsCapacity(ID);
4107 myCells[ID] = volvtk;
4108 myInfo.myNbQuadTetras++;
4110 // if (!registerElement(ID, volvtk)) {
4111 // RemoveElement(volvtk, false);
4118 //=======================================================================
4119 //function : AddVolume
4121 //=======================================================================
4122 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4123 const SMDS_MeshNode * n2,
4124 const SMDS_MeshNode * n3,
4125 const SMDS_MeshNode * n4,
4126 const SMDS_MeshNode * n5,
4127 const SMDS_MeshNode * n12,
4128 const SMDS_MeshNode * n23,
4129 const SMDS_MeshNode * n34,
4130 const SMDS_MeshNode * n41,
4131 const SMDS_MeshNode * n15,
4132 const SMDS_MeshNode * n25,
4133 const SMDS_MeshNode * n35,
4134 const SMDS_MeshNode * n45)
4136 int ID = myElementIDFactory->GetFreeID();
4137 SMDS_MeshVolume * v =
4138 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
4139 n15, n25, n35, n45, ID);
4140 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4144 //=======================================================================
4145 //function : AddVolumeWithID
4147 //=======================================================================
4148 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
4149 int n12,int n23,int n34,int n41,
4150 int n15,int n25,int n35,int n45, int ID)
4152 return SMDS_Mesh::AddVolumeWithID
4153 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4154 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4155 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4156 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4157 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4158 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4159 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4160 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4161 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4162 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4163 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4164 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
4165 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4169 //=======================================================================
4170 //function : AddVolumeWithID
4171 //purpose : 2d order pyramid of 13 nodes
4172 //=======================================================================
4173 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4174 const SMDS_MeshNode * n2,
4175 const SMDS_MeshNode * n3,
4176 const SMDS_MeshNode * n4,
4177 const SMDS_MeshNode * n5,
4178 const SMDS_MeshNode * n12,
4179 const SMDS_MeshNode * n23,
4180 const SMDS_MeshNode * n34,
4181 const SMDS_MeshNode * n41,
4182 const SMDS_MeshNode * n15,
4183 const SMDS_MeshNode * n25,
4184 const SMDS_MeshNode * n35,
4185 const SMDS_MeshNode * n45,
4188 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
4189 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
4191 if(hasConstructionFaces()) {
4192 // creation quadratic faces - not implemented
4195 // --- retrieve nodes ID
4196 myNodeIds.resize(13);
4197 myNodeIds[0] = n1->getVtkId();
4198 myNodeIds[1] = n4->getVtkId();
4199 myNodeIds[2] = n3->getVtkId();
4200 myNodeIds[3] = n2->getVtkId();
4201 myNodeIds[4] = n5->getVtkId();
4203 myNodeIds[5] = n41->getVtkId();
4204 myNodeIds[6] = n34->getVtkId();
4205 myNodeIds[7] = n23->getVtkId();
4206 myNodeIds[8] = n12->getVtkId();
4208 myNodeIds[9] = n15->getVtkId();
4209 myNodeIds[10] = n45->getVtkId();
4210 myNodeIds[11] = n35->getVtkId();
4211 myNodeIds[12] = n25->getVtkId();
4213 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4214 volvtk->init(myNodeIds, this);
4215 if (!this->registerElement(ID,volvtk))
4217 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4218 myVolumePool->destroy(volvtk);
4221 adjustmyCellsCapacity(ID);
4222 myCells[ID] = volvtk;
4223 myInfo.myNbQuadPyramids++;
4225 // if (!registerElement(ID, volvtk)) {
4226 // RemoveElement(volvtk, false);
4233 //=======================================================================
4234 //function : AddVolume
4236 //=======================================================================
4237 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4238 const SMDS_MeshNode * n2,
4239 const SMDS_MeshNode * n3,
4240 const SMDS_MeshNode * n4,
4241 const SMDS_MeshNode * n5,
4242 const SMDS_MeshNode * n6,
4243 const SMDS_MeshNode * n12,
4244 const SMDS_MeshNode * n23,
4245 const SMDS_MeshNode * n31,
4246 const SMDS_MeshNode * n45,
4247 const SMDS_MeshNode * n56,
4248 const SMDS_MeshNode * n64,
4249 const SMDS_MeshNode * n14,
4250 const SMDS_MeshNode * n25,
4251 const SMDS_MeshNode * n36)
4253 int ID = myElementIDFactory->GetFreeID();
4254 SMDS_MeshVolume * v =
4255 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4256 n45, n56, n64, n14, n25, n36, ID);
4257 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4261 //=======================================================================
4262 //function : AddVolumeWithID
4264 //=======================================================================
4265 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4266 int n4, int n5, int n6,
4267 int n12,int n23,int n31,
4268 int n45,int n56,int n64,
4269 int n14,int n25,int n36, int ID)
4271 return SMDS_Mesh::AddVolumeWithID
4272 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4273 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4274 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4275 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4276 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4277 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4278 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4279 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4280 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4281 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4282 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4283 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4290 //=======================================================================
4291 //function : AddVolumeWithID
4292 //purpose : 2d order Pentahedron with 15 nodes
4293 //=======================================================================
4294 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4295 const SMDS_MeshNode * n2,
4296 const SMDS_MeshNode * n3,
4297 const SMDS_MeshNode * n4,
4298 const SMDS_MeshNode * n5,
4299 const SMDS_MeshNode * n6,
4300 const SMDS_MeshNode * n12,
4301 const SMDS_MeshNode * n23,
4302 const SMDS_MeshNode * n31,
4303 const SMDS_MeshNode * n45,
4304 const SMDS_MeshNode * n56,
4305 const SMDS_MeshNode * n64,
4306 const SMDS_MeshNode * n14,
4307 const SMDS_MeshNode * n25,
4308 const SMDS_MeshNode * n36,
4311 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4312 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
4314 if(hasConstructionFaces()) {
4315 // creation quadratic faces - not implemented
4318 // --- retrieve nodes ID
4319 myNodeIds.resize(15);
4320 myNodeIds[0] = n1->getVtkId();
4321 myNodeIds[1] = n2->getVtkId();
4322 myNodeIds[2] = n3->getVtkId();
4324 myNodeIds[3] = n4->getVtkId();
4325 myNodeIds[4] = n5->getVtkId();
4326 myNodeIds[5] = n6->getVtkId();
4328 myNodeIds[6] = n12->getVtkId();
4329 myNodeIds[7] = n23->getVtkId();
4330 myNodeIds[8] = n31->getVtkId();
4332 myNodeIds[9] = n45->getVtkId();
4333 myNodeIds[10] = n56->getVtkId();
4334 myNodeIds[11] = n64->getVtkId();
4336 myNodeIds[12] = n14->getVtkId();
4337 myNodeIds[13] = n25->getVtkId();
4338 myNodeIds[14] = n36->getVtkId();
4340 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4341 volvtk->init(myNodeIds, this);
4342 if (!this->registerElement(ID,volvtk))
4344 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4345 myVolumePool->destroy(volvtk);
4348 adjustmyCellsCapacity(ID);
4349 myCells[ID] = volvtk;
4350 myInfo.myNbQuadPrisms++;
4352 // if (!registerElement(ID, volvtk)) {
4353 // RemoveElement(volvtk, false);
4360 //=======================================================================
4361 //function : AddVolume
4363 //=======================================================================
4364 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4365 const SMDS_MeshNode * n2,
4366 const SMDS_MeshNode * n3,
4367 const SMDS_MeshNode * n4,
4368 const SMDS_MeshNode * n5,
4369 const SMDS_MeshNode * n6,
4370 const SMDS_MeshNode * n7,
4371 const SMDS_MeshNode * n8,
4372 const SMDS_MeshNode * n12,
4373 const SMDS_MeshNode * n23,
4374 const SMDS_MeshNode * n34,
4375 const SMDS_MeshNode * n41,
4376 const SMDS_MeshNode * n56,
4377 const SMDS_MeshNode * n67,
4378 const SMDS_MeshNode * n78,
4379 const SMDS_MeshNode * n85,
4380 const SMDS_MeshNode * n15,
4381 const SMDS_MeshNode * n26,
4382 const SMDS_MeshNode * n37,
4383 const SMDS_MeshNode * n48)
4385 int ID = myElementIDFactory->GetFreeID();
4386 SMDS_MeshVolume * v =
4387 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4388 n56, n67, n78, n85, n15, n26, n37, n48, ID);
4389 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4393 //=======================================================================
4394 //function : AddVolumeWithID
4396 //=======================================================================
4397 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4398 int n5, int n6, int n7, int n8,
4399 int n12,int n23,int n34,int n41,
4400 int n56,int n67,int n78,int n85,
4401 int n15,int n26,int n37,int n48, int ID)
4403 return SMDS_Mesh::AddVolumeWithID
4404 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4405 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4406 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4407 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4408 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4409 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4410 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4411 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4412 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4413 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4414 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4415 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4416 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4417 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4418 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4419 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4420 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4421 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4422 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4423 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4427 //=======================================================================
4428 //function : AddVolumeWithID
4429 //purpose : 2d order Hexahedrons with 20 nodes
4430 //=======================================================================
4431 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4432 const SMDS_MeshNode * n2,
4433 const SMDS_MeshNode * n3,
4434 const SMDS_MeshNode * n4,
4435 const SMDS_MeshNode * n5,
4436 const SMDS_MeshNode * n6,
4437 const SMDS_MeshNode * n7,
4438 const SMDS_MeshNode * n8,
4439 const SMDS_MeshNode * n12,
4440 const SMDS_MeshNode * n23,
4441 const SMDS_MeshNode * n34,
4442 const SMDS_MeshNode * n41,
4443 const SMDS_MeshNode * n56,
4444 const SMDS_MeshNode * n67,
4445 const SMDS_MeshNode * n78,
4446 const SMDS_MeshNode * n85,
4447 const SMDS_MeshNode * n15,
4448 const SMDS_MeshNode * n26,
4449 const SMDS_MeshNode * n37,
4450 const SMDS_MeshNode * n48,
4453 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4454 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4456 if(hasConstructionFaces()) {
4458 // creation quadratic faces - not implemented
4460 // --- retrieve nodes ID
4461 myNodeIds.resize(20);
4462 myNodeIds[0] = n1->getVtkId();
4463 myNodeIds[1] = n4->getVtkId();
4464 myNodeIds[2] = n3->getVtkId();
4465 myNodeIds[3] = n2->getVtkId();
4467 myNodeIds[4] = n5->getVtkId();
4468 myNodeIds[5] = n8->getVtkId();
4469 myNodeIds[6] = n7->getVtkId();
4470 myNodeIds[7] = n6->getVtkId();
4472 myNodeIds[8] = n41->getVtkId();
4473 myNodeIds[9] = n34->getVtkId();
4474 myNodeIds[10] = n23->getVtkId();
4475 myNodeIds[11] = n12->getVtkId();
4477 myNodeIds[12] = n85->getVtkId();
4478 myNodeIds[13] = n78->getVtkId();
4479 myNodeIds[14] = n67->getVtkId();
4480 myNodeIds[15] = n56->getVtkId();
4482 myNodeIds[16] = n15->getVtkId();
4483 myNodeIds[17] = n48->getVtkId();
4484 myNodeIds[18] = n37->getVtkId();
4485 myNodeIds[19] = n26->getVtkId();
4487 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4488 volvtk->init(myNodeIds, this);
4489 if (!this->registerElement(ID,volvtk))
4491 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4492 myVolumePool->destroy(volvtk);
4495 adjustmyCellsCapacity(ID);
4496 myCells[ID] = volvtk;
4497 myInfo.myNbQuadHexas++;
4499 // if (!registerElement(ID, volvtk)) {
4500 // RemoveElement(volvtk, false);
4506 //=======================================================================
4507 //function : AddVolume
4509 //=======================================================================
4510 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4511 const SMDS_MeshNode * n2,
4512 const SMDS_MeshNode * n3,
4513 const SMDS_MeshNode * n4,
4514 const SMDS_MeshNode * n5,
4515 const SMDS_MeshNode * n6,
4516 const SMDS_MeshNode * n7,
4517 const SMDS_MeshNode * n8,
4518 const SMDS_MeshNode * n12,
4519 const SMDS_MeshNode * n23,
4520 const SMDS_MeshNode * n34,
4521 const SMDS_MeshNode * n41,
4522 const SMDS_MeshNode * n56,
4523 const SMDS_MeshNode * n67,
4524 const SMDS_MeshNode * n78,
4525 const SMDS_MeshNode * n85,
4526 const SMDS_MeshNode * n15,
4527 const SMDS_MeshNode * n26,
4528 const SMDS_MeshNode * n37,
4529 const SMDS_MeshNode * n48,
4530 const SMDS_MeshNode * n1234,
4531 const SMDS_MeshNode * n1256,
4532 const SMDS_MeshNode * n2367,
4533 const SMDS_MeshNode * n3478,
4534 const SMDS_MeshNode * n1458,
4535 const SMDS_MeshNode * n5678,
4536 const SMDS_MeshNode * nCenter)
4538 int ID = myElementIDFactory->GetFreeID();
4539 SMDS_MeshVolume * v =
4540 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4541 n56, n67, n78, n85, n15, n26, n37, n48,
4542 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
4544 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4548 //=======================================================================
4549 //function : AddVolumeWithID
4551 //=======================================================================
4552 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4553 int n5, int n6, int n7, int n8,
4554 int n12,int n23,int n34,int n41,
4555 int n56,int n67,int n78,int n85,
4556 int n15,int n26,int n37,int n48,
4557 int n1234,int n1256,int n2367,int n3478,
4558 int n1458,int n5678,int nCenter, int ID)
4560 return SMDS_Mesh::AddVolumeWithID
4561 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4562 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4563 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4564 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4565 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4566 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4567 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4568 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4569 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4570 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4571 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4572 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4573 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4574 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4575 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4576 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4577 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4578 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4579 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4580 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4581 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
4582 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
4583 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
4584 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
4585 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
4586 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
4587 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
4591 //=======================================================================
4592 //function : AddVolumeWithID
4593 //purpose : 2d order Hexahedrons with 20 nodes
4594 //=======================================================================
4595 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4596 const SMDS_MeshNode * n2,
4597 const SMDS_MeshNode * n3,
4598 const SMDS_MeshNode * n4,
4599 const SMDS_MeshNode * n5,
4600 const SMDS_MeshNode * n6,
4601 const SMDS_MeshNode * n7,
4602 const SMDS_MeshNode * n8,
4603 const SMDS_MeshNode * n12,
4604 const SMDS_MeshNode * n23,
4605 const SMDS_MeshNode * n34,
4606 const SMDS_MeshNode * n41,
4607 const SMDS_MeshNode * n56,
4608 const SMDS_MeshNode * n67,
4609 const SMDS_MeshNode * n78,
4610 const SMDS_MeshNode * n85,
4611 const SMDS_MeshNode * n15,
4612 const SMDS_MeshNode * n26,
4613 const SMDS_MeshNode * n37,
4614 const SMDS_MeshNode * n48,
4615 const SMDS_MeshNode * n1234,
4616 const SMDS_MeshNode * n1256,
4617 const SMDS_MeshNode * n2367,
4618 const SMDS_MeshNode * n3478,
4619 const SMDS_MeshNode * n1458,
4620 const SMDS_MeshNode * n5678,
4621 const SMDS_MeshNode * nCenter,
4624 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4625 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
4626 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
4628 if(hasConstructionFaces()) {
4630 // creation quadratic faces - not implemented
4632 // --- retrieve nodes ID
4633 myNodeIds.resize(27);
4634 myNodeIds[0] = n1->getVtkId();
4635 myNodeIds[1] = n4->getVtkId();
4636 myNodeIds[2] = n3->getVtkId();
4637 myNodeIds[3] = n2->getVtkId();
4639 myNodeIds[4] = n5->getVtkId();
4640 myNodeIds[5] = n8->getVtkId();
4641 myNodeIds[6] = n7->getVtkId();
4642 myNodeIds[7] = n6->getVtkId();
4644 myNodeIds[8] = n41->getVtkId();
4645 myNodeIds[9] = n34->getVtkId();
4646 myNodeIds[10] = n23->getVtkId();
4647 myNodeIds[11] = n12->getVtkId();
4649 myNodeIds[12] = n85->getVtkId();
4650 myNodeIds[13] = n78->getVtkId();
4651 myNodeIds[14] = n67->getVtkId();
4652 myNodeIds[15] = n56->getVtkId();
4654 myNodeIds[16] = n15->getVtkId();
4655 myNodeIds[17] = n48->getVtkId();
4656 myNodeIds[18] = n37->getVtkId();
4657 myNodeIds[19] = n26->getVtkId();
4659 myNodeIds[20] = n1256->getVtkId();
4660 myNodeIds[21] = n3478->getVtkId();
4661 myNodeIds[22] = n1458->getVtkId();
4662 myNodeIds[23] = n2367->getVtkId();
4663 myNodeIds[24] = n1234->getVtkId();
4664 myNodeIds[25] = n5678->getVtkId();
4665 myNodeIds[26] = nCenter->getVtkId();
4667 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4668 volvtk->init(myNodeIds, this);
4669 if (!this->registerElement(ID,volvtk))
4671 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4672 myVolumePool->destroy(volvtk);
4675 adjustmyCellsCapacity(ID);
4676 myCells[ID] = volvtk;
4677 myInfo.myNbTriQuadHexas++;
4683 void SMDS_Mesh::updateNodeMinMax()
4686 if (myNodes.size() == 0)
4691 while ( !myNodes[myNodeMin] && myNodeMin < (int)myNodes.size() )
4693 myNodeMax=myNodes.size()-1;
4694 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4698 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4700 // int val = myCellIdSmdsToVtk.size();
4701 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4702 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4703 int val = myNodes.size();
4704 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4705 myNodes.resize(val +nbNodes, 0);
4708 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4710 int val = myCellIdVtkToSmds.size();
4711 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4712 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4713 val = myCells.size();
4714 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4715 myNodes.resize(val +nbCells, 0);
4718 void SMDS_Mesh::adjustStructure()
4720 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4723 void SMDS_Mesh::dumpGrid(string ficdump)
4725 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4726 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4727 // aWriter->SetFileName(ficdump.c_str());
4728 // aWriter->SetInput(myGrid);
4729 // if(myGrid->GetNumberOfCells())
4731 // aWriter->Write();
4733 // aWriter->Delete();
4734 ficdump = ficdump + "_connectivity";
4735 ofstream ficcon(ficdump.c_str(), ios::out);
4736 int nbPoints = myGrid->GetNumberOfPoints();
4737 ficcon << "-------------------------------- points " << nbPoints << endl;
4738 for (int i=0; i<nbPoints; i++)
4740 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4742 int nbCells = myGrid->GetNumberOfCells();
4743 ficcon << "-------------------------------- cells " << nbCells << endl;
4744 for (int i=0; i<nbCells; i++)
4746 // MESSAGE(i << " " << myGrid->GetCell(i));
4747 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4748 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4749 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4750 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4751 for (int j=0; j<nbptcell; j++)
4753 ficcon << " " << listid->GetId(j);
4757 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4758 vtkCellLinks *links = myGrid->GetCellLinks();
4759 for (int i=0; i<nbPoints; i++)
4761 int ncells = links->GetNcells(i);
4762 vtkIdType *cells = links->GetCells(i);
4763 ficcon << i << " - " << ncells << " -";
4764 for (int j=0; j<ncells; j++)
4766 ficcon << " " << cells[j];
4774 void SMDS_Mesh::compactMesh()
4776 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4779 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4781 if (vtkid >= 0 && vtkid < (int)myCellIdVtkToSmds.size())
4782 return myCellIdVtkToSmds[vtkid];
4783 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4786 void SMDS_Mesh::updateBoundingBox()
4791 vtkPoints *points = myGrid->GetPoints();
4792 int myNodesSize = this->myNodes.size();
4793 for (int i = 0; i < myNodesSize; i++)
4795 if (SMDS_MeshNode *n = myNodes[i])
4798 points->GetPoint(n->myVtkID, coords);
4799 if (coords[0] < xmin) xmin = coords[0];
4800 else if (coords[0] > xmax) xmax = coords[0];
4801 if (coords[1] < ymin) ymin = coords[1];
4802 else if (coords[1] > ymax) ymax = coords[1];
4803 if (coords[2] < zmin) zmin = coords[2];
4804 else if (coords[2] > zmax) zmax = coords[2];
4809 double SMDS_Mesh::getMaxDim()
4811 double dmax = 1.e-3;
4812 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4813 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4814 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4815 MESSAGE("getMaxDim " << dmax);
4819 //! modification that needs compact structure and redraw
4820 void SMDS_Mesh::Modified()
4822 if (this->myModified)
4824 this->myModifTime++;
4825 MESSAGE("modified");
4830 //! get last modification timeStamp
4831 unsigned long SMDS_Mesh::GetMTime() const
4833 return this->myModifTime;
4836 bool SMDS_Mesh::isCompacted()
4838 if (this->myModifTime > this->myCompactTime)
4840 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4841 this->myCompactTime = this->myModifTime;