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);
219 MESSAGE("=============> Bad Node Id: " << ID);
220 ID = myNodeIDFactory->GetFreeID();
222 myNodeIDFactory->adjustMaxId(ID);
223 SMDS_MeshNode * node = myNodePool->getNew();
224 node->init(ID, myMeshId, 0, x, y, z);
226 //rnv: Set SMDS_SpacePosition for node if need
227 if( node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE)
228 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
230 if (ID >= myNodes.size())
232 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
233 MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
236 myNodeIDFactory->BindID(ID,node);
239 this->adjustBoundingBox(x, y, z);
245 ///////////////////////////////////////////////////////////////////////////////
246 /// create a Mesh0DElement and add it to the current Mesh
247 /// @return : The created Mesh0DElement
248 ///////////////////////////////////////////////////////////////////////////////
249 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
251 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
252 if (!node) return NULL;
253 return SMDS_Mesh::Add0DElementWithID(node, ID);
256 ///////////////////////////////////////////////////////////////////////////////
257 /// create a Mesh0DElement and add it to the current Mesh
258 /// @return : The created Mesh0DElement
259 ///////////////////////////////////////////////////////////////////////////////
260 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
262 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
265 ///////////////////////////////////////////////////////////////////////////////
266 /// Create a new Mesh0DElement and at it to the mesh
267 /// @param idnode ID of the node
268 /// @param ID ID of the 0D element to create
269 /// @return The created 0D element or NULL if an element with this
270 /// ID already exists or if input node is not found.
271 ///////////////////////////////////////////////////////////////////////////////
272 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
276 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
277 //MESSAGE("Add0DElementWithID" << ID)
278 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
279 if (myElementIDFactory->BindID(ID, el0d)) {
280 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
281 //node->AddInverseElement(el0d);// --- fait avec BindID
282 adjustmyCellsCapacity(ID);
284 myInfo.myNb0DElements++;
292 ///////////////////////////////////////////////////////////////////////////////
293 /// create a MeshEdge and add it to the current Mesh
294 /// @return : The created MeshEdge
295 ///////////////////////////////////////////////////////////////////////////////
297 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
299 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
300 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
301 if(!node1 || !node2) return NULL;
302 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
305 ///////////////////////////////////////////////////////////////////////////////
306 /// create a MeshEdge and add it to the current Mesh
307 /// @return : The created MeshEdge
308 ///////////////////////////////////////////////////////////////////////////////
310 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
311 const SMDS_MeshNode * node2)
313 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
316 ///////////////////////////////////////////////////////////////////////////////
317 /// Create a new edge and at it to the mesh
318 /// @param idnode1 ID of the first node
319 /// @param idnode2 ID of the second node
320 /// @param ID ID of the edge to create
321 /// @return The created edge or NULL if an element with this ID already exists or
322 /// if input nodes are not found.
323 ///////////////////////////////////////////////////////////////////////////////
325 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
326 const SMDS_MeshNode * n2,
329 if ( !n1 || !n2 ) return 0;
330 SMDS_MeshEdge * edge = 0;
332 // --- retreive nodes ID
333 vector<vtkIdType> nodeIds;
335 nodeIds.push_back(n1->getVtkId());
336 nodeIds.push_back(n2->getVtkId());
338 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
339 edgevtk->init(nodeIds, this);
340 if (!this->registerElement(ID,edgevtk))
342 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
343 myEdgePool->destroy(edgevtk);
347 adjustmyCellsCapacity(ID);
351 // if (edge && !registerElement(ID, edge))
353 // RemoveElement(edge, false);
359 ///////////////////////////////////////////////////////////////////////////////
360 /// Add a triangle defined by its nodes. An ID is automatically affected to the
362 ///////////////////////////////////////////////////////////////////////////////
364 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
365 const SMDS_MeshNode * n2,
366 const SMDS_MeshNode * n3)
368 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
371 ///////////////////////////////////////////////////////////////////////////////
372 /// Add a triangle defined by its nodes IDs
373 ///////////////////////////////////////////////////////////////////////////////
375 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
377 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
378 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
379 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
380 if(!node1 || !node2 || !node3) return NULL;
381 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
384 ///////////////////////////////////////////////////////////////////////////////
385 /// Add a triangle defined by its nodes
386 ///////////////////////////////////////////////////////////////////////////////
388 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
389 const SMDS_MeshNode * n2,
390 const SMDS_MeshNode * n3,
393 //MESSAGE("AddFaceWithID " << ID)
394 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
396 // if (face && !registerElement(ID, face)) {
397 // RemoveElement(face, false);
403 ///////////////////////////////////////////////////////////////////////////////
404 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
406 ///////////////////////////////////////////////////////////////////////////////
408 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
409 const SMDS_MeshNode * n2,
410 const SMDS_MeshNode * n3,
411 const SMDS_MeshNode * n4)
413 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
416 ///////////////////////////////////////////////////////////////////////////////
417 /// Add a quadrangle defined by its nodes IDs
418 ///////////////////////////////////////////////////////////////////////////////
420 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
426 SMDS_MeshNode *node1, *node2, *node3, *node4;
427 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
428 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
429 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
430 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
431 if(!node1 || !node2 || !node3 || !node4) return NULL;
432 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
435 ///////////////////////////////////////////////////////////////////////////////
436 /// Add a quadrangle defined by its nodes
437 ///////////////////////////////////////////////////////////////////////////////
439 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
440 const SMDS_MeshNode * n2,
441 const SMDS_MeshNode * n3,
442 const SMDS_MeshNode * n4,
445 //MESSAGE("AddFaceWithID " << ID);
446 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
448 // if (face && !registerElement(ID, face)) {
449 // RemoveElement(face, false);
455 ///////////////////////////////////////////////////////////////////////////////
456 /// Add a triangle defined by its edges. An ID is automatically assigned to the
458 ///////////////////////////////////////////////////////////////////////////////
460 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
461 const SMDS_MeshEdge * e2,
462 const SMDS_MeshEdge * e3)
464 if (!hasConstructionEdges())
466 //MESSAGE("AddFaceWithID");
467 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
470 ///////////////////////////////////////////////////////////////////////////////
471 /// Add a triangle defined by its edges
472 ///////////////////////////////////////////////////////////////////////////////
474 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
475 const SMDS_MeshEdge * e2,
476 const SMDS_MeshEdge * e3,
479 if (!hasConstructionEdges())
481 if ( !e1 || !e2 || !e3 ) return 0;
483 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
484 MESSAGE("AddFaceWithID" << ID);
486 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
487 adjustmyCellsCapacity(ID);
489 myInfo.myNbTriangles++;
491 if (!registerElement(ID, face)) {
492 registerElement(myElementIDFactory->GetFreeID(), face);
493 //RemoveElement(face, false);
499 ///////////////////////////////////////////////////////////////////////////////
500 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
502 ///////////////////////////////////////////////////////////////////////////////
504 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
505 const SMDS_MeshEdge * e2,
506 const SMDS_MeshEdge * e3,
507 const SMDS_MeshEdge * e4)
509 if (!hasConstructionEdges())
511 //MESSAGE("AddFaceWithID" );
512 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
515 ///////////////////////////////////////////////////////////////////////////////
516 /// Add a quadrangle defined by its edges
517 ///////////////////////////////////////////////////////////////////////////////
519 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
520 const SMDS_MeshEdge * e2,
521 const SMDS_MeshEdge * e3,
522 const SMDS_MeshEdge * e4,
525 if (!hasConstructionEdges())
527 MESSAGE("AddFaceWithID" << ID);
528 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
529 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
530 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
531 adjustmyCellsCapacity(ID);
533 myInfo.myNbQuadrangles++;
535 if (!registerElement(ID, face))
537 registerElement(myElementIDFactory->GetFreeID(), face);
538 //RemoveElement(face, false);
544 ///////////////////////////////////////////////////////////////////////////////
545 ///Create a new tetrahedron and add it to the mesh.
546 ///@return The created tetrahedron
547 ///////////////////////////////////////////////////////////////////////////////
549 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
550 const SMDS_MeshNode * n2,
551 const SMDS_MeshNode * n3,
552 const SMDS_MeshNode * n4)
554 int ID = myElementIDFactory->GetFreeID();
555 //MESSAGE("AddVolumeWithID " << ID);
556 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
557 if(v==NULL) myElementIDFactory->ReleaseID(ID);
561 ///////////////////////////////////////////////////////////////////////////////
562 ///Create a new tetrahedron and add it to the mesh.
563 ///@param ID The ID of the new volume
564 ///@return The created tetrahedron or NULL if an element with this ID already exists
565 ///or if input nodes are not found.
566 ///////////////////////////////////////////////////////////////////////////////
568 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
574 //MESSAGE("AddVolumeWithID" << ID);
575 SMDS_MeshNode *node1, *node2, *node3, *node4;
576 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
577 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
578 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
579 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
580 if(!node1 || !node2 || !node3 || !node4) return NULL;
581 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
584 ///////////////////////////////////////////////////////////////////////////////
585 ///Create a new tetrahedron and add it to the mesh.
586 ///@param ID The ID of the new volume
587 ///@return The created tetrahedron
588 ///////////////////////////////////////////////////////////////////////////////
590 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
591 const SMDS_MeshNode * n2,
592 const SMDS_MeshNode * n3,
593 const SMDS_MeshNode * n4,
596 //MESSAGE("AddVolumeWithID " << ID);
597 SMDS_MeshVolume* volume = 0;
598 if ( !n1 || !n2 || !n3 || !n4) return volume;
599 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
600 if(hasConstructionFaces()) {
601 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
602 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
603 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
604 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
605 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
606 adjustmyCellsCapacity(ID);
607 myCells[ID] = volume;
610 else if(hasConstructionEdges()) {
611 MESSAGE("Error : Not implemented");
615 // --- retrieve nodes ID
616 vector<vtkIdType> nodeIds;
618 nodeIds.push_back(n1->getVtkId());
619 nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
620 nodeIds.push_back(n2->getVtkId());
621 nodeIds.push_back(n4->getVtkId());
623 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
624 volvtk->init(nodeIds, this);
625 if (!this->registerElement(ID,volvtk))
627 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
628 myVolumePool->destroy(volvtk);
632 adjustmyCellsCapacity(ID);
633 myCells[ID] = volume;
637 // if (!registerElement(ID, volume)) {
638 // RemoveElement(volume, false);
644 ///////////////////////////////////////////////////////////////////////////////
645 ///Create a new pyramid and add it to the mesh.
646 ///Nodes 1,2,3 and 4 define the base of the pyramid
647 ///@return The created pyramid
648 ///////////////////////////////////////////////////////////////////////////////
650 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
651 const SMDS_MeshNode * n2,
652 const SMDS_MeshNode * n3,
653 const SMDS_MeshNode * n4,
654 const SMDS_MeshNode * n5)
656 int ID = myElementIDFactory->GetFreeID();
657 //MESSAGE("AddVolumeWithID " << ID);
658 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
659 if(v==NULL) myElementIDFactory->ReleaseID(ID);
663 ///////////////////////////////////////////////////////////////////////////////
664 ///Create a new pyramid and add it to the mesh.
665 ///Nodes 1,2,3 and 4 define the base of the pyramid
666 ///@param ID The ID of the new volume
667 ///@return The created pyramid or NULL if an element with this ID already exists
668 ///or if input nodes are not found.
669 ///////////////////////////////////////////////////////////////////////////////
671 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
678 //MESSAGE("AddVolumeWithID " << ID);
679 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
680 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
681 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
682 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
683 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
684 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
685 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
686 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
689 ///////////////////////////////////////////////////////////////////////////////
690 ///Create a new pyramid and add it to the mesh.
691 ///Nodes 1,2,3 and 4 define the base of the pyramid
692 ///@param ID The ID of the new volume
693 ///@return The created pyramid
694 ///////////////////////////////////////////////////////////////////////////////
696 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
697 const SMDS_MeshNode * n2,
698 const SMDS_MeshNode * n3,
699 const SMDS_MeshNode * n4,
700 const SMDS_MeshNode * n5,
703 //MESSAGE("AddVolumeWithID " << ID);
704 SMDS_MeshVolume* volume = 0;
705 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
706 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
707 if(hasConstructionFaces()) {
708 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
709 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
710 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
711 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
712 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
713 adjustmyCellsCapacity(ID);
714 myCells[ID] = volume;
715 myInfo.myNbPyramids++;
717 else if(hasConstructionEdges()) {
718 MESSAGE("Error : Not implemented");
722 // --- retrieve nodes ID
723 vector<vtkIdType> nodeIds;
725 nodeIds.push_back(n1->getVtkId());
726 nodeIds.push_back(n4->getVtkId());
727 nodeIds.push_back(n3->getVtkId());
728 nodeIds.push_back(n2->getVtkId());
729 nodeIds.push_back(n5->getVtkId());
731 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
732 volvtk->init(nodeIds, this);
733 if (!this->registerElement(ID,volvtk))
735 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
736 myVolumePool->destroy(volvtk);
740 adjustmyCellsCapacity(ID);
741 myCells[ID] = volume;
742 myInfo.myNbPyramids++;
745 // if (!registerElement(ID, volume)) {
746 // RemoveElement(volume, false);
752 ///////////////////////////////////////////////////////////////////////////////
753 ///Create a new prism and add it to the mesh.
754 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
755 ///@return The created prism
756 ///////////////////////////////////////////////////////////////////////////////
758 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
759 const SMDS_MeshNode * n2,
760 const SMDS_MeshNode * n3,
761 const SMDS_MeshNode * n4,
762 const SMDS_MeshNode * n5,
763 const SMDS_MeshNode * n6)
765 int ID = myElementIDFactory->GetFreeID();
766 //MESSAGE("AddVolumeWithID " << ID);
767 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
768 if(v==NULL) myElementIDFactory->ReleaseID(ID);
772 ///////////////////////////////////////////////////////////////////////////////
773 ///Create a new prism and add it to the mesh.
774 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
775 ///@param ID The ID of the new volume
776 ///@return The created prism or NULL if an element with this ID already exists
777 ///or if input nodes are not found.
778 ///////////////////////////////////////////////////////////////////////////////
780 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
788 //MESSAGE("AddVolumeWithID " << ID);
789 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
790 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
791 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
792 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
793 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
794 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
795 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
796 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
797 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
800 ///////////////////////////////////////////////////////////////////////////////
801 ///Create a new prism and add it to the mesh.
802 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
803 ///@param ID The ID of the new volume
804 ///@return The created prism
805 ///////////////////////////////////////////////////////////////////////////////
807 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
808 const SMDS_MeshNode * n2,
809 const SMDS_MeshNode * n3,
810 const SMDS_MeshNode * n4,
811 const SMDS_MeshNode * n5,
812 const SMDS_MeshNode * n6,
815 //MESSAGE("AddVolumeWithID " << ID);
816 SMDS_MeshVolume* volume = 0;
817 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
818 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
819 if(hasConstructionFaces()) {
820 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
821 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
822 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
823 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
824 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
825 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
826 adjustmyCellsCapacity(ID);
827 myCells[ID] = volume;
830 else if(hasConstructionEdges()) {
831 MESSAGE("Error : Not implemented");
835 // --- retrieve nodes ID
836 vector<vtkIdType> nodeIds;
838 nodeIds.push_back(n1->getVtkId());
839 nodeIds.push_back(n2->getVtkId());
840 nodeIds.push_back(n3->getVtkId());
841 nodeIds.push_back(n4->getVtkId());
842 nodeIds.push_back(n5->getVtkId());
843 nodeIds.push_back(n6->getVtkId());
845 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
846 volvtk->init(nodeIds, this);
847 if (!this->registerElement(ID,volvtk))
849 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
850 myVolumePool->destroy(volvtk);
854 adjustmyCellsCapacity(ID);
855 myCells[ID] = volume;
859 // if (!registerElement(ID, volume)) {
860 // RemoveElement(volume, false);
866 ///////////////////////////////////////////////////////////////////////////////
867 ///Create a new hexahedron and add it to the mesh.
868 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
869 ///@return The created hexahedron
870 ///////////////////////////////////////////////////////////////////////////////
872 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
873 const SMDS_MeshNode * n2,
874 const SMDS_MeshNode * n3,
875 const SMDS_MeshNode * n4,
876 const SMDS_MeshNode * n5,
877 const SMDS_MeshNode * n6,
878 const SMDS_MeshNode * n7,
879 const SMDS_MeshNode * n8)
881 int ID = myElementIDFactory->GetFreeID();
882 //MESSAGE("AddVolumeWithID " << ID);
883 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
884 if(v==NULL) myElementIDFactory->ReleaseID(ID);
888 ///////////////////////////////////////////////////////////////////////////////
889 ///Create a new hexahedron and add it to the mesh.
890 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
891 ///@param ID The ID of the new volume
892 ///@return The created hexahedron or NULL if an element with this ID already
893 ///exists or if input nodes are not found.
894 ///////////////////////////////////////////////////////////////////////////////
896 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
906 //MESSAGE("AddVolumeWithID " << ID);
907 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
908 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
909 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
910 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
911 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
912 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
913 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
914 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
915 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
916 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
918 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
922 ///////////////////////////////////////////////////////////////////////////////
923 ///Create a new hexahedron and add it to the mesh.
924 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
925 ///@param ID The ID of the new volume
926 ///@return The created prism or NULL if an element with this ID already exists
927 ///or if input nodes are not found.
928 ///////////////////////////////////////////////////////////////////////////////
930 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
931 const SMDS_MeshNode * n2,
932 const SMDS_MeshNode * n3,
933 const SMDS_MeshNode * n4,
934 const SMDS_MeshNode * n5,
935 const SMDS_MeshNode * n6,
936 const SMDS_MeshNode * n7,
937 const SMDS_MeshNode * n8,
940 //MESSAGE("AddVolumeWithID " << ID);
941 SMDS_MeshVolume* volume = 0;
942 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
943 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
944 if(hasConstructionFaces()) {
945 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
946 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
947 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
948 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
949 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
950 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
951 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
952 adjustmyCellsCapacity(ID);
953 myCells[ID] = volume;
956 else if(hasConstructionEdges()) {
957 MESSAGE("Error : Not implemented");
961 // --- retrieve nodes ID
962 vector<vtkIdType> nodeIds;
964 nodeIds.push_back(n1->getVtkId());
965 nodeIds.push_back(n4->getVtkId());
966 nodeIds.push_back(n3->getVtkId());
967 nodeIds.push_back(n2->getVtkId());
968 nodeIds.push_back(n5->getVtkId());
969 nodeIds.push_back(n8->getVtkId());
970 nodeIds.push_back(n7->getVtkId());
971 nodeIds.push_back(n6->getVtkId());
973 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
974 volvtk->init(nodeIds, this);
975 if (!this->registerElement(ID,volvtk))
977 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
978 myVolumePool->destroy(volvtk);
982 adjustmyCellsCapacity(ID);
983 myCells[ID] = volume;
987 // if (!registerElement(ID, volume)) {
988 // RemoveElement(volume, false);
994 ///////////////////////////////////////////////////////////////////////////////
995 ///Create a new tetrahedron defined by its faces and add it to the mesh.
996 ///@return The created tetrahedron
997 ///////////////////////////////////////////////////////////////////////////////
999 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1000 const SMDS_MeshFace * f2,
1001 const SMDS_MeshFace * f3,
1002 const SMDS_MeshFace * f4)
1004 //MESSAGE("AddVolumeWithID");
1005 if (!hasConstructionFaces())
1007 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1010 ///////////////////////////////////////////////////////////////////////////////
1011 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1012 ///@param ID The ID of the new volume
1013 ///@return The created tetrahedron
1014 ///////////////////////////////////////////////////////////////////////////////
1016 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1017 const SMDS_MeshFace * f2,
1018 const SMDS_MeshFace * f3,
1019 const SMDS_MeshFace * f4,
1022 MESSAGE("AddVolumeWithID" << ID);
1023 if (!hasConstructionFaces())
1025 if ( !f1 || !f2 || !f3 || !f4) return 0;
1026 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1027 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1028 adjustmyCellsCapacity(ID);
1029 myCells[ID] = volume;
1030 myInfo.myNbTetras++;
1032 if (!registerElement(ID, volume)) {
1033 registerElement(myElementIDFactory->GetFreeID(), volume);
1034 //RemoveElement(volume, false);
1040 ///////////////////////////////////////////////////////////////////////////////
1041 ///Create a new pyramid defined by its faces and add it to the mesh.
1042 ///@return The created pyramid
1043 ///////////////////////////////////////////////////////////////////////////////
1045 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1046 const SMDS_MeshFace * f2,
1047 const SMDS_MeshFace * f3,
1048 const SMDS_MeshFace * f4,
1049 const SMDS_MeshFace * f5)
1051 //MESSAGE("AddVolumeWithID");
1052 if (!hasConstructionFaces())
1054 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1057 ///////////////////////////////////////////////////////////////////////////////
1058 ///Create a new pyramid defined by its faces and add it to the mesh.
1059 ///@param ID The ID of the new volume
1060 ///@return The created pyramid
1061 ///////////////////////////////////////////////////////////////////////////////
1063 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1064 const SMDS_MeshFace * f2,
1065 const SMDS_MeshFace * f3,
1066 const SMDS_MeshFace * f4,
1067 const SMDS_MeshFace * f5,
1070 MESSAGE("AddVolumeWithID" << ID);
1071 if (!hasConstructionFaces())
1073 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1074 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1075 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1076 adjustmyCellsCapacity(ID);
1077 myCells[ID] = volume;
1078 myInfo.myNbPyramids++;
1080 if (!registerElement(ID, volume)) {
1081 registerElement(myElementIDFactory->GetFreeID(), volume);
1082 //RemoveElement(volume, false);
1088 ///////////////////////////////////////////////////////////////////////////////
1089 ///Create a new prism defined by its faces and add it to the mesh.
1090 ///@return The created prism
1091 ///////////////////////////////////////////////////////////////////////////////
1093 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1094 const SMDS_MeshFace * f2,
1095 const SMDS_MeshFace * f3,
1096 const SMDS_MeshFace * f4,
1097 const SMDS_MeshFace * f5,
1098 const SMDS_MeshFace * f6)
1100 //MESSAGE("AddVolumeWithID" );
1101 if (!hasConstructionFaces())
1103 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1106 ///////////////////////////////////////////////////////////////////////////////
1107 ///Create a new prism defined by its faces and add it to the mesh.
1108 ///@param ID The ID of the new volume
1109 ///@return The created prism
1110 ///////////////////////////////////////////////////////////////////////////////
1112 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1113 const SMDS_MeshFace * f2,
1114 const SMDS_MeshFace * f3,
1115 const SMDS_MeshFace * f4,
1116 const SMDS_MeshFace * f5,
1117 const SMDS_MeshFace * f6,
1120 MESSAGE("AddVolumeWithID" << ID);
1121 if (!hasConstructionFaces())
1123 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1124 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1125 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1126 adjustmyCellsCapacity(ID);
1127 myCells[ID] = volume;
1128 myInfo.myNbPrisms++;
1130 if (!registerElement(ID, volume)) {
1131 registerElement(myElementIDFactory->GetFreeID(), volume);
1132 //RemoveElement(volume, false);
1138 ///////////////////////////////////////////////////////////////////////////////
1139 /// Add a polygon defined by its nodes IDs
1140 ///////////////////////////////////////////////////////////////////////////////
1142 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
1145 int nbNodes = nodes_ids.size();
1146 vector<const SMDS_MeshNode*> nodes (nbNodes);
1147 for (int i = 0; i < nbNodes; i++) {
1148 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1149 if (!nodes[i]) return NULL;
1151 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1154 ///////////////////////////////////////////////////////////////////////////////
1155 /// Add a polygon defined by its nodes
1156 ///////////////////////////////////////////////////////////////////////////////
1158 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1159 (vector<const SMDS_MeshNode*> nodes,
1162 SMDS_MeshFace * face;
1164 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1165 if (hasConstructionEdges())
1167 MESSAGE("Error : Not implemented");
1172 //#ifdef VTK_HAVE_POLYHEDRON
1173 //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
1174 vector<vtkIdType> nodeIds;
1176 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1177 for ( ; it != nodes.end(); ++it)
1178 nodeIds.push_back((*it)->getVtkId());
1180 SMDS_VtkFace *facevtk = myFacePool->getNew();
1181 facevtk->initPoly(nodeIds, this);
1182 if (!this->registerElement(ID,facevtk))
1184 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1185 myFacePool->destroy(facevtk);
1190 // MESSAGE("AddPolygonalFaceWithID smds " << ID);
1191 // for ( int i = 0; i < nodes.size(); ++i )
1192 // if ( !nodes[ i ] ) return 0;
1193 // face = new SMDS_PolygonalFaceOfNodes(nodes);
1195 adjustmyCellsCapacity(ID);
1197 myInfo.myNbPolygons++;
1200 //#ifndef VTK_HAVE_POLYHEDRON
1201 // if (!registerElement(ID, face))
1203 // registerElement(myElementIDFactory->GetFreeID(), face);
1204 // //RemoveElement(face, false);
1211 ///////////////////////////////////////////////////////////////////////////////
1212 /// Add a polygon defined by its nodes.
1213 /// An ID is automatically affected to the created face.
1214 ///////////////////////////////////////////////////////////////////////////////
1216 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
1218 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1221 ///////////////////////////////////////////////////////////////////////////////
1222 /// Create a new polyhedral volume and add it to the mesh.
1223 /// @param ID The ID of the new volume
1224 /// @return The created volume or NULL if an element with this ID already exists
1225 /// or if input nodes are not found.
1226 ///////////////////////////////////////////////////////////////////////////////
1228 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1229 (vector<int> nodes_ids,
1230 vector<int> quantities,
1233 int nbNodes = nodes_ids.size();
1234 vector<const SMDS_MeshNode*> nodes (nbNodes);
1235 for (int i = 0; i < nbNodes; i++) {
1236 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1237 if (!nodes[i]) return NULL;
1239 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1242 ///////////////////////////////////////////////////////////////////////////////
1243 /// Create a new polyhedral volume and add it to the mesh.
1244 /// @param ID The ID of the new volume
1245 /// @return The created volume
1246 ///////////////////////////////////////////////////////////////////////////////
1248 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1249 (vector<const SMDS_MeshNode*> nodes,
1250 vector<int> quantities,
1253 SMDS_MeshVolume* volume;
1254 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1255 if (hasConstructionFaces())
1257 MESSAGE("Error : Not implemented");
1260 else if (hasConstructionEdges())
1262 MESSAGE("Error : Not implemented");
1267 //#ifdef VTK_HAVE_POLYHEDRON
1268 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1269 vector<vtkIdType> nodeIds;
1271 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1272 for (; it != nodes.end(); ++it)
1273 nodeIds.push_back((*it)->getVtkId());
1275 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1276 volvtk->initPoly(nodeIds, quantities, this);
1277 if (!this->registerElement(ID, volvtk))
1279 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1280 myVolumePool->destroy(volvtk);
1285 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1286 // for ( int i = 0; i < nodes.size(); ++i )
1287 // if ( !nodes[ i ] ) return 0;
1288 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1290 adjustmyCellsCapacity(ID);
1291 myCells[ID] = volume;
1292 myInfo.myNbPolyhedrons++;
1295 //#ifndef VTK_HAVE_POLYHEDRON
1296 // if (!registerElement(ID, volume))
1298 // registerElement(myElementIDFactory->GetFreeID(), volume);
1299 // //RemoveElement(volume, false);
1306 ///////////////////////////////////////////////////////////////////////////////
1307 /// Create a new polyhedral volume and add it to the mesh.
1308 /// @return The created volume
1309 ///////////////////////////////////////////////////////////////////////////////
1311 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1312 (vector<const SMDS_MeshNode*> nodes,
1313 vector<int> quantities)
1315 int ID = myElementIDFactory->GetFreeID();
1316 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1317 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1321 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1323 int ID = myElementIDFactory->GetFreeID();
1324 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1325 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1329 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1331 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1332 volvtk->init(vtkNodeIds, this);
1333 if (!this->registerElement(ID,volvtk))
1335 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1336 myVolumePool->destroy(volvtk);
1339 adjustmyCellsCapacity(ID);
1340 myCells[ID] = volvtk;
1341 vtkIdType aVtkType = volvtk->GetVtkType();
1345 myInfo.myNbTetras++;
1348 myInfo.myNbPyramids++;
1351 myInfo.myNbPrisms++;
1353 case VTK_HEXAHEDRON:
1356 case VTK_QUADRATIC_TETRA:
1357 myInfo.myNbQuadTetras++;
1359 case VTK_QUADRATIC_PYRAMID:
1360 myInfo.myNbQuadPyramids++;
1362 case VTK_QUADRATIC_WEDGE:
1363 myInfo.myNbQuadPrisms++;
1365 case VTK_QUADRATIC_HEXAHEDRON:
1366 myInfo.myNbQuadHexas++;
1368 //#ifdef VTK_HAVE_POLYHEDRON
1369 case VTK_POLYHEDRON:
1370 myInfo.myNbPolyhedrons++;
1374 myInfo.myNbPolyhedrons++;
1380 ///////////////////////////////////////////////////////////////////////////////
1381 /// Registers element with the given ID, maintains inverse connections
1382 ///////////////////////////////////////////////////////////////////////////////
1383 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1385 //MESSAGE("registerElement " << ID);
1386 if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1388 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1393 element->myMeshId = myMeshId;
1395 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1397 int vtkId = cell->getVtkId();
1399 vtkId = myElementIDFactory->SetInVtkGrid(element);
1401 if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1403 MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1404 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1406 myCellIdVtkToSmds[vtkId] = ID;
1408 myElementIDFactory->updateMinMax(ID);
1412 ///////////////////////////////////////////////////////////////////////////////
1413 /// Return the node whose SMDS ID is 'ID'.
1414 ///////////////////////////////////////////////////////////////////////////////
1415 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1417 if (ID < 1 || ID >= myNodes.size())
1419 MESSAGE("------------------------------------------------------------------------- ");
1420 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1421 MESSAGE("------------------------------------------------------------------------- ");
1424 return (const SMDS_MeshNode *)myNodes[ID];
1427 ///////////////////////////////////////////////////////////////////////////////
1428 /// Return the node whose VTK ID is 'vtkId'.
1429 ///////////////////////////////////////////////////////////////////////////////
1430 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1432 // TODO if needed use mesh->nodeIdFromVtkToSmds
1433 if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1435 MESSAGE("------------------------------------------------------------------------- ");
1436 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1437 MESSAGE("------------------------------------------------------------------------- ");
1440 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1443 ///////////////////////////////////////////////////////////////////////////////
1444 ///Create a triangle and add it to the current mesh. This method do not bind an
1445 ///ID to the create triangle.
1446 ///////////////////////////////////////////////////////////////////////////////
1447 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1448 const SMDS_MeshNode * node2,
1449 const SMDS_MeshNode * node3,
1452 if ( !node1 || !node2 || !node3) return 0;
1453 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1454 if(hasConstructionEdges())
1456 SMDS_MeshEdge *edge1, *edge2, *edge3;
1457 edge1=FindEdgeOrCreate(node1,node2);
1458 edge2=FindEdgeOrCreate(node2,node3);
1459 edge3=FindEdgeOrCreate(node3,node1);
1461 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1462 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1463 adjustmyCellsCapacity(ID);
1465 myInfo.myNbTriangles++;
1470 // --- retrieve nodes ID
1471 vector<vtkIdType> nodeIds;
1473 nodeIds.push_back(node1->getVtkId());
1474 nodeIds.push_back(node2->getVtkId());
1475 nodeIds.push_back(node3->getVtkId());
1477 SMDS_MeshFace * face = 0;
1478 SMDS_VtkFace *facevtk = myFacePool->getNew();
1479 facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1480 if (!this->registerElement(ID,facevtk))
1482 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1483 myFacePool->destroy(facevtk);
1487 adjustmyCellsCapacity(ID);
1489 //MESSAGE("createTriangle " << ID << " " << face);
1490 myInfo.myNbTriangles++;
1495 ///////////////////////////////////////////////////////////////////////////////
1496 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1497 ///a ID to the create triangle.
1498 ///////////////////////////////////////////////////////////////////////////////
1499 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1500 const SMDS_MeshNode * node2,
1501 const SMDS_MeshNode * node3,
1502 const SMDS_MeshNode * node4,
1505 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1506 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1507 if(hasConstructionEdges())
1509 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1510 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1511 edge1=FindEdgeOrCreate(node1,node2);
1512 edge2=FindEdgeOrCreate(node2,node3);
1513 edge3=FindEdgeOrCreate(node3,node4);
1514 edge4=FindEdgeOrCreate(node4,node1);
1516 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1517 adjustmyCellsCapacity(ID);
1519 myInfo.myNbQuadrangles++;
1524 // --- retrieve nodes ID
1525 vector<vtkIdType> nodeIds;
1527 nodeIds.push_back(node1->getVtkId());
1528 nodeIds.push_back(node2->getVtkId());
1529 nodeIds.push_back(node3->getVtkId());
1530 nodeIds.push_back(node4->getVtkId());
1532 SMDS_MeshFace * face = 0;
1533 SMDS_VtkFace *facevtk = myFacePool->getNew();
1534 facevtk->init(nodeIds, this);
1535 if (!this->registerElement(ID,facevtk))
1537 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1538 myFacePool->destroy(facevtk);
1542 adjustmyCellsCapacity(ID);
1544 myInfo.myNbQuadrangles++;
1549 ///////////////////////////////////////////////////////////////////////////////
1550 /// Remove a node and all the elements which own this node
1551 ///////////////////////////////////////////////////////////////////////////////
1553 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1555 MESSAGE("RemoveNode");
1556 RemoveElement(node, true);
1559 ///////////////////////////////////////////////////////////////////////////////
1560 /// Remove an edge and all the elements which own this edge
1561 ///////////////////////////////////////////////////////////////////////////////
1563 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1565 MESSAGE("Remove0DElement");
1566 RemoveElement(elem0d,true);
1569 ///////////////////////////////////////////////////////////////////////////////
1570 /// Remove an edge and all the elements which own this edge
1571 ///////////////////////////////////////////////////////////////////////////////
1573 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1575 MESSAGE("RemoveEdge");
1576 RemoveElement(edge,true);
1579 ///////////////////////////////////////////////////////////////////////////////
1580 /// Remove an face and all the elements which own this face
1581 ///////////////////////////////////////////////////////////////////////////////
1583 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1585 MESSAGE("RemoveFace");
1586 RemoveElement(face, true);
1589 ///////////////////////////////////////////////////////////////////////////////
1591 ///////////////////////////////////////////////////////////////////////////////
1593 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1595 MESSAGE("RemoveVolume");
1596 RemoveElement(volume, true);
1599 //=======================================================================
1600 //function : RemoveFromParent
1602 //=======================================================================
1604 bool SMDS_Mesh::RemoveFromParent()
1606 if (myParent==NULL) return false;
1607 else return (myParent->RemoveSubMesh(this));
1610 //=======================================================================
1611 //function : RemoveSubMesh
1613 //=======================================================================
1615 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1619 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1620 for (; itmsh!=myChildren.end() && !found; itmsh++)
1622 SMDS_Mesh * submesh = *itmsh;
1623 if (submesh == aMesh)
1626 myChildren.erase(itmsh);
1633 //=======================================================================
1634 //function : ChangeElementNodes
1636 //=======================================================================
1638 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1639 const SMDS_MeshNode * nodes[],
1642 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1643 // keep current nodes of elem
1644 set<const SMDS_MeshElement*> oldNodes;
1645 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1647 oldNodes.insert(itn->next());
1651 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1654 Ok = cell->vtkOrder(nodes, nbnodes);
1655 Ok = cell->ChangeNodes(nodes, nbnodes);
1658 if ( Ok ) { // update InverseElements
1660 set<const SMDS_MeshElement*>::iterator it;
1662 // AddInverseElement to new nodes
1663 for ( int i = 0; i < nbnodes; i++ ) {
1664 it = oldNodes.find( nodes[i] );
1665 if ( it == oldNodes.end() )
1667 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1669 // remove from oldNodes a node that remains in elem
1670 oldNodes.erase( it );
1672 // RemoveInverseElement from the nodes removed from elem
1673 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1675 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1676 (const_cast<SMDS_MeshElement *>( *it ));
1677 n->RemoveInverseElement( cell );
1684 //=======================================================================
1685 //function : ChangePolyhedronNodes
1686 //purpose : to change nodes of polyhedral volume
1687 //=======================================================================
1688 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1689 const vector<const SMDS_MeshNode*>& nodes,
1690 const vector<int> & quantities)
1692 if (elem->GetType() != SMDSAbs_Volume) {
1693 MESSAGE("WRONG ELEM TYPE");
1697 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1702 // keep current nodes of elem
1703 set<const SMDS_MeshElement*> oldNodes;
1704 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1705 while (itn->more()) {
1706 oldNodes.insert(itn->next());
1710 // TODO remove this function
1711 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1717 // update InverseElements
1719 // AddInverseElement to new nodes
1720 int nbnodes = nodes.size();
1721 set<const SMDS_MeshElement*>::iterator it;
1722 for (int i = 0; i < nbnodes; i++) {
1723 it = oldNodes.find(nodes[i]);
1724 if (it == oldNodes.end()) {
1726 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1728 // remove from oldNodes a node that remains in elem
1733 // RemoveInverseElement from the nodes removed from elem
1734 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1735 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1736 (const_cast<SMDS_MeshElement *>( *it ));
1737 n->RemoveInverseElement(elem);
1744 //=======================================================================
1745 //function : Find0DElement
1747 //=======================================================================
1748 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1750 const SMDS_MeshNode * node = FindNode(idnode);
1751 if(node == NULL) return NULL;
1752 return Find0DElement(node);
1755 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1757 if (!node) return 0;
1758 const SMDS_Mesh0DElement* toReturn = NULL;
1759 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1760 while (it1->more() && (toReturn == NULL)) {
1761 const SMDS_MeshElement* e = it1->next();
1762 if (e->NbNodes() == 1) {
1763 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1769 //=======================================================================
1770 //function : Find0DElementOrCreate
1772 //=======================================================================
1773 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1775 // if (!node) return 0;
1776 // SMDS_Mesh0DElement * toReturn = NULL;
1777 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1778 // if (toReturn == NULL) {
1779 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1780 // toReturn = new SMDS_Mesh0DElement(node);
1781 // my0DElements.Add(toReturn);
1782 // myInfo.myNb0DElements++;
1788 //=======================================================================
1789 //function : FindEdge
1791 //=======================================================================
1793 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1795 const SMDS_MeshNode * node1=FindNode(idnode1);
1796 const SMDS_MeshNode * node2=FindNode(idnode2);
1797 if((node1==NULL)||(node2==NULL)) return NULL;
1798 return FindEdge(node1,node2);
1801 //#include "Profiler.h"
1802 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1803 const SMDS_MeshNode * node2)
1805 if ( !node1 ) return 0;
1806 const SMDS_MeshEdge * toReturn=NULL;
1809 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1812 while(it1->more()) {
1813 const SMDS_MeshElement * e = it1->next();
1814 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1815 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1824 //=======================================================================
1825 //function : FindEdgeOrCreate
1827 //=======================================================================
1829 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1830 const SMDS_MeshNode * node2)
1832 if ( !node1 || !node2) return 0;
1833 SMDS_MeshEdge * toReturn=NULL;
1834 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1835 if(toReturn==NULL) {
1836 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1837 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1838 adjustmyCellsCapacity(ID);
1839 vector<vtkIdType> nodeIds;
1841 nodeIds.push_back(node1->getVtkId());
1842 nodeIds.push_back(node2->getVtkId());
1844 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1845 edgevtk->init(nodeIds, this);
1846 if (!this->registerElement(ID,edgevtk))
1848 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
1849 myEdgePool->destroy(edgevtk);
1853 myCells[ID] = toReturn;
1860 //=======================================================================
1861 //function : FindEdge
1863 //=======================================================================
1865 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1868 const SMDS_MeshNode * node1=FindNode(idnode1);
1869 const SMDS_MeshNode * node2=FindNode(idnode2);
1870 const SMDS_MeshNode * node3=FindNode(idnode3);
1871 return FindEdge(node1,node2,node3);
1874 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1875 const SMDS_MeshNode * node2,
1876 const SMDS_MeshNode * node3)
1878 if ( !node1 ) return 0;
1879 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1880 while(it1->more()) {
1881 const SMDS_MeshElement * e = it1->next();
1882 if ( e->NbNodes() == 3 ) {
1883 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1884 while(it2->more()) {
1885 const SMDS_MeshElement* n = it2->next();
1895 return static_cast<const SMDS_MeshEdge *> (e);
1902 //=======================================================================
1903 //function : FindFace
1905 //=======================================================================
1907 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1910 const SMDS_MeshNode * node1=FindNode(idnode1);
1911 const SMDS_MeshNode * node2=FindNode(idnode2);
1912 const SMDS_MeshNode * node3=FindNode(idnode3);
1913 return FindFace(node1, node2, node3);
1916 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1917 const SMDS_MeshNode *node2,
1918 const SMDS_MeshNode *node3)
1920 if ( !node1 ) return 0;
1921 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1922 while(it1->more()) {
1923 const SMDS_MeshElement * e = it1->next();
1924 if ( e->NbNodes() == 3 ) {
1925 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1926 while(it2->more()) {
1927 const SMDS_MeshElement* n = it2->next();
1937 return static_cast<const SMDS_MeshFace *> (e);
1943 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1944 const SMDS_MeshNode *node2,
1945 const SMDS_MeshNode *node3)
1947 SMDS_MeshFace * toReturn=NULL;
1948 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1949 if(toReturn==NULL) {
1950 int ID = myElementIDFactory->GetFreeID();
1951 toReturn = createTriangle(node1,node2,node3, ID);
1957 //=======================================================================
1958 //function : FindFace
1960 //=======================================================================
1962 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1963 int idnode3, int idnode4) const
1965 const SMDS_MeshNode * node1=FindNode(idnode1);
1966 const SMDS_MeshNode * node2=FindNode(idnode2);
1967 const SMDS_MeshNode * node3=FindNode(idnode3);
1968 const SMDS_MeshNode * node4=FindNode(idnode4);
1969 return FindFace(node1, node2, node3, node4);
1972 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1973 const SMDS_MeshNode *node2,
1974 const SMDS_MeshNode *node3,
1975 const SMDS_MeshNode *node4)
1977 if ( !node1 ) return 0;
1978 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1979 while(it1->more()) {
1980 const SMDS_MeshElement * e = it1->next();
1981 if ( e->NbNodes() == 4 ) {
1982 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1983 while(it2->more()) {
1984 const SMDS_MeshElement* n = it2->next();
1995 return static_cast<const SMDS_MeshFace *> (e);
2001 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2002 const SMDS_MeshNode *node2,
2003 const SMDS_MeshNode *node3,
2004 const SMDS_MeshNode *node4)
2006 SMDS_MeshFace * toReturn=NULL;
2007 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2008 if(toReturn==NULL) {
2009 int ID = myElementIDFactory->GetFreeID();
2010 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2016 //=======================================================================
2017 //function : FindFace
2018 //purpose :quadratic triangle
2019 //=======================================================================
2021 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2022 int idnode3, int idnode4,
2023 int idnode5, int idnode6) const
2025 const SMDS_MeshNode * node1 = FindNode(idnode1);
2026 const SMDS_MeshNode * node2 = FindNode(idnode2);
2027 const SMDS_MeshNode * node3 = FindNode(idnode3);
2028 const SMDS_MeshNode * node4 = FindNode(idnode4);
2029 const SMDS_MeshNode * node5 = FindNode(idnode5);
2030 const SMDS_MeshNode * node6 = FindNode(idnode6);
2031 return FindFace(node1, node2, node3, node4, node5, node6);
2034 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2035 const SMDS_MeshNode *node2,
2036 const SMDS_MeshNode *node3,
2037 const SMDS_MeshNode *node4,
2038 const SMDS_MeshNode *node5,
2039 const SMDS_MeshNode *node6)
2041 if ( !node1 ) return 0;
2042 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2043 while(it1->more()) {
2044 const SMDS_MeshElement * e = it1->next();
2045 if ( e->NbNodes() == 6 ) {
2046 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2047 while(it2->more()) {
2048 const SMDS_MeshElement* n = it2->next();
2061 return static_cast<const SMDS_MeshFace *> (e);
2068 //=======================================================================
2069 //function : FindFace
2070 //purpose : quadratic quadrangle
2071 //=======================================================================
2073 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2074 int idnode3, int idnode4,
2075 int idnode5, int idnode6,
2076 int idnode7, int idnode8) const
2078 const SMDS_MeshNode * node1 = FindNode(idnode1);
2079 const SMDS_MeshNode * node2 = FindNode(idnode2);
2080 const SMDS_MeshNode * node3 = FindNode(idnode3);
2081 const SMDS_MeshNode * node4 = FindNode(idnode4);
2082 const SMDS_MeshNode * node5 = FindNode(idnode5);
2083 const SMDS_MeshNode * node6 = FindNode(idnode6);
2084 const SMDS_MeshNode * node7 = FindNode(idnode7);
2085 const SMDS_MeshNode * node8 = FindNode(idnode8);
2086 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2089 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2090 const SMDS_MeshNode *node2,
2091 const SMDS_MeshNode *node3,
2092 const SMDS_MeshNode *node4,
2093 const SMDS_MeshNode *node5,
2094 const SMDS_MeshNode *node6,
2095 const SMDS_MeshNode *node7,
2096 const SMDS_MeshNode *node8)
2098 if ( !node1 ) return 0;
2099 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2100 while(it1->more()) {
2101 const SMDS_MeshElement * e = it1->next();
2102 if ( e->NbNodes() == 8 ) {
2103 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2104 while(it2->more()) {
2105 const SMDS_MeshElement* n = it2->next();
2120 return static_cast<const SMDS_MeshFace *> (e);
2127 //=======================================================================
2128 //function : FindElement
2130 //=======================================================================
2132 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2134 if ((IDelem <= 0) || IDelem >= myCells.size())
2136 MESSAGE("--------------------------------------------------------------------------------- ");
2137 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2138 MESSAGE("--------------------------------------------------------------------------------- ");
2139 // TODO raise an exception
2143 return myCells[IDelem];
2146 //=======================================================================
2147 //function : FindFace
2148 //purpose : find polygon
2149 //=======================================================================
2151 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2153 int nbnodes = nodes_ids.size();
2154 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2155 for (int inode = 0; inode < nbnodes; inode++) {
2156 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2157 if (node == NULL) return NULL;
2158 poly_nodes[inode] = node;
2160 return FindFace(poly_nodes);
2163 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2165 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2169 //================================================================================
2171 * \brief Return element based on all given nodes
2172 * \param nodes - node of element
2173 * \param type - type of element
2174 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2175 * \retval const SMDS_MeshElement* - found element or NULL
2177 //================================================================================
2179 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2180 const SMDSAbs_ElementType type,
2181 const bool noMedium)
2183 if ( nodes.size() > 0 && nodes[0] )
2185 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2188 const SMDS_MeshElement* e = itF->next();
2189 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2190 if ( nbNodesToCheck == nodes.size() )
2192 for ( int i = 1; e && i < nodes.size(); ++ i )
2194 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2195 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2199 return static_cast<const SMDS_MeshFace *> (e);
2206 //=======================================================================
2207 //function : DumpNodes
2209 //=======================================================================
2211 void SMDS_Mesh::DumpNodes() const
2213 MESSAGE("dump nodes of mesh : ");
2214 SMDS_NodeIteratorPtr itnode=nodesIterator();
2215 while(itnode->more()) ; //MESSAGE(itnode->next());
2218 //=======================================================================
2219 //function : Dump0DElements
2221 //=======================================================================
2222 void SMDS_Mesh::Dump0DElements() const
2224 MESSAGE("dump 0D elements of mesh : ");
2225 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2226 while(it0d->more()) ; //MESSAGE(it0d->next());
2229 //=======================================================================
2230 //function : DumpEdges
2232 //=======================================================================
2234 void SMDS_Mesh::DumpEdges() const
2236 MESSAGE("dump edges of mesh : ");
2237 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2238 while(itedge->more()) ; //MESSAGE(itedge->next());
2241 //=======================================================================
2242 //function : DumpFaces
2244 //=======================================================================
2246 void SMDS_Mesh::DumpFaces() const
2248 MESSAGE("dump faces of mesh : ");
2249 SMDS_FaceIteratorPtr itface=facesIterator();
2250 while(itface->more()) ; //MESSAGE(itface->next());
2253 //=======================================================================
2254 //function : DumpVolumes
2256 //=======================================================================
2258 void SMDS_Mesh::DumpVolumes() const
2260 MESSAGE("dump volumes of mesh : ");
2261 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2262 while(itvol->more()) ; //MESSAGE(itvol->next());
2265 //=======================================================================
2266 //function : DebugStats
2268 //=======================================================================
2270 void SMDS_Mesh::DebugStats() const
2272 MESSAGE("Debug stats of mesh : ");
2274 MESSAGE("===== NODES ====="<<NbNodes());
2275 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2276 MESSAGE("===== EDGES ====="<<NbEdges());
2277 MESSAGE("===== FACES ====="<<NbFaces());
2278 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2280 MESSAGE("End Debug stats of mesh ");
2284 SMDS_NodeIteratorPtr itnode=nodesIterator();
2285 int sizeofnodes = 0;
2286 int sizeoffaces = 0;
2288 while(itnode->more())
2290 const SMDS_MeshNode *node = itnode->next();
2292 sizeofnodes += sizeof(*node);
2294 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2297 const SMDS_MeshElement *me = it->next();
2298 sizeofnodes += sizeof(me);
2302 SMDS_FaceIteratorPtr itface=facesIterator();
2303 while(itface->more())
2305 const SMDS_MeshElement *face = itface->next();
2306 sizeoffaces += sizeof(*face);
2309 MESSAGE("total size of node elements = " << sizeofnodes);;
2310 MESSAGE("total size of face elements = " << sizeoffaces);;
2315 ///////////////////////////////////////////////////////////////////////////////
2316 /// Return the number of nodes
2317 ///////////////////////////////////////////////////////////////////////////////
2318 int SMDS_Mesh::NbNodes() const
2320 //MESSAGE(myGrid->GetNumberOfPoints());
2321 //MESSAGE(myInfo.NbNodes());
2322 //MESSAGE(myNodeMax);
2323 return myInfo.NbNodes();
2326 ///////////////////////////////////////////////////////////////////////////////
2327 /// Return the number of 0D elements
2328 ///////////////////////////////////////////////////////////////////////////////
2329 int SMDS_Mesh::Nb0DElements() const
2331 return myInfo.Nb0DElements(); // -PR- a verfier
2334 ///////////////////////////////////////////////////////////////////////////////
2335 /// Return the number of edges (including construction edges)
2336 ///////////////////////////////////////////////////////////////////////////////
2337 int SMDS_Mesh::NbEdges() const
2339 return myInfo.NbEdges(); // -PR- a verfier
2342 ///////////////////////////////////////////////////////////////////////////////
2343 /// Return the number of faces (including construction faces)
2344 ///////////////////////////////////////////////////////////////////////////////
2345 int SMDS_Mesh::NbFaces() const
2347 return myInfo.NbFaces(); // -PR- a verfier
2350 ///////////////////////////////////////////////////////////////////////////////
2351 /// Return the number of volumes
2352 ///////////////////////////////////////////////////////////////////////////////
2353 int SMDS_Mesh::NbVolumes() const
2355 return myInfo.NbVolumes(); // -PR- a verfier
2358 ///////////////////////////////////////////////////////////////////////////////
2359 /// Return the number of child mesh of this mesh.
2360 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2361 /// (2003-09-08) of SMESH
2362 ///////////////////////////////////////////////////////////////////////////////
2363 int SMDS_Mesh::NbSubMesh() const
2365 return myChildren.size();
2368 ///////////////////////////////////////////////////////////////////////////////
2369 /// Destroy the mesh and all its elements
2370 /// All pointer on elements owned by this mesh become illegals.
2371 ///////////////////////////////////////////////////////////////////////////////
2372 SMDS_Mesh::~SMDS_Mesh()
2374 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2375 while(itc!=myChildren.end())
2383 delete myNodeIDFactory;
2384 delete myElementIDFactory;
2388 SMDS_ElemIteratorPtr eIt = elementsIterator();
2389 while ( eIt->more() )
2391 const SMDS_MeshElement *elem = eIt->next();
2392 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2394 SMDS_NodeIteratorPtr itn = nodesIterator();
2397 const SMDS_MeshNode *node = itn->next();
2398 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2402 // SetOfNodes::Iterator itn(myNodes);
2403 // for (; itn.More(); itn.Next())
2404 // delete itn.Value();
2406 // SetOf0DElements::Iterator it0d (my0DElements);
2407 // for (; it0d.More(); it0d.Next())
2409 // SMDS_MeshElement* elem = it0d.Value();
2413 // SetOfEdges::Iterator ite(myEdges);
2414 // for (; ite.More(); ite.Next())
2416 // SMDS_MeshElement* elem = ite.Value();
2420 // SetOfFaces::Iterator itf(myFaces);
2421 // for (; itf.More(); itf.Next())
2423 // SMDS_MeshElement* elem = itf.Value();
2427 // SetOfVolumes::Iterator itv(myVolumes);
2428 // for (; itv.More(); itv.Next())
2430 // SMDS_MeshElement* elem = itv.Value();
2435 //================================================================================
2437 * \brief Clear all data
2439 //================================================================================
2441 void SMDS_Mesh::Clear()
2443 MESSAGE("SMDS_Mesh::Clear");
2446 SMDS_ElemIteratorPtr eIt = elementsIterator();
2447 while ( eIt->more() )
2449 const SMDS_MeshElement *elem = eIt->next();
2450 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2452 SMDS_NodeIteratorPtr itn = nodesIterator();
2455 const SMDS_MeshNode *node = itn->next();
2456 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2461 myNodeIDFactory->Clear();
2462 myElementIDFactory->Clear();
2465 SMDS_ElemIteratorPtr itv = elementsIterator();
2468 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2469 SMDSAbs_ElementType aType = elem->GetType();
2472 case SMDSAbs_0DElement:
2476 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2479 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2481 case SMDSAbs_Volume:
2482 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2489 myCellIdVtkToSmds.clear();
2490 //myCellIdSmdsToVtk.clear();
2492 SMDS_NodeIteratorPtr itn = nodesIterator();
2495 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2496 myNodePool->destroy(node);
2500 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2501 while(itc!=myChildren.end())
2511 myGrid->Initialize();
2513 vtkPoints* points = vtkPoints::New();
2514 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2515 // using double type for storing coordinates of nodes instead float.
2516 points->SetDataType(VTK_DOUBLE);
2517 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
2518 myGrid->SetPoints( points );
2520 myGrid->BuildLinks();
2523 ///////////////////////////////////////////////////////////////////////////////
2524 /// Return true if this mesh create faces with edges.
2525 /// A false returned value mean that faces are created with nodes. A concequence
2526 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2527 ///////////////////////////////////////////////////////////////////////////////
2528 bool SMDS_Mesh::hasConstructionEdges()
2530 return myHasConstructionEdges;
2533 ///////////////////////////////////////////////////////////////////////////////
2534 /// Return true if this mesh create volumes with faces
2535 /// A false returned value mean that volumes are created with nodes or edges.
2536 /// (see hasConstructionEdges)
2537 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2539 ///////////////////////////////////////////////////////////////////////////////
2540 bool SMDS_Mesh::hasConstructionFaces()
2542 return myHasConstructionFaces;
2545 ///////////////////////////////////////////////////////////////////////////////
2546 /// Return true if nodes are linked to the finit elements, they are belonging to.
2547 /// Currently, It always return true.
2548 ///////////////////////////////////////////////////////////////////////////////
2549 bool SMDS_Mesh::hasInverseElements()
2551 return myHasInverseElements;
2554 ///////////////////////////////////////////////////////////////////////////////
2555 /// Make this mesh creating construction edges (see hasConstructionEdges)
2556 /// @param b true to have construction edges, else false.
2557 ///////////////////////////////////////////////////////////////////////////////
2558 void SMDS_Mesh::setConstructionEdges(bool b)
2560 myHasConstructionEdges=b;
2563 ///////////////////////////////////////////////////////////////////////////////
2564 /// Make this mesh creating construction faces (see hasConstructionFaces)
2565 /// @param b true to have construction faces, else false.
2566 ///////////////////////////////////////////////////////////////////////////////
2567 void SMDS_Mesh::setConstructionFaces(bool b)
2569 myHasConstructionFaces=b;
2572 ///////////////////////////////////////////////////////////////////////////////
2573 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2574 /// @param b true to link nodes to elements, else false.
2575 ///////////////////////////////////////////////////////////////////////////////
2576 void SMDS_Mesh::setInverseElements(bool b)
2578 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2579 myHasInverseElements=b;
2584 ///////////////////////////////////////////////////////////////////////////////
2585 ///Iterator on NCollection_Map
2586 ///////////////////////////////////////////////////////////////////////////////
2587 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2588 struct MYNode_Map_Iterator: public FATHER
2592 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2599 while (_ctr < _map.size())
2610 ELEM current = _map[_ctr];
2616 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2617 struct MYElem_Map_Iterator: public FATHER
2622 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2626 while (_ctr < _map.size()) // go to the first valid element
2629 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2637 while (_ctr < _map.size())
2640 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2649 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2655 //================================================================================
2657 * \brief Iterator on elements in id increasing order
2659 //================================================================================
2661 template <typename ELEM=const SMDS_MeshElement*>
2662 class IdSortedIterator : public SMDS_Iterator<ELEM>
2664 const SMDS_MeshElementIDFactory& myIDFact;
2665 int myID, myMaxID, myNbFound, myTotalNb;
2666 SMDSAbs_ElementType myType;
2670 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2671 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2674 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2686 ELEM current = myElem;
2688 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2689 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2690 && myElem->GetType() != myType )
2693 myNbFound += bool(myElem);
2700 ///////////////////////////////////////////////////////////////////////////////
2701 /// Return an iterator on nodes of the current mesh factory
2702 ///////////////////////////////////////////////////////////////////////////////
2704 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2706 typedef MYNode_Map_Iterator
2707 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2708 return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2710 // typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2711 // return ( idInceasingOrder ?
2712 // SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2713 // SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2716 ///////////////////////////////////////////////////////////////////////////////
2717 ///Return an iterator on 0D elements of the current mesh.
2718 ///////////////////////////////////////////////////////////////////////////////
2720 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2722 typedef MYElem_Map_Iterator
2723 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2724 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2726 // typedef MYNCollection_Map_Iterator
2727 // < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2728 // typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator;
2729 // return ( idInceasingOrder ?
2730 // SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2731 // SMDSAbs_0DElement,
2732 // Nb0DElements() )) :
2733 // SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2736 ///////////////////////////////////////////////////////////////////////////////
2737 ///Return an iterator on edges of the current mesh.
2738 ///////////////////////////////////////////////////////////////////////////////
2740 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2742 typedef MYElem_Map_Iterator
2743 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2744 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2746 // typedef MYNCollection_Map_Iterator
2747 // < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2748 // typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator;
2749 // return ( idInceasingOrder ?
2750 // SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2753 // SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2756 ///////////////////////////////////////////////////////////////////////////////
2757 ///Return an iterator on faces of the current mesh.
2758 ///////////////////////////////////////////////////////////////////////////////
2760 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2762 typedef MYElem_Map_Iterator
2763 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2764 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2766 // typedef MYNCollection_Map_Iterator
2767 // < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2768 // typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator;
2769 // return ( idInceasingOrder ?
2770 // SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2773 // SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2776 ///////////////////////////////////////////////////////////////////////////////
2777 ///Return an iterator on volumes of the current mesh.
2778 ///////////////////////////////////////////////////////////////////////////////
2780 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2782 typedef MYElem_Map_Iterator
2783 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2784 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2786 // typedef MYNCollection_Map_Iterator
2787 // < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2788 // typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator;
2789 // return ( idInceasingOrder ?
2790 // SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2793 // SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2796 ///////////////////////////////////////////////////////////////////////////////
2797 /// Return an iterator on elements of the current mesh factory
2798 ///////////////////////////////////////////////////////////////////////////////
2799 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2803 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2805 case SMDSAbs_Volume:
2806 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2808 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2810 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2811 case SMDSAbs_0DElement:
2812 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2814 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2815 //return myNodeIDFactory->elementsIterator();
2818 return myElementIDFactory->elementsIterator();
2821 ///////////////////////////////////////////////////////////////////////////////
2822 /// Do intersection of sets (more than 2)
2823 ///////////////////////////////////////////////////////////////////////////////
2824 static set<const SMDS_MeshElement*> * intersectionOfSets(
2825 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2827 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2828 set<const SMDS_MeshElement*>* rsetB;
2830 for(int i=0; i<numberOfSets-1; i++)
2832 rsetB=new set<const SMDS_MeshElement*>();
2834 rsetA->begin(), rsetA->end(),
2835 vs[i+1].begin(), vs[i+1].end(),
2836 inserter(*rsetB, rsetB->begin()));
2843 ///////////////////////////////////////////////////////////////////////////////
2844 /// Return the list of finite elements owning the given element: elements
2845 /// containing all the nodes of the given element, for instance faces and
2846 /// volumes containing a given edge.
2847 ///////////////////////////////////////////////////////////////////////////////
2848 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2850 int numberOfSets=element->NbNodes();
2851 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2853 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2856 while(itNodes->more())
2858 const SMDS_MeshElement* node = itNodes->next();
2860 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2861 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2863 //initSet[i]=set<const SMDS_MeshElement*>();
2866 const SMDS_MeshElement* elem = itFe->next();
2868 initSet[i].insert(elem);
2874 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2875 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2880 ///////////////////////////////////////////////////////////////////////////////
2881 /// Return the list of nodes used only by the given elements
2882 ///////////////////////////////////////////////////////////////////////////////
2883 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2884 set<const SMDS_MeshElement*>& elements)
2886 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2887 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2889 while(itElements!=elements.end())
2891 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2894 while(itNodes->more())
2896 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2897 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2898 set<const SMDS_MeshElement*> s;
2900 s.insert(itFe->next());
2901 if(s==elements) toReturn->insert(n);
2907 ///////////////////////////////////////////////////////////////////////////////
2908 ///Find the children of an element that are made of given nodes
2909 ///@param setOfChildren The set in which matching children will be inserted
2910 ///@param element The element were to search matching children
2911 ///@param nodes The nodes that the children must have to be selected
2912 ///////////////////////////////////////////////////////////////////////////////
2913 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2914 const SMDS_MeshElement * element,
2915 set<const SMDS_MeshElement*>& nodes)
2917 switch(element->GetType())
2920 MESSAGE("Internal Error: This should not happen");
2922 case SMDSAbs_0DElement:
2928 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2931 const SMDS_MeshElement * e=itn->next();
2932 if(nodes.find(e)!=nodes.end())
2934 setOfChildren.insert(element);
2941 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2944 const SMDS_MeshElement * e=itn->next();
2945 if(nodes.find(e)!=nodes.end())
2947 setOfChildren.insert(element);
2951 if(hasConstructionEdges())
2953 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2955 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2958 case SMDSAbs_Volume:
2960 if(hasConstructionFaces())
2962 SMDS_ElemIteratorPtr ite=element->facesIterator();
2964 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2966 else if(hasConstructionEdges())
2968 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2970 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2976 ///////////////////////////////////////////////////////////////////////////////
2977 ///@param elem The element to delete
2978 ///@param removenodes if true remaining nodes will be removed
2979 ///////////////////////////////////////////////////////////////////////////////
2980 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2981 const bool removenodes)
2983 list<const SMDS_MeshElement *> removedElems;
2984 list<const SMDS_MeshElement *> removedNodes;
2985 RemoveElement( elem, removedElems, removedNodes, removenodes );
2988 ///////////////////////////////////////////////////////////////////////////////
2989 ///@param elem The element to delete
2990 ///@param removedElems to be filled with all removed elements
2991 ///@param removedNodes to be filled with all removed nodes
2992 ///@param removenodes if true remaining nodes will be removed
2993 ///////////////////////////////////////////////////////////////////////////////
2994 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2995 list<const SMDS_MeshElement *>& removedElems,
2996 list<const SMDS_MeshElement *>& removedNodes,
2999 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
3000 // get finite elements built on elem
3001 set<const SMDS_MeshElement*> * s1;
3002 if ( (elem->GetType() == SMDSAbs_0DElement)
3003 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3004 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3005 || (elem->GetType() == SMDSAbs_Volume) )
3007 s1 = new set<const SMDS_MeshElement*> ();
3011 s1 = getFinitElements(elem);
3013 // get exclusive nodes (which would become free afterwards)
3014 set<const SMDS_MeshElement*> * s2;
3015 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3017 // do not remove nodes except elem
3018 s2 = new set<const SMDS_MeshElement*> ();
3023 s2 = getExclusiveNodes(*s1);
3025 // form the set of finite and construction elements to remove
3026 set<const SMDS_MeshElement*> s3;
3027 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3028 while (it != s1->end())
3030 addChildrenWithNodes(s3, *it, *s2);
3034 if (elem->GetType() != SMDSAbs_Node)
3037 // remove finite and construction elements
3039 while (it != s3.end())
3041 // Remove element from <InverseElements> of its nodes
3042 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3045 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3046 n->RemoveInverseElement((*it));
3048 int IdToRemove = (*it)->GetID();
3049 int vtkid = (*it)->getVtkId();
3050 //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3051 // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3052 switch ((*it)->GetType())
3055 MYASSERT("Internal Error: This should not happen")
3058 case SMDSAbs_0DElement:
3059 if (IdToRemove >= 0)
3061 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3064 removedElems.push_back((*it));
3065 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3069 if (IdToRemove >= 0)
3071 myCells[IdToRemove] = 0;
3072 myInfo.RemoveEdge(*it);
3074 removedElems.push_back((*it));
3075 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3076 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3077 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3082 if (IdToRemove >= 0)
3084 myCells[IdToRemove] = 0;
3085 myInfo.RemoveFace(*it);
3087 removedElems.push_back((*it));
3088 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3089 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3090 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3094 case SMDSAbs_Volume:
3095 if (IdToRemove >= 0)
3097 myCells[IdToRemove] = 0;
3098 myInfo.RemoveVolume(*it);
3100 removedElems.push_back((*it));
3101 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3102 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3103 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3110 //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3111 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3116 // remove exclusive (free) nodes
3120 while (it != s2->end())
3122 int IdToRemove = (*it)->GetID();
3123 //MESSAGE( "SMDS: RM node " << IdToRemove);
3124 if (IdToRemove >= 0)
3126 myNodes[IdToRemove] = 0;
3129 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3130 removedNodes.push_back((*it));
3131 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3132 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 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3163 myNodeIDFactory->ReleaseID(elemId, vtkId);
3166 if (hasConstructionEdges() || hasConstructionFaces())
3167 // this methods is only for meshes without descendants
3170 //MESSAGE("Remove free element " << elemId);
3171 // Remove element from <InverseElements> of its nodes
3172 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3173 while (itn->more()) {
3174 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3175 (const_cast<SMDS_MeshElement *>(itn->next()));
3176 n->RemoveInverseElement(elem);
3179 // in meshes without descendants elements are always free
3181 case SMDSAbs_0DElement:
3182 myCells[elemId] = 0;
3183 myInfo.remove(elem);
3187 myCells[elemId] = 0;
3188 myInfo.RemoveEdge(elem);
3189 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3192 myCells[elemId] = 0;
3193 myInfo.RemoveFace(elem);
3194 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3196 case SMDSAbs_Volume:
3197 myCells[elemId] = 0;
3198 myInfo.RemoveVolume(elem);
3199 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3204 myElementIDFactory->ReleaseID(elemId, vtkId);
3206 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3207 // --- to do: keep vtkid in a list of reusable cells
3212 * Checks if the element is present in mesh.
3213 * Useful to determine dead pointers.
3215 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3217 // we should not imply on validity of *elem, so iterate on containers
3218 // of all types in the hope of finding <elem> somewhere there
3219 SMDS_NodeIteratorPtr itn = nodesIterator();
3221 if (elem == itn->next())
3223 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3224 while (it0d->more())
3225 if (elem == it0d->next())
3227 SMDS_EdgeIteratorPtr ite = edgesIterator();
3229 if (elem == ite->next())
3231 SMDS_FaceIteratorPtr itf = facesIterator();
3233 if (elem == itf->next())
3235 SMDS_VolumeIteratorPtr itv = volumesIterator();
3237 if (elem == itv->next())
3242 //=======================================================================
3243 //function : MaxNodeID
3245 //=======================================================================
3247 int SMDS_Mesh::MaxNodeID() const
3252 //=======================================================================
3253 //function : MinNodeID
3255 //=======================================================================
3257 int SMDS_Mesh::MinNodeID() const
3262 //=======================================================================
3263 //function : MaxElementID
3265 //=======================================================================
3267 int SMDS_Mesh::MaxElementID() const
3269 return myElementIDFactory->GetMaxID();
3272 //=======================================================================
3273 //function : MinElementID
3275 //=======================================================================
3277 int SMDS_Mesh::MinElementID() const
3279 return myElementIDFactory->GetMinID();
3282 //=======================================================================
3283 //function : Renumber
3284 //purpose : Renumber all nodes or elements.
3285 //=======================================================================
3287 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3289 MESSAGE("Renumber");
3293 SMDS_MeshNodeIDFactory * idFactory =
3294 isNodes ? myNodeIDFactory : myElementIDFactory;
3296 // get existing elements in the order of ID increasing
3297 map<int,SMDS_MeshElement*> elemMap;
3298 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3299 while ( idElemIt->more() ) {
3300 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3301 int id = elem->GetID();
3302 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3304 // release their ids
3305 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3307 // for ( ; elemIt != elemMap.end(); elemIt++ )
3309 // int id = (*elemIt).first;
3310 // idFactory->ReleaseID( id );
3314 elemIt = elemMap.begin();
3315 for ( ; elemIt != elemMap.end(); elemIt++ )
3317 idFactory->BindID( ID, (*elemIt).second );
3322 //=======================================================================
3323 //function : GetElementType
3324 //purpose : Return type of element or node with id
3325 //=======================================================================
3327 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3329 SMDS_MeshElement* elem = 0;
3331 elem = myElementIDFactory->MeshElement( id );
3333 elem = myNodeIDFactory->MeshElement( id );
3337 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3341 return elem->GetType();
3346 //********************************************************************
3347 //********************************************************************
3348 //******** *********
3349 //***** Methods for addition of quadratic elements ******
3350 //******** *********
3351 //********************************************************************
3352 //********************************************************************
3354 //=======================================================================
3355 //function : AddEdgeWithID
3357 //=======================================================================
3358 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3360 return SMDS_Mesh::AddEdgeWithID
3361 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3362 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3363 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3367 //=======================================================================
3368 //function : AddEdge
3370 //=======================================================================
3371 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3372 const SMDS_MeshNode* n2,
3373 const SMDS_MeshNode* n12)
3375 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3378 //=======================================================================
3379 //function : AddEdgeWithID
3381 //=======================================================================
3382 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3383 const SMDS_MeshNode * n2,
3384 const SMDS_MeshNode * n12,
3387 if ( !n1 || !n2 || !n12 ) return 0;
3389 // --- retrieve nodes ID
3390 vector<vtkIdType> nodeIds;
3392 nodeIds.push_back(n1->getVtkId());
3393 nodeIds.push_back(n2->getVtkId());
3394 nodeIds.push_back(n12->getVtkId());
3396 SMDS_MeshEdge * edge = 0;
3397 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3398 edgevtk->init(nodeIds, this);
3399 if (!this->registerElement(ID,edgevtk))
3401 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3402 myEdgePool->destroy(edgevtk);
3406 adjustmyCellsCapacity(ID);
3408 myInfo.myNbQuadEdges++;
3410 // if (!registerElement(ID, edge)) {
3411 // RemoveElement(edge, false);
3419 //=======================================================================
3420 //function : AddFace
3422 //=======================================================================
3423 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3424 const SMDS_MeshNode * n2,
3425 const SMDS_MeshNode * n3,
3426 const SMDS_MeshNode * n12,
3427 const SMDS_MeshNode * n23,
3428 const SMDS_MeshNode * n31)
3430 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3431 myElementIDFactory->GetFreeID());
3434 //=======================================================================
3435 //function : AddFaceWithID
3437 //=======================================================================
3438 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3439 int n12,int n23,int n31, int ID)
3441 return SMDS_Mesh::AddFaceWithID
3442 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3443 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3444 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3445 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3446 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3447 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3451 //=======================================================================
3452 //function : AddFaceWithID
3454 //=======================================================================
3455 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3456 const SMDS_MeshNode * n2,
3457 const SMDS_MeshNode * n3,
3458 const SMDS_MeshNode * n12,
3459 const SMDS_MeshNode * n23,
3460 const SMDS_MeshNode * n31,
3463 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3464 if(hasConstructionEdges()) {
3465 // creation quadratic edges - not implemented
3470 // --- retrieve nodes ID
3471 vector<vtkIdType> nodeIds;
3473 nodeIds.push_back(n1->getVtkId());
3474 nodeIds.push_back(n2->getVtkId());
3475 nodeIds.push_back(n3->getVtkId());
3476 nodeIds.push_back(n12->getVtkId());
3477 nodeIds.push_back(n23->getVtkId());
3478 nodeIds.push_back(n31->getVtkId());
3480 SMDS_MeshFace * face = 0;
3481 SMDS_VtkFace *facevtk = myFacePool->getNew();
3482 facevtk->init(nodeIds, this);
3483 if (!this->registerElement(ID,facevtk))
3485 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3486 myFacePool->destroy(facevtk);
3490 adjustmyCellsCapacity(ID);
3492 myInfo.myNbQuadTriangles++;
3494 // if (!registerElement(ID, face)) {
3495 // RemoveElement(face, false);
3503 //=======================================================================
3504 //function : AddFace
3506 //=======================================================================
3507 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3508 const SMDS_MeshNode * n2,
3509 const SMDS_MeshNode * n3,
3510 const SMDS_MeshNode * n4,
3511 const SMDS_MeshNode * n12,
3512 const SMDS_MeshNode * n23,
3513 const SMDS_MeshNode * n34,
3514 const SMDS_MeshNode * n41)
3516 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3517 myElementIDFactory->GetFreeID());
3520 //=======================================================================
3521 //function : AddFaceWithID
3523 //=======================================================================
3524 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3525 int n12,int n23,int n34,int n41, int ID)
3527 return SMDS_Mesh::AddFaceWithID
3528 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3529 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3530 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3531 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3532 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3533 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3534 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3535 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3539 //=======================================================================
3540 //function : AddFaceWithID
3542 //=======================================================================
3543 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3544 const SMDS_MeshNode * n2,
3545 const SMDS_MeshNode * n3,
3546 const SMDS_MeshNode * n4,
3547 const SMDS_MeshNode * n12,
3548 const SMDS_MeshNode * n23,
3549 const SMDS_MeshNode * n34,
3550 const SMDS_MeshNode * n41,
3553 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3554 if(hasConstructionEdges()) {
3555 // creation quadratic edges - not implemented
3560 // --- retrieve nodes ID
3561 vector<vtkIdType> nodeIds;
3563 nodeIds.push_back(n1->getVtkId());
3564 nodeIds.push_back(n2->getVtkId());
3565 nodeIds.push_back(n3->getVtkId());
3566 nodeIds.push_back(n4->getVtkId());
3567 nodeIds.push_back(n12->getVtkId());
3568 nodeIds.push_back(n23->getVtkId());
3569 nodeIds.push_back(n34->getVtkId());
3570 nodeIds.push_back(n41->getVtkId());
3572 SMDS_MeshFace * face = 0;
3573 SMDS_VtkFace *facevtk = myFacePool->getNew();
3574 facevtk->init(nodeIds, this);
3575 if (!this->registerElement(ID,facevtk))
3577 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3578 myFacePool->destroy(facevtk);
3582 adjustmyCellsCapacity(ID);
3584 myInfo.myNbQuadQuadrangles++;
3586 // if (!registerElement(ID, face)) {
3587 // RemoveElement(face, false);
3595 //=======================================================================
3596 //function : AddVolume
3598 //=======================================================================
3599 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3600 const SMDS_MeshNode * n2,
3601 const SMDS_MeshNode * n3,
3602 const SMDS_MeshNode * n4,
3603 const SMDS_MeshNode * n12,
3604 const SMDS_MeshNode * n23,
3605 const SMDS_MeshNode * n31,
3606 const SMDS_MeshNode * n14,
3607 const SMDS_MeshNode * n24,
3608 const SMDS_MeshNode * n34)
3610 int ID = myElementIDFactory->GetFreeID();
3611 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3612 n31, n14, n24, n34, ID);
3613 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3617 //=======================================================================
3618 //function : AddVolumeWithID
3620 //=======================================================================
3621 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3622 int n12,int n23,int n31,
3623 int n14,int n24,int n34, int ID)
3625 return SMDS_Mesh::AddVolumeWithID
3626 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3627 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3628 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3629 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3630 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3631 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3632 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3633 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3634 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3635 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3639 //=======================================================================
3640 //function : AddVolumeWithID
3641 //purpose : 2d order tetrahedron of 10 nodes
3642 //=======================================================================
3643 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3644 const SMDS_MeshNode * n2,
3645 const SMDS_MeshNode * n3,
3646 const SMDS_MeshNode * n4,
3647 const SMDS_MeshNode * n12,
3648 const SMDS_MeshNode * n23,
3649 const SMDS_MeshNode * n31,
3650 const SMDS_MeshNode * n14,
3651 const SMDS_MeshNode * n24,
3652 const SMDS_MeshNode * n34,
3655 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3657 if(hasConstructionFaces()) {
3658 // creation quadratic faces - not implemented
3661 // --- retrieve nodes ID
3662 vector<vtkIdType> nodeIds;
3664 nodeIds.push_back(n1->getVtkId());
3665 nodeIds.push_back(n3->getVtkId());
3666 nodeIds.push_back(n2->getVtkId());
3667 nodeIds.push_back(n4->getVtkId());
3669 nodeIds.push_back(n31->getVtkId());
3670 nodeIds.push_back(n23->getVtkId());
3671 nodeIds.push_back(n12->getVtkId());
3673 nodeIds.push_back(n14->getVtkId());
3674 nodeIds.push_back(n34->getVtkId());
3675 nodeIds.push_back(n24->getVtkId());
3677 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3678 volvtk->init(nodeIds, this);
3679 if (!this->registerElement(ID,volvtk))
3681 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3682 myVolumePool->destroy(volvtk);
3685 adjustmyCellsCapacity(ID);
3686 myCells[ID] = volvtk;
3687 myInfo.myNbQuadTetras++;
3689 // if (!registerElement(ID, volvtk)) {
3690 // RemoveElement(volvtk, false);
3697 //=======================================================================
3698 //function : AddVolume
3700 //=======================================================================
3701 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3702 const SMDS_MeshNode * n2,
3703 const SMDS_MeshNode * n3,
3704 const SMDS_MeshNode * n4,
3705 const SMDS_MeshNode * n5,
3706 const SMDS_MeshNode * n12,
3707 const SMDS_MeshNode * n23,
3708 const SMDS_MeshNode * n34,
3709 const SMDS_MeshNode * n41,
3710 const SMDS_MeshNode * n15,
3711 const SMDS_MeshNode * n25,
3712 const SMDS_MeshNode * n35,
3713 const SMDS_MeshNode * n45)
3715 int ID = myElementIDFactory->GetFreeID();
3716 SMDS_MeshVolume * v =
3717 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3718 n15, n25, n35, n45, ID);
3719 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3723 //=======================================================================
3724 //function : AddVolumeWithID
3726 //=======================================================================
3727 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3728 int n12,int n23,int n34,int n41,
3729 int n15,int n25,int n35,int n45, int ID)
3731 return SMDS_Mesh::AddVolumeWithID
3732 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3733 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3734 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3735 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3736 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3737 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3738 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3739 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3740 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3741 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3742 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3743 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3744 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3748 //=======================================================================
3749 //function : AddVolumeWithID
3750 //purpose : 2d order pyramid of 13 nodes
3751 //=======================================================================
3752 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3753 const SMDS_MeshNode * n2,
3754 const SMDS_MeshNode * n3,
3755 const SMDS_MeshNode * n4,
3756 const SMDS_MeshNode * n5,
3757 const SMDS_MeshNode * n12,
3758 const SMDS_MeshNode * n23,
3759 const SMDS_MeshNode * n34,
3760 const SMDS_MeshNode * n41,
3761 const SMDS_MeshNode * n15,
3762 const SMDS_MeshNode * n25,
3763 const SMDS_MeshNode * n35,
3764 const SMDS_MeshNode * n45,
3767 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3768 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3770 if(hasConstructionFaces()) {
3771 // creation quadratic faces - not implemented
3774 // --- retrieve nodes ID
3775 vector<vtkIdType> nodeIds;
3777 nodeIds.push_back(n1->getVtkId());
3778 nodeIds.push_back(n4->getVtkId());
3779 nodeIds.push_back(n3->getVtkId());
3780 nodeIds.push_back(n2->getVtkId());
3781 nodeIds.push_back(n5->getVtkId());
3783 nodeIds.push_back(n41->getVtkId());
3784 nodeIds.push_back(n34->getVtkId());
3785 nodeIds.push_back(n23->getVtkId());
3786 nodeIds.push_back(n12->getVtkId());
3788 nodeIds.push_back(n15->getVtkId());
3789 nodeIds.push_back(n45->getVtkId());
3790 nodeIds.push_back(n35->getVtkId());
3791 nodeIds.push_back(n25->getVtkId());
3793 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3794 volvtk->init(nodeIds, this);
3795 if (!this->registerElement(ID,volvtk))
3797 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3798 myVolumePool->destroy(volvtk);
3801 adjustmyCellsCapacity(ID);
3802 myCells[ID] = volvtk;
3803 myInfo.myNbQuadPyramids++;
3805 // if (!registerElement(ID, volvtk)) {
3806 // RemoveElement(volvtk, false);
3813 //=======================================================================
3814 //function : AddVolume
3816 //=======================================================================
3817 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3818 const SMDS_MeshNode * n2,
3819 const SMDS_MeshNode * n3,
3820 const SMDS_MeshNode * n4,
3821 const SMDS_MeshNode * n5,
3822 const SMDS_MeshNode * n6,
3823 const SMDS_MeshNode * n12,
3824 const SMDS_MeshNode * n23,
3825 const SMDS_MeshNode * n31,
3826 const SMDS_MeshNode * n45,
3827 const SMDS_MeshNode * n56,
3828 const SMDS_MeshNode * n64,
3829 const SMDS_MeshNode * n14,
3830 const SMDS_MeshNode * n25,
3831 const SMDS_MeshNode * n36)
3833 int ID = myElementIDFactory->GetFreeID();
3834 SMDS_MeshVolume * v =
3835 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3836 n45, n56, n64, n14, n25, n36, ID);
3837 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3841 //=======================================================================
3842 //function : AddVolumeWithID
3844 //=======================================================================
3845 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3846 int n4, int n5, int n6,
3847 int n12,int n23,int n31,
3848 int n45,int n56,int n64,
3849 int n14,int n25,int n36, int ID)
3851 return SMDS_Mesh::AddVolumeWithID
3852 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3853 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3854 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3855 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3856 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3857 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3858 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3859 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3860 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3861 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3862 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3863 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3864 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3865 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3866 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3870 //=======================================================================
3871 //function : AddVolumeWithID
3872 //purpose : 2d order Pentahedron with 15 nodes
3873 //=======================================================================
3874 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3875 const SMDS_MeshNode * n2,
3876 const SMDS_MeshNode * n3,
3877 const SMDS_MeshNode * n4,
3878 const SMDS_MeshNode * n5,
3879 const SMDS_MeshNode * n6,
3880 const SMDS_MeshNode * n12,
3881 const SMDS_MeshNode * n23,
3882 const SMDS_MeshNode * n31,
3883 const SMDS_MeshNode * n45,
3884 const SMDS_MeshNode * n56,
3885 const SMDS_MeshNode * n64,
3886 const SMDS_MeshNode * n14,
3887 const SMDS_MeshNode * n25,
3888 const SMDS_MeshNode * n36,
3891 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3892 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3894 if(hasConstructionFaces()) {
3895 // creation quadratic faces - not implemented
3898 // --- retrieve nodes ID
3899 vector<vtkIdType> nodeIds;
3901 nodeIds.push_back(n1->getVtkId());
3902 nodeIds.push_back(n2->getVtkId());
3903 nodeIds.push_back(n3->getVtkId());
3905 nodeIds.push_back(n4->getVtkId());
3906 nodeIds.push_back(n5->getVtkId());
3907 nodeIds.push_back(n6->getVtkId());
3909 nodeIds.push_back(n12->getVtkId());
3910 nodeIds.push_back(n23->getVtkId());
3911 nodeIds.push_back(n31->getVtkId());
3913 nodeIds.push_back(n45->getVtkId());
3914 nodeIds.push_back(n56->getVtkId());
3915 nodeIds.push_back(n64->getVtkId());
3917 nodeIds.push_back(n14->getVtkId());
3918 nodeIds.push_back(n25->getVtkId());
3919 nodeIds.push_back(n36->getVtkId());
3921 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3922 volvtk->init(nodeIds, this);
3923 if (!this->registerElement(ID,volvtk))
3925 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3926 myVolumePool->destroy(volvtk);
3929 adjustmyCellsCapacity(ID);
3930 myCells[ID] = volvtk;
3931 myInfo.myNbQuadPrisms++;
3933 // if (!registerElement(ID, volvtk)) {
3934 // RemoveElement(volvtk, false);
3941 //=======================================================================
3942 //function : AddVolume
3944 //=======================================================================
3945 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3946 const SMDS_MeshNode * n2,
3947 const SMDS_MeshNode * n3,
3948 const SMDS_MeshNode * n4,
3949 const SMDS_MeshNode * n5,
3950 const SMDS_MeshNode * n6,
3951 const SMDS_MeshNode * n7,
3952 const SMDS_MeshNode * n8,
3953 const SMDS_MeshNode * n12,
3954 const SMDS_MeshNode * n23,
3955 const SMDS_MeshNode * n34,
3956 const SMDS_MeshNode * n41,
3957 const SMDS_MeshNode * n56,
3958 const SMDS_MeshNode * n67,
3959 const SMDS_MeshNode * n78,
3960 const SMDS_MeshNode * n85,
3961 const SMDS_MeshNode * n15,
3962 const SMDS_MeshNode * n26,
3963 const SMDS_MeshNode * n37,
3964 const SMDS_MeshNode * n48)
3966 int ID = myElementIDFactory->GetFreeID();
3967 SMDS_MeshVolume * v =
3968 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3969 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3970 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3974 //=======================================================================
3975 //function : AddVolumeWithID
3977 //=======================================================================
3978 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3979 int n5, int n6, int n7, int n8,
3980 int n12,int n23,int n34,int n41,
3981 int n56,int n67,int n78,int n85,
3982 int n15,int n26,int n37,int n48, int ID)
3984 return SMDS_Mesh::AddVolumeWithID
3985 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3986 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3987 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3997 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3999 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4000 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4001 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4002 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4003 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4004 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4008 //=======================================================================
4009 //function : AddVolumeWithID
4010 //purpose : 2d order Hexahedrons with 20 nodes
4011 //=======================================================================
4012 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4013 const SMDS_MeshNode * n2,
4014 const SMDS_MeshNode * n3,
4015 const SMDS_MeshNode * n4,
4016 const SMDS_MeshNode * n5,
4017 const SMDS_MeshNode * n6,
4018 const SMDS_MeshNode * n7,
4019 const SMDS_MeshNode * n8,
4020 const SMDS_MeshNode * n12,
4021 const SMDS_MeshNode * n23,
4022 const SMDS_MeshNode * n34,
4023 const SMDS_MeshNode * n41,
4024 const SMDS_MeshNode * n56,
4025 const SMDS_MeshNode * n67,
4026 const SMDS_MeshNode * n78,
4027 const SMDS_MeshNode * n85,
4028 const SMDS_MeshNode * n15,
4029 const SMDS_MeshNode * n26,
4030 const SMDS_MeshNode * n37,
4031 const SMDS_MeshNode * n48,
4034 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4035 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4037 if(hasConstructionFaces()) {
4039 // creation quadratic faces - not implemented
4041 // --- retrieve nodes ID
4042 vector<vtkIdType> nodeIds;
4044 nodeIds.push_back(n1->getVtkId());
4045 nodeIds.push_back(n4->getVtkId());
4046 nodeIds.push_back(n3->getVtkId());
4047 nodeIds.push_back(n2->getVtkId());
4049 nodeIds.push_back(n5->getVtkId());
4050 nodeIds.push_back(n8->getVtkId());
4051 nodeIds.push_back(n7->getVtkId());
4052 nodeIds.push_back(n6->getVtkId());
4054 nodeIds.push_back(n41->getVtkId());
4055 nodeIds.push_back(n34->getVtkId());
4056 nodeIds.push_back(n23->getVtkId());
4057 nodeIds.push_back(n12->getVtkId());
4059 nodeIds.push_back(n85->getVtkId());
4060 nodeIds.push_back(n78->getVtkId());
4061 nodeIds.push_back(n67->getVtkId());
4062 nodeIds.push_back(n56->getVtkId());
4064 nodeIds.push_back(n15->getVtkId());
4065 nodeIds.push_back(n48->getVtkId());
4066 nodeIds.push_back(n37->getVtkId());
4067 nodeIds.push_back(n26->getVtkId());
4069 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4070 volvtk->init(nodeIds, this);
4071 if (!this->registerElement(ID,volvtk))
4073 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4074 myVolumePool->destroy(volvtk);
4077 adjustmyCellsCapacity(ID);
4078 myCells[ID] = volvtk;
4079 myInfo.myNbQuadHexas++;
4081 // if (!registerElement(ID, volvtk)) {
4082 // RemoveElement(volvtk, false);
4088 void SMDS_Mesh::updateNodeMinMax()
4091 if (myNodes.size() == 0)
4096 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4098 myNodeMax=myNodes.size()-1;
4099 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4103 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4105 // int val = myCellIdSmdsToVtk.size();
4106 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4107 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4108 int val = myNodes.size();
4109 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4110 myNodes.resize(val +nbNodes, 0);
4113 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4115 int val = myCellIdVtkToSmds.size();
4116 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4117 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4118 val = myCells.size();
4119 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4120 myNodes.resize(val +nbCells, 0);
4123 void SMDS_Mesh::adjustStructure()
4125 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4128 void SMDS_Mesh::dumpGrid(string ficdump)
4130 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4131 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4132 // aWriter->SetFileName(ficdump.c_str());
4133 // aWriter->SetInput(myGrid);
4134 // if(myGrid->GetNumberOfCells())
4136 // aWriter->Write();
4138 // aWriter->Delete();
4139 ficdump = ficdump + "_connectivity";
4140 ofstream ficcon(ficdump.c_str(), ios::out);
4141 int nbPoints = myGrid->GetNumberOfPoints();
4142 ficcon << "-------------------------------- points " << nbPoints << endl;
4143 for (int i=0; i<nbPoints; i++)
4145 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4147 int nbCells = myGrid->GetNumberOfCells();
4148 ficcon << "-------------------------------- cells " << nbCells << endl;
4149 for (int i=0; i<nbCells; i++)
4151 // MESSAGE(i << " " << myGrid->GetCell(i));
4152 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4153 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4154 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4155 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4156 for (int j=0; j<nbptcell; j++)
4158 ficcon << " " << listid->GetId(j);
4162 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4163 vtkCellLinks *links = myGrid->GetCellLinks();
4164 for (int i=0; i<nbPoints; i++)
4166 int ncells = links->GetNcells(i);
4167 vtkIdType *cells = links->GetCells(i);
4168 ficcon << i << " - " << ncells << " -";
4169 for (int j=0; j<ncells; j++)
4171 ficcon << " " << cells[j];
4179 void SMDS_Mesh::compactMesh()
4181 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4184 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4186 if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4187 return myCellIdVtkToSmds[vtkid];
4188 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4191 void SMDS_Mesh::updateBoundingBox()
4196 vtkPoints *points = myGrid->GetPoints();
4197 int myNodesSize = this->myNodes.size();
4198 for (int i = 0; i < myNodesSize; i++)
4200 if (SMDS_MeshNode *n = myNodes[i])
4203 points->GetPoint(n->myVtkID, coords);
4204 if (coords[0] < xmin) xmin = coords[0];
4205 else if (coords[0] > xmax) xmax = coords[0];
4206 if (coords[1] < ymin) ymin = coords[1];
4207 else if (coords[1] > ymax) ymax = coords[1];
4208 if (coords[2] < zmin) zmin = coords[2];
4209 else if (coords[2] > zmax) zmax = coords[2];
4214 double SMDS_Mesh::getMaxDim()
4216 double dmax = 1.e-3;
4217 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4218 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4219 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4220 MESSAGE("getMaxDim " << dmax);
4224 //! modification that needs compact structure and redraw
4225 void SMDS_Mesh::Modified()
4227 if (this->myModified)
4229 this->myModifTime++;
4230 MESSAGE("modified");
4235 //! get last modification timeStamp
4236 unsigned long SMDS_Mesh::GetMTime()
4238 return this->myModifTime;
4241 bool SMDS_Mesh::isCompacted()
4243 if (this->myModifTime > this->myCompactTime)
4245 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4246 this->myCompactTime = this->myModifTime;