1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "SMDS_FaceOfEdges.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_Mesh.hxx"
32 #include "SMDS_PolygonalFaceOfNodes.hxx"
33 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_SpacePosition.hxx"
39 #include "SMDS_UnstructuredGrid.hxx"
40 #include "SMDS_VolumeOfFaces.hxx"
41 #include "SMDS_VolumeOfNodes.hxx"
43 #include "utilities.h"
45 #include <vtkUnstructuredGrid.h>
46 #include <vtkUnstructuredGridWriter.h>
47 #include <vtkUnsignedCharArray.h>
49 #include <vtkCellLinks.h>
50 #include <vtkIdList.h>
60 #include <sys/sysinfo.h>
63 // number of added entities to check memory after
64 #define CHECKMEMORY_INTERVAL 100000
66 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
67 int SMDS_Mesh::chunkSize = 1024;
70 //================================================================================
72 * \brief Raise an exception if free memory (ram+swap) too low
73 * \param doNotRaise - if true, suppres exception, just return free memory size
74 * \retval int - amount of available memory in MB or negative number in failure case
76 //================================================================================
78 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
82 int err = sysinfo( &si );
86 const unsigned long Mbyte = 1024 * 1024;
88 static int limit = -1;
90 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
92 limit = WEXITSTATUS(status);
95 double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
96 limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
101 limit = int ( limit * 1.5 );
102 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
105 // compute separately to avoid overflow
107 ( si.freeram * si.mem_unit ) / Mbyte +
108 ( si.freeswap * si.mem_unit ) / Mbyte;
109 //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
111 if ( freeMb > limit )
112 return freeMb - limit;
117 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
118 throw std::bad_alloc();
124 ///////////////////////////////////////////////////////////////////////////////
125 /// Create a new mesh object
126 ///////////////////////////////////////////////////////////////////////////////
127 SMDS_Mesh::SMDS_Mesh():
128 myNodePool(0), myVolumePool(0), myFacePool(0), myEdgePool(0), myBallPool(0),
130 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
131 myElementIDFactory(new SMDS_MeshElementIDFactory()),
132 myModified(false), myModifTime(0), myCompactTime(0),
133 myNodeMin(0), myNodeMax(0),
134 myHasConstructionEdges(false), myHasConstructionFaces(false),
135 myHasInverseElements(true),
136 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
138 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
139 myNodeIDFactory->SetMesh(this);
140 myElementIDFactory->SetMesh(this);
141 _meshList.push_back(this);
142 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
143 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
144 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
145 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
146 myBallPool = new ObjectPool<SMDS_BallElement>(SMDS_Mesh::chunkSize);
150 //myCellIdSmdsToVtk.clear();
151 myCellIdVtkToSmds.clear();
152 myGrid = SMDS_UnstructuredGrid::New();
153 myGrid->setSMDS_mesh(this);
154 myGrid->Initialize();
156 vtkPoints* points = vtkPoints::New();
157 // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
158 // Use double type for storing coordinates of nodes instead of float.
159 points->SetDataType(VTK_DOUBLE);
160 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
161 myGrid->SetPoints( points );
163 myGrid->BuildLinks();
167 ///////////////////////////////////////////////////////////////////////////////
168 /// Create a new child mesh
169 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
170 /// (2003-09-08) of SMESH
171 ///////////////////////////////////////////////////////////////////////////////
172 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
173 myNodePool(parent->myNodePool),
174 myVolumePool(parent->myVolumePool),
175 myFacePool(parent->myFacePool),
176 myEdgePool(parent->myEdgePool),
177 myBallPool(parent->myBallPool),
178 myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
179 myElementIDFactory(parent->myElementIDFactory),
180 myHasConstructionEdges(false), myHasConstructionFaces(false),
181 myHasInverseElements(true)
185 ///////////////////////////////////////////////////////////////////////////////
186 ///Create a submesh and add it to the current mesh
187 ///////////////////////////////////////////////////////////////////////////////
189 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
191 SMDS_Mesh *submesh = new SMDS_Mesh(this);
192 myChildren.insert(myChildren.end(), submesh);
196 ///////////////////////////////////////////////////////////////////////////////
197 ///create a MeshNode and add it to the current Mesh
198 ///An ID is automatically assigned to the node.
199 ///@return : The created node
200 ///////////////////////////////////////////////////////////////////////////////
202 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
204 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
207 ///////////////////////////////////////////////////////////////////////////////
208 ///create a MeshNode and add it to the current Mesh
209 ///@param ID : The ID of the MeshNode to create
210 ///@return : The created node or NULL if a node with this ID already exists
211 ///////////////////////////////////////////////////////////////////////////////
212 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
214 // find the MeshNode corresponding to ID
215 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
219 MESSAGE("=============> Bad Node Id: " << ID);
220 ID = myNodeIDFactory->GetFreeID();
222 myNodeIDFactory->adjustMaxId(ID);
223 SMDS_MeshNode * node = myNodePool->getNew();
224 node->init(ID, myMeshId, 0, x, y, z);
226 if (ID >= (int)myNodes.size())
228 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
229 // MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
232 myNodeIDFactory->BindID(ID,node);
235 this->adjustBoundingBox(x, y, z);
241 ///////////////////////////////////////////////////////////////////////////////
242 /// create a Mesh0DElement and add it to the current Mesh
243 /// @return : The created Mesh0DElement
244 ///////////////////////////////////////////////////////////////////////////////
245 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
247 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
248 if (!node) return NULL;
249 return SMDS_Mesh::Add0DElementWithID(node, ID);
252 ///////////////////////////////////////////////////////////////////////////////
253 /// create a Mesh0DElement and add it to the current Mesh
254 /// @return : The created Mesh0DElement
255 ///////////////////////////////////////////////////////////////////////////////
256 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
258 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
261 ///////////////////////////////////////////////////////////////////////////////
262 /// Create a new Mesh0DElement and at it to the mesh
263 /// @param idnode ID of the node
264 /// @param ID ID of the 0D element to create
265 /// @return The created 0D element or NULL if an element with this
266 /// ID already exists or if input node is not found.
267 ///////////////////////////////////////////////////////////////////////////////
268 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
272 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
273 //MESSAGE("Add0DElementWithID" << ID)
274 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
275 if (myElementIDFactory->BindID(ID, el0d)) {
276 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
277 //node->AddInverseElement(el0d);// --- fait avec BindID
278 adjustmyCellsCapacity(ID);
280 myInfo.myNb0DElements++;
288 ///////////////////////////////////////////////////////////////////////////////
289 /// create a Ball and add it to the current Mesh
290 /// @return : The created Ball
291 ///////////////////////////////////////////////////////////////////////////////
292 SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID)
294 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
295 if (!node) return NULL;
296 return SMDS_Mesh::AddBallWithID(node, diameter, ID);
299 ///////////////////////////////////////////////////////////////////////////////
300 /// create a Ball and add it to the current Mesh
301 /// @return : The created Ball
302 ///////////////////////////////////////////////////////////////////////////////
303 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
305 return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID());
308 ///////////////////////////////////////////////////////////////////////////////
309 /// Create a new Ball and at it to the mesh
310 /// @param idnode ID of the node
311 // @param diameter ball diameter
312 /// @param ID ID of the 0D element to create
313 /// @return The created 0D element or NULL if an element with this
314 /// ID already exists or if input node is not found.
315 ///////////////////////////////////////////////////////////////////////////////
316 SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
320 if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
322 SMDS_BallElement *ball = myBallPool->getNew();
323 ball->init(n->getVtkId(), diameter, this);
324 if (!this->registerElement(ID,ball))
326 this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
327 myBallPool->destroy(ball);
330 adjustmyCellsCapacity(ID);
336 ///////////////////////////////////////////////////////////////////////////////
337 /// create a MeshEdge and add it to the current Mesh
338 /// @return : The created MeshEdge
339 ///////////////////////////////////////////////////////////////////////////////
341 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
343 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
344 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
345 if(!node1 || !node2) return NULL;
346 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
349 ///////////////////////////////////////////////////////////////////////////////
350 /// create a MeshEdge and add it to the current Mesh
351 /// @return : The created MeshEdge
352 ///////////////////////////////////////////////////////////////////////////////
354 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
355 const SMDS_MeshNode * node2)
357 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
360 ///////////////////////////////////////////////////////////////////////////////
361 /// Create a new edge and at it to the mesh
362 /// @param idnode1 ID of the first node
363 /// @param idnode2 ID of the second node
364 /// @param ID ID of the edge to create
365 /// @return The created edge or NULL if an element with this ID already exists or
366 /// if input nodes are not found.
367 ///////////////////////////////////////////////////////////////////////////////
369 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
370 const SMDS_MeshNode * n2,
373 if ( !n1 || !n2 ) return 0;
374 SMDS_MeshEdge * edge = 0;
376 // --- retreive nodes ID
377 vector<vtkIdType> nodeIds;
379 nodeIds.push_back(n1->getVtkId());
380 nodeIds.push_back(n2->getVtkId());
382 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
383 edgevtk->init(nodeIds, this);
384 if (!this->registerElement(ID,edgevtk))
386 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
387 myEdgePool->destroy(edgevtk);
391 adjustmyCellsCapacity(ID);
395 // if (edge && !registerElement(ID, edge))
397 // RemoveElement(edge, false);
403 ///////////////////////////////////////////////////////////////////////////////
404 /// Add a triangle defined by its nodes. An ID is automatically affected to the
406 ///////////////////////////////////////////////////////////////////////////////
408 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
409 const SMDS_MeshNode * n2,
410 const SMDS_MeshNode * n3)
412 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
415 ///////////////////////////////////////////////////////////////////////////////
416 /// Add a triangle defined by its nodes IDs
417 ///////////////////////////////////////////////////////////////////////////////
419 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
421 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
422 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
423 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
424 if(!node1 || !node2 || !node3) return NULL;
425 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
428 ///////////////////////////////////////////////////////////////////////////////
429 /// Add a triangle defined by its nodes
430 ///////////////////////////////////////////////////////////////////////////////
432 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
433 const SMDS_MeshNode * n2,
434 const SMDS_MeshNode * n3,
437 //MESSAGE("AddFaceWithID " << ID)
438 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
440 // if (face && !registerElement(ID, face)) {
441 // RemoveElement(face, false);
447 ///////////////////////////////////////////////////////////////////////////////
448 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
450 ///////////////////////////////////////////////////////////////////////////////
452 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
453 const SMDS_MeshNode * n2,
454 const SMDS_MeshNode * n3,
455 const SMDS_MeshNode * n4)
457 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
460 ///////////////////////////////////////////////////////////////////////////////
461 /// Add a quadrangle defined by its nodes IDs
462 ///////////////////////////////////////////////////////////////////////////////
464 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
470 SMDS_MeshNode *node1, *node2, *node3, *node4;
471 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
472 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
473 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
474 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
475 if(!node1 || !node2 || !node3 || !node4) return NULL;
476 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
479 ///////////////////////////////////////////////////////////////////////////////
480 /// Add a quadrangle defined by its nodes
481 ///////////////////////////////////////////////////////////////////////////////
483 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
484 const SMDS_MeshNode * n2,
485 const SMDS_MeshNode * n3,
486 const SMDS_MeshNode * n4,
489 //MESSAGE("AddFaceWithID " << ID);
490 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
492 // if (face && !registerElement(ID, face)) {
493 // RemoveElement(face, false);
499 ///////////////////////////////////////////////////////////////////////////////
500 /// Add a triangle defined by its edges. An ID is automatically assigned to the
502 ///////////////////////////////////////////////////////////////////////////////
504 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
505 const SMDS_MeshEdge * e2,
506 const SMDS_MeshEdge * e3)
508 if (!hasConstructionEdges())
510 //MESSAGE("AddFaceWithID");
511 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
514 ///////////////////////////////////////////////////////////////////////////////
515 /// Add a triangle defined by its edges
516 ///////////////////////////////////////////////////////////////////////////////
518 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
519 const SMDS_MeshEdge * e2,
520 const SMDS_MeshEdge * e3,
523 if (!hasConstructionEdges())
525 if ( !e1 || !e2 || !e3 ) return 0;
527 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
528 MESSAGE("AddFaceWithID" << ID);
530 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
531 adjustmyCellsCapacity(ID);
533 myInfo.myNbTriangles++;
535 if (!registerElement(ID, face)) {
536 registerElement(myElementIDFactory->GetFreeID(), face);
537 //RemoveElement(face, false);
543 ///////////////////////////////////////////////////////////////////////////////
544 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
546 ///////////////////////////////////////////////////////////////////////////////
548 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
549 const SMDS_MeshEdge * e2,
550 const SMDS_MeshEdge * e3,
551 const SMDS_MeshEdge * e4)
553 if (!hasConstructionEdges())
555 //MESSAGE("AddFaceWithID" );
556 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
559 ///////////////////////////////////////////////////////////////////////////////
560 /// Add a quadrangle defined by its edges
561 ///////////////////////////////////////////////////////////////////////////////
563 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
564 const SMDS_MeshEdge * e2,
565 const SMDS_MeshEdge * e3,
566 const SMDS_MeshEdge * e4,
569 if (!hasConstructionEdges())
571 MESSAGE("AddFaceWithID" << ID);
572 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
573 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
574 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
575 adjustmyCellsCapacity(ID);
577 myInfo.myNbQuadrangles++;
579 if (!registerElement(ID, face))
581 registerElement(myElementIDFactory->GetFreeID(), face);
582 //RemoveElement(face, false);
588 ///////////////////////////////////////////////////////////////////////////////
589 ///Create a new tetrahedron and add it to the mesh.
590 ///@return The created tetrahedron
591 ///////////////////////////////////////////////////////////////////////////////
593 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
594 const SMDS_MeshNode * n2,
595 const SMDS_MeshNode * n3,
596 const SMDS_MeshNode * n4)
598 int ID = myElementIDFactory->GetFreeID();
599 //MESSAGE("AddVolumeWithID " << ID);
600 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
601 if(v==NULL) myElementIDFactory->ReleaseID(ID);
605 ///////////////////////////////////////////////////////////////////////////////
606 ///Create a new tetrahedron and add it to the mesh.
607 ///@param ID The ID of the new volume
608 ///@return The created tetrahedron or NULL if an element with this ID already exists
609 ///or if input nodes are not found.
610 ///////////////////////////////////////////////////////////////////////////////
612 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
618 //MESSAGE("AddVolumeWithID" << ID);
619 SMDS_MeshNode *node1, *node2, *node3, *node4;
620 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
621 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
622 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
623 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
624 if(!node1 || !node2 || !node3 || !node4) return NULL;
625 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
628 ///////////////////////////////////////////////////////////////////////////////
629 ///Create a new tetrahedron and add it to the mesh.
630 ///@param ID The ID of the new volume
631 ///@return The created tetrahedron
632 ///////////////////////////////////////////////////////////////////////////////
634 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
635 const SMDS_MeshNode * n2,
636 const SMDS_MeshNode * n3,
637 const SMDS_MeshNode * n4,
640 //MESSAGE("AddVolumeWithID " << ID);
641 SMDS_MeshVolume* volume = 0;
642 if ( !n1 || !n2 || !n3 || !n4) return volume;
643 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
644 if(hasConstructionFaces()) {
645 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
646 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
647 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
648 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
649 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
650 adjustmyCellsCapacity(ID);
651 myCells[ID] = volume;
654 else if(hasConstructionEdges()) {
655 MESSAGE("Error : Not implemented");
659 // --- retrieve nodes ID
661 myNodeIds[0] = n1->getVtkId();
662 myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK
663 myNodeIds[2] = n2->getVtkId();
664 myNodeIds[3] = n4->getVtkId();
666 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
667 volvtk->init(myNodeIds, this);
668 if (!this->registerElement(ID,volvtk))
670 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
671 myVolumePool->destroy(volvtk);
675 adjustmyCellsCapacity(ID);
676 myCells[ID] = volume;
680 // if (!registerElement(ID, volume)) {
681 // RemoveElement(volume, false);
687 ///////////////////////////////////////////////////////////////////////////////
688 ///Create a new pyramid and add it to the mesh.
689 ///Nodes 1,2,3 and 4 define the base of the pyramid
690 ///@return The created pyramid
691 ///////////////////////////////////////////////////////////////////////////////
693 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
694 const SMDS_MeshNode * n2,
695 const SMDS_MeshNode * n3,
696 const SMDS_MeshNode * n4,
697 const SMDS_MeshNode * n5)
699 int ID = myElementIDFactory->GetFreeID();
700 //MESSAGE("AddVolumeWithID " << ID);
701 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
702 if(v==NULL) myElementIDFactory->ReleaseID(ID);
706 ///////////////////////////////////////////////////////////////////////////////
707 ///Create a new pyramid and add it to the mesh.
708 ///Nodes 1,2,3 and 4 define the base of the pyramid
709 ///@param ID The ID of the new volume
710 ///@return The created pyramid or NULL if an element with this ID already exists
711 ///or if input nodes are not found.
712 ///////////////////////////////////////////////////////////////////////////////
714 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
721 //MESSAGE("AddVolumeWithID " << ID);
722 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
723 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
724 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
725 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
726 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
727 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
728 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
729 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
732 ///////////////////////////////////////////////////////////////////////////////
733 ///Create a new pyramid and add it to the mesh.
734 ///Nodes 1,2,3 and 4 define the base of the pyramid
735 ///@param ID The ID of the new volume
736 ///@return The created pyramid
737 ///////////////////////////////////////////////////////////////////////////////
739 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
740 const SMDS_MeshNode * n2,
741 const SMDS_MeshNode * n3,
742 const SMDS_MeshNode * n4,
743 const SMDS_MeshNode * n5,
746 //MESSAGE("AddVolumeWithID " << ID);
747 SMDS_MeshVolume* volume = 0;
748 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
749 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
750 if(hasConstructionFaces()) {
751 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
752 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
753 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
754 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
755 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
756 adjustmyCellsCapacity(ID);
757 myCells[ID] = volume;
758 myInfo.myNbPyramids++;
760 else if(hasConstructionEdges()) {
761 MESSAGE("Error : Not implemented");
765 // --- retrieve nodes ID
767 myNodeIds[0] = n1->getVtkId();
768 myNodeIds[1] = n4->getVtkId();
769 myNodeIds[2] = n3->getVtkId();
770 myNodeIds[3] = n2->getVtkId();
771 myNodeIds[4] = n5->getVtkId();
773 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
774 volvtk->init(myNodeIds, this);
775 if (!this->registerElement(ID,volvtk))
777 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
778 myVolumePool->destroy(volvtk);
782 adjustmyCellsCapacity(ID);
783 myCells[ID] = volume;
784 myInfo.myNbPyramids++;
787 // if (!registerElement(ID, volume)) {
788 // RemoveElement(volume, false);
794 ///////////////////////////////////////////////////////////////////////////////
795 ///Create a new prism and add it to the mesh.
796 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
797 ///@return The created prism
798 ///////////////////////////////////////////////////////////////////////////////
800 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
801 const SMDS_MeshNode * n2,
802 const SMDS_MeshNode * n3,
803 const SMDS_MeshNode * n4,
804 const SMDS_MeshNode * n5,
805 const SMDS_MeshNode * n6)
807 int ID = myElementIDFactory->GetFreeID();
808 //MESSAGE("AddVolumeWithID " << ID);
809 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
810 if(v==NULL) myElementIDFactory->ReleaseID(ID);
814 ///////////////////////////////////////////////////////////////////////////////
815 ///Create a new prism and add it to the mesh.
816 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
817 ///@param ID The ID of the new volume
818 ///@return The created prism or NULL if an element with this ID already exists
819 ///or if input nodes are not found.
820 ///////////////////////////////////////////////////////////////////////////////
822 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
830 //MESSAGE("AddVolumeWithID " << ID);
831 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
832 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
833 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
834 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
835 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
836 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
837 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
838 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
839 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
842 ///////////////////////////////////////////////////////////////////////////////
843 ///Create a new prism and add it to the mesh.
844 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
845 ///@param ID The ID of the new volume
846 ///@return The created prism
847 ///////////////////////////////////////////////////////////////////////////////
849 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
850 const SMDS_MeshNode * n2,
851 const SMDS_MeshNode * n3,
852 const SMDS_MeshNode * n4,
853 const SMDS_MeshNode * n5,
854 const SMDS_MeshNode * n6,
857 //MESSAGE("AddVolumeWithID " << ID);
858 SMDS_MeshVolume* volume = 0;
859 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
860 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
861 if(hasConstructionFaces()) {
862 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
863 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
864 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
865 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
866 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
867 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
868 adjustmyCellsCapacity(ID);
869 myCells[ID] = volume;
872 else if(hasConstructionEdges()) {
873 MESSAGE("Error : Not implemented");
877 // --- retrieve nodes ID
879 myNodeIds[0] = n1->getVtkId();
880 myNodeIds[1] = n2->getVtkId();
881 myNodeIds[2] = n3->getVtkId();
882 myNodeIds[3] = n4->getVtkId();
883 myNodeIds[4] = n5->getVtkId();
884 myNodeIds[5] = n6->getVtkId();
886 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
887 volvtk->init(myNodeIds, this);
888 if (!this->registerElement(ID,volvtk))
890 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
891 myVolumePool->destroy(volvtk);
895 adjustmyCellsCapacity(ID);
896 myCells[ID] = volume;
900 // if (!registerElement(ID, volume)) {
901 // RemoveElement(volume, false);
907 ///////////////////////////////////////////////////////////////////////////////
908 ///Create a new hexagonal prism and add it to the mesh.
909 ///@return The created prism
910 ///////////////////////////////////////////////////////////////////////////////
912 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
913 const SMDS_MeshNode * n2,
914 const SMDS_MeshNode * n3,
915 const SMDS_MeshNode * n4,
916 const SMDS_MeshNode * n5,
917 const SMDS_MeshNode * n6,
918 const SMDS_MeshNode * n7,
919 const SMDS_MeshNode * n8,
920 const SMDS_MeshNode * n9,
921 const SMDS_MeshNode * n10,
922 const SMDS_MeshNode * n11,
923 const SMDS_MeshNode * n12)
925 int ID = myElementIDFactory->GetFreeID();
926 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
927 n7, n8, n9, n10, n11, n12,
929 if(v==NULL) myElementIDFactory->ReleaseID(ID);
933 ///////////////////////////////////////////////////////////////////////////////
934 ///Create a new hexagonal prism and add it to the mesh.
935 ///@param ID The ID of the new volume
936 ///@return The created prism or NULL if an element with this ID already exists
937 ///or if input nodes are not found.
938 ///////////////////////////////////////////////////////////////////////////////
940 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
954 SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
955 SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
956 SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
957 SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
958 SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
959 SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
960 SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
961 SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
962 SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
963 SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
964 SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
965 SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
966 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
967 node7, node8, node9, node10, node11, node12,
971 ///////////////////////////////////////////////////////////////////////////////
972 ///Create a new hexagonal prism and add it to the mesh.
973 ///@param ID The ID of the new volume
974 ///@return The created prism
975 ///////////////////////////////////////////////////////////////////////////////
977 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
978 const SMDS_MeshNode * n2,
979 const SMDS_MeshNode * n3,
980 const SMDS_MeshNode * n4,
981 const SMDS_MeshNode * n5,
982 const SMDS_MeshNode * n6,
983 const SMDS_MeshNode * n7,
984 const SMDS_MeshNode * n8,
985 const SMDS_MeshNode * n9,
986 const SMDS_MeshNode * n10,
987 const SMDS_MeshNode * n11,
988 const SMDS_MeshNode * n12,
991 SMDS_MeshVolume* volume = 0;
992 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
993 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
995 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
996 if(hasConstructionFaces()) {
997 MESSAGE("Error : Not implemented");
1000 else if(hasConstructionEdges()) {
1001 MESSAGE("Error : Not implemented");
1005 // --- retrieve nodes ID
1006 myNodeIds.resize(12);
1007 myNodeIds[0] = n1->getVtkId();
1008 myNodeIds[1] = n6->getVtkId();
1009 myNodeIds[2] = n5->getVtkId();
1010 myNodeIds[3] = n4->getVtkId();
1011 myNodeIds[4] = n3->getVtkId();
1012 myNodeIds[5] = n2->getVtkId();
1014 myNodeIds[6] = n7->getVtkId();
1015 myNodeIds[7] = n12->getVtkId();
1016 myNodeIds[8] = n11->getVtkId();
1017 myNodeIds[9] = n10->getVtkId();
1018 myNodeIds[10] = n9->getVtkId();
1019 myNodeIds[11] = n8->getVtkId();
1021 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1022 volvtk->init(myNodeIds, this);
1023 if (!this->registerElement(ID,volvtk))
1025 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1026 myVolumePool->destroy(volvtk);
1030 adjustmyCellsCapacity(ID);
1031 myCells[ID] = volume;
1032 myInfo.myNbHexPrism++;
1038 ///////////////////////////////////////////////////////////////////////////////
1039 ///Create a new hexahedron and add it to the mesh.
1040 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1041 ///@return The created hexahedron
1042 ///////////////////////////////////////////////////////////////////////////////
1044 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1045 const SMDS_MeshNode * n2,
1046 const SMDS_MeshNode * n3,
1047 const SMDS_MeshNode * n4,
1048 const SMDS_MeshNode * n5,
1049 const SMDS_MeshNode * n6,
1050 const SMDS_MeshNode * n7,
1051 const SMDS_MeshNode * n8)
1053 int ID = myElementIDFactory->GetFreeID();
1054 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
1055 if(v==NULL) myElementIDFactory->ReleaseID(ID);
1059 ///////////////////////////////////////////////////////////////////////////////
1060 ///Create a new hexahedron and add it to the mesh.
1061 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1062 ///@param ID The ID of the new volume
1063 ///@return The created hexahedron or NULL if an element with this ID already
1064 ///exists or if input nodes are not found.
1065 ///////////////////////////////////////////////////////////////////////////////
1067 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
1077 //MESSAGE("AddVolumeWithID " << ID);
1078 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
1079 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
1080 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
1081 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
1082 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
1083 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
1084 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
1085 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
1086 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
1087 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
1089 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
1093 ///////////////////////////////////////////////////////////////////////////////
1094 ///Create a new hexahedron and add it to the mesh.
1095 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1096 ///@param ID The ID of the new volume
1097 ///@return The created prism or NULL if an element with this ID already exists
1098 ///or if input nodes are not found.
1099 ///////////////////////////////////////////////////////////////////////////////
1101 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1102 const SMDS_MeshNode * n2,
1103 const SMDS_MeshNode * n3,
1104 const SMDS_MeshNode * n4,
1105 const SMDS_MeshNode * n5,
1106 const SMDS_MeshNode * n6,
1107 const SMDS_MeshNode * n7,
1108 const SMDS_MeshNode * n8,
1111 //MESSAGE("AddVolumeWithID " << ID);
1112 SMDS_MeshVolume* volume = 0;
1113 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
1114 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1115 if(hasConstructionFaces()) {
1116 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
1117 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
1118 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
1119 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
1120 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
1121 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
1122 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1123 adjustmyCellsCapacity(ID);
1124 myCells[ID] = volume;
1127 else if(hasConstructionEdges()) {
1128 MESSAGE("Error : Not implemented");
1132 // --- retrieve nodes ID
1133 myNodeIds.resize(8);
1134 myNodeIds[0] = n1->getVtkId();
1135 myNodeIds[1] = n4->getVtkId();
1136 myNodeIds[2] = n3->getVtkId();
1137 myNodeIds[3] = n2->getVtkId();
1138 myNodeIds[4] = n5->getVtkId();
1139 myNodeIds[5] = n8->getVtkId();
1140 myNodeIds[6] = n7->getVtkId();
1141 myNodeIds[7] = n6->getVtkId();
1143 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1144 volvtk->init(myNodeIds, this);
1145 if (!this->registerElement(ID,volvtk))
1147 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1148 myVolumePool->destroy(volvtk);
1152 adjustmyCellsCapacity(ID);
1153 myCells[ID] = volume;
1157 // if (!registerElement(ID, volume)) {
1158 // RemoveElement(volume, false);
1164 ///////////////////////////////////////////////////////////////////////////////
1165 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1166 ///@return The created tetrahedron
1167 ///////////////////////////////////////////////////////////////////////////////
1169 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1170 const SMDS_MeshFace * f2,
1171 const SMDS_MeshFace * f3,
1172 const SMDS_MeshFace * f4)
1174 //MESSAGE("AddVolumeWithID");
1175 if (!hasConstructionFaces())
1177 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1180 ///////////////////////////////////////////////////////////////////////////////
1181 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1182 ///@param ID The ID of the new volume
1183 ///@return The created tetrahedron
1184 ///////////////////////////////////////////////////////////////////////////////
1186 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1187 const SMDS_MeshFace * f2,
1188 const SMDS_MeshFace * f3,
1189 const SMDS_MeshFace * f4,
1192 MESSAGE("AddVolumeWithID" << ID);
1193 if (!hasConstructionFaces())
1195 if ( !f1 || !f2 || !f3 || !f4) return 0;
1196 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1197 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1198 adjustmyCellsCapacity(ID);
1199 myCells[ID] = volume;
1200 myInfo.myNbTetras++;
1202 if (!registerElement(ID, volume)) {
1203 registerElement(myElementIDFactory->GetFreeID(), volume);
1204 //RemoveElement(volume, false);
1210 ///////////////////////////////////////////////////////////////////////////////
1211 ///Create a new pyramid defined by its faces and add it to the mesh.
1212 ///@return The created pyramid
1213 ///////////////////////////////////////////////////////////////////////////////
1215 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1216 const SMDS_MeshFace * f2,
1217 const SMDS_MeshFace * f3,
1218 const SMDS_MeshFace * f4,
1219 const SMDS_MeshFace * f5)
1221 //MESSAGE("AddVolumeWithID");
1222 if (!hasConstructionFaces())
1224 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1227 ///////////////////////////////////////////////////////////////////////////////
1228 ///Create a new pyramid defined by its faces and add it to the mesh.
1229 ///@param ID The ID of the new volume
1230 ///@return The created pyramid
1231 ///////////////////////////////////////////////////////////////////////////////
1233 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1234 const SMDS_MeshFace * f2,
1235 const SMDS_MeshFace * f3,
1236 const SMDS_MeshFace * f4,
1237 const SMDS_MeshFace * f5,
1240 MESSAGE("AddVolumeWithID" << ID);
1241 if (!hasConstructionFaces())
1243 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1244 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1245 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1246 adjustmyCellsCapacity(ID);
1247 myCells[ID] = volume;
1248 myInfo.myNbPyramids++;
1250 if (!registerElement(ID, volume)) {
1251 registerElement(myElementIDFactory->GetFreeID(), volume);
1252 //RemoveElement(volume, false);
1258 ///////////////////////////////////////////////////////////////////////////////
1259 ///Create a new prism defined by its faces and add it to the mesh.
1260 ///@return The created prism
1261 ///////////////////////////////////////////////////////////////////////////////
1263 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1264 const SMDS_MeshFace * f2,
1265 const SMDS_MeshFace * f3,
1266 const SMDS_MeshFace * f4,
1267 const SMDS_MeshFace * f5,
1268 const SMDS_MeshFace * f6)
1270 //MESSAGE("AddVolumeWithID" );
1271 if (!hasConstructionFaces())
1273 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1276 ///////////////////////////////////////////////////////////////////////////////
1277 ///Create a new prism defined by its faces and add it to the mesh.
1278 ///@param ID The ID of the new volume
1279 ///@return The created prism
1280 ///////////////////////////////////////////////////////////////////////////////
1282 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1283 const SMDS_MeshFace * f2,
1284 const SMDS_MeshFace * f3,
1285 const SMDS_MeshFace * f4,
1286 const SMDS_MeshFace * f5,
1287 const SMDS_MeshFace * f6,
1290 MESSAGE("AddVolumeWithID" << ID);
1291 if (!hasConstructionFaces())
1293 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1294 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1295 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1296 adjustmyCellsCapacity(ID);
1297 myCells[ID] = volume;
1298 myInfo.myNbPrisms++;
1300 if (!registerElement(ID, volume)) {
1301 registerElement(myElementIDFactory->GetFreeID(), volume);
1302 //RemoveElement(volume, false);
1308 ///////////////////////////////////////////////////////////////////////////////
1309 /// Add a polygon defined by its nodes IDs
1310 ///////////////////////////////////////////////////////////////////////////////
1312 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
1315 int nbNodes = nodes_ids.size();
1316 vector<const SMDS_MeshNode*> nodes (nbNodes);
1317 for (int i = 0; i < nbNodes; i++) {
1318 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1319 if (!nodes[i]) return NULL;
1321 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1324 ///////////////////////////////////////////////////////////////////////////////
1325 /// Add a polygon defined by its nodes
1326 ///////////////////////////////////////////////////////////////////////////////
1329 SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1332 SMDS_MeshFace * face;
1334 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1335 if (hasConstructionEdges())
1337 MESSAGE("Error : Not implemented");
1342 myNodeIds.resize( nodes.size() );
1343 for ( size_t i = 0; i < nodes.size(); ++i )
1344 myNodeIds[i] = nodes[i]->getVtkId();
1346 SMDS_VtkFace *facevtk = myFacePool->getNew();
1347 facevtk->initPoly(myNodeIds, this);
1348 if (!this->registerElement(ID,facevtk))
1350 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1351 myFacePool->destroy(facevtk);
1356 adjustmyCellsCapacity(ID);
1358 myInfo.myNbPolygons++;
1364 ///////////////////////////////////////////////////////////////////////////////
1365 /// Add a polygon defined by its nodes.
1366 /// An ID is automatically affected to the created face.
1367 ///////////////////////////////////////////////////////////////////////////////
1369 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1371 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1374 ///////////////////////////////////////////////////////////////////////////////
1375 /// Add a quadratic polygon defined by its nodes IDs
1376 ///////////////////////////////////////////////////////////////////////////////
1378 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
1381 vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
1382 for ( size_t i = 0; i < nodes.size(); i++) {
1383 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1384 if (!nodes[i]) return NULL;
1386 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
1389 ///////////////////////////////////////////////////////////////////////////////
1390 /// Add a quadratic polygon defined by its nodes
1391 ///////////////////////////////////////////////////////////////////////////////
1394 SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
1397 SMDS_MeshFace * face;
1399 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1400 if (hasConstructionEdges())
1402 MESSAGE("Error : Not implemented");
1407 myNodeIds.resize( nodes.size() );
1408 for ( size_t i = 0; i < nodes.size(); ++i )
1409 myNodeIds[i] = nodes[i]->getVtkId();
1411 SMDS_VtkFace *facevtk = myFacePool->getNew();
1412 facevtk->initQuadPoly(myNodeIds, this);
1413 if (!this->registerElement(ID,facevtk))
1415 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1416 myFacePool->destroy(facevtk);
1420 adjustmyCellsCapacity(ID);
1422 myInfo.myNbQuadPolygons++;
1427 ///////////////////////////////////////////////////////////////////////////////
1428 /// Add a quadratic polygon defined by its nodes.
1429 /// An ID is automatically affected to the created face.
1430 ///////////////////////////////////////////////////////////////////////////////
1432 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1434 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1437 ///////////////////////////////////////////////////////////////////////////////
1438 /// Create a new polyhedral volume and add it to the mesh.
1439 /// @param ID The ID of the new volume
1440 /// @return The created volume or NULL if an element with this ID already exists
1441 /// or if input nodes are not found.
1442 ///////////////////////////////////////////////////////////////////////////////
1444 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1445 (const vector<int> & nodes_ids,
1446 const vector<int> & quantities,
1449 int nbNodes = nodes_ids.size();
1450 vector<const SMDS_MeshNode*> nodes (nbNodes);
1451 for (int i = 0; i < nbNodes; i++) {
1452 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1453 if (!nodes[i]) return NULL;
1455 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1458 ///////////////////////////////////////////////////////////////////////////////
1459 /// Create a new polyhedral volume and add it to the mesh.
1460 /// @param ID The ID of the new volume
1461 /// @return The created volume
1462 ///////////////////////////////////////////////////////////////////////////////
1465 SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
1466 const vector<int> & quantities,
1469 SMDS_MeshVolume* volume = 0;
1470 if ( nodes.empty() || quantities.empty() )
1472 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1473 if (hasConstructionFaces())
1475 MESSAGE("Error : Not implemented");
1478 else if (hasConstructionEdges())
1480 MESSAGE("Error : Not implemented");
1485 //#ifdef VTK_HAVE_POLYHEDRON
1486 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1487 myNodeIds.resize( nodes.size() );
1488 for ( size_t i = 0; i < nodes.size(); ++i )
1489 myNodeIds[i] = nodes[i]->getVtkId();
1491 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1492 volvtk->initPoly(myNodeIds, quantities, this);
1493 if (!this->registerElement(ID, volvtk))
1495 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1496 myVolumePool->destroy(volvtk);
1501 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1502 // for ( int i = 0; i < nodes.size(); ++i )
1503 // if ( !nodes[ i ] ) return 0;
1504 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1506 adjustmyCellsCapacity(ID);
1507 myCells[ID] = volume;
1508 myInfo.myNbPolyhedrons++;
1511 //#ifndef VTK_HAVE_POLYHEDRON
1512 // if (!registerElement(ID, volume))
1514 // registerElement(myElementIDFactory->GetFreeID(), volume);
1515 // //RemoveElement(volume, false);
1522 ///////////////////////////////////////////////////////////////////////////////
1523 /// Create a new polyhedral volume and add it to the mesh.
1524 /// @return The created volume
1525 ///////////////////////////////////////////////////////////////////////////////
1527 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1528 (const vector<const SMDS_MeshNode*> & nodes,
1529 const vector<int> & quantities)
1531 int ID = myElementIDFactory->GetFreeID();
1532 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1533 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1537 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1539 int ID = myElementIDFactory->GetFreeID();
1540 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1541 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1545 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1547 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1548 volvtk->init(vtkNodeIds, this);
1549 if (!this->registerElement(ID,volvtk))
1551 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1552 myVolumePool->destroy(volvtk);
1555 adjustmyCellsCapacity(ID);
1556 myCells[ID] = volvtk;
1557 vtkIdType aVtkType = volvtk->GetVtkType();
1561 myInfo.myNbTetras++;
1564 myInfo.myNbPyramids++;
1567 myInfo.myNbPrisms++;
1569 case VTK_HEXAHEDRON:
1572 case VTK_QUADRATIC_TETRA:
1573 myInfo.myNbQuadTetras++;
1575 case VTK_QUADRATIC_PYRAMID:
1576 myInfo.myNbQuadPyramids++;
1578 case VTK_QUADRATIC_WEDGE:
1579 myInfo.myNbQuadPrisms++;
1581 case VTK_QUADRATIC_HEXAHEDRON:
1582 myInfo.myNbQuadHexas++;
1584 //#ifdef VTK_HAVE_POLYHEDRON
1585 case VTK_POLYHEDRON:
1586 myInfo.myNbPolyhedrons++;
1590 myInfo.myNbPolyhedrons++;
1596 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1598 int ID = myElementIDFactory->GetFreeID();
1599 SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
1600 if (f == NULL) myElementIDFactory->ReleaseID(ID);
1604 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1606 SMDS_VtkFace *facevtk = myFacePool->getNew();
1607 facevtk->init(vtkNodeIds, this);
1608 if (!this->registerElement(ID,facevtk))
1610 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1611 myFacePool->destroy(facevtk);
1614 adjustmyCellsCapacity(ID);
1615 myCells[ID] = facevtk;
1616 vtkIdType aVtkType = facevtk->GetVtkType();
1620 myInfo.myNbTriangles++;
1623 myInfo.myNbQuadrangles++;
1625 case VTK_QUADRATIC_TRIANGLE:
1626 myInfo.myNbQuadTriangles++;
1628 case VTK_QUADRATIC_QUAD:
1629 myInfo.myNbQuadQuadrangles++;
1631 case VTK_BIQUADRATIC_QUAD:
1632 myInfo.myNbBiQuadQuadrangles++;
1634 case VTK_BIQUADRATIC_TRIANGLE:
1635 myInfo.myNbBiQuadTriangles++;
1638 myInfo.myNbPolygons++;
1641 myInfo.myNbPolygons++;
1646 ///////////////////////////////////////////////////////////////////////////////
1647 /// Registers element with the given ID, maintains inverse connections
1648 ///////////////////////////////////////////////////////////////////////////////
1649 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1651 //MESSAGE("registerElement " << ID);
1652 if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound
1654 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1659 element->myMeshId = myMeshId;
1661 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1663 int vtkId = cell->getVtkId();
1665 vtkId = myElementIDFactory->SetInVtkGrid(element);
1667 if (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector
1669 // MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1670 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1672 myCellIdVtkToSmds[vtkId] = ID;
1674 myElementIDFactory->updateMinMax(ID);
1678 //=======================================================================
1679 //function : MoveNode
1681 //=======================================================================
1683 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
1685 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
1686 node->setXYZ(x,y,z);
1689 ///////////////////////////////////////////////////////////////////////////////
1690 /// Return the node whose SMDS ID is 'ID'.
1691 ///////////////////////////////////////////////////////////////////////////////
1692 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1694 if (ID < 1 || ID >= (int)myNodes.size())
1696 // MESSAGE("------------------------------------------------------------------------- ");
1697 // MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1698 // MESSAGE("------------------------------------------------------------------------- ");
1701 return (const SMDS_MeshNode *)myNodes[ID];
1704 ///////////////////////////////////////////////////////////////////////////////
1705 /// Return the node whose VTK ID is 'vtkId'.
1706 ///////////////////////////////////////////////////////////////////////////////
1707 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1709 // TODO if needed use mesh->nodeIdFromVtkToSmds
1710 if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() )
1712 MESSAGE("------------------------------------------------------------------------- ");
1713 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1714 MESSAGE("------------------------------------------------------------------------- ");
1717 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1720 ///////////////////////////////////////////////////////////////////////////////
1721 ///Create a triangle and add it to the current mesh. This method do not bind an
1722 ///ID to the create triangle.
1723 ///////////////////////////////////////////////////////////////////////////////
1724 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1725 const SMDS_MeshNode * node2,
1726 const SMDS_MeshNode * node3,
1729 if ( !node1 || !node2 || !node3) return 0;
1730 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1731 if(hasConstructionEdges())
1733 SMDS_MeshEdge *edge1, *edge2, *edge3;
1734 edge1=FindEdgeOrCreate(node1,node2);
1735 edge2=FindEdgeOrCreate(node2,node3);
1736 edge3=FindEdgeOrCreate(node3,node1);
1738 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1739 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1740 adjustmyCellsCapacity(ID);
1742 myInfo.myNbTriangles++;
1747 // --- retrieve nodes ID
1748 myNodeIds.resize(3);
1749 myNodeIds[0] = node1->getVtkId();
1750 myNodeIds[1] = node2->getVtkId();
1751 myNodeIds[2] = node3->getVtkId();
1753 SMDS_MeshFace * face = 0;
1754 SMDS_VtkFace *facevtk = myFacePool->getNew();
1755 facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid
1756 if (!this->registerElement(ID,facevtk))
1758 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1759 myFacePool->destroy(facevtk);
1763 adjustmyCellsCapacity(ID);
1765 //MESSAGE("createTriangle " << ID << " " << face);
1766 myInfo.myNbTriangles++;
1771 ///////////////////////////////////////////////////////////////////////////////
1772 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1773 ///a ID to the create triangle.
1774 ///////////////////////////////////////////////////////////////////////////////
1775 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1776 const SMDS_MeshNode * node2,
1777 const SMDS_MeshNode * node3,
1778 const SMDS_MeshNode * node4,
1781 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1782 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1783 if(hasConstructionEdges())
1785 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1786 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1787 edge1=FindEdgeOrCreate(node1,node2);
1788 edge2=FindEdgeOrCreate(node2,node3);
1789 edge3=FindEdgeOrCreate(node3,node4);
1790 edge4=FindEdgeOrCreate(node4,node1);
1792 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1793 adjustmyCellsCapacity(ID);
1795 myInfo.myNbQuadrangles++;
1800 // --- retrieve nodes ID
1801 myNodeIds.resize(4);
1802 myNodeIds[0] = node1->getVtkId();
1803 myNodeIds[1] = node2->getVtkId();
1804 myNodeIds[2] = node3->getVtkId();
1805 myNodeIds[3] = node4->getVtkId();
1807 SMDS_MeshFace * face = 0;
1808 SMDS_VtkFace *facevtk = myFacePool->getNew();
1809 facevtk->init(myNodeIds, this);
1810 if (!this->registerElement(ID,facevtk))
1812 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1813 myFacePool->destroy(facevtk);
1817 adjustmyCellsCapacity(ID);
1819 myInfo.myNbQuadrangles++;
1824 ///////////////////////////////////////////////////////////////////////////////
1825 /// Remove a node and all the elements which own this node
1826 ///////////////////////////////////////////////////////////////////////////////
1828 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1830 MESSAGE("RemoveNode");
1831 RemoveElement(node, true);
1834 ///////////////////////////////////////////////////////////////////////////////
1835 /// Remove an edge and all the elements which own this edge
1836 ///////////////////////////////////////////////////////////////////////////////
1838 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1840 MESSAGE("Remove0DElement");
1841 RemoveElement(elem0d,true);
1844 ///////////////////////////////////////////////////////////////////////////////
1845 /// Remove an edge and all the elements which own this edge
1846 ///////////////////////////////////////////////////////////////////////////////
1848 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1850 MESSAGE("RemoveEdge");
1851 RemoveElement(edge,true);
1854 ///////////////////////////////////////////////////////////////////////////////
1855 /// Remove an face and all the elements which own this face
1856 ///////////////////////////////////////////////////////////////////////////////
1858 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1860 MESSAGE("RemoveFace");
1861 RemoveElement(face, true);
1864 ///////////////////////////////////////////////////////////////////////////////
1866 ///////////////////////////////////////////////////////////////////////////////
1868 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1870 MESSAGE("RemoveVolume");
1871 RemoveElement(volume, true);
1874 //=======================================================================
1875 //function : RemoveFromParent
1877 //=======================================================================
1879 bool SMDS_Mesh::RemoveFromParent()
1881 if (myParent==NULL) return false;
1882 else return (myParent->RemoveSubMesh(this));
1885 //=======================================================================
1886 //function : RemoveSubMesh
1888 //=======================================================================
1890 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1894 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1895 for (; itmsh!=myChildren.end() && !found; itmsh++)
1897 SMDS_Mesh * submesh = *itmsh;
1898 if (submesh == aMesh)
1901 myChildren.erase(itmsh);
1908 //=======================================================================
1909 //function : ChangeElementNodes
1911 //=======================================================================
1913 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1914 const SMDS_MeshNode * nodes[],
1917 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1918 // keep current nodes of elem
1919 set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1923 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1926 Ok = cell->vtkOrder(nodes, nbnodes);
1927 Ok = cell->ChangeNodes(nodes, nbnodes);
1930 if ( Ok ) { // update InverseElements
1932 set<const SMDS_MeshNode*>::iterator it;
1934 // AddInverseElement to new nodes
1935 for ( int i = 0; i < nbnodes; i++ ) {
1936 it = oldNodes.find( nodes[i] );
1937 if ( it == oldNodes.end() )
1939 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1941 // remove from oldNodes a node that remains in elem
1942 oldNodes.erase( it );
1944 // RemoveInverseElement from the nodes removed from elem
1945 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1947 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1948 n->RemoveInverseElement( cell );
1955 //=======================================================================
1956 //function : ChangePolyhedronNodes
1957 //purpose : to change nodes of polyhedral volume
1958 //=======================================================================
1959 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1960 const vector<const SMDS_MeshNode*>& nodes,
1961 const vector<int> & quantities)
1963 if (elem->GetType() != SMDSAbs_Volume) {
1964 MESSAGE("WRONG ELEM TYPE");
1968 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1973 // keep current nodes of elem
1974 set<const SMDS_MeshElement*> oldNodes;
1975 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1976 while (itn->more()) {
1977 oldNodes.insert(itn->next());
1981 // TODO remove this function
1982 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1988 // update InverseElements
1990 // AddInverseElement to new nodes
1991 int nbnodes = nodes.size();
1992 set<const SMDS_MeshElement*>::iterator it;
1993 for (int i = 0; i < nbnodes; i++) {
1994 it = oldNodes.find(nodes[i]);
1995 if (it == oldNodes.end()) {
1997 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1999 // remove from oldNodes a node that remains in elem
2004 // RemoveInverseElement from the nodes removed from elem
2005 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
2006 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2007 (const_cast<SMDS_MeshElement *>( *it ));
2008 n->RemoveInverseElement(elem);
2015 //=======================================================================
2016 //function : Find0DElement
2018 //=======================================================================
2019 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
2021 const SMDS_MeshNode * node = FindNode(idnode);
2022 if(node == NULL) return NULL;
2023 return Find0DElement(node);
2026 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
2028 if (!node) return 0;
2029 const SMDS_Mesh0DElement* toReturn = NULL;
2030 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
2031 while (it1->more() && (toReturn == NULL)) {
2032 const SMDS_MeshElement* e = it1->next();
2033 if (e->NbNodes() == 1) {
2034 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
2040 //=======================================================================
2041 //function : FindBall
2043 //=======================================================================
2045 const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const
2047 const SMDS_MeshNode * node = FindNode(idnode);
2048 if(node == NULL) return NULL;
2049 return FindBall(node);
2052 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
2054 if (!node) return 0;
2055 const SMDS_BallElement* toReturn = NULL;
2056 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
2057 while (it1->more() && (toReturn == NULL)) {
2058 const SMDS_MeshElement* e = it1->next();
2059 if (e->GetGeomType() == SMDSGeom_BALL)
2060 toReturn = static_cast<const SMDS_BallElement*>(e);
2065 //=======================================================================
2066 //function : Find0DElementOrCreate
2068 //=======================================================================
2069 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
2071 // if (!node) return 0;
2072 // SMDS_Mesh0DElement * toReturn = NULL;
2073 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
2074 // if (toReturn == NULL) {
2075 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
2076 // toReturn = new SMDS_Mesh0DElement(node);
2077 // my0DElements.Add(toReturn);
2078 // myInfo.myNb0DElements++;
2084 //=======================================================================
2085 //function : FindEdge
2087 //=======================================================================
2089 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
2091 const SMDS_MeshNode * node1=FindNode(idnode1);
2092 const SMDS_MeshNode * node2=FindNode(idnode2);
2093 if((node1==NULL)||(node2==NULL)) return NULL;
2094 return FindEdge(node1,node2);
2097 //#include "Profiler.h"
2098 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2099 const SMDS_MeshNode * node2)
2101 if ( !node1 ) return 0;
2102 const SMDS_MeshEdge * toReturn=NULL;
2105 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
2108 while(it1->more()) {
2109 const SMDS_MeshElement * e = it1->next();
2110 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
2111 toReturn = static_cast<const SMDS_MeshEdge*>( e );
2120 //=======================================================================
2121 //function : FindEdgeOrCreate
2123 //=======================================================================
2125 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
2126 const SMDS_MeshNode * node2)
2128 if ( !node1 || !node2) return 0;
2129 SMDS_MeshEdge * toReturn=NULL;
2130 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
2131 if(toReturn==NULL) {
2132 if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2133 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
2134 adjustmyCellsCapacity(ID);
2135 myNodeIds.resize(2);
2136 myNodeIds[0] = node1->getVtkId();
2137 myNodeIds[1] = node2->getVtkId();
2139 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
2140 edgevtk->init(myNodeIds, this);
2141 if (!this->registerElement(ID,edgevtk))
2143 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
2144 myEdgePool->destroy(edgevtk);
2148 myCells[ID] = toReturn;
2155 //=======================================================================
2156 //function : FindEdge
2158 //=======================================================================
2160 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
2163 const SMDS_MeshNode * node1=FindNode(idnode1);
2164 const SMDS_MeshNode * node2=FindNode(idnode2);
2165 const SMDS_MeshNode * node3=FindNode(idnode3);
2166 return FindEdge(node1,node2,node3);
2169 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2170 const SMDS_MeshNode * node2,
2171 const SMDS_MeshNode * node3)
2173 if ( !node1 ) return 0;
2174 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
2175 while(it1->more()) {
2176 const SMDS_MeshElement * e = it1->next();
2177 if ( e->NbNodes() == 3 ) {
2178 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2179 while(it2->more()) {
2180 const SMDS_MeshElement* n = it2->next();
2190 return static_cast<const SMDS_MeshEdge *> (e);
2197 //=======================================================================
2198 //function : FindFace
2200 //=======================================================================
2202 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2205 const SMDS_MeshNode * node1=FindNode(idnode1);
2206 const SMDS_MeshNode * node2=FindNode(idnode2);
2207 const SMDS_MeshNode * node3=FindNode(idnode3);
2208 return FindFace(node1, node2, node3);
2211 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2212 const SMDS_MeshNode *node2,
2213 const SMDS_MeshNode *node3)
2215 if ( !node1 ) return 0;
2216 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2217 while(it1->more()) {
2218 const SMDS_MeshElement * e = it1->next();
2219 if ( e->NbNodes() == 3 ) {
2220 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2221 while(it2->more()) {
2222 const SMDS_MeshElement* n = it2->next();
2232 return static_cast<const SMDS_MeshFace *> (e);
2238 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2239 const SMDS_MeshNode *node2,
2240 const SMDS_MeshNode *node3)
2242 SMDS_MeshFace * toReturn=NULL;
2243 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
2244 if(toReturn==NULL) {
2245 int ID = myElementIDFactory->GetFreeID();
2246 toReturn = createTriangle(node1,node2,node3, ID);
2252 //=======================================================================
2253 //function : FindFace
2255 //=======================================================================
2257 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2258 int idnode3, int idnode4) const
2260 const SMDS_MeshNode * node1=FindNode(idnode1);
2261 const SMDS_MeshNode * node2=FindNode(idnode2);
2262 const SMDS_MeshNode * node3=FindNode(idnode3);
2263 const SMDS_MeshNode * node4=FindNode(idnode4);
2264 return FindFace(node1, node2, node3, node4);
2267 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2268 const SMDS_MeshNode *node2,
2269 const SMDS_MeshNode *node3,
2270 const SMDS_MeshNode *node4)
2272 if ( !node1 ) return 0;
2273 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2274 while(it1->more()) {
2275 const SMDS_MeshElement * e = it1->next();
2276 if ( e->NbNodes() == 4 ) {
2277 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2278 while(it2->more()) {
2279 const SMDS_MeshElement* n = it2->next();
2290 return static_cast<const SMDS_MeshFace *> (e);
2296 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2297 const SMDS_MeshNode *node2,
2298 const SMDS_MeshNode *node3,
2299 const SMDS_MeshNode *node4)
2301 SMDS_MeshFace * toReturn=NULL;
2302 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2303 if(toReturn==NULL) {
2304 int ID = myElementIDFactory->GetFreeID();
2305 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2311 //=======================================================================
2312 //function : FindFace
2313 //purpose :quadratic triangle
2314 //=======================================================================
2316 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2317 int idnode3, int idnode4,
2318 int idnode5, int idnode6) const
2320 const SMDS_MeshNode * node1 = FindNode(idnode1);
2321 const SMDS_MeshNode * node2 = FindNode(idnode2);
2322 const SMDS_MeshNode * node3 = FindNode(idnode3);
2323 const SMDS_MeshNode * node4 = FindNode(idnode4);
2324 const SMDS_MeshNode * node5 = FindNode(idnode5);
2325 const SMDS_MeshNode * node6 = FindNode(idnode6);
2326 return FindFace(node1, node2, node3, node4, node5, node6);
2329 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2330 const SMDS_MeshNode *node2,
2331 const SMDS_MeshNode *node3,
2332 const SMDS_MeshNode *node4,
2333 const SMDS_MeshNode *node5,
2334 const SMDS_MeshNode *node6)
2336 if ( !node1 ) return 0;
2337 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2338 while(it1->more()) {
2339 const SMDS_MeshElement * e = it1->next();
2340 if ( e->NbNodes() == 6 ) {
2341 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2342 while(it2->more()) {
2343 const SMDS_MeshElement* n = it2->next();
2356 return static_cast<const SMDS_MeshFace *> (e);
2363 //=======================================================================
2364 //function : FindFace
2365 //purpose : quadratic quadrangle
2366 //=======================================================================
2368 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2369 int idnode3, int idnode4,
2370 int idnode5, int idnode6,
2371 int idnode7, int idnode8) const
2373 const SMDS_MeshNode * node1 = FindNode(idnode1);
2374 const SMDS_MeshNode * node2 = FindNode(idnode2);
2375 const SMDS_MeshNode * node3 = FindNode(idnode3);
2376 const SMDS_MeshNode * node4 = FindNode(idnode4);
2377 const SMDS_MeshNode * node5 = FindNode(idnode5);
2378 const SMDS_MeshNode * node6 = FindNode(idnode6);
2379 const SMDS_MeshNode * node7 = FindNode(idnode7);
2380 const SMDS_MeshNode * node8 = FindNode(idnode8);
2381 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2384 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2385 const SMDS_MeshNode *node2,
2386 const SMDS_MeshNode *node3,
2387 const SMDS_MeshNode *node4,
2388 const SMDS_MeshNode *node5,
2389 const SMDS_MeshNode *node6,
2390 const SMDS_MeshNode *node7,
2391 const SMDS_MeshNode *node8)
2393 if ( !node1 ) return 0;
2394 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2395 while(it1->more()) {
2396 const SMDS_MeshElement * e = it1->next();
2397 if ( e->NbNodes() == 8 ) {
2398 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2399 while(it2->more()) {
2400 const SMDS_MeshElement* n = it2->next();
2415 return static_cast<const SMDS_MeshFace *> (e);
2422 //=======================================================================
2423 //function : FindElement
2425 //=======================================================================
2427 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2429 if ( IDelem <= 0 || IDelem >= (int)myCells.size() )
2431 MESSAGE("--------------------------------------------------------------------------------- ");
2432 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2433 MESSAGE("--------------------------------------------------------------------------------- ");
2434 // TODO raise an exception
2438 return myCells[IDelem];
2441 //=======================================================================
2442 //function : FindFace
2443 //purpose : find polygon
2444 //=======================================================================
2446 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2448 int nbnodes = nodes_ids.size();
2449 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2450 for (int inode = 0; inode < nbnodes; inode++) {
2451 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2452 if (node == NULL) return NULL;
2453 poly_nodes[inode] = node;
2455 return FindFace(poly_nodes);
2458 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2460 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2464 //================================================================================
2466 * \brief Return element based on all given nodes
2467 * \param nodes - node of element
2468 * \param type - type of element
2469 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2470 * \retval const SMDS_MeshElement* - found element or NULL
2472 //================================================================================
2474 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2475 const SMDSAbs_ElementType type,
2476 const bool noMedium)
2478 if ( nodes.size() > 0 && nodes[0] )
2480 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2483 const SMDS_MeshElement* e = itF->next();
2484 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2485 if ( nbNodesToCheck == (int)nodes.size() )
2487 for ( size_t i = 1; e && i < nodes.size(); ++i )
2489 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2490 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2501 //=======================================================================
2502 //function : DumpNodes
2504 //=======================================================================
2506 void SMDS_Mesh::DumpNodes() const
2508 MESSAGE("dump nodes of mesh : ");
2509 SMDS_NodeIteratorPtr itnode=nodesIterator();
2510 while(itnode->more()) ; //MESSAGE(itnode->next());
2513 //=======================================================================
2514 //function : Dump0DElements
2516 //=======================================================================
2517 void SMDS_Mesh::Dump0DElements() const
2519 MESSAGE("dump 0D elements of mesh : ");
2520 SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement);
2521 while(it0d->more()) ; //MESSAGE(it0d->next());
2524 //=======================================================================
2525 //function : DumpEdges
2527 //=======================================================================
2529 void SMDS_Mesh::DumpEdges() const
2531 MESSAGE("dump edges of mesh : ");
2532 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2533 while(itedge->more()) ; //MESSAGE(itedge->next());
2536 //=======================================================================
2537 //function : DumpFaces
2539 //=======================================================================
2541 void SMDS_Mesh::DumpFaces() const
2543 MESSAGE("dump faces of mesh : ");
2544 SMDS_FaceIteratorPtr itface=facesIterator();
2545 while(itface->more()) ; //MESSAGE(itface->next());
2548 //=======================================================================
2549 //function : DumpVolumes
2551 //=======================================================================
2553 void SMDS_Mesh::DumpVolumes() const
2555 MESSAGE("dump volumes of mesh : ");
2556 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2557 while(itvol->more()) ; //MESSAGE(itvol->next());
2560 //=======================================================================
2561 //function : DebugStats
2563 //=======================================================================
2565 void SMDS_Mesh::DebugStats() const
2567 MESSAGE("Debug stats of mesh : ");
2569 MESSAGE("===== NODES ====="<<NbNodes());
2570 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2571 MESSAGE("===== EDGES ====="<<NbEdges());
2572 MESSAGE("===== FACES ====="<<NbFaces());
2573 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2575 MESSAGE("End Debug stats of mesh ");
2579 SMDS_NodeIteratorPtr itnode=nodesIterator();
2580 int sizeofnodes = 0;
2581 int sizeoffaces = 0;
2583 while(itnode->more())
2585 const SMDS_MeshNode *node = itnode->next();
2587 sizeofnodes += sizeof(*node);
2589 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2592 const SMDS_MeshElement *me = it->next();
2593 sizeofnodes += sizeof(me);
2597 SMDS_FaceIteratorPtr itface=facesIterator();
2598 while(itface->more())
2600 const SMDS_MeshElement *face = itface->next();
2601 sizeoffaces += sizeof(*face);
2604 MESSAGE("total size of node elements = " << sizeofnodes);;
2605 MESSAGE("total size of face elements = " << sizeoffaces);;
2610 ///////////////////////////////////////////////////////////////////////////////
2611 /// Return the number of nodes
2612 ///////////////////////////////////////////////////////////////////////////////
2613 int SMDS_Mesh::NbNodes() const
2615 //MESSAGE(myGrid->GetNumberOfPoints());
2616 //MESSAGE(myInfo.NbNodes());
2617 //MESSAGE(myNodeMax);
2618 return myInfo.NbNodes();
2621 ///////////////////////////////////////////////////////////////////////////////
2622 /// Return the number of 0D elements
2623 ///////////////////////////////////////////////////////////////////////////////
2624 int SMDS_Mesh::Nb0DElements() const
2626 return myInfo.Nb0DElements();
2629 ///////////////////////////////////////////////////////////////////////////////
2630 /// Return the number of 0D elements
2631 ///////////////////////////////////////////////////////////////////////////////
2632 int SMDS_Mesh::NbBalls() const
2634 return myInfo.NbBalls();
2637 ///////////////////////////////////////////////////////////////////////////////
2638 /// Return the number of edges (including construction edges)
2639 ///////////////////////////////////////////////////////////////////////////////
2640 int SMDS_Mesh::NbEdges() const
2642 return myInfo.NbEdges();
2645 ///////////////////////////////////////////////////////////////////////////////
2646 /// Return the number of faces (including construction faces)
2647 ///////////////////////////////////////////////////////////////////////////////
2648 int SMDS_Mesh::NbFaces() const
2650 return myInfo.NbFaces();
2653 ///////////////////////////////////////////////////////////////////////////////
2654 /// Return the number of volumes
2655 ///////////////////////////////////////////////////////////////////////////////
2656 int SMDS_Mesh::NbVolumes() const
2658 return myInfo.NbVolumes();
2661 ///////////////////////////////////////////////////////////////////////////////
2662 /// Return the number of child mesh of this mesh.
2663 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
2664 ///////////////////////////////////////////////////////////////////////////////
2665 int SMDS_Mesh::NbSubMesh() const
2667 return myChildren.size();
2670 ///////////////////////////////////////////////////////////////////////////////
2671 /// Destroy the mesh and all its elements
2672 /// All pointer on elements owned by this mesh become illegals.
2673 ///////////////////////////////////////////////////////////////////////////////
2674 SMDS_Mesh::~SMDS_Mesh()
2676 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2677 while(itc!=myChildren.end())
2685 delete myNodeIDFactory;
2686 delete myElementIDFactory;
2690 SMDS_ElemIteratorPtr eIt = elementsIterator();
2691 while ( eIt->more() )
2693 const SMDS_MeshElement *elem = eIt->next();
2694 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2696 SMDS_NodeIteratorPtr itn = nodesIterator();
2699 const SMDS_MeshNode *node = itn->next();
2700 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2701 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2707 delete myVolumePool;
2713 //================================================================================
2715 * \brief Clear all data
2717 //================================================================================
2719 void SMDS_Mesh::Clear()
2721 MESSAGE("SMDS_Mesh::Clear");
2724 SMDS_ElemIteratorPtr eIt = elementsIterator();
2725 while ( eIt->more() )
2727 const SMDS_MeshElement *elem = eIt->next();
2728 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2730 SMDS_NodeIteratorPtr itn = nodesIterator();
2733 const SMDS_MeshNode *node = itn->next();
2734 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2739 myNodeIDFactory->Clear();
2740 myElementIDFactory->Clear();
2743 // SMDS_ElemIteratorPtr itv = elementsIterator();
2744 // while (itv->more())
2746 // SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2747 // SMDSAbs_ElementType aType = elem->GetType();
2750 // case SMDSAbs_0DElement:
2753 // case SMDSAbs_Edge:
2754 // myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2756 // case SMDSAbs_Face:
2757 // myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2759 // case SMDSAbs_Volume:
2760 // myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2762 // case SMDSAbs_Ball:
2763 // myBallPool->destroy(static_cast<SMDS_BallElement*>(elem));
2769 myVolumePool->clear();
2770 myFacePool->clear();
2771 myEdgePool->clear();
2772 myBallPool->clear();
2774 clearVector( myCells );
2775 clearVector( myCellIdVtkToSmds );
2777 SMDS_NodeIteratorPtr itn = nodesIterator();
2780 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2781 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2782 //myNodePool->destroy(node);
2784 myNodePool->clear();
2785 clearVector( myNodes );
2787 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2788 while(itc!=myChildren.end())
2799 myGrid->Initialize();
2801 vtkPoints* points = vtkPoints::New();
2802 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2803 // using double type for storing coordinates of nodes instead float.
2804 points->SetDataType(VTK_DOUBLE);
2805 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2806 myGrid->SetPoints( points );
2808 myGrid->BuildLinks();
2811 ///////////////////////////////////////////////////////////////////////////////
2812 /// Return true if this mesh create faces with edges.
2813 /// A false returned value mean that faces are created with nodes. A concequence
2814 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2815 ///////////////////////////////////////////////////////////////////////////////
2816 bool SMDS_Mesh::hasConstructionEdges()
2818 return myHasConstructionEdges;
2821 ///////////////////////////////////////////////////////////////////////////////
2822 /// Return true if this mesh create volumes with faces
2823 /// A false returned value mean that volumes are created with nodes or edges.
2824 /// (see hasConstructionEdges)
2825 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2827 ///////////////////////////////////////////////////////////////////////////////
2828 bool SMDS_Mesh::hasConstructionFaces()
2830 return myHasConstructionFaces;
2833 ///////////////////////////////////////////////////////////////////////////////
2834 /// Return true if nodes are linked to the finit elements, they are belonging to.
2835 /// Currently, It always return true.
2836 ///////////////////////////////////////////////////////////////////////////////
2837 bool SMDS_Mesh::hasInverseElements()
2839 return myHasInverseElements;
2842 ///////////////////////////////////////////////////////////////////////////////
2843 /// Make this mesh creating construction edges (see hasConstructionEdges)
2844 /// @param b true to have construction edges, else false.
2845 ///////////////////////////////////////////////////////////////////////////////
2846 void SMDS_Mesh::setConstructionEdges(bool b)
2848 myHasConstructionEdges=b;
2851 ///////////////////////////////////////////////////////////////////////////////
2852 /// Make this mesh creating construction faces (see hasConstructionFaces)
2853 /// @param b true to have construction faces, else false.
2854 ///////////////////////////////////////////////////////////////////////////////
2855 void SMDS_Mesh::setConstructionFaces(bool b)
2857 myHasConstructionFaces=b;
2860 ///////////////////////////////////////////////////////////////////////////////
2861 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2862 /// @param b true to link nodes to elements, else false.
2863 ///////////////////////////////////////////////////////////////////////////////
2864 void SMDS_Mesh::setInverseElements(bool b)
2866 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2867 myHasInverseElements=b;
2872 //================================================================================
2874 * \brief Iterator on elements in id increasing order
2876 //================================================================================
2878 template <typename ELEM=const SMDS_MeshElement*>
2879 class IdSortedIterator : public SMDS_Iterator<ELEM>
2881 SMDS_MeshElementIDFactory& myIDFact;
2882 int myID, myMaxID, myNbFound, myTotalNb;
2883 SMDSAbs_ElementType myType;
2887 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2888 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2891 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2903 ELEM current = myElem;
2905 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2906 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2907 && myElem->GetType() != myType )
2910 myNbFound += bool(myElem);
2916 //================================================================================
2918 * \brief Iterator on vector of elements, possibly being resized while iteration
2920 //================================================================================
2922 template<typename RETURN_VALUE,
2923 typename VECTOR_VALUE=SMDS_MeshCell*,
2924 typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
2925 class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
2927 const std::vector<VECTOR_VALUE>& _vector;
2930 VALUE_FILTER _filter;
2932 ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
2933 const VALUE_FILTER& filter=VALUE_FILTER() )
2934 :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
2936 if ( _more && !_filter( _vector[ _index ]))
2943 virtual RETURN_VALUE next()
2945 if ( !_more ) return NULL;
2946 VECTOR_VALUE current = _vector[ _index ];
2948 while ( !_more && ++_index < _vector.size() )
2949 _more = _filter( _vector[ _index ]);
2950 return (RETURN_VALUE) current;
2955 ///////////////////////////////////////////////////////////////////////////////
2956 /// Return an iterator on nodes of the current mesh factory
2957 ///////////////////////////////////////////////////////////////////////////////
2959 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2961 // naturally always sorted by ID
2962 typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
2963 return SMDS_NodeIteratorPtr( new TIterator(myNodes));
2966 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
2968 // naturally always sorted by ID
2969 typedef ElemVecIterator
2970 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
2971 return SMDS_ElemIteratorPtr
2972 (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
2975 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
2977 if ( type == SMDSEntity_Node )
2979 typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
2980 return SMDS_ElemIteratorPtr( new TIterator(myNodes));
2982 // naturally always sorted by ID
2983 typedef ElemVecIterator
2984 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
2985 return SMDS_ElemIteratorPtr
2986 (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
2989 ///////////////////////////////////////////////////////////////////////////////
2990 /// Return an iterator on elements of the current mesh factory
2991 ///////////////////////////////////////////////////////////////////////////////
2992 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2994 // naturally always sorted by ID
2998 return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
3001 return SMDS_ElemIteratorPtr
3002 ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
3005 typedef ElemVecIterator
3006 < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3007 return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
3009 return SMDS_ElemIteratorPtr();
3012 ///////////////////////////////////////////////////////////////////////////////
3013 ///Return an iterator on edges of the current mesh.
3014 ///////////////////////////////////////////////////////////////////////////////
3016 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
3018 // naturally always sorted by ID
3019 typedef ElemVecIterator
3020 < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3021 return SMDS_EdgeIteratorPtr
3022 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
3025 ///////////////////////////////////////////////////////////////////////////////
3026 ///Return an iterator on faces of the current mesh.
3027 ///////////////////////////////////////////////////////////////////////////////
3029 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
3031 // naturally always sorted by ID
3032 typedef ElemVecIterator
3033 < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3034 return SMDS_FaceIteratorPtr
3035 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
3038 ///////////////////////////////////////////////////////////////////////////////
3039 ///Return an iterator on volumes of the current mesh.
3040 ///////////////////////////////////////////////////////////////////////////////
3042 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
3044 // naturally always sorted by ID
3045 typedef ElemVecIterator
3046 < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
3047 return SMDS_VolumeIteratorPtr
3048 (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
3051 ///////////////////////////////////////////////////////////////////////////////
3052 /// Do intersection of sets (more than 2)
3053 ///////////////////////////////////////////////////////////////////////////////
3054 static set<const SMDS_MeshElement*> * intersectionOfSets(
3055 set<const SMDS_MeshElement*> vs[], int numberOfSets)
3057 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
3058 set<const SMDS_MeshElement*>* rsetB;
3060 for(int i=0; i<numberOfSets-1; i++)
3062 rsetB=new set<const SMDS_MeshElement*>();
3064 rsetA->begin(), rsetA->end(),
3065 vs[i+1].begin(), vs[i+1].end(),
3066 inserter(*rsetB, rsetB->begin()));
3073 ///////////////////////////////////////////////////////////////////////////////
3074 /// Return the list of finite elements owning the given element: elements
3075 /// containing all the nodes of the given element, for instance faces and
3076 /// volumes containing a given edge.
3077 ///////////////////////////////////////////////////////////////////////////////
3078 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
3080 int numberOfSets=element->NbNodes();
3081 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
3083 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
3086 while(itNodes->more())
3088 const SMDS_MeshElement* node = itNodes->next();
3090 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
3091 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3093 //initSet[i]=set<const SMDS_MeshElement*>();
3096 const SMDS_MeshElement* elem = itFe->next();
3098 initSet[i].insert(elem);
3104 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
3105 // MESSAGE("nb elems " << i << " intersection " << retSet->size());
3110 ///////////////////////////////////////////////////////////////////////////////
3111 /// Return the list of nodes used only by the given elements
3112 ///////////////////////////////////////////////////////////////////////////////
3113 static set<const SMDS_MeshElement*> * getExclusiveNodes(set<const SMDS_MeshElement*>& elements)
3115 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
3116 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
3118 while(itElements!=elements.end())
3120 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
3123 while(itNodes->more())
3125 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
3126 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3127 set<const SMDS_MeshElement*> s;
3129 s.insert(itFe->next());
3130 if(s==elements) toReturn->insert(n);
3136 ///////////////////////////////////////////////////////////////////////////////
3137 ///Find the children of an element that are made of given nodes
3138 ///@param setOfChildren The set in which matching children will be inserted
3139 ///@param element The element were to search matching children
3140 ///@param nodes The nodes that the children must have to be selected
3141 ///////////////////////////////////////////////////////////////////////////////
3142 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
3143 const SMDS_MeshElement * element,
3144 set<const SMDS_MeshElement*>& nodes)
3146 switch(element->GetType())
3149 MESSAGE("Internal Error: This should not happen");
3151 case SMDSAbs_0DElement:
3158 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3161 const SMDS_MeshElement * e=itn->next();
3162 if(nodes.find(e)!=nodes.end())
3164 setOfChildren.insert(element);
3171 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3174 const SMDS_MeshElement * e=itn->next();
3175 if(nodes.find(e)!=nodes.end())
3177 setOfChildren.insert(element);
3181 if(hasConstructionEdges())
3183 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3185 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3188 case SMDSAbs_Volume:
3190 if(hasConstructionFaces())
3192 SMDS_ElemIteratorPtr ite=element->facesIterator();
3194 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3196 else if(hasConstructionEdges())
3198 SMDS_ElemIteratorPtr ite=element->edgesIterator();
3200 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3203 case SMDSAbs_NbElementTypes:
3204 case SMDSAbs_All: break;
3208 ///////////////////////////////////////////////////////////////////////////////
3209 ///@param elem The element to delete
3210 ///@param removenodes if true remaining nodes will be removed
3211 ///////////////////////////////////////////////////////////////////////////////
3212 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3213 const bool removenodes)
3215 list<const SMDS_MeshElement *> removedElems;
3216 list<const SMDS_MeshElement *> removedNodes;
3217 RemoveElement( elem, removedElems, removedNodes, removenodes );
3220 ///////////////////////////////////////////////////////////////////////////////
3221 ///@param elem The element to delete
3222 ///@param removedElems to be filled with all removed elements
3223 ///@param removedNodes to be filled with all removed nodes
3224 ///@param removenodes if true remaining nodes will be removed
3225 ///////////////////////////////////////////////////////////////////////////////
3226 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3227 list<const SMDS_MeshElement *>& removedElems,
3228 list<const SMDS_MeshElement *>& removedNodes,
3231 // get finite elements built on elem
3232 set<const SMDS_MeshElement*> * s1;
3233 if ( (elem->GetType() == SMDSAbs_0DElement)
3234 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3235 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3236 || (elem->GetType() == SMDSAbs_Volume) )
3238 s1 = new set<const SMDS_MeshElement*> ();
3242 s1 = getFinitElements(elem);
3244 // get exclusive nodes (which would become free afterwards)
3245 set<const SMDS_MeshElement*> * s2;
3246 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3248 // do not remove nodes except elem
3249 s2 = new set<const SMDS_MeshElement*> ();
3254 s2 = getExclusiveNodes(*s1);
3256 // form the set of finite and construction elements to remove
3257 set<const SMDS_MeshElement*> s3;
3258 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3259 while (it != s1->end())
3261 addChildrenWithNodes(s3, *it, *s2);
3265 if (elem->GetType() != SMDSAbs_Node)
3268 // remove finite and construction elements
3270 while (it != s3.end())
3272 // Remove element from <InverseElements> of its nodes
3273 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3276 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3277 n->RemoveInverseElement((*it));
3279 int IdToRemove = (*it)->GetID();
3280 int vtkid = (*it)->getVtkId();
3281 switch ((*it)->GetType())
3284 MYASSERT("Internal Error: This should not happen");
3286 case SMDSAbs_0DElement:
3287 if (IdToRemove >= 0)
3289 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3292 removedElems.push_back((*it));
3293 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3297 if (IdToRemove >= 0)
3299 myCells[IdToRemove] = 0;
3300 myInfo.RemoveEdge(*it);
3302 removedElems.push_back((*it));
3303 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3304 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3305 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3307 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3312 if (IdToRemove >= 0)
3314 myCells[IdToRemove] = 0;
3315 myInfo.RemoveFace(*it);
3317 removedElems.push_back((*it));
3318 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3319 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3320 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3322 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3326 case SMDSAbs_Volume:
3327 if (IdToRemove >= 0)
3329 myCells[IdToRemove] = 0;
3330 myInfo.RemoveVolume(*it);
3332 removedElems.push_back((*it));
3333 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3334 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3335 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3337 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3342 if (IdToRemove >= 0)
3344 myCells[IdToRemove] = 0;
3347 removedElems.push_back((*it));
3348 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3349 if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
3350 myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
3352 ((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
3357 case SMDSAbs_All: // avoid compilation warning
3358 case SMDSAbs_NbElementTypes: break;
3362 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3367 // remove exclusive (free) nodes
3371 while (it != s2->end())
3373 int IdToRemove = (*it)->GetID();
3374 if (IdToRemove >= 0)
3376 myNodes[IdToRemove] = 0;
3379 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3380 removedNodes.push_back((*it));
3381 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3383 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3384 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3397 ///////////////////////////////////////////////////////////////////////////////
3398 ///@param elem The element to delete
3399 ///////////////////////////////////////////////////////////////////////////////
3400 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3402 int elemId = elem->GetID();
3403 int vtkId = elem->getVtkId();
3404 //MESSAGE("RemoveFreeElement " << elemId);
3405 SMDSAbs_ElementType aType = elem->GetType();
3406 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3407 if (aType == SMDSAbs_Node) {
3408 //MESSAGE("Remove free node " << elemId);
3409 // only free node can be removed by this method
3410 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3411 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3412 if (!itFe->more()) { // free node
3413 myNodes[elemId] = 0;
3415 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3416 ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( -1, -1, -1 ); // avoid reuse
3417 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3418 myNodeIDFactory->ReleaseID(elemId, vtkId);
3421 if (hasConstructionEdges() || hasConstructionFaces())
3422 // this methods is only for meshes without descendants
3425 //MESSAGE("Remove free element " << elemId);
3426 // Remove element from <InverseElements> of its nodes
3427 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3428 while (itn->more()) {
3429 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3430 (const_cast<SMDS_MeshElement *>(itn->next()));
3431 n->RemoveInverseElement(elem);
3434 // in meshes without descendants elements are always free
3436 case SMDSAbs_0DElement:
3437 myCells[elemId] = 0;
3438 myInfo.remove(elem);
3443 myCells[elemId] = 0;
3444 myInfo.RemoveEdge(elem);
3445 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3448 myCells[elemId] = 0;
3449 myInfo.RemoveFace(elem);
3450 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3452 case SMDSAbs_Volume:
3453 myCells[elemId] = 0;
3454 myInfo.RemoveVolume(elem);
3455 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3458 myCells[elemId] = 0;
3459 myInfo.remove(elem);
3460 myBallPool->destroy(static_cast<SMDS_BallElement*>(todest));
3465 myElementIDFactory->ReleaseID(elemId, vtkId);
3467 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3468 // --- to do: keep vtkid in a list of reusable cells
3471 ((SMDS_MeshElement*) elem)->init( -1, -1, -1 ); // avoid reuse
3476 * Checks if the element is present in mesh.
3477 * Useful to determine dead pointers.
3479 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3481 // we should not imply on validity of *elem, so iterate on containers
3482 // of all types in the hope of finding <elem> somewhere there
3483 SMDS_NodeIteratorPtr itn = nodesIterator();
3485 if (elem == itn->next())
3487 SMDS_ElemIteratorPtr ite = elementsIterator();
3489 if (elem == ite->next())
3494 //=======================================================================
3495 //function : MaxNodeID
3497 //=======================================================================
3499 int SMDS_Mesh::MaxNodeID() const
3504 //=======================================================================
3505 //function : MinNodeID
3507 //=======================================================================
3509 int SMDS_Mesh::MinNodeID() const
3514 //=======================================================================
3515 //function : MaxElementID
3517 //=======================================================================
3519 int SMDS_Mesh::MaxElementID() const
3521 return myElementIDFactory->GetMaxID();
3524 //=======================================================================
3525 //function : MinElementID
3527 //=======================================================================
3529 int SMDS_Mesh::MinElementID() const
3531 return myElementIDFactory->GetMinID();
3534 //=======================================================================
3535 //function : Renumber
3536 //purpose : Renumber all nodes or elements.
3537 //=======================================================================
3539 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3541 MESSAGE("Renumber");
3545 SMDS_MeshNodeIDFactory * idFactory =
3546 isNodes ? myNodeIDFactory : myElementIDFactory;
3548 // get existing elements in the order of ID increasing
3549 map<int,SMDS_MeshElement*> elemMap;
3550 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3551 while ( idElemIt->more() ) {
3552 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3553 int id = elem->GetID();
3554 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3556 // release their ids
3557 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3559 // for ( ; elemIt != elemMap.end(); elemIt++ )
3561 // int id = (*elemIt).first;
3562 // idFactory->ReleaseID( id );
3566 elemIt = elemMap.begin();
3567 for ( ; elemIt != elemMap.end(); elemIt++ )
3569 idFactory->BindID( ID, (*elemIt).second );
3574 //=======================================================================
3575 //function : GetElementType
3576 //purpose : Return type of element or node with id
3577 //=======================================================================
3579 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3581 SMDS_MeshElement* elem = 0;
3583 elem = myElementIDFactory->MeshElement( id );
3585 elem = myNodeIDFactory->MeshElement( id );
3589 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3593 return elem->GetType();
3598 //********************************************************************
3599 //********************************************************************
3600 //******** *********
3601 //***** Methods for addition of quadratic elements ******
3602 //******** *********
3603 //********************************************************************
3604 //********************************************************************
3606 //=======================================================================
3607 //function : AddEdgeWithID
3609 //=======================================================================
3610 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3612 return SMDS_Mesh::AddEdgeWithID
3613 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3614 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3615 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3619 //=======================================================================
3620 //function : AddEdge
3622 //=======================================================================
3623 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3624 const SMDS_MeshNode* n2,
3625 const SMDS_MeshNode* n12)
3627 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3630 //=======================================================================
3631 //function : AddEdgeWithID
3633 //=======================================================================
3634 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3635 const SMDS_MeshNode * n2,
3636 const SMDS_MeshNode * n12,
3639 if ( !n1 || !n2 || !n12 ) return 0;
3641 // --- retrieve nodes ID
3642 myNodeIds.resize(3);
3643 myNodeIds[0] = n1->getVtkId();
3644 myNodeIds[1] = n2->getVtkId();
3645 myNodeIds[2] = n12->getVtkId();
3647 SMDS_MeshEdge * edge = 0;
3648 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3649 edgevtk->init(myNodeIds, this);
3650 if (!this->registerElement(ID,edgevtk))
3652 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3653 myEdgePool->destroy(edgevtk);
3657 adjustmyCellsCapacity(ID);
3659 myInfo.myNbQuadEdges++;
3661 // if (!registerElement(ID, edge)) {
3662 // RemoveElement(edge, false);
3670 //=======================================================================
3671 //function : AddFace
3673 //=======================================================================
3674 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3675 const SMDS_MeshNode * n2,
3676 const SMDS_MeshNode * n3,
3677 const SMDS_MeshNode * n12,
3678 const SMDS_MeshNode * n23,
3679 const SMDS_MeshNode * n31)
3681 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3682 myElementIDFactory->GetFreeID());
3685 //=======================================================================
3686 //function : AddFaceWithID
3688 //=======================================================================
3689 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3690 int n12,int n23,int n31, int ID)
3692 return SMDS_Mesh::AddFaceWithID
3693 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3694 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3695 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3696 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3697 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3698 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3702 //=======================================================================
3703 //function : AddFaceWithID
3705 //=======================================================================
3706 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3707 const SMDS_MeshNode * n2,
3708 const SMDS_MeshNode * n3,
3709 const SMDS_MeshNode * n12,
3710 const SMDS_MeshNode * n23,
3711 const SMDS_MeshNode * n31,
3714 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3715 if(hasConstructionEdges()) {
3716 // creation quadratic edges - not implemented
3721 // --- retrieve nodes ID
3722 myNodeIds.resize(6);
3723 myNodeIds[0] = n1->getVtkId();
3724 myNodeIds[1] = n2->getVtkId();
3725 myNodeIds[2] = n3->getVtkId();
3726 myNodeIds[3] = n12->getVtkId();
3727 myNodeIds[4] = n23->getVtkId();
3728 myNodeIds[5] = n31->getVtkId();
3730 SMDS_MeshFace * face = 0;
3731 SMDS_VtkFace *facevtk = myFacePool->getNew();
3732 facevtk->init(myNodeIds, this);
3733 if (!this->registerElement(ID,facevtk))
3735 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3736 myFacePool->destroy(facevtk);
3740 adjustmyCellsCapacity(ID);
3742 myInfo.myNbQuadTriangles++;
3744 // if (!registerElement(ID, face)) {
3745 // RemoveElement(face, false);
3753 //=======================================================================
3754 //function : AddFace
3756 //=======================================================================
3757 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3758 const SMDS_MeshNode * n2,
3759 const SMDS_MeshNode * n3,
3760 const SMDS_MeshNode * n12,
3761 const SMDS_MeshNode * n23,
3762 const SMDS_MeshNode * n31,
3763 const SMDS_MeshNode * nCenter)
3765 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
3766 myElementIDFactory->GetFreeID());
3769 //=======================================================================
3770 //function : AddFaceWithID
3772 //=======================================================================
3773 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3774 int n12,int n23,int n31, int nCenter, int ID)
3776 return SMDS_Mesh::AddFaceWithID
3777 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3778 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3779 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3780 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3781 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3782 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3783 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3787 //=======================================================================
3788 //function : AddFaceWithID
3790 //=======================================================================
3791 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3792 const SMDS_MeshNode * n2,
3793 const SMDS_MeshNode * n3,
3794 const SMDS_MeshNode * n12,
3795 const SMDS_MeshNode * n23,
3796 const SMDS_MeshNode * n31,
3797 const SMDS_MeshNode * nCenter,
3800 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
3801 if(hasConstructionEdges()) {
3802 // creation quadratic edges - not implemented
3807 // --- retrieve nodes ID
3808 myNodeIds.resize(7);
3809 myNodeIds[0] = n1->getVtkId();
3810 myNodeIds[1] = n2->getVtkId();
3811 myNodeIds[2] = n3->getVtkId();
3812 myNodeIds[3] = n12->getVtkId();
3813 myNodeIds[4] = n23->getVtkId();
3814 myNodeIds[5] = n31->getVtkId();
3815 myNodeIds[6] = nCenter->getVtkId();
3817 SMDS_MeshFace * face = 0;
3818 SMDS_VtkFace *facevtk = myFacePool->getNew();
3819 facevtk->init(myNodeIds, this);
3820 if (!this->registerElement(ID,facevtk))
3822 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3823 myFacePool->destroy(facevtk);
3827 adjustmyCellsCapacity(ID);
3829 myInfo.myNbBiQuadTriangles++;
3831 // if (!registerElement(ID, face)) {
3832 // RemoveElement(face, false);
3840 //=======================================================================
3841 //function : AddFace
3843 //=======================================================================
3844 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3845 const SMDS_MeshNode * n2,
3846 const SMDS_MeshNode * n3,
3847 const SMDS_MeshNode * n4,
3848 const SMDS_MeshNode * n12,
3849 const SMDS_MeshNode * n23,
3850 const SMDS_MeshNode * n34,
3851 const SMDS_MeshNode * n41)
3853 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3854 myElementIDFactory->GetFreeID());
3857 //=======================================================================
3858 //function : AddFaceWithID
3860 //=======================================================================
3861 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3862 int n12,int n23,int n34,int n41, int ID)
3864 return SMDS_Mesh::AddFaceWithID
3865 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3866 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3867 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3868 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3869 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3870 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3871 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3872 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3876 //=======================================================================
3877 //function : AddFaceWithID
3879 //=======================================================================
3880 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3881 const SMDS_MeshNode * n2,
3882 const SMDS_MeshNode * n3,
3883 const SMDS_MeshNode * n4,
3884 const SMDS_MeshNode * n12,
3885 const SMDS_MeshNode * n23,
3886 const SMDS_MeshNode * n34,
3887 const SMDS_MeshNode * n41,
3890 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3891 if(hasConstructionEdges()) {
3892 // creation quadratic edges - not implemented
3897 // --- retrieve nodes ID
3898 myNodeIds.resize(8);
3899 myNodeIds[0] = n1->getVtkId();
3900 myNodeIds[1] = n2->getVtkId();
3901 myNodeIds[2] = n3->getVtkId();
3902 myNodeIds[3] = n4->getVtkId();
3903 myNodeIds[4] = n12->getVtkId();
3904 myNodeIds[5] = n23->getVtkId();
3905 myNodeIds[6] = n34->getVtkId();
3906 myNodeIds[7] = n41->getVtkId();
3908 SMDS_MeshFace * face = 0;
3909 SMDS_VtkFace *facevtk = myFacePool->getNew();
3910 facevtk->init(myNodeIds, this);
3911 if (!this->registerElement(ID,facevtk))
3913 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3914 myFacePool->destroy(facevtk);
3918 adjustmyCellsCapacity(ID);
3920 myInfo.myNbQuadQuadrangles++;
3922 // if (!registerElement(ID, face)) {
3923 // RemoveElement(face, false);
3930 //=======================================================================
3931 //function : AddFace
3933 //=======================================================================
3934 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3935 const SMDS_MeshNode * n2,
3936 const SMDS_MeshNode * n3,
3937 const SMDS_MeshNode * n4,
3938 const SMDS_MeshNode * n12,
3939 const SMDS_MeshNode * n23,
3940 const SMDS_MeshNode * n34,
3941 const SMDS_MeshNode * n41,
3942 const SMDS_MeshNode * nCenter)
3944 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
3945 myElementIDFactory->GetFreeID());
3948 //=======================================================================
3949 //function : AddFaceWithID
3951 //=======================================================================
3952 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3953 int n12,int n23,int n34,int n41, int nCenter, int ID)
3955 return SMDS_Mesh::AddFaceWithID
3956 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3957 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3958 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3959 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3960 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3961 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3962 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3963 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3964 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3968 //=======================================================================
3969 //function : AddFaceWithID
3971 //=======================================================================
3972 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3973 const SMDS_MeshNode * n2,
3974 const SMDS_MeshNode * n3,
3975 const SMDS_MeshNode * n4,
3976 const SMDS_MeshNode * n12,
3977 const SMDS_MeshNode * n23,
3978 const SMDS_MeshNode * n34,
3979 const SMDS_MeshNode * n41,
3980 const SMDS_MeshNode * nCenter,
3983 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
3984 if(hasConstructionEdges()) {
3985 // creation quadratic edges - not implemented
3990 // --- retrieve nodes ID
3991 myNodeIds.resize(9);
3992 myNodeIds[0] = n1->getVtkId();
3993 myNodeIds[1] = n2->getVtkId();
3994 myNodeIds[2] = n3->getVtkId();
3995 myNodeIds[3] = n4->getVtkId();
3996 myNodeIds[4] = n12->getVtkId();
3997 myNodeIds[5] = n23->getVtkId();
3998 myNodeIds[6] = n34->getVtkId();
3999 myNodeIds[7] = n41->getVtkId();
4000 myNodeIds[8] = nCenter->getVtkId();
4002 SMDS_MeshFace * face = 0;
4003 SMDS_VtkFace *facevtk = myFacePool->getNew();
4004 facevtk->init(myNodeIds, this);
4005 if (!this->registerElement(ID,facevtk))
4007 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
4008 myFacePool->destroy(facevtk);
4012 adjustmyCellsCapacity(ID);
4014 myInfo.myNbBiQuadQuadrangles++;
4016 // if (!registerElement(ID, face)) {
4017 // RemoveElement(face, false);
4025 //=======================================================================
4026 //function : AddVolume
4028 //=======================================================================
4029 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4030 const SMDS_MeshNode * n2,
4031 const SMDS_MeshNode * n3,
4032 const SMDS_MeshNode * n4,
4033 const SMDS_MeshNode * n12,
4034 const SMDS_MeshNode * n23,
4035 const SMDS_MeshNode * n31,
4036 const SMDS_MeshNode * n14,
4037 const SMDS_MeshNode * n24,
4038 const SMDS_MeshNode * n34)
4040 int ID = myElementIDFactory->GetFreeID();
4041 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
4042 n31, n14, n24, n34, ID);
4043 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4047 //=======================================================================
4048 //function : AddVolumeWithID
4050 //=======================================================================
4051 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4052 int n12,int n23,int n31,
4053 int n14,int n24,int n34, int ID)
4055 return SMDS_Mesh::AddVolumeWithID
4056 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4057 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4058 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4059 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4060 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4061 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4062 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4063 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4064 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
4065 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4069 //=======================================================================
4070 //function : AddVolumeWithID
4071 //purpose : 2d order tetrahedron of 10 nodes
4072 //=======================================================================
4073 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4074 const SMDS_MeshNode * n2,
4075 const SMDS_MeshNode * n3,
4076 const SMDS_MeshNode * n4,
4077 const SMDS_MeshNode * n12,
4078 const SMDS_MeshNode * n23,
4079 const SMDS_MeshNode * n31,
4080 const SMDS_MeshNode * n14,
4081 const SMDS_MeshNode * n24,
4082 const SMDS_MeshNode * n34,
4085 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
4087 if(hasConstructionFaces()) {
4088 // creation quadratic faces - not implemented
4091 // --- retrieve nodes ID
4092 myNodeIds.resize(10);
4093 myNodeIds[0] = n1->getVtkId();
4094 myNodeIds[1] = n3->getVtkId();
4095 myNodeIds[2] = n2->getVtkId();
4096 myNodeIds[3] = n4->getVtkId();
4098 myNodeIds[4] = n31->getVtkId();
4099 myNodeIds[5] = n23->getVtkId();
4100 myNodeIds[6] = n12->getVtkId();
4102 myNodeIds[7] = n14->getVtkId();
4103 myNodeIds[8] = n34->getVtkId();
4104 myNodeIds[9] = n24->getVtkId();
4106 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4107 volvtk->init(myNodeIds, this);
4108 if (!this->registerElement(ID,volvtk))
4110 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4111 myVolumePool->destroy(volvtk);
4114 adjustmyCellsCapacity(ID);
4115 myCells[ID] = volvtk;
4116 myInfo.myNbQuadTetras++;
4118 // if (!registerElement(ID, volvtk)) {
4119 // RemoveElement(volvtk, false);
4126 //=======================================================================
4127 //function : AddVolume
4129 //=======================================================================
4130 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4131 const SMDS_MeshNode * n2,
4132 const SMDS_MeshNode * n3,
4133 const SMDS_MeshNode * n4,
4134 const SMDS_MeshNode * n5,
4135 const SMDS_MeshNode * n12,
4136 const SMDS_MeshNode * n23,
4137 const SMDS_MeshNode * n34,
4138 const SMDS_MeshNode * n41,
4139 const SMDS_MeshNode * n15,
4140 const SMDS_MeshNode * n25,
4141 const SMDS_MeshNode * n35,
4142 const SMDS_MeshNode * n45)
4144 int ID = myElementIDFactory->GetFreeID();
4145 SMDS_MeshVolume * v =
4146 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
4147 n15, n25, n35, n45, ID);
4148 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4152 //=======================================================================
4153 //function : AddVolumeWithID
4155 //=======================================================================
4156 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
4157 int n12,int n23,int n34,int n41,
4158 int n15,int n25,int n35,int n45, int ID)
4160 return SMDS_Mesh::AddVolumeWithID
4161 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4162 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4163 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4164 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4165 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4166 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4167 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4168 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4169 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4170 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4171 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4172 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
4173 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4177 //=======================================================================
4178 //function : AddVolumeWithID
4179 //purpose : 2d order pyramid of 13 nodes
4180 //=======================================================================
4181 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4182 const SMDS_MeshNode * n2,
4183 const SMDS_MeshNode * n3,
4184 const SMDS_MeshNode * n4,
4185 const SMDS_MeshNode * n5,
4186 const SMDS_MeshNode * n12,
4187 const SMDS_MeshNode * n23,
4188 const SMDS_MeshNode * n34,
4189 const SMDS_MeshNode * n41,
4190 const SMDS_MeshNode * n15,
4191 const SMDS_MeshNode * n25,
4192 const SMDS_MeshNode * n35,
4193 const SMDS_MeshNode * n45,
4196 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
4197 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
4199 if(hasConstructionFaces()) {
4200 // creation quadratic faces - not implemented
4203 // --- retrieve nodes ID
4204 myNodeIds.resize(13);
4205 myNodeIds[0] = n1->getVtkId();
4206 myNodeIds[1] = n4->getVtkId();
4207 myNodeIds[2] = n3->getVtkId();
4208 myNodeIds[3] = n2->getVtkId();
4209 myNodeIds[4] = n5->getVtkId();
4211 myNodeIds[5] = n41->getVtkId();
4212 myNodeIds[6] = n34->getVtkId();
4213 myNodeIds[7] = n23->getVtkId();
4214 myNodeIds[8] = n12->getVtkId();
4216 myNodeIds[9] = n15->getVtkId();
4217 myNodeIds[10] = n45->getVtkId();
4218 myNodeIds[11] = n35->getVtkId();
4219 myNodeIds[12] = n25->getVtkId();
4221 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4222 volvtk->init(myNodeIds, this);
4223 if (!this->registerElement(ID,volvtk))
4225 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4226 myVolumePool->destroy(volvtk);
4229 adjustmyCellsCapacity(ID);
4230 myCells[ID] = volvtk;
4231 myInfo.myNbQuadPyramids++;
4233 // if (!registerElement(ID, volvtk)) {
4234 // RemoveElement(volvtk, false);
4241 //=======================================================================
4242 //function : AddVolume
4244 //=======================================================================
4245 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4246 const SMDS_MeshNode * n2,
4247 const SMDS_MeshNode * n3,
4248 const SMDS_MeshNode * n4,
4249 const SMDS_MeshNode * n5,
4250 const SMDS_MeshNode * n6,
4251 const SMDS_MeshNode * n12,
4252 const SMDS_MeshNode * n23,
4253 const SMDS_MeshNode * n31,
4254 const SMDS_MeshNode * n45,
4255 const SMDS_MeshNode * n56,
4256 const SMDS_MeshNode * n64,
4257 const SMDS_MeshNode * n14,
4258 const SMDS_MeshNode * n25,
4259 const SMDS_MeshNode * n36)
4261 int ID = myElementIDFactory->GetFreeID();
4262 SMDS_MeshVolume * v =
4263 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4264 n45, n56, n64, n14, n25, n36, ID);
4265 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4269 //=======================================================================
4270 //function : AddVolumeWithID
4272 //=======================================================================
4273 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4274 int n4, int n5, int n6,
4275 int n12,int n23,int n31,
4276 int n45,int n56,int n64,
4277 int n14,int n25,int n36, int ID)
4279 return SMDS_Mesh::AddVolumeWithID
4280 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4281 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4282 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4283 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4284 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4288 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4289 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4290 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4291 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4292 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4293 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4294 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4298 //=======================================================================
4299 //function : AddVolumeWithID
4300 //purpose : 2d order Pentahedron with 15 nodes
4301 //=======================================================================
4302 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4303 const SMDS_MeshNode * n2,
4304 const SMDS_MeshNode * n3,
4305 const SMDS_MeshNode * n4,
4306 const SMDS_MeshNode * n5,
4307 const SMDS_MeshNode * n6,
4308 const SMDS_MeshNode * n12,
4309 const SMDS_MeshNode * n23,
4310 const SMDS_MeshNode * n31,
4311 const SMDS_MeshNode * n45,
4312 const SMDS_MeshNode * n56,
4313 const SMDS_MeshNode * n64,
4314 const SMDS_MeshNode * n14,
4315 const SMDS_MeshNode * n25,
4316 const SMDS_MeshNode * n36,
4319 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4320 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
4322 if(hasConstructionFaces()) {
4323 // creation quadratic faces - not implemented
4326 // --- retrieve nodes ID
4327 myNodeIds.resize(15);
4328 myNodeIds[0] = n1->getVtkId();
4329 myNodeIds[1] = n2->getVtkId();
4330 myNodeIds[2] = n3->getVtkId();
4332 myNodeIds[3] = n4->getVtkId();
4333 myNodeIds[4] = n5->getVtkId();
4334 myNodeIds[5] = n6->getVtkId();
4336 myNodeIds[6] = n12->getVtkId();
4337 myNodeIds[7] = n23->getVtkId();
4338 myNodeIds[8] = n31->getVtkId();
4340 myNodeIds[9] = n45->getVtkId();
4341 myNodeIds[10] = n56->getVtkId();
4342 myNodeIds[11] = n64->getVtkId();
4344 myNodeIds[12] = n14->getVtkId();
4345 myNodeIds[13] = n25->getVtkId();
4346 myNodeIds[14] = n36->getVtkId();
4348 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4349 volvtk->init(myNodeIds, this);
4350 if (!this->registerElement(ID,volvtk))
4352 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4353 myVolumePool->destroy(volvtk);
4356 adjustmyCellsCapacity(ID);
4357 myCells[ID] = volvtk;
4358 myInfo.myNbQuadPrisms++;
4360 // if (!registerElement(ID, volvtk)) {
4361 // RemoveElement(volvtk, false);
4368 //=======================================================================
4369 //function : AddVolume
4371 //=======================================================================
4372 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4373 const SMDS_MeshNode * n2,
4374 const SMDS_MeshNode * n3,
4375 const SMDS_MeshNode * n4,
4376 const SMDS_MeshNode * n5,
4377 const SMDS_MeshNode * n6,
4378 const SMDS_MeshNode * n7,
4379 const SMDS_MeshNode * n8,
4380 const SMDS_MeshNode * n12,
4381 const SMDS_MeshNode * n23,
4382 const SMDS_MeshNode * n34,
4383 const SMDS_MeshNode * n41,
4384 const SMDS_MeshNode * n56,
4385 const SMDS_MeshNode * n67,
4386 const SMDS_MeshNode * n78,
4387 const SMDS_MeshNode * n85,
4388 const SMDS_MeshNode * n15,
4389 const SMDS_MeshNode * n26,
4390 const SMDS_MeshNode * n37,
4391 const SMDS_MeshNode * n48)
4393 int ID = myElementIDFactory->GetFreeID();
4394 SMDS_MeshVolume * v =
4395 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4396 n56, n67, n78, n85, n15, n26, n37, n48, ID);
4397 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4401 //=======================================================================
4402 //function : AddVolumeWithID
4404 //=======================================================================
4405 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4406 int n5, int n6, int n7, int n8,
4407 int n12,int n23,int n34,int n41,
4408 int n56,int n67,int n78,int n85,
4409 int n15,int n26,int n37,int n48, int ID)
4411 return SMDS_Mesh::AddVolumeWithID
4412 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4413 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4414 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4415 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4416 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4417 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4418 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4419 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4420 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4421 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4422 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4423 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4424 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4425 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4426 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4427 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4428 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4429 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4430 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4431 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4435 //=======================================================================
4436 //function : AddVolumeWithID
4437 //purpose : 2d order Hexahedrons with 20 nodes
4438 //=======================================================================
4439 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4440 const SMDS_MeshNode * n2,
4441 const SMDS_MeshNode * n3,
4442 const SMDS_MeshNode * n4,
4443 const SMDS_MeshNode * n5,
4444 const SMDS_MeshNode * n6,
4445 const SMDS_MeshNode * n7,
4446 const SMDS_MeshNode * n8,
4447 const SMDS_MeshNode * n12,
4448 const SMDS_MeshNode * n23,
4449 const SMDS_MeshNode * n34,
4450 const SMDS_MeshNode * n41,
4451 const SMDS_MeshNode * n56,
4452 const SMDS_MeshNode * n67,
4453 const SMDS_MeshNode * n78,
4454 const SMDS_MeshNode * n85,
4455 const SMDS_MeshNode * n15,
4456 const SMDS_MeshNode * n26,
4457 const SMDS_MeshNode * n37,
4458 const SMDS_MeshNode * n48,
4461 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4462 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4464 if(hasConstructionFaces()) {
4466 // creation quadratic faces - not implemented
4468 // --- retrieve nodes ID
4469 myNodeIds.resize(20);
4470 myNodeIds[0] = n1->getVtkId();
4471 myNodeIds[1] = n4->getVtkId();
4472 myNodeIds[2] = n3->getVtkId();
4473 myNodeIds[3] = n2->getVtkId();
4475 myNodeIds[4] = n5->getVtkId();
4476 myNodeIds[5] = n8->getVtkId();
4477 myNodeIds[6] = n7->getVtkId();
4478 myNodeIds[7] = n6->getVtkId();
4480 myNodeIds[8] = n41->getVtkId();
4481 myNodeIds[9] = n34->getVtkId();
4482 myNodeIds[10] = n23->getVtkId();
4483 myNodeIds[11] = n12->getVtkId();
4485 myNodeIds[12] = n85->getVtkId();
4486 myNodeIds[13] = n78->getVtkId();
4487 myNodeIds[14] = n67->getVtkId();
4488 myNodeIds[15] = n56->getVtkId();
4490 myNodeIds[16] = n15->getVtkId();
4491 myNodeIds[17] = n48->getVtkId();
4492 myNodeIds[18] = n37->getVtkId();
4493 myNodeIds[19] = n26->getVtkId();
4495 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4496 volvtk->init(myNodeIds, this);
4497 if (!this->registerElement(ID,volvtk))
4499 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4500 myVolumePool->destroy(volvtk);
4503 adjustmyCellsCapacity(ID);
4504 myCells[ID] = volvtk;
4505 myInfo.myNbQuadHexas++;
4507 // if (!registerElement(ID, volvtk)) {
4508 // RemoveElement(volvtk, false);
4514 //=======================================================================
4515 //function : AddVolume
4517 //=======================================================================
4518 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4519 const SMDS_MeshNode * n2,
4520 const SMDS_MeshNode * n3,
4521 const SMDS_MeshNode * n4,
4522 const SMDS_MeshNode * n5,
4523 const SMDS_MeshNode * n6,
4524 const SMDS_MeshNode * n7,
4525 const SMDS_MeshNode * n8,
4526 const SMDS_MeshNode * n12,
4527 const SMDS_MeshNode * n23,
4528 const SMDS_MeshNode * n34,
4529 const SMDS_MeshNode * n41,
4530 const SMDS_MeshNode * n56,
4531 const SMDS_MeshNode * n67,
4532 const SMDS_MeshNode * n78,
4533 const SMDS_MeshNode * n85,
4534 const SMDS_MeshNode * n15,
4535 const SMDS_MeshNode * n26,
4536 const SMDS_MeshNode * n37,
4537 const SMDS_MeshNode * n48,
4538 const SMDS_MeshNode * n1234,
4539 const SMDS_MeshNode * n1256,
4540 const SMDS_MeshNode * n2367,
4541 const SMDS_MeshNode * n3478,
4542 const SMDS_MeshNode * n1458,
4543 const SMDS_MeshNode * n5678,
4544 const SMDS_MeshNode * nCenter)
4546 int ID = myElementIDFactory->GetFreeID();
4547 SMDS_MeshVolume * v =
4548 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4549 n56, n67, n78, n85, n15, n26, n37, n48,
4550 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
4552 if(v==NULL) myElementIDFactory->ReleaseID(ID);
4556 //=======================================================================
4557 //function : AddVolumeWithID
4559 //=======================================================================
4560 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4561 int n5, int n6, int n7, int n8,
4562 int n12,int n23,int n34,int n41,
4563 int n56,int n67,int n78,int n85,
4564 int n15,int n26,int n37,int n48,
4565 int n1234,int n1256,int n2367,int n3478,
4566 int n1458,int n5678,int nCenter, int ID)
4568 return SMDS_Mesh::AddVolumeWithID
4569 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4570 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4571 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4572 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4573 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4574 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4575 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4576 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4577 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4578 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4579 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4580 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4581 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4582 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4583 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4584 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4585 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4586 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4587 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4588 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4589 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
4590 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
4591 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
4592 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
4593 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
4594 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
4595 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
4599 //=======================================================================
4600 //function : AddVolumeWithID
4601 //purpose : 2d order Hexahedrons with 20 nodes
4602 //=======================================================================
4603 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4604 const SMDS_MeshNode * n2,
4605 const SMDS_MeshNode * n3,
4606 const SMDS_MeshNode * n4,
4607 const SMDS_MeshNode * n5,
4608 const SMDS_MeshNode * n6,
4609 const SMDS_MeshNode * n7,
4610 const SMDS_MeshNode * n8,
4611 const SMDS_MeshNode * n12,
4612 const SMDS_MeshNode * n23,
4613 const SMDS_MeshNode * n34,
4614 const SMDS_MeshNode * n41,
4615 const SMDS_MeshNode * n56,
4616 const SMDS_MeshNode * n67,
4617 const SMDS_MeshNode * n78,
4618 const SMDS_MeshNode * n85,
4619 const SMDS_MeshNode * n15,
4620 const SMDS_MeshNode * n26,
4621 const SMDS_MeshNode * n37,
4622 const SMDS_MeshNode * n48,
4623 const SMDS_MeshNode * n1234,
4624 const SMDS_MeshNode * n1256,
4625 const SMDS_MeshNode * n2367,
4626 const SMDS_MeshNode * n3478,
4627 const SMDS_MeshNode * n1458,
4628 const SMDS_MeshNode * n5678,
4629 const SMDS_MeshNode * nCenter,
4632 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4633 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
4634 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
4636 if(hasConstructionFaces()) {
4638 // creation quadratic faces - not implemented
4640 // --- retrieve nodes ID
4641 myNodeIds.resize(27);
4642 myNodeIds[0] = n1->getVtkId();
4643 myNodeIds[1] = n4->getVtkId();
4644 myNodeIds[2] = n3->getVtkId();
4645 myNodeIds[3] = n2->getVtkId();
4647 myNodeIds[4] = n5->getVtkId();
4648 myNodeIds[5] = n8->getVtkId();
4649 myNodeIds[6] = n7->getVtkId();
4650 myNodeIds[7] = n6->getVtkId();
4652 myNodeIds[8] = n41->getVtkId();
4653 myNodeIds[9] = n34->getVtkId();
4654 myNodeIds[10] = n23->getVtkId();
4655 myNodeIds[11] = n12->getVtkId();
4657 myNodeIds[12] = n85->getVtkId();
4658 myNodeIds[13] = n78->getVtkId();
4659 myNodeIds[14] = n67->getVtkId();
4660 myNodeIds[15] = n56->getVtkId();
4662 myNodeIds[16] = n15->getVtkId();
4663 myNodeIds[17] = n48->getVtkId();
4664 myNodeIds[18] = n37->getVtkId();
4665 myNodeIds[19] = n26->getVtkId();
4667 myNodeIds[20] = n1256->getVtkId();
4668 myNodeIds[21] = n3478->getVtkId();
4669 myNodeIds[22] = n1458->getVtkId();
4670 myNodeIds[23] = n2367->getVtkId();
4671 myNodeIds[24] = n1234->getVtkId();
4672 myNodeIds[25] = n5678->getVtkId();
4673 myNodeIds[26] = nCenter->getVtkId();
4675 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4676 volvtk->init(myNodeIds, this);
4677 if (!this->registerElement(ID,volvtk))
4679 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4680 myVolumePool->destroy(volvtk);
4683 adjustmyCellsCapacity(ID);
4684 myCells[ID] = volvtk;
4685 myInfo.myNbTriQuadHexas++;
4691 void SMDS_Mesh::updateNodeMinMax()
4694 if (myNodes.size() == 0)
4699 while ( !myNodes[myNodeMin] && myNodeMin < (int)myNodes.size() )
4701 myNodeMax=myNodes.size()-1;
4702 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4706 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4708 // int val = myCellIdSmdsToVtk.size();
4709 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4710 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4711 int val = myNodes.size();
4712 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4713 myNodes.resize(val +nbNodes, 0);
4716 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4718 int val = myCellIdVtkToSmds.size();
4719 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4720 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4721 val = myCells.size();
4722 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4723 myNodes.resize(val +nbCells, 0);
4726 void SMDS_Mesh::adjustStructure()
4728 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4731 void SMDS_Mesh::dumpGrid(string ficdump)
4733 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4734 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4735 // aWriter->SetFileName(ficdump.c_str());
4736 // aWriter->SetInput(myGrid);
4737 // if(myGrid->GetNumberOfCells())
4739 // aWriter->Write();
4741 // aWriter->Delete();
4742 ficdump = ficdump + "_connectivity";
4743 ofstream ficcon(ficdump.c_str(), ios::out);
4744 int nbPoints = myGrid->GetNumberOfPoints();
4745 ficcon << "-------------------------------- points " << nbPoints << endl;
4746 for (int i=0; i<nbPoints; i++)
4748 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4750 int nbCells = myGrid->GetNumberOfCells();
4751 ficcon << "-------------------------------- cells " << nbCells << endl;
4752 for (int i=0; i<nbCells; i++)
4754 // MESSAGE(i << " " << myGrid->GetCell(i));
4755 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4756 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4757 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4758 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4759 for (int j=0; j<nbptcell; j++)
4761 ficcon << " " << listid->GetId(j);
4765 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4766 vtkCellLinks *links = myGrid->GetCellLinks();
4767 for (int i=0; i<nbPoints; i++)
4769 int ncells = links->GetNcells(i);
4770 vtkIdType *cells = links->GetCells(i);
4771 ficcon << i << " - " << ncells << " -";
4772 for (int j=0; j<ncells; j++)
4774 ficcon << " " << cells[j];
4782 void SMDS_Mesh::compactMesh()
4784 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4787 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4789 if (vtkid >= 0 && vtkid < (int)myCellIdVtkToSmds.size())
4790 return myCellIdVtkToSmds[vtkid];
4791 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4794 void SMDS_Mesh::updateBoundingBox()
4799 vtkPoints *points = myGrid->GetPoints();
4800 int myNodesSize = this->myNodes.size();
4801 for (int i = 0; i < myNodesSize; i++)
4803 if (SMDS_MeshNode *n = myNodes[i])
4806 points->GetPoint(n->myVtkID, coords);
4807 if (coords[0] < xmin) xmin = coords[0];
4808 else if (coords[0] > xmax) xmax = coords[0];
4809 if (coords[1] < ymin) ymin = coords[1];
4810 else if (coords[1] > ymax) ymax = coords[1];
4811 if (coords[2] < zmin) zmin = coords[2];
4812 else if (coords[2] > zmax) zmax = coords[2];
4817 double SMDS_Mesh::getMaxDim()
4819 double dmax = 1.e-3;
4820 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4821 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4822 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4823 MESSAGE("getMaxDim " << dmax);
4827 //! modification that needs compact structure and redraw
4828 void SMDS_Mesh::Modified()
4830 if (this->myModified)
4832 this->myModifTime++;
4833 MESSAGE("modified");
4838 //! get last modification timeStamp
4839 unsigned long SMDS_Mesh::GetMTime() const
4841 return this->myModifTime;
4844 bool SMDS_Mesh::isCompacted()
4846 if (this->myModifTime > this->myCompactTime)
4848 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4849 this->myCompactTime = this->myModifTime;