1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "utilities.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_VolumeOfNodes.hxx"
32 #include "SMDS_VolumeOfFaces.hxx"
33 #include "SMDS_FaceOfNodes.hxx"
34 #include "SMDS_FaceOfEdges.hxx"
35 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
36 #include "SMDS_PolygonalFaceOfNodes.hxx"
37 #include "SMDS_QuadraticEdge.hxx"
38 #include "SMDS_QuadraticFaceOfNodes.hxx"
39 #include "SMDS_QuadraticVolumeOfNodes.hxx"
40 #include "SMDS_SpacePosition.hxx"
41 #include "SMDS_UnstructuredGrid.hxx"
43 #include <vtkUnstructuredGrid.h>
44 #include <vtkUnstructuredGridWriter.h>
45 #include <vtkUnsignedCharArray.h>
47 #include <vtkCellLinks.h>
48 #include <vtkIdList.h>
57 #include <sys/sysinfo.h>
60 // number of added entities to check memory after
61 #define CHECKMEMORY_INTERVAL 1000
63 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
64 int SMDS_Mesh::chunkSize = 1024;
67 //================================================================================
69 * \brief Raise an exception if free memory (ram+swap) too low
70 * \param doNotRaise - if true, suppres exception, just return free memory size
71 * \retval int - amount of available memory in MB or negative number in failure case
73 //================================================================================
75 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
79 int err = sysinfo( &si );
83 static int limit = -1;
85 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
87 limit = WEXITSTATUS(status);
92 limit = int( limit * 1.5 );
94 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
98 const unsigned long Mbyte = 1024 * 1024;
99 // compute separately to avoid overflow
101 ( si.freeram * si.mem_unit ) / Mbyte +
102 ( si.freeswap * si.mem_unit ) / Mbyte;
104 if ( freeMb > limit )
105 return freeMb - limit;
110 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
112 throw std::bad_alloc();
118 ///////////////////////////////////////////////////////////////////////////////
119 /// Create a new mesh object
120 ///////////////////////////////////////////////////////////////////////////////
121 SMDS_Mesh::SMDS_Mesh()
123 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
124 myElementIDFactory(new SMDS_MeshElementIDFactory()),
125 myHasConstructionEdges(false), myHasConstructionFaces(false),
126 myHasInverseElements(true),
127 myNodeMin(0), myNodeMax(0),
128 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),
129 myModified(false), myModifTime(0), myCompactTime(0),
130 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
132 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
133 MESSAGE("myMeshId=" << myMeshId);
134 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
135 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
136 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
137 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
138 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
139 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
140 myNodeIDFactory->SetMesh(this);
141 myElementIDFactory->SetMesh(this);
142 _meshList.push_back(this);
143 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
144 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
145 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
146 myVolumePool = new ObjectPool<SMDS_VtkVolume>(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 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
158 // using double type for storing coordinates of nodes instead float.
159 points->SetDataType(VTK_DOUBLE);
160 points->SetNumberOfPoints(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 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
174 myElementIDFactory(parent->myElementIDFactory),
175 myHasConstructionEdges(false), myHasConstructionFaces(false),
176 myHasInverseElements(true),
177 myNodePool(parent->myNodePool),
178 myEdgePool(parent->myEdgePool),
179 myFacePool(parent->myFacePool),
180 myVolumePool(parent->myVolumePool)
184 ///////////////////////////////////////////////////////////////////////////////
185 ///Create a submesh and add it to the current mesh
186 ///////////////////////////////////////////////////////////////////////////////
188 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
190 SMDS_Mesh *submesh = new SMDS_Mesh(this);
191 myChildren.insert(myChildren.end(), submesh);
195 ///////////////////////////////////////////////////////////////////////////////
196 ///create a MeshNode and add it to the current Mesh
197 ///An ID is automatically assigned to the node.
198 ///@return : The created node
199 ///////////////////////////////////////////////////////////////////////////////
201 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
203 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
206 ///////////////////////////////////////////////////////////////////////////////
207 ///create a MeshNode and add it to the current Mesh
208 ///@param ID : The ID of the MeshNode to create
209 ///@return : The created node or NULL if a node with this ID already exists
210 ///////////////////////////////////////////////////////////////////////////////
211 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
213 // find the MeshNode corresponding to ID
214 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
218 MESSAGE("=============> Bad Node Id: " << ID);
219 ID = myNodeIDFactory->GetFreeID();
221 myNodeIDFactory->adjustMaxId(ID);
222 SMDS_MeshNode * node = myNodePool->getNew();
223 node->init(ID, myMeshId, 0, x, y, z);
225 if (ID >= myNodes.size())
227 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
228 MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
231 myNodeIDFactory->BindID(ID,node);
234 this->adjustBoundingBox(x, y, z);
240 ///////////////////////////////////////////////////////////////////////////////
241 /// create a Mesh0DElement and add it to the current Mesh
242 /// @return : The created Mesh0DElement
243 ///////////////////////////////////////////////////////////////////////////////
244 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
246 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
247 if (!node) return NULL;
248 return SMDS_Mesh::Add0DElementWithID(node, ID);
251 ///////////////////////////////////////////////////////////////////////////////
252 /// create a Mesh0DElement and add it to the current Mesh
253 /// @return : The created Mesh0DElement
254 ///////////////////////////////////////////////////////////////////////////////
255 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
257 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
260 ///////////////////////////////////////////////////////////////////////////////
261 /// Create a new Mesh0DElement and at it to the mesh
262 /// @param idnode ID of the node
263 /// @param ID ID of the 0D element to create
264 /// @return The created 0D element or NULL if an element with this
265 /// ID already exists or if input node is not found.
266 ///////////////////////////////////////////////////////////////////////////////
267 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
271 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
272 //MESSAGE("Add0DElementWithID" << ID)
273 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
274 if (myElementIDFactory->BindID(ID, el0d)) {
275 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
276 //node->AddInverseElement(el0d);// --- fait avec BindID
277 adjustmyCellsCapacity(ID);
279 myInfo.myNb0DElements++;
287 ///////////////////////////////////////////////////////////////////////////////
288 /// create a MeshEdge and add it to the current Mesh
289 /// @return : The created MeshEdge
290 ///////////////////////////////////////////////////////////////////////////////
292 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
294 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
295 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
296 if(!node1 || !node2) return NULL;
297 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
300 ///////////////////////////////////////////////////////////////////////////////
301 /// create a MeshEdge and add it to the current Mesh
302 /// @return : The created MeshEdge
303 ///////////////////////////////////////////////////////////////////////////////
305 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
306 const SMDS_MeshNode * node2)
308 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
311 ///////////////////////////////////////////////////////////////////////////////
312 /// Create a new edge and at it to the mesh
313 /// @param idnode1 ID of the first node
314 /// @param idnode2 ID of the second node
315 /// @param ID ID of the edge to create
316 /// @return The created edge or NULL if an element with this ID already exists or
317 /// if input nodes are not found.
318 ///////////////////////////////////////////////////////////////////////////////
320 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
321 const SMDS_MeshNode * n2,
324 if ( !n1 || !n2 ) return 0;
325 SMDS_MeshEdge * edge = 0;
327 // --- retreive nodes ID
328 vector<vtkIdType> nodeIds;
330 nodeIds.push_back(n1->getVtkId());
331 nodeIds.push_back(n2->getVtkId());
333 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
334 edgevtk->init(nodeIds, this);
335 if (!this->registerElement(ID,edgevtk))
337 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
338 myEdgePool->destroy(edgevtk);
342 adjustmyCellsCapacity(ID);
346 // if (edge && !registerElement(ID, edge))
348 // RemoveElement(edge, false);
354 ///////////////////////////////////////////////////////////////////////////////
355 /// Add a triangle defined by its nodes. An ID is automatically affected to the
357 ///////////////////////////////////////////////////////////////////////////////
359 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
360 const SMDS_MeshNode * n2,
361 const SMDS_MeshNode * n3)
363 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
366 ///////////////////////////////////////////////////////////////////////////////
367 /// Add a triangle defined by its nodes IDs
368 ///////////////////////////////////////////////////////////////////////////////
370 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
372 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
373 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
374 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
375 if(!node1 || !node2 || !node3) return NULL;
376 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
379 ///////////////////////////////////////////////////////////////////////////////
380 /// Add a triangle defined by its nodes
381 ///////////////////////////////////////////////////////////////////////////////
383 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
384 const SMDS_MeshNode * n2,
385 const SMDS_MeshNode * n3,
388 //MESSAGE("AddFaceWithID " << ID)
389 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
391 // if (face && !registerElement(ID, face)) {
392 // RemoveElement(face, false);
398 ///////////////////////////////////////////////////////////////////////////////
399 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
401 ///////////////////////////////////////////////////////////////////////////////
403 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
404 const SMDS_MeshNode * n2,
405 const SMDS_MeshNode * n3,
406 const SMDS_MeshNode * n4)
408 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
411 ///////////////////////////////////////////////////////////////////////////////
412 /// Add a quadrangle defined by its nodes IDs
413 ///////////////////////////////////////////////////////////////////////////////
415 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
421 SMDS_MeshNode *node1, *node2, *node3, *node4;
422 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
423 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
424 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
425 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
426 if(!node1 || !node2 || !node3 || !node4) return NULL;
427 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
430 ///////////////////////////////////////////////////////////////////////////////
431 /// Add a quadrangle defined by its nodes
432 ///////////////////////////////////////////////////////////////////////////////
434 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
435 const SMDS_MeshNode * n2,
436 const SMDS_MeshNode * n3,
437 const SMDS_MeshNode * n4,
440 //MESSAGE("AddFaceWithID " << ID);
441 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
443 // if (face && !registerElement(ID, face)) {
444 // RemoveElement(face, false);
450 ///////////////////////////////////////////////////////////////////////////////
451 /// Add a triangle defined by its edges. An ID is automatically assigned to the
453 ///////////////////////////////////////////////////////////////////////////////
455 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
456 const SMDS_MeshEdge * e2,
457 const SMDS_MeshEdge * e3)
459 if (!hasConstructionEdges())
461 //MESSAGE("AddFaceWithID");
462 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
465 ///////////////////////////////////////////////////////////////////////////////
466 /// Add a triangle defined by its edges
467 ///////////////////////////////////////////////////////////////////////////////
469 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
470 const SMDS_MeshEdge * e2,
471 const SMDS_MeshEdge * e3,
474 if (!hasConstructionEdges())
476 if ( !e1 || !e2 || !e3 ) return 0;
478 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
479 MESSAGE("AddFaceWithID" << ID);
481 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
482 adjustmyCellsCapacity(ID);
484 myInfo.myNbTriangles++;
486 if (!registerElement(ID, face)) {
487 registerElement(myElementIDFactory->GetFreeID(), face);
488 //RemoveElement(face, false);
494 ///////////////////////////////////////////////////////////////////////////////
495 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
497 ///////////////////////////////////////////////////////////////////////////////
499 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
500 const SMDS_MeshEdge * e2,
501 const SMDS_MeshEdge * e3,
502 const SMDS_MeshEdge * e4)
504 if (!hasConstructionEdges())
506 //MESSAGE("AddFaceWithID" );
507 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
510 ///////////////////////////////////////////////////////////////////////////////
511 /// Add a quadrangle defined by its edges
512 ///////////////////////////////////////////////////////////////////////////////
514 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
515 const SMDS_MeshEdge * e2,
516 const SMDS_MeshEdge * e3,
517 const SMDS_MeshEdge * e4,
520 if (!hasConstructionEdges())
522 MESSAGE("AddFaceWithID" << ID);
523 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
524 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
525 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
526 adjustmyCellsCapacity(ID);
528 myInfo.myNbQuadrangles++;
530 if (!registerElement(ID, face))
532 registerElement(myElementIDFactory->GetFreeID(), face);
533 //RemoveElement(face, false);
539 ///////////////////////////////////////////////////////////////////////////////
540 ///Create a new tetrahedron and add it to the mesh.
541 ///@return The created tetrahedron
542 ///////////////////////////////////////////////////////////////////////////////
544 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
545 const SMDS_MeshNode * n2,
546 const SMDS_MeshNode * n3,
547 const SMDS_MeshNode * n4)
549 int ID = myElementIDFactory->GetFreeID();
550 //MESSAGE("AddVolumeWithID " << ID);
551 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
552 if(v==NULL) myElementIDFactory->ReleaseID(ID);
556 ///////////////////////////////////////////////////////////////////////////////
557 ///Create a new tetrahedron and add it to the mesh.
558 ///@param ID The ID of the new volume
559 ///@return The created tetrahedron or NULL if an element with this ID already exists
560 ///or if input nodes are not found.
561 ///////////////////////////////////////////////////////////////////////////////
563 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
569 //MESSAGE("AddVolumeWithID" << ID);
570 SMDS_MeshNode *node1, *node2, *node3, *node4;
571 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
572 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
573 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
574 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
575 if(!node1 || !node2 || !node3 || !node4) return NULL;
576 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
579 ///////////////////////////////////////////////////////////////////////////////
580 ///Create a new tetrahedron and add it to the mesh.
581 ///@param ID The ID of the new volume
582 ///@return The created tetrahedron
583 ///////////////////////////////////////////////////////////////////////////////
585 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
586 const SMDS_MeshNode * n2,
587 const SMDS_MeshNode * n3,
588 const SMDS_MeshNode * n4,
591 //MESSAGE("AddVolumeWithID " << ID);
592 SMDS_MeshVolume* volume = 0;
593 if ( !n1 || !n2 || !n3 || !n4) return volume;
594 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
595 if(hasConstructionFaces()) {
596 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
597 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
598 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
599 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
600 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
601 adjustmyCellsCapacity(ID);
602 myCells[ID] = volume;
605 else if(hasConstructionEdges()) {
606 MESSAGE("Error : Not implemented");
610 // --- retrieve nodes ID
611 vector<vtkIdType> nodeIds;
613 nodeIds.push_back(n1->getVtkId());
614 nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
615 nodeIds.push_back(n2->getVtkId());
616 nodeIds.push_back(n4->getVtkId());
618 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
619 volvtk->init(nodeIds, this);
620 if (!this->registerElement(ID,volvtk))
622 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
623 myVolumePool->destroy(volvtk);
627 adjustmyCellsCapacity(ID);
628 myCells[ID] = volume;
632 // if (!registerElement(ID, volume)) {
633 // RemoveElement(volume, false);
639 ///////////////////////////////////////////////////////////////////////////////
640 ///Create a new pyramid and add it to the mesh.
641 ///Nodes 1,2,3 and 4 define the base of the pyramid
642 ///@return The created pyramid
643 ///////////////////////////////////////////////////////////////////////////////
645 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
646 const SMDS_MeshNode * n2,
647 const SMDS_MeshNode * n3,
648 const SMDS_MeshNode * n4,
649 const SMDS_MeshNode * n5)
651 int ID = myElementIDFactory->GetFreeID();
652 //MESSAGE("AddVolumeWithID " << ID);
653 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
654 if(v==NULL) myElementIDFactory->ReleaseID(ID);
658 ///////////////////////////////////////////////////////////////////////////////
659 ///Create a new pyramid and add it to the mesh.
660 ///Nodes 1,2,3 and 4 define the base of the pyramid
661 ///@param ID The ID of the new volume
662 ///@return The created pyramid or NULL if an element with this ID already exists
663 ///or if input nodes are not found.
664 ///////////////////////////////////////////////////////////////////////////////
666 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
673 //MESSAGE("AddVolumeWithID " << ID);
674 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
675 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
676 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
677 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
678 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
679 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
680 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
681 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
684 ///////////////////////////////////////////////////////////////////////////////
685 ///Create a new pyramid and add it to the mesh.
686 ///Nodes 1,2,3 and 4 define the base of the pyramid
687 ///@param ID The ID of the new volume
688 ///@return The created pyramid
689 ///////////////////////////////////////////////////////////////////////////////
691 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
692 const SMDS_MeshNode * n2,
693 const SMDS_MeshNode * n3,
694 const SMDS_MeshNode * n4,
695 const SMDS_MeshNode * n5,
698 //MESSAGE("AddVolumeWithID " << ID);
699 SMDS_MeshVolume* volume = 0;
700 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
701 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
702 if(hasConstructionFaces()) {
703 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
704 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
705 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
706 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
707 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
708 adjustmyCellsCapacity(ID);
709 myCells[ID] = volume;
710 myInfo.myNbPyramids++;
712 else if(hasConstructionEdges()) {
713 MESSAGE("Error : Not implemented");
717 // --- retrieve nodes ID
718 vector<vtkIdType> nodeIds;
720 nodeIds.push_back(n1->getVtkId());
721 nodeIds.push_back(n4->getVtkId());
722 nodeIds.push_back(n3->getVtkId());
723 nodeIds.push_back(n2->getVtkId());
724 nodeIds.push_back(n5->getVtkId());
726 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
727 volvtk->init(nodeIds, this);
728 if (!this->registerElement(ID,volvtk))
730 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
731 myVolumePool->destroy(volvtk);
735 adjustmyCellsCapacity(ID);
736 myCells[ID] = volume;
737 myInfo.myNbPyramids++;
740 // if (!registerElement(ID, volume)) {
741 // RemoveElement(volume, false);
747 ///////////////////////////////////////////////////////////////////////////////
748 ///Create a new prism and add it to the mesh.
749 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
750 ///@return The created prism
751 ///////////////////////////////////////////////////////////////////////////////
753 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
754 const SMDS_MeshNode * n2,
755 const SMDS_MeshNode * n3,
756 const SMDS_MeshNode * n4,
757 const SMDS_MeshNode * n5,
758 const SMDS_MeshNode * n6)
760 int ID = myElementIDFactory->GetFreeID();
761 //MESSAGE("AddVolumeWithID " << ID);
762 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
763 if(v==NULL) myElementIDFactory->ReleaseID(ID);
767 ///////////////////////////////////////////////////////////////////////////////
768 ///Create a new prism and add it to the mesh.
769 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
770 ///@param ID The ID of the new volume
771 ///@return The created prism or NULL if an element with this ID already exists
772 ///or if input nodes are not found.
773 ///////////////////////////////////////////////////////////////////////////////
775 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
783 //MESSAGE("AddVolumeWithID " << ID);
784 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
785 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
786 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
787 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
788 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
789 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
790 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
791 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
792 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
795 ///////////////////////////////////////////////////////////////////////////////
796 ///Create a new prism and add it to the mesh.
797 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
798 ///@param ID The ID of the new volume
799 ///@return The created prism
800 ///////////////////////////////////////////////////////////////////////////////
802 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
803 const SMDS_MeshNode * n2,
804 const SMDS_MeshNode * n3,
805 const SMDS_MeshNode * n4,
806 const SMDS_MeshNode * n5,
807 const SMDS_MeshNode * n6,
810 //MESSAGE("AddVolumeWithID " << ID);
811 SMDS_MeshVolume* volume = 0;
812 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
813 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
814 if(hasConstructionFaces()) {
815 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
816 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
817 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
818 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
819 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
820 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
821 adjustmyCellsCapacity(ID);
822 myCells[ID] = volume;
825 else if(hasConstructionEdges()) {
826 MESSAGE("Error : Not implemented");
830 // --- retrieve nodes ID
831 vector<vtkIdType> nodeIds;
833 nodeIds.push_back(n1->getVtkId());
834 nodeIds.push_back(n2->getVtkId());
835 nodeIds.push_back(n3->getVtkId());
836 nodeIds.push_back(n4->getVtkId());
837 nodeIds.push_back(n5->getVtkId());
838 nodeIds.push_back(n6->getVtkId());
840 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
841 volvtk->init(nodeIds, this);
842 if (!this->registerElement(ID,volvtk))
844 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
845 myVolumePool->destroy(volvtk);
849 adjustmyCellsCapacity(ID);
850 myCells[ID] = volume;
854 // if (!registerElement(ID, volume)) {
855 // RemoveElement(volume, false);
861 ///////////////////////////////////////////////////////////////////////////////
862 ///Create a new hexahedron and add it to the mesh.
863 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
864 ///@return The created hexahedron
865 ///////////////////////////////////////////////////////////////////////////////
867 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
868 const SMDS_MeshNode * n2,
869 const SMDS_MeshNode * n3,
870 const SMDS_MeshNode * n4,
871 const SMDS_MeshNode * n5,
872 const SMDS_MeshNode * n6,
873 const SMDS_MeshNode * n7,
874 const SMDS_MeshNode * n8)
876 int ID = myElementIDFactory->GetFreeID();
877 //MESSAGE("AddVolumeWithID " << ID);
878 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
879 if(v==NULL) myElementIDFactory->ReleaseID(ID);
883 ///////////////////////////////////////////////////////////////////////////////
884 ///Create a new hexahedron and add it to the mesh.
885 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
886 ///@param ID The ID of the new volume
887 ///@return The created hexahedron or NULL if an element with this ID already
888 ///exists or if input nodes are not found.
889 ///////////////////////////////////////////////////////////////////////////////
891 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
901 //MESSAGE("AddVolumeWithID " << ID);
902 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
903 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
904 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
905 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
906 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
907 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
908 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
909 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
910 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
911 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
913 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
917 ///////////////////////////////////////////////////////////////////////////////
918 ///Create a new hexahedron and add it to the mesh.
919 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
920 ///@param ID The ID of the new volume
921 ///@return The created prism or NULL if an element with this ID already exists
922 ///or if input nodes are not found.
923 ///////////////////////////////////////////////////////////////////////////////
925 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
926 const SMDS_MeshNode * n2,
927 const SMDS_MeshNode * n3,
928 const SMDS_MeshNode * n4,
929 const SMDS_MeshNode * n5,
930 const SMDS_MeshNode * n6,
931 const SMDS_MeshNode * n7,
932 const SMDS_MeshNode * n8,
935 //MESSAGE("AddVolumeWithID " << ID);
936 SMDS_MeshVolume* volume = 0;
937 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
938 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
939 if(hasConstructionFaces()) {
940 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
941 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
942 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
943 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
944 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
945 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
946 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
947 adjustmyCellsCapacity(ID);
948 myCells[ID] = volume;
951 else if(hasConstructionEdges()) {
952 MESSAGE("Error : Not implemented");
956 // --- retrieve nodes ID
957 vector<vtkIdType> nodeIds;
959 nodeIds.push_back(n1->getVtkId());
960 nodeIds.push_back(n4->getVtkId());
961 nodeIds.push_back(n3->getVtkId());
962 nodeIds.push_back(n2->getVtkId());
963 nodeIds.push_back(n5->getVtkId());
964 nodeIds.push_back(n8->getVtkId());
965 nodeIds.push_back(n7->getVtkId());
966 nodeIds.push_back(n6->getVtkId());
968 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
969 volvtk->init(nodeIds, this);
970 if (!this->registerElement(ID,volvtk))
972 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
973 myVolumePool->destroy(volvtk);
977 adjustmyCellsCapacity(ID);
978 myCells[ID] = volume;
982 // if (!registerElement(ID, volume)) {
983 // RemoveElement(volume, false);
989 ///////////////////////////////////////////////////////////////////////////////
990 ///Create a new tetrahedron defined by its faces and add it to the mesh.
991 ///@return The created tetrahedron
992 ///////////////////////////////////////////////////////////////////////////////
994 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
995 const SMDS_MeshFace * f2,
996 const SMDS_MeshFace * f3,
997 const SMDS_MeshFace * f4)
999 //MESSAGE("AddVolumeWithID");
1000 if (!hasConstructionFaces())
1002 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1005 ///////////////////////////////////////////////////////////////////////////////
1006 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1007 ///@param ID The ID of the new volume
1008 ///@return The created tetrahedron
1009 ///////////////////////////////////////////////////////////////////////////////
1011 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1012 const SMDS_MeshFace * f2,
1013 const SMDS_MeshFace * f3,
1014 const SMDS_MeshFace * f4,
1017 MESSAGE("AddVolumeWithID" << ID);
1018 if (!hasConstructionFaces())
1020 if ( !f1 || !f2 || !f3 || !f4) return 0;
1021 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1022 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1023 adjustmyCellsCapacity(ID);
1024 myCells[ID] = volume;
1025 myInfo.myNbTetras++;
1027 if (!registerElement(ID, volume)) {
1028 registerElement(myElementIDFactory->GetFreeID(), volume);
1029 //RemoveElement(volume, false);
1035 ///////////////////////////////////////////////////////////////////////////////
1036 ///Create a new pyramid defined by its faces and add it to the mesh.
1037 ///@return The created pyramid
1038 ///////////////////////////////////////////////////////////////////////////////
1040 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1041 const SMDS_MeshFace * f2,
1042 const SMDS_MeshFace * f3,
1043 const SMDS_MeshFace * f4,
1044 const SMDS_MeshFace * f5)
1046 //MESSAGE("AddVolumeWithID");
1047 if (!hasConstructionFaces())
1049 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1052 ///////////////////////////////////////////////////////////////////////////////
1053 ///Create a new pyramid defined by its faces and add it to the mesh.
1054 ///@param ID The ID of the new volume
1055 ///@return The created pyramid
1056 ///////////////////////////////////////////////////////////////////////////////
1058 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1059 const SMDS_MeshFace * f2,
1060 const SMDS_MeshFace * f3,
1061 const SMDS_MeshFace * f4,
1062 const SMDS_MeshFace * f5,
1065 MESSAGE("AddVolumeWithID" << ID);
1066 if (!hasConstructionFaces())
1068 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1069 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1070 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1071 adjustmyCellsCapacity(ID);
1072 myCells[ID] = volume;
1073 myInfo.myNbPyramids++;
1075 if (!registerElement(ID, volume)) {
1076 registerElement(myElementIDFactory->GetFreeID(), volume);
1077 //RemoveElement(volume, false);
1083 ///////////////////////////////////////////////////////////////////////////////
1084 ///Create a new prism defined by its faces and add it to the mesh.
1085 ///@return The created prism
1086 ///////////////////////////////////////////////////////////////////////////////
1088 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1089 const SMDS_MeshFace * f2,
1090 const SMDS_MeshFace * f3,
1091 const SMDS_MeshFace * f4,
1092 const SMDS_MeshFace * f5,
1093 const SMDS_MeshFace * f6)
1095 //MESSAGE("AddVolumeWithID" );
1096 if (!hasConstructionFaces())
1098 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1101 ///////////////////////////////////////////////////////////////////////////////
1102 ///Create a new prism defined by its faces and add it to the mesh.
1103 ///@param ID The ID of the new volume
1104 ///@return The created prism
1105 ///////////////////////////////////////////////////////////////////////////////
1107 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1108 const SMDS_MeshFace * f2,
1109 const SMDS_MeshFace * f3,
1110 const SMDS_MeshFace * f4,
1111 const SMDS_MeshFace * f5,
1112 const SMDS_MeshFace * f6,
1115 MESSAGE("AddVolumeWithID" << ID);
1116 if (!hasConstructionFaces())
1118 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1119 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1120 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1121 adjustmyCellsCapacity(ID);
1122 myCells[ID] = volume;
1123 myInfo.myNbPrisms++;
1125 if (!registerElement(ID, volume)) {
1126 registerElement(myElementIDFactory->GetFreeID(), volume);
1127 //RemoveElement(volume, false);
1133 ///////////////////////////////////////////////////////////////////////////////
1134 /// Add a polygon defined by its nodes IDs
1135 ///////////////////////////////////////////////////////////////////////////////
1137 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
1140 int nbNodes = nodes_ids.size();
1141 vector<const SMDS_MeshNode*> nodes (nbNodes);
1142 for (int i = 0; i < nbNodes; i++) {
1143 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1144 if (!nodes[i]) return NULL;
1146 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1149 ///////////////////////////////////////////////////////////////////////////////
1150 /// Add a polygon defined by its nodes
1151 ///////////////////////////////////////////////////////////////////////////////
1153 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1154 (vector<const SMDS_MeshNode*> nodes,
1157 SMDS_MeshFace * face;
1159 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1160 if (hasConstructionEdges())
1162 MESSAGE("Error : Not implemented");
1167 //#ifdef VTK_HAVE_POLYHEDRON
1168 //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
1169 vector<vtkIdType> nodeIds;
1171 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1172 for ( ; it != nodes.end(); ++it)
1173 nodeIds.push_back((*it)->getVtkId());
1175 SMDS_VtkFace *facevtk = myFacePool->getNew();
1176 facevtk->initPoly(nodeIds, this);
1177 if (!this->registerElement(ID,facevtk))
1179 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1180 myFacePool->destroy(facevtk);
1185 // MESSAGE("AddPolygonalFaceWithID smds " << ID);
1186 // for ( int i = 0; i < nodes.size(); ++i )
1187 // if ( !nodes[ i ] ) return 0;
1188 // face = new SMDS_PolygonalFaceOfNodes(nodes);
1190 adjustmyCellsCapacity(ID);
1192 myInfo.myNbPolygons++;
1195 //#ifndef VTK_HAVE_POLYHEDRON
1196 // if (!registerElement(ID, face))
1198 // registerElement(myElementIDFactory->GetFreeID(), face);
1199 // //RemoveElement(face, false);
1206 ///////////////////////////////////////////////////////////////////////////////
1207 /// Add a polygon defined by its nodes.
1208 /// An ID is automatically affected to the created face.
1209 ///////////////////////////////////////////////////////////////////////////////
1211 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
1213 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1216 ///////////////////////////////////////////////////////////////////////////////
1217 /// Create a new polyhedral volume and add it to the mesh.
1218 /// @param ID The ID of the new volume
1219 /// @return The created volume or NULL if an element with this ID already exists
1220 /// or if input nodes are not found.
1221 ///////////////////////////////////////////////////////////////////////////////
1223 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1224 (vector<int> nodes_ids,
1225 vector<int> quantities,
1228 int nbNodes = nodes_ids.size();
1229 vector<const SMDS_MeshNode*> nodes (nbNodes);
1230 for (int i = 0; i < nbNodes; i++) {
1231 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1232 if (!nodes[i]) return NULL;
1234 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1237 ///////////////////////////////////////////////////////////////////////////////
1238 /// Create a new polyhedral volume and add it to the mesh.
1239 /// @param ID The ID of the new volume
1240 /// @return The created volume
1241 ///////////////////////////////////////////////////////////////////////////////
1243 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1244 (vector<const SMDS_MeshNode*> nodes,
1245 vector<int> quantities,
1248 SMDS_MeshVolume* volume;
1249 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1250 if (hasConstructionFaces())
1252 MESSAGE("Error : Not implemented");
1255 else if (hasConstructionEdges())
1257 MESSAGE("Error : Not implemented");
1262 //#ifdef VTK_HAVE_POLYHEDRON
1263 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1264 vector<vtkIdType> nodeIds;
1266 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1267 for (; it != nodes.end(); ++it)
1268 nodeIds.push_back((*it)->getVtkId());
1270 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1271 volvtk->initPoly(nodeIds, quantities, this);
1272 if (!this->registerElement(ID, volvtk))
1274 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1275 myVolumePool->destroy(volvtk);
1280 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1281 // for ( int i = 0; i < nodes.size(); ++i )
1282 // if ( !nodes[ i ] ) return 0;
1283 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1285 adjustmyCellsCapacity(ID);
1286 myCells[ID] = volume;
1287 myInfo.myNbPolyhedrons++;
1290 //#ifndef VTK_HAVE_POLYHEDRON
1291 // if (!registerElement(ID, volume))
1293 // registerElement(myElementIDFactory->GetFreeID(), volume);
1294 // //RemoveElement(volume, false);
1301 ///////////////////////////////////////////////////////////////////////////////
1302 /// Create a new polyhedral volume and add it to the mesh.
1303 /// @return The created volume
1304 ///////////////////////////////////////////////////////////////////////////////
1306 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1307 (vector<const SMDS_MeshNode*> nodes,
1308 vector<int> quantities)
1310 int ID = myElementIDFactory->GetFreeID();
1311 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1312 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1316 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1318 int ID = myElementIDFactory->GetFreeID();
1319 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1320 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1324 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1326 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1327 volvtk->init(vtkNodeIds, this);
1328 if (!this->registerElement(ID,volvtk))
1330 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1331 myVolumePool->destroy(volvtk);
1334 adjustmyCellsCapacity(ID);
1335 myCells[ID] = volvtk;
1336 vtkIdType aVtkType = volvtk->GetVtkType();
1340 myInfo.myNbTetras++;
1343 myInfo.myNbPyramids++;
1346 myInfo.myNbPrisms++;
1348 case VTK_HEXAHEDRON:
1351 case VTK_QUADRATIC_TETRA:
1352 myInfo.myNbQuadTetras++;
1354 case VTK_QUADRATIC_PYRAMID:
1355 myInfo.myNbQuadPyramids++;
1357 case VTK_QUADRATIC_WEDGE:
1358 myInfo.myNbQuadPrisms++;
1360 case VTK_QUADRATIC_HEXAHEDRON:
1361 myInfo.myNbQuadHexas++;
1363 //#ifdef VTK_HAVE_POLYHEDRON
1364 case VTK_POLYHEDRON:
1365 myInfo.myNbPolyhedrons++;
1369 myInfo.myNbPolyhedrons++;
1375 ///////////////////////////////////////////////////////////////////////////////
1376 /// Registers element with the given ID, maintains inverse connections
1377 ///////////////////////////////////////////////////////////////////////////////
1378 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1380 //MESSAGE("registerElement " << ID);
1381 if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1383 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1388 element->myMeshId = myMeshId;
1390 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1392 int vtkId = cell->getVtkId();
1394 vtkId = myElementIDFactory->SetInVtkGrid(element);
1396 if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1398 MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1399 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1401 myCellIdVtkToSmds[vtkId] = ID;
1403 myElementIDFactory->updateMinMax(ID);
1407 ///////////////////////////////////////////////////////////////////////////////
1408 /// Return the node whose SMDS ID is 'ID'.
1409 ///////////////////////////////////////////////////////////////////////////////
1410 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1412 if (ID < 1 || ID >= myNodes.size())
1414 MESSAGE("------------------------------------------------------------------------- ");
1415 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1416 MESSAGE("------------------------------------------------------------------------- ");
1419 return (const SMDS_MeshNode *)myNodes[ID];
1422 ///////////////////////////////////////////////////////////////////////////////
1423 /// Return the node whose VTK ID is 'vtkId'.
1424 ///////////////////////////////////////////////////////////////////////////////
1425 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1427 // TODO if needed use mesh->nodeIdFromVtkToSmds
1428 if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1430 MESSAGE("------------------------------------------------------------------------- ");
1431 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1432 MESSAGE("------------------------------------------------------------------------- ");
1435 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1438 ///////////////////////////////////////////////////////////////////////////////
1439 ///Create a triangle and add it to the current mesh. This method do not bind an
1440 ///ID to the create triangle.
1441 ///////////////////////////////////////////////////////////////////////////////
1442 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1443 const SMDS_MeshNode * node2,
1444 const SMDS_MeshNode * node3,
1447 if ( !node1 || !node2 || !node3) return 0;
1448 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1449 if(hasConstructionEdges())
1451 SMDS_MeshEdge *edge1, *edge2, *edge3;
1452 edge1=FindEdgeOrCreate(node1,node2);
1453 edge2=FindEdgeOrCreate(node2,node3);
1454 edge3=FindEdgeOrCreate(node3,node1);
1456 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1457 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1458 adjustmyCellsCapacity(ID);
1460 myInfo.myNbTriangles++;
1465 // --- retrieve nodes ID
1466 vector<vtkIdType> nodeIds;
1468 nodeIds.push_back(node1->getVtkId());
1469 nodeIds.push_back(node2->getVtkId());
1470 nodeIds.push_back(node3->getVtkId());
1472 SMDS_MeshFace * face = 0;
1473 SMDS_VtkFace *facevtk = myFacePool->getNew();
1474 facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1475 if (!this->registerElement(ID,facevtk))
1477 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1478 myFacePool->destroy(facevtk);
1482 adjustmyCellsCapacity(ID);
1484 //MESSAGE("createTriangle " << ID << " " << face);
1485 myInfo.myNbTriangles++;
1490 ///////////////////////////////////////////////////////////////////////////////
1491 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1492 ///a ID to the create triangle.
1493 ///////////////////////////////////////////////////////////////////////////////
1494 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1495 const SMDS_MeshNode * node2,
1496 const SMDS_MeshNode * node3,
1497 const SMDS_MeshNode * node4,
1500 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1501 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1502 if(hasConstructionEdges())
1504 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1505 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1506 edge1=FindEdgeOrCreate(node1,node2);
1507 edge2=FindEdgeOrCreate(node2,node3);
1508 edge3=FindEdgeOrCreate(node3,node4);
1509 edge4=FindEdgeOrCreate(node4,node1);
1511 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1512 adjustmyCellsCapacity(ID);
1514 myInfo.myNbQuadrangles++;
1519 // --- retrieve nodes ID
1520 vector<vtkIdType> nodeIds;
1522 nodeIds.push_back(node1->getVtkId());
1523 nodeIds.push_back(node2->getVtkId());
1524 nodeIds.push_back(node3->getVtkId());
1525 nodeIds.push_back(node4->getVtkId());
1527 SMDS_MeshFace * face = 0;
1528 SMDS_VtkFace *facevtk = myFacePool->getNew();
1529 facevtk->init(nodeIds, this);
1530 if (!this->registerElement(ID,facevtk))
1532 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1533 myFacePool->destroy(facevtk);
1537 adjustmyCellsCapacity(ID);
1539 myInfo.myNbQuadrangles++;
1544 ///////////////////////////////////////////////////////////////////////////////
1545 /// Remove a node and all the elements which own this node
1546 ///////////////////////////////////////////////////////////////////////////////
1548 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1550 MESSAGE("RemoveNode");
1551 RemoveElement(node, true);
1554 ///////////////////////////////////////////////////////////////////////////////
1555 /// Remove an edge and all the elements which own this edge
1556 ///////////////////////////////////////////////////////////////////////////////
1558 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1560 MESSAGE("Remove0DElement");
1561 RemoveElement(elem0d,true);
1564 ///////////////////////////////////////////////////////////////////////////////
1565 /// Remove an edge and all the elements which own this edge
1566 ///////////////////////////////////////////////////////////////////////////////
1568 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1570 MESSAGE("RemoveEdge");
1571 RemoveElement(edge,true);
1574 ///////////////////////////////////////////////////////////////////////////////
1575 /// Remove an face and all the elements which own this face
1576 ///////////////////////////////////////////////////////////////////////////////
1578 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1580 MESSAGE("RemoveFace");
1581 RemoveElement(face, true);
1584 ///////////////////////////////////////////////////////////////////////////////
1586 ///////////////////////////////////////////////////////////////////////////////
1588 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1590 MESSAGE("RemoveVolume");
1591 RemoveElement(volume, true);
1594 //=======================================================================
1595 //function : RemoveFromParent
1597 //=======================================================================
1599 bool SMDS_Mesh::RemoveFromParent()
1601 if (myParent==NULL) return false;
1602 else return (myParent->RemoveSubMesh(this));
1605 //=======================================================================
1606 //function : RemoveSubMesh
1608 //=======================================================================
1610 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1614 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1615 for (; itmsh!=myChildren.end() && !found; itmsh++)
1617 SMDS_Mesh * submesh = *itmsh;
1618 if (submesh == aMesh)
1621 myChildren.erase(itmsh);
1628 //=======================================================================
1629 //function : ChangeElementNodes
1631 //=======================================================================
1633 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1634 const SMDS_MeshNode * nodes[],
1637 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1638 // keep current nodes of elem
1639 set<const SMDS_MeshElement*> oldNodes;
1640 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1642 oldNodes.insert(itn->next());
1646 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1649 Ok = cell->vtkOrder(nodes, nbnodes);
1650 Ok = cell->ChangeNodes(nodes, nbnodes);
1653 if ( Ok ) { // update InverseElements
1655 set<const SMDS_MeshElement*>::iterator it;
1657 // AddInverseElement to new nodes
1658 for ( int i = 0; i < nbnodes; i++ ) {
1659 it = oldNodes.find( nodes[i] );
1660 if ( it == oldNodes.end() )
1662 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1664 // remove from oldNodes a node that remains in elem
1665 oldNodes.erase( it );
1667 // RemoveInverseElement from the nodes removed from elem
1668 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1670 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1671 (const_cast<SMDS_MeshElement *>( *it ));
1672 n->RemoveInverseElement( cell );
1679 //=======================================================================
1680 //function : ChangePolyhedronNodes
1681 //purpose : to change nodes of polyhedral volume
1682 //=======================================================================
1683 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1684 const vector<const SMDS_MeshNode*>& nodes,
1685 const vector<int> & quantities)
1687 if (elem->GetType() != SMDSAbs_Volume) {
1688 MESSAGE("WRONG ELEM TYPE");
1692 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1697 // keep current nodes of elem
1698 set<const SMDS_MeshElement*> oldNodes;
1699 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1700 while (itn->more()) {
1701 oldNodes.insert(itn->next());
1705 // TODO remove this function
1706 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1712 // update InverseElements
1714 // AddInverseElement to new nodes
1715 int nbnodes = nodes.size();
1716 set<const SMDS_MeshElement*>::iterator it;
1717 for (int i = 0; i < nbnodes; i++) {
1718 it = oldNodes.find(nodes[i]);
1719 if (it == oldNodes.end()) {
1721 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1723 // remove from oldNodes a node that remains in elem
1728 // RemoveInverseElement from the nodes removed from elem
1729 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1730 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1731 (const_cast<SMDS_MeshElement *>( *it ));
1732 n->RemoveInverseElement(elem);
1739 //=======================================================================
1740 //function : Find0DElement
1742 //=======================================================================
1743 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1745 const SMDS_MeshNode * node = FindNode(idnode);
1746 if(node == NULL) return NULL;
1747 return Find0DElement(node);
1750 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1752 if (!node) return 0;
1753 const SMDS_Mesh0DElement* toReturn = NULL;
1754 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1755 while (it1->more() && (toReturn == NULL)) {
1756 const SMDS_MeshElement* e = it1->next();
1757 if (e->NbNodes() == 1) {
1758 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1764 //=======================================================================
1765 //function : Find0DElementOrCreate
1767 //=======================================================================
1768 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1770 // if (!node) return 0;
1771 // SMDS_Mesh0DElement * toReturn = NULL;
1772 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1773 // if (toReturn == NULL) {
1774 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1775 // toReturn = new SMDS_Mesh0DElement(node);
1776 // my0DElements.Add(toReturn);
1777 // myInfo.myNb0DElements++;
1783 //=======================================================================
1784 //function : FindEdge
1786 //=======================================================================
1788 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1790 const SMDS_MeshNode * node1=FindNode(idnode1);
1791 const SMDS_MeshNode * node2=FindNode(idnode2);
1792 if((node1==NULL)||(node2==NULL)) return NULL;
1793 return FindEdge(node1,node2);
1796 //#include "Profiler.h"
1797 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1798 const SMDS_MeshNode * node2)
1800 if ( !node1 ) return 0;
1801 const SMDS_MeshEdge * toReturn=NULL;
1804 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1807 while(it1->more()) {
1808 const SMDS_MeshElement * e = it1->next();
1809 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1810 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1819 //=======================================================================
1820 //function : FindEdgeOrCreate
1822 //=======================================================================
1824 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1825 const SMDS_MeshNode * node2)
1827 if ( !node1 || !node2) return 0;
1828 SMDS_MeshEdge * toReturn=NULL;
1829 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1830 if(toReturn==NULL) {
1831 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1832 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1833 adjustmyCellsCapacity(ID);
1834 vector<vtkIdType> nodeIds;
1836 nodeIds.push_back(node1->getVtkId());
1837 nodeIds.push_back(node2->getVtkId());
1839 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1840 edgevtk->init(nodeIds, this);
1841 if (!this->registerElement(ID,edgevtk))
1843 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
1844 myEdgePool->destroy(edgevtk);
1848 myCells[ID] = toReturn;
1855 //=======================================================================
1856 //function : FindEdge
1858 //=======================================================================
1860 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1863 const SMDS_MeshNode * node1=FindNode(idnode1);
1864 const SMDS_MeshNode * node2=FindNode(idnode2);
1865 const SMDS_MeshNode * node3=FindNode(idnode3);
1866 return FindEdge(node1,node2,node3);
1869 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1870 const SMDS_MeshNode * node2,
1871 const SMDS_MeshNode * node3)
1873 if ( !node1 ) return 0;
1874 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1875 while(it1->more()) {
1876 const SMDS_MeshElement * e = it1->next();
1877 if ( e->NbNodes() == 3 ) {
1878 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1879 while(it2->more()) {
1880 const SMDS_MeshElement* n = it2->next();
1890 return static_cast<const SMDS_MeshEdge *> (e);
1897 //=======================================================================
1898 //function : FindFace
1900 //=======================================================================
1902 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1905 const SMDS_MeshNode * node1=FindNode(idnode1);
1906 const SMDS_MeshNode * node2=FindNode(idnode2);
1907 const SMDS_MeshNode * node3=FindNode(idnode3);
1908 return FindFace(node1, node2, node3);
1911 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1912 const SMDS_MeshNode *node2,
1913 const SMDS_MeshNode *node3)
1915 if ( !node1 ) return 0;
1916 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1917 while(it1->more()) {
1918 const SMDS_MeshElement * e = it1->next();
1919 if ( e->NbNodes() == 3 ) {
1920 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1921 while(it2->more()) {
1922 const SMDS_MeshElement* n = it2->next();
1932 return static_cast<const SMDS_MeshFace *> (e);
1938 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1939 const SMDS_MeshNode *node2,
1940 const SMDS_MeshNode *node3)
1942 SMDS_MeshFace * toReturn=NULL;
1943 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1944 if(toReturn==NULL) {
1945 int ID = myElementIDFactory->GetFreeID();
1946 toReturn = createTriangle(node1,node2,node3, ID);
1952 //=======================================================================
1953 //function : FindFace
1955 //=======================================================================
1957 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1958 int idnode3, int idnode4) const
1960 const SMDS_MeshNode * node1=FindNode(idnode1);
1961 const SMDS_MeshNode * node2=FindNode(idnode2);
1962 const SMDS_MeshNode * node3=FindNode(idnode3);
1963 const SMDS_MeshNode * node4=FindNode(idnode4);
1964 return FindFace(node1, node2, node3, node4);
1967 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1968 const SMDS_MeshNode *node2,
1969 const SMDS_MeshNode *node3,
1970 const SMDS_MeshNode *node4)
1972 if ( !node1 ) return 0;
1973 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1974 while(it1->more()) {
1975 const SMDS_MeshElement * e = it1->next();
1976 if ( e->NbNodes() == 4 ) {
1977 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1978 while(it2->more()) {
1979 const SMDS_MeshElement* n = it2->next();
1990 return static_cast<const SMDS_MeshFace *> (e);
1996 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1997 const SMDS_MeshNode *node2,
1998 const SMDS_MeshNode *node3,
1999 const SMDS_MeshNode *node4)
2001 SMDS_MeshFace * toReturn=NULL;
2002 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2003 if(toReturn==NULL) {
2004 int ID = myElementIDFactory->GetFreeID();
2005 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2011 //=======================================================================
2012 //function : FindFace
2013 //purpose :quadratic triangle
2014 //=======================================================================
2016 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2017 int idnode3, int idnode4,
2018 int idnode5, int idnode6) const
2020 const SMDS_MeshNode * node1 = FindNode(idnode1);
2021 const SMDS_MeshNode * node2 = FindNode(idnode2);
2022 const SMDS_MeshNode * node3 = FindNode(idnode3);
2023 const SMDS_MeshNode * node4 = FindNode(idnode4);
2024 const SMDS_MeshNode * node5 = FindNode(idnode5);
2025 const SMDS_MeshNode * node6 = FindNode(idnode6);
2026 return FindFace(node1, node2, node3, node4, node5, node6);
2029 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2030 const SMDS_MeshNode *node2,
2031 const SMDS_MeshNode *node3,
2032 const SMDS_MeshNode *node4,
2033 const SMDS_MeshNode *node5,
2034 const SMDS_MeshNode *node6)
2036 if ( !node1 ) return 0;
2037 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2038 while(it1->more()) {
2039 const SMDS_MeshElement * e = it1->next();
2040 if ( e->NbNodes() == 6 ) {
2041 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2042 while(it2->more()) {
2043 const SMDS_MeshElement* n = it2->next();
2056 return static_cast<const SMDS_MeshFace *> (e);
2063 //=======================================================================
2064 //function : FindFace
2065 //purpose : quadratic quadrangle
2066 //=======================================================================
2068 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2069 int idnode3, int idnode4,
2070 int idnode5, int idnode6,
2071 int idnode7, int idnode8) const
2073 const SMDS_MeshNode * node1 = FindNode(idnode1);
2074 const SMDS_MeshNode * node2 = FindNode(idnode2);
2075 const SMDS_MeshNode * node3 = FindNode(idnode3);
2076 const SMDS_MeshNode * node4 = FindNode(idnode4);
2077 const SMDS_MeshNode * node5 = FindNode(idnode5);
2078 const SMDS_MeshNode * node6 = FindNode(idnode6);
2079 const SMDS_MeshNode * node7 = FindNode(idnode7);
2080 const SMDS_MeshNode * node8 = FindNode(idnode8);
2081 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2084 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2085 const SMDS_MeshNode *node2,
2086 const SMDS_MeshNode *node3,
2087 const SMDS_MeshNode *node4,
2088 const SMDS_MeshNode *node5,
2089 const SMDS_MeshNode *node6,
2090 const SMDS_MeshNode *node7,
2091 const SMDS_MeshNode *node8)
2093 if ( !node1 ) return 0;
2094 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2095 while(it1->more()) {
2096 const SMDS_MeshElement * e = it1->next();
2097 if ( e->NbNodes() == 8 ) {
2098 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2099 while(it2->more()) {
2100 const SMDS_MeshElement* n = it2->next();
2115 return static_cast<const SMDS_MeshFace *> (e);
2122 //=======================================================================
2123 //function : FindElement
2125 //=======================================================================
2127 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2129 if ((IDelem <= 0) || IDelem >= myCells.size())
2131 MESSAGE("--------------------------------------------------------------------------------- ");
2132 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2133 MESSAGE("--------------------------------------------------------------------------------- ");
2134 // TODO raise an exception
2138 return myCells[IDelem];
2141 //=======================================================================
2142 //function : FindFace
2143 //purpose : find polygon
2144 //=======================================================================
2146 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2148 int nbnodes = nodes_ids.size();
2149 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2150 for (int inode = 0; inode < nbnodes; inode++) {
2151 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2152 if (node == NULL) return NULL;
2153 poly_nodes[inode] = node;
2155 return FindFace(poly_nodes);
2158 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2160 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2164 //================================================================================
2166 * \brief Return element based on all given nodes
2167 * \param nodes - node of element
2168 * \param type - type of element
2169 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2170 * \retval const SMDS_MeshElement* - found element or NULL
2172 //================================================================================
2174 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2175 const SMDSAbs_ElementType type,
2176 const bool noMedium)
2178 if ( nodes.size() > 0 && nodes[0] )
2180 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2183 const SMDS_MeshElement* e = itF->next();
2184 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2185 if ( nbNodesToCheck == nodes.size() )
2187 for ( int i = 1; e && i < nodes.size(); ++ i )
2189 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2190 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2194 return static_cast<const SMDS_MeshFace *> (e);
2201 //=======================================================================
2202 //function : DumpNodes
2204 //=======================================================================
2206 void SMDS_Mesh::DumpNodes() const
2208 MESSAGE("dump nodes of mesh : ");
2209 SMDS_NodeIteratorPtr itnode=nodesIterator();
2210 while(itnode->more()) ; //MESSAGE(itnode->next());
2213 //=======================================================================
2214 //function : Dump0DElements
2216 //=======================================================================
2217 void SMDS_Mesh::Dump0DElements() const
2219 MESSAGE("dump 0D elements of mesh : ");
2220 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2221 while(it0d->more()) ; //MESSAGE(it0d->next());
2224 //=======================================================================
2225 //function : DumpEdges
2227 //=======================================================================
2229 void SMDS_Mesh::DumpEdges() const
2231 MESSAGE("dump edges of mesh : ");
2232 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2233 while(itedge->more()) ; //MESSAGE(itedge->next());
2236 //=======================================================================
2237 //function : DumpFaces
2239 //=======================================================================
2241 void SMDS_Mesh::DumpFaces() const
2243 MESSAGE("dump faces of mesh : ");
2244 SMDS_FaceIteratorPtr itface=facesIterator();
2245 while(itface->more()) ; //MESSAGE(itface->next());
2248 //=======================================================================
2249 //function : DumpVolumes
2251 //=======================================================================
2253 void SMDS_Mesh::DumpVolumes() const
2255 MESSAGE("dump volumes of mesh : ");
2256 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2257 while(itvol->more()) ; //MESSAGE(itvol->next());
2260 //=======================================================================
2261 //function : DebugStats
2263 //=======================================================================
2265 void SMDS_Mesh::DebugStats() const
2267 MESSAGE("Debug stats of mesh : ");
2269 MESSAGE("===== NODES ====="<<NbNodes());
2270 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2271 MESSAGE("===== EDGES ====="<<NbEdges());
2272 MESSAGE("===== FACES ====="<<NbFaces());
2273 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2275 MESSAGE("End Debug stats of mesh ");
2279 SMDS_NodeIteratorPtr itnode=nodesIterator();
2280 int sizeofnodes = 0;
2281 int sizeoffaces = 0;
2283 while(itnode->more())
2285 const SMDS_MeshNode *node = itnode->next();
2287 sizeofnodes += sizeof(*node);
2289 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2292 const SMDS_MeshElement *me = it->next();
2293 sizeofnodes += sizeof(me);
2297 SMDS_FaceIteratorPtr itface=facesIterator();
2298 while(itface->more())
2300 const SMDS_MeshElement *face = itface->next();
2301 sizeoffaces += sizeof(*face);
2304 MESSAGE("total size of node elements = " << sizeofnodes);;
2305 MESSAGE("total size of face elements = " << sizeoffaces);;
2310 ///////////////////////////////////////////////////////////////////////////////
2311 /// Return the number of nodes
2312 ///////////////////////////////////////////////////////////////////////////////
2313 int SMDS_Mesh::NbNodes() const
2315 //MESSAGE(myGrid->GetNumberOfPoints());
2316 //MESSAGE(myInfo.NbNodes());
2317 //MESSAGE(myNodeMax);
2318 return myInfo.NbNodes();
2321 ///////////////////////////////////////////////////////////////////////////////
2322 /// Return the number of 0D elements
2323 ///////////////////////////////////////////////////////////////////////////////
2324 int SMDS_Mesh::Nb0DElements() const
2326 return myInfo.Nb0DElements(); // -PR- a verfier
2329 ///////////////////////////////////////////////////////////////////////////////
2330 /// Return the number of edges (including construction edges)
2331 ///////////////////////////////////////////////////////////////////////////////
2332 int SMDS_Mesh::NbEdges() const
2334 return myInfo.NbEdges(); // -PR- a verfier
2337 ///////////////////////////////////////////////////////////////////////////////
2338 /// Return the number of faces (including construction faces)
2339 ///////////////////////////////////////////////////////////////////////////////
2340 int SMDS_Mesh::NbFaces() const
2342 return myInfo.NbFaces(); // -PR- a verfier
2345 ///////////////////////////////////////////////////////////////////////////////
2346 /// Return the number of volumes
2347 ///////////////////////////////////////////////////////////////////////////////
2348 int SMDS_Mesh::NbVolumes() const
2350 return myInfo.NbVolumes(); // -PR- a verfier
2353 ///////////////////////////////////////////////////////////////////////////////
2354 /// Return the number of child mesh of this mesh.
2355 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2356 /// (2003-09-08) of SMESH
2357 ///////////////////////////////////////////////////////////////////////////////
2358 int SMDS_Mesh::NbSubMesh() const
2360 return myChildren.size();
2363 ///////////////////////////////////////////////////////////////////////////////
2364 /// Destroy the mesh and all its elements
2365 /// All pointer on elements owned by this mesh become illegals.
2366 ///////////////////////////////////////////////////////////////////////////////
2367 SMDS_Mesh::~SMDS_Mesh()
2369 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2370 while(itc!=myChildren.end())
2378 delete myNodeIDFactory;
2379 delete myElementIDFactory;
2383 SMDS_ElemIteratorPtr eIt = elementsIterator();
2384 while ( eIt->more() )
2386 const SMDS_MeshElement *elem = eIt->next();
2387 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2389 SMDS_NodeIteratorPtr itn = nodesIterator();
2392 const SMDS_MeshNode *node = itn->next();
2393 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2394 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2398 // SetOfNodes::Iterator itn(myNodes);
2399 // for (; itn.More(); itn.Next())
2400 // delete itn.Value();
2402 // SetOf0DElements::Iterator it0d (my0DElements);
2403 // for (; it0d.More(); it0d.Next())
2405 // SMDS_MeshElement* elem = it0d.Value();
2409 // SetOfEdges::Iterator ite(myEdges);
2410 // for (; ite.More(); ite.Next())
2412 // SMDS_MeshElement* elem = ite.Value();
2416 // SetOfFaces::Iterator itf(myFaces);
2417 // for (; itf.More(); itf.Next())
2419 // SMDS_MeshElement* elem = itf.Value();
2423 // SetOfVolumes::Iterator itv(myVolumes);
2424 // for (; itv.More(); itv.Next())
2426 // SMDS_MeshElement* elem = itv.Value();
2431 //================================================================================
2433 * \brief Clear all data
2435 //================================================================================
2437 void SMDS_Mesh::Clear()
2439 MESSAGE("SMDS_Mesh::Clear");
2442 SMDS_ElemIteratorPtr eIt = elementsIterator();
2443 while ( eIt->more() )
2445 const SMDS_MeshElement *elem = eIt->next();
2446 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2448 SMDS_NodeIteratorPtr itn = nodesIterator();
2451 const SMDS_MeshNode *node = itn->next();
2452 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2457 myNodeIDFactory->Clear();
2458 myElementIDFactory->Clear();
2461 SMDS_ElemIteratorPtr itv = elementsIterator();
2464 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2465 SMDSAbs_ElementType aType = elem->GetType();
2468 case SMDSAbs_0DElement:
2472 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2475 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2477 case SMDSAbs_Volume:
2478 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2485 myCellIdVtkToSmds.clear();
2486 //myCellIdSmdsToVtk.clear();
2488 SMDS_NodeIteratorPtr itn = nodesIterator();
2491 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2492 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2493 myNodePool->destroy(node);
2497 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2498 while(itc!=myChildren.end())
2508 myGrid->Initialize();
2510 vtkPoints* points = vtkPoints::New();
2511 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2512 // using double type for storing coordinates of nodes instead float.
2513 points->SetDataType(VTK_DOUBLE);
2514 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2515 myGrid->SetPoints( points );
2517 myGrid->BuildLinks();
2520 ///////////////////////////////////////////////////////////////////////////////
2521 /// Return true if this mesh create faces with edges.
2522 /// A false returned value mean that faces are created with nodes. A concequence
2523 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2524 ///////////////////////////////////////////////////////////////////////////////
2525 bool SMDS_Mesh::hasConstructionEdges()
2527 return myHasConstructionEdges;
2530 ///////////////////////////////////////////////////////////////////////////////
2531 /// Return true if this mesh create volumes with faces
2532 /// A false returned value mean that volumes are created with nodes or edges.
2533 /// (see hasConstructionEdges)
2534 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2536 ///////////////////////////////////////////////////////////////////////////////
2537 bool SMDS_Mesh::hasConstructionFaces()
2539 return myHasConstructionFaces;
2542 ///////////////////////////////////////////////////////////////////////////////
2543 /// Return true if nodes are linked to the finit elements, they are belonging to.
2544 /// Currently, It always return true.
2545 ///////////////////////////////////////////////////////////////////////////////
2546 bool SMDS_Mesh::hasInverseElements()
2548 return myHasInverseElements;
2551 ///////////////////////////////////////////////////////////////////////////////
2552 /// Make this mesh creating construction edges (see hasConstructionEdges)
2553 /// @param b true to have construction edges, else false.
2554 ///////////////////////////////////////////////////////////////////////////////
2555 void SMDS_Mesh::setConstructionEdges(bool b)
2557 myHasConstructionEdges=b;
2560 ///////////////////////////////////////////////////////////////////////////////
2561 /// Make this mesh creating construction faces (see hasConstructionFaces)
2562 /// @param b true to have construction faces, else false.
2563 ///////////////////////////////////////////////////////////////////////////////
2564 void SMDS_Mesh::setConstructionFaces(bool b)
2566 myHasConstructionFaces=b;
2569 ///////////////////////////////////////////////////////////////////////////////
2570 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2571 /// @param b true to link nodes to elements, else false.
2572 ///////////////////////////////////////////////////////////////////////////////
2573 void SMDS_Mesh::setInverseElements(bool b)
2575 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2576 myHasInverseElements=b;
2581 ///////////////////////////////////////////////////////////////////////////////
2582 ///Iterator on NCollection_Map
2583 ///////////////////////////////////////////////////////////////////////////////
2584 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2585 struct MYNode_Map_Iterator: public FATHER
2589 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2596 while (_ctr < _map.size())
2607 ELEM current = _map[_ctr];
2613 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2614 struct MYElem_Map_Iterator: public FATHER
2619 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2623 while (_ctr < _map.size()) // go to the first valid element
2626 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2634 while (_ctr < _map.size())
2637 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2646 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2652 //================================================================================
2654 * \brief Iterator on elements in id increasing order
2656 //================================================================================
2658 template <typename ELEM=const SMDS_MeshElement*>
2659 class IdSortedIterator : public SMDS_Iterator<ELEM>
2661 const SMDS_MeshElementIDFactory& myIDFact;
2662 int myID, myMaxID, myNbFound, myTotalNb;
2663 SMDSAbs_ElementType myType;
2667 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2668 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2671 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2683 ELEM current = myElem;
2685 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2686 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2687 && myElem->GetType() != myType )
2690 myNbFound += bool(myElem);
2697 ///////////////////////////////////////////////////////////////////////////////
2698 /// Return an iterator on nodes of the current mesh factory
2699 ///////////////////////////////////////////////////////////////////////////////
2701 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2703 typedef MYNode_Map_Iterator
2704 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2705 return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2707 // typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2708 // return ( idInceasingOrder ?
2709 // SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2710 // SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2713 ///////////////////////////////////////////////////////////////////////////////
2714 ///Return an iterator on 0D elements of the current mesh.
2715 ///////////////////////////////////////////////////////////////////////////////
2717 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2719 typedef MYElem_Map_Iterator
2720 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2721 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2723 // typedef MYNCollection_Map_Iterator
2724 // < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2725 // typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator;
2726 // return ( idInceasingOrder ?
2727 // SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2728 // SMDSAbs_0DElement,
2729 // Nb0DElements() )) :
2730 // SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2733 ///////////////////////////////////////////////////////////////////////////////
2734 ///Return an iterator on edges of the current mesh.
2735 ///////////////////////////////////////////////////////////////////////////////
2737 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2739 typedef MYElem_Map_Iterator
2740 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2741 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2743 // typedef MYNCollection_Map_Iterator
2744 // < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2745 // typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator;
2746 // return ( idInceasingOrder ?
2747 // SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2750 // SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2753 ///////////////////////////////////////////////////////////////////////////////
2754 ///Return an iterator on faces of the current mesh.
2755 ///////////////////////////////////////////////////////////////////////////////
2757 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2759 typedef MYElem_Map_Iterator
2760 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2761 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2763 // typedef MYNCollection_Map_Iterator
2764 // < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2765 // typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator;
2766 // return ( idInceasingOrder ?
2767 // SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2770 // SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2773 ///////////////////////////////////////////////////////////////////////////////
2774 ///Return an iterator on volumes of the current mesh.
2775 ///////////////////////////////////////////////////////////////////////////////
2777 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2779 typedef MYElem_Map_Iterator
2780 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2781 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2783 // typedef MYNCollection_Map_Iterator
2784 // < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2785 // typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator;
2786 // return ( idInceasingOrder ?
2787 // SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2790 // SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2793 ///////////////////////////////////////////////////////////////////////////////
2794 /// Return an iterator on elements of the current mesh factory
2795 ///////////////////////////////////////////////////////////////////////////////
2796 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2800 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2802 case SMDSAbs_Volume:
2803 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2805 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2807 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2808 case SMDSAbs_0DElement:
2809 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2811 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2812 //return myNodeIDFactory->elementsIterator();
2815 return myElementIDFactory->elementsIterator();
2818 ///////////////////////////////////////////////////////////////////////////////
2819 /// Do intersection of sets (more than 2)
2820 ///////////////////////////////////////////////////////////////////////////////
2821 static set<const SMDS_MeshElement*> * intersectionOfSets(
2822 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2824 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2825 set<const SMDS_MeshElement*>* rsetB;
2827 for(int i=0; i<numberOfSets-1; i++)
2829 rsetB=new set<const SMDS_MeshElement*>();
2831 rsetA->begin(), rsetA->end(),
2832 vs[i+1].begin(), vs[i+1].end(),
2833 inserter(*rsetB, rsetB->begin()));
2840 ///////////////////////////////////////////////////////////////////////////////
2841 /// Return the list of finite elements owning the given element: elements
2842 /// containing all the nodes of the given element, for instance faces and
2843 /// volumes containing a given edge.
2844 ///////////////////////////////////////////////////////////////////////////////
2845 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2847 int numberOfSets=element->NbNodes();
2848 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2850 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2853 while(itNodes->more())
2855 const SMDS_MeshElement* node = itNodes->next();
2857 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2858 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2860 //initSet[i]=set<const SMDS_MeshElement*>();
2863 const SMDS_MeshElement* elem = itFe->next();
2865 initSet[i].insert(elem);
2871 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2872 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2877 ///////////////////////////////////////////////////////////////////////////////
2878 /// Return the list of nodes used only by the given elements
2879 ///////////////////////////////////////////////////////////////////////////////
2880 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2881 set<const SMDS_MeshElement*>& elements)
2883 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2884 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2886 while(itElements!=elements.end())
2888 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2891 while(itNodes->more())
2893 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2894 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2895 set<const SMDS_MeshElement*> s;
2897 s.insert(itFe->next());
2898 if(s==elements) toReturn->insert(n);
2904 ///////////////////////////////////////////////////////////////////////////////
2905 ///Find the children of an element that are made of given nodes
2906 ///@param setOfChildren The set in which matching children will be inserted
2907 ///@param element The element were to search matching children
2908 ///@param nodes The nodes that the children must have to be selected
2909 ///////////////////////////////////////////////////////////////////////////////
2910 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2911 const SMDS_MeshElement * element,
2912 set<const SMDS_MeshElement*>& nodes)
2914 switch(element->GetType())
2917 MESSAGE("Internal Error: This should not happen");
2919 case SMDSAbs_0DElement:
2925 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2928 const SMDS_MeshElement * e=itn->next();
2929 if(nodes.find(e)!=nodes.end())
2931 setOfChildren.insert(element);
2938 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2941 const SMDS_MeshElement * e=itn->next();
2942 if(nodes.find(e)!=nodes.end())
2944 setOfChildren.insert(element);
2948 if(hasConstructionEdges())
2950 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2952 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2955 case SMDSAbs_Volume:
2957 if(hasConstructionFaces())
2959 SMDS_ElemIteratorPtr ite=element->facesIterator();
2961 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2963 else if(hasConstructionEdges())
2965 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2967 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2973 ///////////////////////////////////////////////////////////////////////////////
2974 ///@param elem The element to delete
2975 ///@param removenodes if true remaining nodes will be removed
2976 ///////////////////////////////////////////////////////////////////////////////
2977 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2978 const bool removenodes)
2980 list<const SMDS_MeshElement *> removedElems;
2981 list<const SMDS_MeshElement *> removedNodes;
2982 RemoveElement( elem, removedElems, removedNodes, removenodes );
2985 ///////////////////////////////////////////////////////////////////////////////
2986 ///@param elem The element to delete
2987 ///@param removedElems to be filled with all removed elements
2988 ///@param removedNodes to be filled with all removed nodes
2989 ///@param removenodes if true remaining nodes will be removed
2990 ///////////////////////////////////////////////////////////////////////////////
2991 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2992 list<const SMDS_MeshElement *>& removedElems,
2993 list<const SMDS_MeshElement *>& removedNodes,
2996 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
2997 // get finite elements built on elem
2998 set<const SMDS_MeshElement*> * s1;
2999 if ( (elem->GetType() == SMDSAbs_0DElement)
3000 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3001 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3002 || (elem->GetType() == SMDSAbs_Volume) )
3004 s1 = new set<const SMDS_MeshElement*> ();
3008 s1 = getFinitElements(elem);
3010 // get exclusive nodes (which would become free afterwards)
3011 set<const SMDS_MeshElement*> * s2;
3012 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3014 // do not remove nodes except elem
3015 s2 = new set<const SMDS_MeshElement*> ();
3020 s2 = getExclusiveNodes(*s1);
3022 // form the set of finite and construction elements to remove
3023 set<const SMDS_MeshElement*> s3;
3024 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3025 while (it != s1->end())
3027 addChildrenWithNodes(s3, *it, *s2);
3031 if (elem->GetType() != SMDSAbs_Node)
3034 // remove finite and construction elements
3036 while (it != s3.end())
3038 // Remove element from <InverseElements> of its nodes
3039 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3042 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3043 n->RemoveInverseElement((*it));
3045 int IdToRemove = (*it)->GetID();
3046 int vtkid = (*it)->getVtkId();
3047 //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3048 // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3049 switch ((*it)->GetType())
3052 MYASSERT("Internal Error: This should not happen")
3055 case SMDSAbs_0DElement:
3056 if (IdToRemove >= 0)
3058 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3061 removedElems.push_back((*it));
3062 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3066 if (IdToRemove >= 0)
3068 myCells[IdToRemove] = 0;
3069 myInfo.RemoveEdge(*it);
3071 removedElems.push_back((*it));
3072 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3073 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3074 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3079 if (IdToRemove >= 0)
3081 myCells[IdToRemove] = 0;
3082 myInfo.RemoveFace(*it);
3084 removedElems.push_back((*it));
3085 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3086 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3087 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3091 case SMDSAbs_Volume:
3092 if (IdToRemove >= 0)
3094 myCells[IdToRemove] = 0;
3095 myInfo.RemoveVolume(*it);
3097 removedElems.push_back((*it));
3098 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3099 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3100 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3107 //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3108 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3113 // remove exclusive (free) nodes
3117 while (it != s2->end())
3119 int IdToRemove = (*it)->GetID();
3120 //MESSAGE( "SMDS: RM node " << IdToRemove);
3121 if (IdToRemove >= 0)
3123 myNodes[IdToRemove] = 0;
3126 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3127 removedNodes.push_back((*it));
3128 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3130 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3131 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3144 ///////////////////////////////////////////////////////////////////////////////
3145 ///@param elem The element to delete
3146 ///////////////////////////////////////////////////////////////////////////////
3147 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3149 int elemId = elem->GetID();
3150 int vtkId = elem->getVtkId();
3151 //MESSAGE("RemoveFreeElement " << elemId);
3152 SMDSAbs_ElementType aType = elem->GetType();
3153 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3154 if (aType == SMDSAbs_Node) {
3155 //MESSAGE("Remove free node " << elemId);
3156 // only free node can be removed by this method
3157 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3158 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3159 if (!itFe->more()) { // free node
3160 myNodes[elemId] = 0;
3162 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3163 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3164 myNodeIDFactory->ReleaseID(elemId, vtkId);
3167 if (hasConstructionEdges() || hasConstructionFaces())
3168 // this methods is only for meshes without descendants
3171 //MESSAGE("Remove free element " << elemId);
3172 // Remove element from <InverseElements> of its nodes
3173 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3174 while (itn->more()) {
3175 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3176 (const_cast<SMDS_MeshElement *>(itn->next()));
3177 n->RemoveInverseElement(elem);
3180 // in meshes without descendants elements are always free
3182 case SMDSAbs_0DElement:
3183 myCells[elemId] = 0;
3184 myInfo.remove(elem);
3188 myCells[elemId] = 0;
3189 myInfo.RemoveEdge(elem);
3190 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3193 myCells[elemId] = 0;
3194 myInfo.RemoveFace(elem);
3195 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3197 case SMDSAbs_Volume:
3198 myCells[elemId] = 0;
3199 myInfo.RemoveVolume(elem);
3200 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3205 myElementIDFactory->ReleaseID(elemId, vtkId);
3207 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3208 // --- to do: keep vtkid in a list of reusable cells
3213 * Checks if the element is present in mesh.
3214 * Useful to determine dead pointers.
3216 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3218 // we should not imply on validity of *elem, so iterate on containers
3219 // of all types in the hope of finding <elem> somewhere there
3220 SMDS_NodeIteratorPtr itn = nodesIterator();
3222 if (elem == itn->next())
3224 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3225 while (it0d->more())
3226 if (elem == it0d->next())
3228 SMDS_EdgeIteratorPtr ite = edgesIterator();
3230 if (elem == ite->next())
3232 SMDS_FaceIteratorPtr itf = facesIterator();
3234 if (elem == itf->next())
3236 SMDS_VolumeIteratorPtr itv = volumesIterator();
3238 if (elem == itv->next())
3243 //=======================================================================
3244 //function : MaxNodeID
3246 //=======================================================================
3248 int SMDS_Mesh::MaxNodeID() const
3253 //=======================================================================
3254 //function : MinNodeID
3256 //=======================================================================
3258 int SMDS_Mesh::MinNodeID() const
3263 //=======================================================================
3264 //function : MaxElementID
3266 //=======================================================================
3268 int SMDS_Mesh::MaxElementID() const
3270 return myElementIDFactory->GetMaxID();
3273 //=======================================================================
3274 //function : MinElementID
3276 //=======================================================================
3278 int SMDS_Mesh::MinElementID() const
3280 return myElementIDFactory->GetMinID();
3283 //=======================================================================
3284 //function : Renumber
3285 //purpose : Renumber all nodes or elements.
3286 //=======================================================================
3288 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3290 MESSAGE("Renumber");
3294 SMDS_MeshNodeIDFactory * idFactory =
3295 isNodes ? myNodeIDFactory : myElementIDFactory;
3297 // get existing elements in the order of ID increasing
3298 map<int,SMDS_MeshElement*> elemMap;
3299 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3300 while ( idElemIt->more() ) {
3301 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3302 int id = elem->GetID();
3303 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3305 // release their ids
3306 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3308 // for ( ; elemIt != elemMap.end(); elemIt++ )
3310 // int id = (*elemIt).first;
3311 // idFactory->ReleaseID( id );
3315 elemIt = elemMap.begin();
3316 for ( ; elemIt != elemMap.end(); elemIt++ )
3318 idFactory->BindID( ID, (*elemIt).second );
3323 //=======================================================================
3324 //function : GetElementType
3325 //purpose : Return type of element or node with id
3326 //=======================================================================
3328 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3330 SMDS_MeshElement* elem = 0;
3332 elem = myElementIDFactory->MeshElement( id );
3334 elem = myNodeIDFactory->MeshElement( id );
3338 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3342 return elem->GetType();
3347 //********************************************************************
3348 //********************************************************************
3349 //******** *********
3350 //***** Methods for addition of quadratic elements ******
3351 //******** *********
3352 //********************************************************************
3353 //********************************************************************
3355 //=======================================================================
3356 //function : AddEdgeWithID
3358 //=======================================================================
3359 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3361 return SMDS_Mesh::AddEdgeWithID
3362 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3363 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3364 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3368 //=======================================================================
3369 //function : AddEdge
3371 //=======================================================================
3372 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3373 const SMDS_MeshNode* n2,
3374 const SMDS_MeshNode* n12)
3376 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3379 //=======================================================================
3380 //function : AddEdgeWithID
3382 //=======================================================================
3383 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3384 const SMDS_MeshNode * n2,
3385 const SMDS_MeshNode * n12,
3388 if ( !n1 || !n2 || !n12 ) return 0;
3390 // --- retrieve nodes ID
3391 vector<vtkIdType> nodeIds;
3393 nodeIds.push_back(n1->getVtkId());
3394 nodeIds.push_back(n2->getVtkId());
3395 nodeIds.push_back(n12->getVtkId());
3397 SMDS_MeshEdge * edge = 0;
3398 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3399 edgevtk->init(nodeIds, this);
3400 if (!this->registerElement(ID,edgevtk))
3402 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3403 myEdgePool->destroy(edgevtk);
3407 adjustmyCellsCapacity(ID);
3409 myInfo.myNbQuadEdges++;
3411 // if (!registerElement(ID, edge)) {
3412 // RemoveElement(edge, false);
3420 //=======================================================================
3421 //function : AddFace
3423 //=======================================================================
3424 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3425 const SMDS_MeshNode * n2,
3426 const SMDS_MeshNode * n3,
3427 const SMDS_MeshNode * n12,
3428 const SMDS_MeshNode * n23,
3429 const SMDS_MeshNode * n31)
3431 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3432 myElementIDFactory->GetFreeID());
3435 //=======================================================================
3436 //function : AddFaceWithID
3438 //=======================================================================
3439 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3440 int n12,int n23,int n31, int ID)
3442 return SMDS_Mesh::AddFaceWithID
3443 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3444 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3445 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3446 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3447 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3448 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3452 //=======================================================================
3453 //function : AddFaceWithID
3455 //=======================================================================
3456 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3457 const SMDS_MeshNode * n2,
3458 const SMDS_MeshNode * n3,
3459 const SMDS_MeshNode * n12,
3460 const SMDS_MeshNode * n23,
3461 const SMDS_MeshNode * n31,
3464 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3465 if(hasConstructionEdges()) {
3466 // creation quadratic edges - not implemented
3471 // --- retrieve nodes ID
3472 vector<vtkIdType> nodeIds;
3474 nodeIds.push_back(n1->getVtkId());
3475 nodeIds.push_back(n2->getVtkId());
3476 nodeIds.push_back(n3->getVtkId());
3477 nodeIds.push_back(n12->getVtkId());
3478 nodeIds.push_back(n23->getVtkId());
3479 nodeIds.push_back(n31->getVtkId());
3481 SMDS_MeshFace * face = 0;
3482 SMDS_VtkFace *facevtk = myFacePool->getNew();
3483 facevtk->init(nodeIds, this);
3484 if (!this->registerElement(ID,facevtk))
3486 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3487 myFacePool->destroy(facevtk);
3491 adjustmyCellsCapacity(ID);
3493 myInfo.myNbQuadTriangles++;
3495 // if (!registerElement(ID, face)) {
3496 // RemoveElement(face, false);
3504 //=======================================================================
3505 //function : AddFace
3507 //=======================================================================
3508 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3509 const SMDS_MeshNode * n2,
3510 const SMDS_MeshNode * n3,
3511 const SMDS_MeshNode * n4,
3512 const SMDS_MeshNode * n12,
3513 const SMDS_MeshNode * n23,
3514 const SMDS_MeshNode * n34,
3515 const SMDS_MeshNode * n41)
3517 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3518 myElementIDFactory->GetFreeID());
3521 //=======================================================================
3522 //function : AddFaceWithID
3524 //=======================================================================
3525 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3526 int n12,int n23,int n34,int n41, int ID)
3528 return SMDS_Mesh::AddFaceWithID
3529 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3530 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3531 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3532 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3533 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3534 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3535 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3536 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3540 //=======================================================================
3541 //function : AddFaceWithID
3543 //=======================================================================
3544 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3545 const SMDS_MeshNode * n2,
3546 const SMDS_MeshNode * n3,
3547 const SMDS_MeshNode * n4,
3548 const SMDS_MeshNode * n12,
3549 const SMDS_MeshNode * n23,
3550 const SMDS_MeshNode * n34,
3551 const SMDS_MeshNode * n41,
3554 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3555 if(hasConstructionEdges()) {
3556 // creation quadratic edges - not implemented
3561 // --- retrieve nodes ID
3562 vector<vtkIdType> nodeIds;
3564 nodeIds.push_back(n1->getVtkId());
3565 nodeIds.push_back(n2->getVtkId());
3566 nodeIds.push_back(n3->getVtkId());
3567 nodeIds.push_back(n4->getVtkId());
3568 nodeIds.push_back(n12->getVtkId());
3569 nodeIds.push_back(n23->getVtkId());
3570 nodeIds.push_back(n34->getVtkId());
3571 nodeIds.push_back(n41->getVtkId());
3573 SMDS_MeshFace * face = 0;
3574 SMDS_VtkFace *facevtk = myFacePool->getNew();
3575 facevtk->init(nodeIds, this);
3576 if (!this->registerElement(ID,facevtk))
3578 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3579 myFacePool->destroy(facevtk);
3583 adjustmyCellsCapacity(ID);
3585 myInfo.myNbQuadQuadrangles++;
3587 // if (!registerElement(ID, face)) {
3588 // RemoveElement(face, false);
3596 //=======================================================================
3597 //function : AddVolume
3599 //=======================================================================
3600 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3601 const SMDS_MeshNode * n2,
3602 const SMDS_MeshNode * n3,
3603 const SMDS_MeshNode * n4,
3604 const SMDS_MeshNode * n12,
3605 const SMDS_MeshNode * n23,
3606 const SMDS_MeshNode * n31,
3607 const SMDS_MeshNode * n14,
3608 const SMDS_MeshNode * n24,
3609 const SMDS_MeshNode * n34)
3611 int ID = myElementIDFactory->GetFreeID();
3612 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3613 n31, n14, n24, n34, ID);
3614 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3618 //=======================================================================
3619 //function : AddVolumeWithID
3621 //=======================================================================
3622 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3623 int n12,int n23,int n31,
3624 int n14,int n24,int n34, int ID)
3626 return SMDS_Mesh::AddVolumeWithID
3627 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3628 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3629 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3630 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3631 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3632 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3633 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3634 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3635 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3636 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3640 //=======================================================================
3641 //function : AddVolumeWithID
3642 //purpose : 2d order tetrahedron of 10 nodes
3643 //=======================================================================
3644 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3645 const SMDS_MeshNode * n2,
3646 const SMDS_MeshNode * n3,
3647 const SMDS_MeshNode * n4,
3648 const SMDS_MeshNode * n12,
3649 const SMDS_MeshNode * n23,
3650 const SMDS_MeshNode * n31,
3651 const SMDS_MeshNode * n14,
3652 const SMDS_MeshNode * n24,
3653 const SMDS_MeshNode * n34,
3656 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3658 if(hasConstructionFaces()) {
3659 // creation quadratic faces - not implemented
3662 // --- retrieve nodes ID
3663 vector<vtkIdType> nodeIds;
3665 nodeIds.push_back(n1->getVtkId());
3666 nodeIds.push_back(n3->getVtkId());
3667 nodeIds.push_back(n2->getVtkId());
3668 nodeIds.push_back(n4->getVtkId());
3670 nodeIds.push_back(n31->getVtkId());
3671 nodeIds.push_back(n23->getVtkId());
3672 nodeIds.push_back(n12->getVtkId());
3674 nodeIds.push_back(n14->getVtkId());
3675 nodeIds.push_back(n34->getVtkId());
3676 nodeIds.push_back(n24->getVtkId());
3678 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3679 volvtk->init(nodeIds, this);
3680 if (!this->registerElement(ID,volvtk))
3682 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3683 myVolumePool->destroy(volvtk);
3686 adjustmyCellsCapacity(ID);
3687 myCells[ID] = volvtk;
3688 myInfo.myNbQuadTetras++;
3690 // if (!registerElement(ID, volvtk)) {
3691 // RemoveElement(volvtk, false);
3698 //=======================================================================
3699 //function : AddVolume
3701 //=======================================================================
3702 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3703 const SMDS_MeshNode * n2,
3704 const SMDS_MeshNode * n3,
3705 const SMDS_MeshNode * n4,
3706 const SMDS_MeshNode * n5,
3707 const SMDS_MeshNode * n12,
3708 const SMDS_MeshNode * n23,
3709 const SMDS_MeshNode * n34,
3710 const SMDS_MeshNode * n41,
3711 const SMDS_MeshNode * n15,
3712 const SMDS_MeshNode * n25,
3713 const SMDS_MeshNode * n35,
3714 const SMDS_MeshNode * n45)
3716 int ID = myElementIDFactory->GetFreeID();
3717 SMDS_MeshVolume * v =
3718 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3719 n15, n25, n35, n45, ID);
3720 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3724 //=======================================================================
3725 //function : AddVolumeWithID
3727 //=======================================================================
3728 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3729 int n12,int n23,int n34,int n41,
3730 int n15,int n25,int n35,int n45, int ID)
3732 return SMDS_Mesh::AddVolumeWithID
3733 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3734 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3735 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3736 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3737 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3738 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3739 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3740 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3741 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3742 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3743 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3744 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3745 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3749 //=======================================================================
3750 //function : AddVolumeWithID
3751 //purpose : 2d order pyramid of 13 nodes
3752 //=======================================================================
3753 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3754 const SMDS_MeshNode * n2,
3755 const SMDS_MeshNode * n3,
3756 const SMDS_MeshNode * n4,
3757 const SMDS_MeshNode * n5,
3758 const SMDS_MeshNode * n12,
3759 const SMDS_MeshNode * n23,
3760 const SMDS_MeshNode * n34,
3761 const SMDS_MeshNode * n41,
3762 const SMDS_MeshNode * n15,
3763 const SMDS_MeshNode * n25,
3764 const SMDS_MeshNode * n35,
3765 const SMDS_MeshNode * n45,
3768 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3769 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3771 if(hasConstructionFaces()) {
3772 // creation quadratic faces - not implemented
3775 // --- retrieve nodes ID
3776 vector<vtkIdType> nodeIds;
3778 nodeIds.push_back(n1->getVtkId());
3779 nodeIds.push_back(n4->getVtkId());
3780 nodeIds.push_back(n3->getVtkId());
3781 nodeIds.push_back(n2->getVtkId());
3782 nodeIds.push_back(n5->getVtkId());
3784 nodeIds.push_back(n41->getVtkId());
3785 nodeIds.push_back(n34->getVtkId());
3786 nodeIds.push_back(n23->getVtkId());
3787 nodeIds.push_back(n12->getVtkId());
3789 nodeIds.push_back(n15->getVtkId());
3790 nodeIds.push_back(n45->getVtkId());
3791 nodeIds.push_back(n35->getVtkId());
3792 nodeIds.push_back(n25->getVtkId());
3794 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3795 volvtk->init(nodeIds, this);
3796 if (!this->registerElement(ID,volvtk))
3798 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3799 myVolumePool->destroy(volvtk);
3802 adjustmyCellsCapacity(ID);
3803 myCells[ID] = volvtk;
3804 myInfo.myNbQuadPyramids++;
3806 // if (!registerElement(ID, volvtk)) {
3807 // RemoveElement(volvtk, false);
3814 //=======================================================================
3815 //function : AddVolume
3817 //=======================================================================
3818 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3819 const SMDS_MeshNode * n2,
3820 const SMDS_MeshNode * n3,
3821 const SMDS_MeshNode * n4,
3822 const SMDS_MeshNode * n5,
3823 const SMDS_MeshNode * n6,
3824 const SMDS_MeshNode * n12,
3825 const SMDS_MeshNode * n23,
3826 const SMDS_MeshNode * n31,
3827 const SMDS_MeshNode * n45,
3828 const SMDS_MeshNode * n56,
3829 const SMDS_MeshNode * n64,
3830 const SMDS_MeshNode * n14,
3831 const SMDS_MeshNode * n25,
3832 const SMDS_MeshNode * n36)
3834 int ID = myElementIDFactory->GetFreeID();
3835 SMDS_MeshVolume * v =
3836 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3837 n45, n56, n64, n14, n25, n36, ID);
3838 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3842 //=======================================================================
3843 //function : AddVolumeWithID
3845 //=======================================================================
3846 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3847 int n4, int n5, int n6,
3848 int n12,int n23,int n31,
3849 int n45,int n56,int n64,
3850 int n14,int n25,int n36, int ID)
3852 return SMDS_Mesh::AddVolumeWithID
3853 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3854 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3855 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3856 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3857 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3858 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3859 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3860 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3861 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3862 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3863 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3864 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3865 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3866 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3867 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3871 //=======================================================================
3872 //function : AddVolumeWithID
3873 //purpose : 2d order Pentahedron with 15 nodes
3874 //=======================================================================
3875 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3876 const SMDS_MeshNode * n2,
3877 const SMDS_MeshNode * n3,
3878 const SMDS_MeshNode * n4,
3879 const SMDS_MeshNode * n5,
3880 const SMDS_MeshNode * n6,
3881 const SMDS_MeshNode * n12,
3882 const SMDS_MeshNode * n23,
3883 const SMDS_MeshNode * n31,
3884 const SMDS_MeshNode * n45,
3885 const SMDS_MeshNode * n56,
3886 const SMDS_MeshNode * n64,
3887 const SMDS_MeshNode * n14,
3888 const SMDS_MeshNode * n25,
3889 const SMDS_MeshNode * n36,
3892 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3893 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3895 if(hasConstructionFaces()) {
3896 // creation quadratic faces - not implemented
3899 // --- retrieve nodes ID
3900 vector<vtkIdType> nodeIds;
3902 nodeIds.push_back(n1->getVtkId());
3903 nodeIds.push_back(n2->getVtkId());
3904 nodeIds.push_back(n3->getVtkId());
3906 nodeIds.push_back(n4->getVtkId());
3907 nodeIds.push_back(n5->getVtkId());
3908 nodeIds.push_back(n6->getVtkId());
3910 nodeIds.push_back(n12->getVtkId());
3911 nodeIds.push_back(n23->getVtkId());
3912 nodeIds.push_back(n31->getVtkId());
3914 nodeIds.push_back(n45->getVtkId());
3915 nodeIds.push_back(n56->getVtkId());
3916 nodeIds.push_back(n64->getVtkId());
3918 nodeIds.push_back(n14->getVtkId());
3919 nodeIds.push_back(n25->getVtkId());
3920 nodeIds.push_back(n36->getVtkId());
3922 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3923 volvtk->init(nodeIds, this);
3924 if (!this->registerElement(ID,volvtk))
3926 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3927 myVolumePool->destroy(volvtk);
3930 adjustmyCellsCapacity(ID);
3931 myCells[ID] = volvtk;
3932 myInfo.myNbQuadPrisms++;
3934 // if (!registerElement(ID, volvtk)) {
3935 // RemoveElement(volvtk, false);
3942 //=======================================================================
3943 //function : AddVolume
3945 //=======================================================================
3946 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3947 const SMDS_MeshNode * n2,
3948 const SMDS_MeshNode * n3,
3949 const SMDS_MeshNode * n4,
3950 const SMDS_MeshNode * n5,
3951 const SMDS_MeshNode * n6,
3952 const SMDS_MeshNode * n7,
3953 const SMDS_MeshNode * n8,
3954 const SMDS_MeshNode * n12,
3955 const SMDS_MeshNode * n23,
3956 const SMDS_MeshNode * n34,
3957 const SMDS_MeshNode * n41,
3958 const SMDS_MeshNode * n56,
3959 const SMDS_MeshNode * n67,
3960 const SMDS_MeshNode * n78,
3961 const SMDS_MeshNode * n85,
3962 const SMDS_MeshNode * n15,
3963 const SMDS_MeshNode * n26,
3964 const SMDS_MeshNode * n37,
3965 const SMDS_MeshNode * n48)
3967 int ID = myElementIDFactory->GetFreeID();
3968 SMDS_MeshVolume * v =
3969 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3970 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3971 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3975 //=======================================================================
3976 //function : AddVolumeWithID
3978 //=======================================================================
3979 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3980 int n5, int n6, int n7, int n8,
3981 int n12,int n23,int n34,int n41,
3982 int n56,int n67,int n78,int n85,
3983 int n15,int n26,int n37,int n48, int ID)
3985 return SMDS_Mesh::AddVolumeWithID
3986 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3997 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3999 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4000 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4001 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4002 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4003 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4004 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4005 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4009 //=======================================================================
4010 //function : AddVolumeWithID
4011 //purpose : 2d order Hexahedrons with 20 nodes
4012 //=======================================================================
4013 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4014 const SMDS_MeshNode * n2,
4015 const SMDS_MeshNode * n3,
4016 const SMDS_MeshNode * n4,
4017 const SMDS_MeshNode * n5,
4018 const SMDS_MeshNode * n6,
4019 const SMDS_MeshNode * n7,
4020 const SMDS_MeshNode * n8,
4021 const SMDS_MeshNode * n12,
4022 const SMDS_MeshNode * n23,
4023 const SMDS_MeshNode * n34,
4024 const SMDS_MeshNode * n41,
4025 const SMDS_MeshNode * n56,
4026 const SMDS_MeshNode * n67,
4027 const SMDS_MeshNode * n78,
4028 const SMDS_MeshNode * n85,
4029 const SMDS_MeshNode * n15,
4030 const SMDS_MeshNode * n26,
4031 const SMDS_MeshNode * n37,
4032 const SMDS_MeshNode * n48,
4035 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4036 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4038 if(hasConstructionFaces()) {
4040 // creation quadratic faces - not implemented
4042 // --- retrieve nodes ID
4043 vector<vtkIdType> nodeIds;
4045 nodeIds.push_back(n1->getVtkId());
4046 nodeIds.push_back(n4->getVtkId());
4047 nodeIds.push_back(n3->getVtkId());
4048 nodeIds.push_back(n2->getVtkId());
4050 nodeIds.push_back(n5->getVtkId());
4051 nodeIds.push_back(n8->getVtkId());
4052 nodeIds.push_back(n7->getVtkId());
4053 nodeIds.push_back(n6->getVtkId());
4055 nodeIds.push_back(n41->getVtkId());
4056 nodeIds.push_back(n34->getVtkId());
4057 nodeIds.push_back(n23->getVtkId());
4058 nodeIds.push_back(n12->getVtkId());
4060 nodeIds.push_back(n85->getVtkId());
4061 nodeIds.push_back(n78->getVtkId());
4062 nodeIds.push_back(n67->getVtkId());
4063 nodeIds.push_back(n56->getVtkId());
4065 nodeIds.push_back(n15->getVtkId());
4066 nodeIds.push_back(n48->getVtkId());
4067 nodeIds.push_back(n37->getVtkId());
4068 nodeIds.push_back(n26->getVtkId());
4070 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4071 volvtk->init(nodeIds, this);
4072 if (!this->registerElement(ID,volvtk))
4074 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4075 myVolumePool->destroy(volvtk);
4078 adjustmyCellsCapacity(ID);
4079 myCells[ID] = volvtk;
4080 myInfo.myNbQuadHexas++;
4082 // if (!registerElement(ID, volvtk)) {
4083 // RemoveElement(volvtk, false);
4089 void SMDS_Mesh::updateNodeMinMax()
4092 if (myNodes.size() == 0)
4097 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4099 myNodeMax=myNodes.size()-1;
4100 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4104 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4106 // int val = myCellIdSmdsToVtk.size();
4107 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4108 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4109 int val = myNodes.size();
4110 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4111 myNodes.resize(val +nbNodes, 0);
4114 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4116 int val = myCellIdVtkToSmds.size();
4117 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4118 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4119 val = myCells.size();
4120 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4121 myNodes.resize(val +nbCells, 0);
4124 void SMDS_Mesh::adjustStructure()
4126 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4129 void SMDS_Mesh::dumpGrid(string ficdump)
4131 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4132 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4133 // aWriter->SetFileName(ficdump.c_str());
4134 // aWriter->SetInput(myGrid);
4135 // if(myGrid->GetNumberOfCells())
4137 // aWriter->Write();
4139 // aWriter->Delete();
4140 ficdump = ficdump + "_connectivity";
4141 ofstream ficcon(ficdump.c_str(), ios::out);
4142 int nbPoints = myGrid->GetNumberOfPoints();
4143 ficcon << "-------------------------------- points " << nbPoints << endl;
4144 for (int i=0; i<nbPoints; i++)
4146 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4148 int nbCells = myGrid->GetNumberOfCells();
4149 ficcon << "-------------------------------- cells " << nbCells << endl;
4150 for (int i=0; i<nbCells; i++)
4152 // MESSAGE(i << " " << myGrid->GetCell(i));
4153 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4154 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4155 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4156 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4157 for (int j=0; j<nbptcell; j++)
4159 ficcon << " " << listid->GetId(j);
4163 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4164 vtkCellLinks *links = myGrid->GetCellLinks();
4165 for (int i=0; i<nbPoints; i++)
4167 int ncells = links->GetNcells(i);
4168 vtkIdType *cells = links->GetCells(i);
4169 ficcon << i << " - " << ncells << " -";
4170 for (int j=0; j<ncells; j++)
4172 ficcon << " " << cells[j];
4180 void SMDS_Mesh::compactMesh()
4182 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4185 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4187 if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4188 return myCellIdVtkToSmds[vtkid];
4189 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4192 void SMDS_Mesh::updateBoundingBox()
4197 vtkPoints *points = myGrid->GetPoints();
4198 int myNodesSize = this->myNodes.size();
4199 for (int i = 0; i < myNodesSize; i++)
4201 if (SMDS_MeshNode *n = myNodes[i])
4204 points->GetPoint(n->myVtkID, coords);
4205 if (coords[0] < xmin) xmin = coords[0];
4206 else if (coords[0] > xmax) xmax = coords[0];
4207 if (coords[1] < ymin) ymin = coords[1];
4208 else if (coords[1] > ymax) ymax = coords[1];
4209 if (coords[2] < zmin) zmin = coords[2];
4210 else if (coords[2] > zmax) zmax = coords[2];
4215 double SMDS_Mesh::getMaxDim()
4217 double dmax = 1.e-3;
4218 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4219 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4220 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4221 MESSAGE("getMaxDim " << dmax);
4225 //! modification that needs compact structure and redraw
4226 void SMDS_Mesh::Modified()
4228 if (this->myModified)
4230 this->myModifTime++;
4231 MESSAGE("modified");
4236 //! get last modification timeStamp
4237 unsigned long SMDS_Mesh::GetMTime()
4239 return this->myModifTime;
4242 bool SMDS_Mesh::isCompacted()
4244 if (this->myModifTime > this->myCompactTime)
4246 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4247 this->myCompactTime = this->myModifTime;