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 if (ID >= myNodes.size())
228 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
229 MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
232 myNodeIDFactory->BindID(ID,node);
235 this->adjustBoundingBox(x, y, z);
241 ///////////////////////////////////////////////////////////////////////////////
242 /// create a Mesh0DElement and add it to the current Mesh
243 /// @return : The created Mesh0DElement
244 ///////////////////////////////////////////////////////////////////////////////
245 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
247 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
248 if (!node) return NULL;
249 return SMDS_Mesh::Add0DElementWithID(node, ID);
252 ///////////////////////////////////////////////////////////////////////////////
253 /// create a Mesh0DElement and add it to the current Mesh
254 /// @return : The created Mesh0DElement
255 ///////////////////////////////////////////////////////////////////////////////
256 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
258 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
261 ///////////////////////////////////////////////////////////////////////////////
262 /// Create a new Mesh0DElement and at it to the mesh
263 /// @param idnode ID of the node
264 /// @param ID ID of the 0D element to create
265 /// @return The created 0D element or NULL if an element with this
266 /// ID already exists or if input node is not found.
267 ///////////////////////////////////////////////////////////////////////////////
268 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
272 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
273 //MESSAGE("Add0DElementWithID" << ID)
274 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
275 if (myElementIDFactory->BindID(ID, el0d)) {
276 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
277 //node->AddInverseElement(el0d);// --- fait avec BindID
278 adjustmyCellsCapacity(ID);
280 myInfo.myNb0DElements++;
288 ///////////////////////////////////////////////////////////////////////////////
289 /// create a MeshEdge and add it to the current Mesh
290 /// @return : The created MeshEdge
291 ///////////////////////////////////////////////////////////////////////////////
293 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
295 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
296 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
297 if(!node1 || !node2) return NULL;
298 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
301 ///////////////////////////////////////////////////////////////////////////////
302 /// create a MeshEdge and add it to the current Mesh
303 /// @return : The created MeshEdge
304 ///////////////////////////////////////////////////////////////////////////////
306 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
307 const SMDS_MeshNode * node2)
309 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
312 ///////////////////////////////////////////////////////////////////////////////
313 /// Create a new edge and at it to the mesh
314 /// @param idnode1 ID of the first node
315 /// @param idnode2 ID of the second node
316 /// @param ID ID of the edge to create
317 /// @return The created edge or NULL if an element with this ID already exists or
318 /// if input nodes are not found.
319 ///////////////////////////////////////////////////////////////////////////////
321 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
322 const SMDS_MeshNode * n2,
325 if ( !n1 || !n2 ) return 0;
326 SMDS_MeshEdge * edge = 0;
328 // --- retreive nodes ID
329 vector<vtkIdType> nodeIds;
331 nodeIds.push_back(n1->getVtkId());
332 nodeIds.push_back(n2->getVtkId());
334 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
335 edgevtk->init(nodeIds, this);
336 if (!this->registerElement(ID,edgevtk))
338 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
339 myEdgePool->destroy(edgevtk);
343 adjustmyCellsCapacity(ID);
347 // if (edge && !registerElement(ID, edge))
349 // RemoveElement(edge, false);
355 ///////////////////////////////////////////////////////////////////////////////
356 /// Add a triangle defined by its nodes. An ID is automatically affected to the
358 ///////////////////////////////////////////////////////////////////////////////
360 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
361 const SMDS_MeshNode * n2,
362 const SMDS_MeshNode * n3)
364 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
367 ///////////////////////////////////////////////////////////////////////////////
368 /// Add a triangle defined by its nodes IDs
369 ///////////////////////////////////////////////////////////////////////////////
371 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
373 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
374 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
375 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
376 if(!node1 || !node2 || !node3) return NULL;
377 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
380 ///////////////////////////////////////////////////////////////////////////////
381 /// Add a triangle defined by its nodes
382 ///////////////////////////////////////////////////////////////////////////////
384 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
385 const SMDS_MeshNode * n2,
386 const SMDS_MeshNode * n3,
389 //MESSAGE("AddFaceWithID " << ID)
390 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
392 // if (face && !registerElement(ID, face)) {
393 // RemoveElement(face, false);
399 ///////////////////////////////////////////////////////////////////////////////
400 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
402 ///////////////////////////////////////////////////////////////////////////////
404 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
405 const SMDS_MeshNode * n2,
406 const SMDS_MeshNode * n3,
407 const SMDS_MeshNode * n4)
409 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
412 ///////////////////////////////////////////////////////////////////////////////
413 /// Add a quadrangle defined by its nodes IDs
414 ///////////////////////////////////////////////////////////////////////////////
416 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
422 SMDS_MeshNode *node1, *node2, *node3, *node4;
423 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
424 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
425 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
426 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
427 if(!node1 || !node2 || !node3 || !node4) return NULL;
428 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
431 ///////////////////////////////////////////////////////////////////////////////
432 /// Add a quadrangle defined by its nodes
433 ///////////////////////////////////////////////////////////////////////////////
435 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
436 const SMDS_MeshNode * n2,
437 const SMDS_MeshNode * n3,
438 const SMDS_MeshNode * n4,
441 //MESSAGE("AddFaceWithID " << ID);
442 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
444 // if (face && !registerElement(ID, face)) {
445 // RemoveElement(face, false);
451 ///////////////////////////////////////////////////////////////////////////////
452 /// Add a triangle defined by its edges. An ID is automatically assigned to the
454 ///////////////////////////////////////////////////////////////////////////////
456 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
457 const SMDS_MeshEdge * e2,
458 const SMDS_MeshEdge * e3)
460 if (!hasConstructionEdges())
462 //MESSAGE("AddFaceWithID");
463 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
466 ///////////////////////////////////////////////////////////////////////////////
467 /// Add a triangle defined by its edges
468 ///////////////////////////////////////////////////////////////////////////////
470 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
471 const SMDS_MeshEdge * e2,
472 const SMDS_MeshEdge * e3,
475 if (!hasConstructionEdges())
477 if ( !e1 || !e2 || !e3 ) return 0;
479 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
480 MESSAGE("AddFaceWithID" << ID);
482 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
483 adjustmyCellsCapacity(ID);
485 myInfo.myNbTriangles++;
487 if (!registerElement(ID, face)) {
488 registerElement(myElementIDFactory->GetFreeID(), face);
489 //RemoveElement(face, false);
495 ///////////////////////////////////////////////////////////////////////////////
496 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
498 ///////////////////////////////////////////////////////////////////////////////
500 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
501 const SMDS_MeshEdge * e2,
502 const SMDS_MeshEdge * e3,
503 const SMDS_MeshEdge * e4)
505 if (!hasConstructionEdges())
507 //MESSAGE("AddFaceWithID" );
508 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
511 ///////////////////////////////////////////////////////////////////////////////
512 /// Add a quadrangle defined by its edges
513 ///////////////////////////////////////////////////////////////////////////////
515 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
516 const SMDS_MeshEdge * e2,
517 const SMDS_MeshEdge * e3,
518 const SMDS_MeshEdge * e4,
521 if (!hasConstructionEdges())
523 MESSAGE("AddFaceWithID" << ID);
524 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
525 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
526 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
527 adjustmyCellsCapacity(ID);
529 myInfo.myNbQuadrangles++;
531 if (!registerElement(ID, face))
533 registerElement(myElementIDFactory->GetFreeID(), face);
534 //RemoveElement(face, false);
540 ///////////////////////////////////////////////////////////////////////////////
541 ///Create a new tetrahedron and add it to the mesh.
542 ///@return The created tetrahedron
543 ///////////////////////////////////////////////////////////////////////////////
545 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
546 const SMDS_MeshNode * n2,
547 const SMDS_MeshNode * n3,
548 const SMDS_MeshNode * n4)
550 int ID = myElementIDFactory->GetFreeID();
551 //MESSAGE("AddVolumeWithID " << ID);
552 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
553 if(v==NULL) myElementIDFactory->ReleaseID(ID);
557 ///////////////////////////////////////////////////////////////////////////////
558 ///Create a new tetrahedron and add it to the mesh.
559 ///@param ID The ID of the new volume
560 ///@return The created tetrahedron or NULL if an element with this ID already exists
561 ///or if input nodes are not found.
562 ///////////////////////////////////////////////////////////////////////////////
564 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
570 //MESSAGE("AddVolumeWithID" << ID);
571 SMDS_MeshNode *node1, *node2, *node3, *node4;
572 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
573 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
574 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
575 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
576 if(!node1 || !node2 || !node3 || !node4) return NULL;
577 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
580 ///////////////////////////////////////////////////////////////////////////////
581 ///Create a new tetrahedron and add it to the mesh.
582 ///@param ID The ID of the new volume
583 ///@return The created tetrahedron
584 ///////////////////////////////////////////////////////////////////////////////
586 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
587 const SMDS_MeshNode * n2,
588 const SMDS_MeshNode * n3,
589 const SMDS_MeshNode * n4,
592 //MESSAGE("AddVolumeWithID " << ID);
593 SMDS_MeshVolume* volume = 0;
594 if ( !n1 || !n2 || !n3 || !n4) return volume;
595 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
596 if(hasConstructionFaces()) {
597 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
598 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
599 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
600 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
601 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
602 adjustmyCellsCapacity(ID);
603 myCells[ID] = volume;
606 else if(hasConstructionEdges()) {
607 MESSAGE("Error : Not implemented");
611 // --- retrieve nodes ID
612 vector<vtkIdType> nodeIds;
614 nodeIds.push_back(n1->getVtkId());
615 nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
616 nodeIds.push_back(n2->getVtkId());
617 nodeIds.push_back(n4->getVtkId());
619 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
620 volvtk->init(nodeIds, this);
621 if (!this->registerElement(ID,volvtk))
623 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
624 myVolumePool->destroy(volvtk);
628 adjustmyCellsCapacity(ID);
629 myCells[ID] = volume;
633 // if (!registerElement(ID, volume)) {
634 // RemoveElement(volume, false);
640 ///////////////////////////////////////////////////////////////////////////////
641 ///Create a new pyramid and add it to the mesh.
642 ///Nodes 1,2,3 and 4 define the base of the pyramid
643 ///@return The created pyramid
644 ///////////////////////////////////////////////////////////////////////////////
646 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
647 const SMDS_MeshNode * n2,
648 const SMDS_MeshNode * n3,
649 const SMDS_MeshNode * n4,
650 const SMDS_MeshNode * n5)
652 int ID = myElementIDFactory->GetFreeID();
653 //MESSAGE("AddVolumeWithID " << ID);
654 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
655 if(v==NULL) myElementIDFactory->ReleaseID(ID);
659 ///////////////////////////////////////////////////////////////////////////////
660 ///Create a new pyramid and add it to the mesh.
661 ///Nodes 1,2,3 and 4 define the base of the pyramid
662 ///@param ID The ID of the new volume
663 ///@return The created pyramid or NULL if an element with this ID already exists
664 ///or if input nodes are not found.
665 ///////////////////////////////////////////////////////////////////////////////
667 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
674 //MESSAGE("AddVolumeWithID " << ID);
675 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
676 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
677 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
678 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
679 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
680 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
681 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
682 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
685 ///////////////////////////////////////////////////////////////////////////////
686 ///Create a new pyramid and add it to the mesh.
687 ///Nodes 1,2,3 and 4 define the base of the pyramid
688 ///@param ID The ID of the new volume
689 ///@return The created pyramid
690 ///////////////////////////////////////////////////////////////////////////////
692 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
693 const SMDS_MeshNode * n2,
694 const SMDS_MeshNode * n3,
695 const SMDS_MeshNode * n4,
696 const SMDS_MeshNode * n5,
699 //MESSAGE("AddVolumeWithID " << ID);
700 SMDS_MeshVolume* volume = 0;
701 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
702 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
703 if(hasConstructionFaces()) {
704 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
705 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
706 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
707 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
708 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
709 adjustmyCellsCapacity(ID);
710 myCells[ID] = volume;
711 myInfo.myNbPyramids++;
713 else if(hasConstructionEdges()) {
714 MESSAGE("Error : Not implemented");
718 // --- retrieve nodes ID
719 vector<vtkIdType> nodeIds;
721 nodeIds.push_back(n1->getVtkId());
722 nodeIds.push_back(n4->getVtkId());
723 nodeIds.push_back(n3->getVtkId());
724 nodeIds.push_back(n2->getVtkId());
725 nodeIds.push_back(n5->getVtkId());
727 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
728 volvtk->init(nodeIds, this);
729 if (!this->registerElement(ID,volvtk))
731 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
732 myVolumePool->destroy(volvtk);
736 adjustmyCellsCapacity(ID);
737 myCells[ID] = volume;
738 myInfo.myNbPyramids++;
741 // if (!registerElement(ID, volume)) {
742 // RemoveElement(volume, false);
748 ///////////////////////////////////////////////////////////////////////////////
749 ///Create a new prism and add it to the mesh.
750 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
751 ///@return The created prism
752 ///////////////////////////////////////////////////////////////////////////////
754 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
755 const SMDS_MeshNode * n2,
756 const SMDS_MeshNode * n3,
757 const SMDS_MeshNode * n4,
758 const SMDS_MeshNode * n5,
759 const SMDS_MeshNode * n6)
761 int ID = myElementIDFactory->GetFreeID();
762 //MESSAGE("AddVolumeWithID " << ID);
763 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
764 if(v==NULL) myElementIDFactory->ReleaseID(ID);
768 ///////////////////////////////////////////////////////////////////////////////
769 ///Create a new prism and add it to the mesh.
770 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
771 ///@param ID The ID of the new volume
772 ///@return The created prism or NULL if an element with this ID already exists
773 ///or if input nodes are not found.
774 ///////////////////////////////////////////////////////////////////////////////
776 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
784 //MESSAGE("AddVolumeWithID " << ID);
785 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
786 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
787 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
788 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
789 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
790 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
791 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
792 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
793 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
796 ///////////////////////////////////////////////////////////////////////////////
797 ///Create a new prism and add it to the mesh.
798 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
799 ///@param ID The ID of the new volume
800 ///@return The created prism
801 ///////////////////////////////////////////////////////////////////////////////
803 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
804 const SMDS_MeshNode * n2,
805 const SMDS_MeshNode * n3,
806 const SMDS_MeshNode * n4,
807 const SMDS_MeshNode * n5,
808 const SMDS_MeshNode * n6,
811 //MESSAGE("AddVolumeWithID " << ID);
812 SMDS_MeshVolume* volume = 0;
813 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
814 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
815 if(hasConstructionFaces()) {
816 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
817 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
818 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
819 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
820 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
821 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
822 adjustmyCellsCapacity(ID);
823 myCells[ID] = volume;
826 else if(hasConstructionEdges()) {
827 MESSAGE("Error : Not implemented");
831 // --- retrieve nodes ID
832 vector<vtkIdType> nodeIds;
834 nodeIds.push_back(n1->getVtkId());
835 nodeIds.push_back(n2->getVtkId());
836 nodeIds.push_back(n3->getVtkId());
837 nodeIds.push_back(n4->getVtkId());
838 nodeIds.push_back(n5->getVtkId());
839 nodeIds.push_back(n6->getVtkId());
841 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
842 volvtk->init(nodeIds, this);
843 if (!this->registerElement(ID,volvtk))
845 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
846 myVolumePool->destroy(volvtk);
850 adjustmyCellsCapacity(ID);
851 myCells[ID] = volume;
855 // if (!registerElement(ID, volume)) {
856 // RemoveElement(volume, false);
862 ///////////////////////////////////////////////////////////////////////////////
863 ///Create a new hexahedron and add it to the mesh.
864 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
865 ///@return The created hexahedron
866 ///////////////////////////////////////////////////////////////////////////////
868 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
869 const SMDS_MeshNode * n2,
870 const SMDS_MeshNode * n3,
871 const SMDS_MeshNode * n4,
872 const SMDS_MeshNode * n5,
873 const SMDS_MeshNode * n6,
874 const SMDS_MeshNode * n7,
875 const SMDS_MeshNode * n8)
877 int ID = myElementIDFactory->GetFreeID();
878 //MESSAGE("AddVolumeWithID " << ID);
879 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
880 if(v==NULL) myElementIDFactory->ReleaseID(ID);
884 ///////////////////////////////////////////////////////////////////////////////
885 ///Create a new hexahedron and add it to the mesh.
886 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
887 ///@param ID The ID of the new volume
888 ///@return The created hexahedron or NULL if an element with this ID already
889 ///exists or if input nodes are not found.
890 ///////////////////////////////////////////////////////////////////////////////
892 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
902 //MESSAGE("AddVolumeWithID " << ID);
903 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
904 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
905 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
906 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
907 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
908 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
909 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
910 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
911 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
912 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
914 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
918 ///////////////////////////////////////////////////////////////////////////////
919 ///Create a new hexahedron and add it to the mesh.
920 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
921 ///@param ID The ID of the new volume
922 ///@return The created prism or NULL if an element with this ID already exists
923 ///or if input nodes are not found.
924 ///////////////////////////////////////////////////////////////////////////////
926 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
927 const SMDS_MeshNode * n2,
928 const SMDS_MeshNode * n3,
929 const SMDS_MeshNode * n4,
930 const SMDS_MeshNode * n5,
931 const SMDS_MeshNode * n6,
932 const SMDS_MeshNode * n7,
933 const SMDS_MeshNode * n8,
936 //MESSAGE("AddVolumeWithID " << ID);
937 SMDS_MeshVolume* volume = 0;
938 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
939 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
940 if(hasConstructionFaces()) {
941 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
942 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
943 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
944 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
945 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
946 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
947 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
948 adjustmyCellsCapacity(ID);
949 myCells[ID] = volume;
952 else if(hasConstructionEdges()) {
953 MESSAGE("Error : Not implemented");
957 // --- retrieve nodes ID
958 vector<vtkIdType> nodeIds;
960 nodeIds.push_back(n1->getVtkId());
961 nodeIds.push_back(n4->getVtkId());
962 nodeIds.push_back(n3->getVtkId());
963 nodeIds.push_back(n2->getVtkId());
964 nodeIds.push_back(n5->getVtkId());
965 nodeIds.push_back(n8->getVtkId());
966 nodeIds.push_back(n7->getVtkId());
967 nodeIds.push_back(n6->getVtkId());
969 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
970 volvtk->init(nodeIds, this);
971 if (!this->registerElement(ID,volvtk))
973 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
974 myVolumePool->destroy(volvtk);
978 adjustmyCellsCapacity(ID);
979 myCells[ID] = volume;
983 // if (!registerElement(ID, volume)) {
984 // RemoveElement(volume, false);
990 ///////////////////////////////////////////////////////////////////////////////
991 ///Create a new tetrahedron defined by its faces and add it to the mesh.
992 ///@return The created tetrahedron
993 ///////////////////////////////////////////////////////////////////////////////
995 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
996 const SMDS_MeshFace * f2,
997 const SMDS_MeshFace * f3,
998 const SMDS_MeshFace * f4)
1000 //MESSAGE("AddVolumeWithID");
1001 if (!hasConstructionFaces())
1003 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1006 ///////////////////////////////////////////////////////////////////////////////
1007 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1008 ///@param ID The ID of the new volume
1009 ///@return The created tetrahedron
1010 ///////////////////////////////////////////////////////////////////////////////
1012 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1013 const SMDS_MeshFace * f2,
1014 const SMDS_MeshFace * f3,
1015 const SMDS_MeshFace * f4,
1018 MESSAGE("AddVolumeWithID" << ID);
1019 if (!hasConstructionFaces())
1021 if ( !f1 || !f2 || !f3 || !f4) return 0;
1022 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1023 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1024 adjustmyCellsCapacity(ID);
1025 myCells[ID] = volume;
1026 myInfo.myNbTetras++;
1028 if (!registerElement(ID, volume)) {
1029 registerElement(myElementIDFactory->GetFreeID(), volume);
1030 //RemoveElement(volume, false);
1036 ///////////////////////////////////////////////////////////////////////////////
1037 ///Create a new pyramid defined by its faces and add it to the mesh.
1038 ///@return The created pyramid
1039 ///////////////////////////////////////////////////////////////////////////////
1041 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1042 const SMDS_MeshFace * f2,
1043 const SMDS_MeshFace * f3,
1044 const SMDS_MeshFace * f4,
1045 const SMDS_MeshFace * f5)
1047 //MESSAGE("AddVolumeWithID");
1048 if (!hasConstructionFaces())
1050 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1053 ///////////////////////////////////////////////////////////////////////////////
1054 ///Create a new pyramid defined by its faces and add it to the mesh.
1055 ///@param ID The ID of the new volume
1056 ///@return The created pyramid
1057 ///////////////////////////////////////////////////////////////////////////////
1059 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1060 const SMDS_MeshFace * f2,
1061 const SMDS_MeshFace * f3,
1062 const SMDS_MeshFace * f4,
1063 const SMDS_MeshFace * f5,
1066 MESSAGE("AddVolumeWithID" << ID);
1067 if (!hasConstructionFaces())
1069 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1070 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1071 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1072 adjustmyCellsCapacity(ID);
1073 myCells[ID] = volume;
1074 myInfo.myNbPyramids++;
1076 if (!registerElement(ID, volume)) {
1077 registerElement(myElementIDFactory->GetFreeID(), volume);
1078 //RemoveElement(volume, false);
1084 ///////////////////////////////////////////////////////////////////////////////
1085 ///Create a new prism defined by its faces and add it to the mesh.
1086 ///@return The created prism
1087 ///////////////////////////////////////////////////////////////////////////////
1089 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1090 const SMDS_MeshFace * f2,
1091 const SMDS_MeshFace * f3,
1092 const SMDS_MeshFace * f4,
1093 const SMDS_MeshFace * f5,
1094 const SMDS_MeshFace * f6)
1096 //MESSAGE("AddVolumeWithID" );
1097 if (!hasConstructionFaces())
1099 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1102 ///////////////////////////////////////////////////////////////////////////////
1103 ///Create a new prism defined by its faces and add it to the mesh.
1104 ///@param ID The ID of the new volume
1105 ///@return The created prism
1106 ///////////////////////////////////////////////////////////////////////////////
1108 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1109 const SMDS_MeshFace * f2,
1110 const SMDS_MeshFace * f3,
1111 const SMDS_MeshFace * f4,
1112 const SMDS_MeshFace * f5,
1113 const SMDS_MeshFace * f6,
1116 MESSAGE("AddVolumeWithID" << ID);
1117 if (!hasConstructionFaces())
1119 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1120 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1121 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1122 adjustmyCellsCapacity(ID);
1123 myCells[ID] = volume;
1124 myInfo.myNbPrisms++;
1126 if (!registerElement(ID, volume)) {
1127 registerElement(myElementIDFactory->GetFreeID(), volume);
1128 //RemoveElement(volume, false);
1134 ///////////////////////////////////////////////////////////////////////////////
1135 /// Add a polygon defined by its nodes IDs
1136 ///////////////////////////////////////////////////////////////////////////////
1138 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
1141 int nbNodes = nodes_ids.size();
1142 vector<const SMDS_MeshNode*> nodes (nbNodes);
1143 for (int i = 0; i < nbNodes; i++) {
1144 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1145 if (!nodes[i]) return NULL;
1147 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1150 ///////////////////////////////////////////////////////////////////////////////
1151 /// Add a polygon defined by its nodes
1152 ///////////////////////////////////////////////////////////////////////////////
1154 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1155 (vector<const SMDS_MeshNode*> nodes,
1158 SMDS_MeshFace * face;
1160 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1161 if (hasConstructionEdges())
1163 MESSAGE("Error : Not implemented");
1168 //#ifdef VTK_HAVE_POLYHEDRON
1169 //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
1170 vector<vtkIdType> nodeIds;
1172 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1173 for ( ; it != nodes.end(); ++it)
1174 nodeIds.push_back((*it)->getVtkId());
1176 SMDS_VtkFace *facevtk = myFacePool->getNew();
1177 facevtk->initPoly(nodeIds, this);
1178 if (!this->registerElement(ID,facevtk))
1180 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1181 myFacePool->destroy(facevtk);
1186 // MESSAGE("AddPolygonalFaceWithID smds " << ID);
1187 // for ( int i = 0; i < nodes.size(); ++i )
1188 // if ( !nodes[ i ] ) return 0;
1189 // face = new SMDS_PolygonalFaceOfNodes(nodes);
1191 adjustmyCellsCapacity(ID);
1193 myInfo.myNbPolygons++;
1196 //#ifndef VTK_HAVE_POLYHEDRON
1197 // if (!registerElement(ID, face))
1199 // registerElement(myElementIDFactory->GetFreeID(), face);
1200 // //RemoveElement(face, false);
1207 ///////////////////////////////////////////////////////////////////////////////
1208 /// Add a polygon defined by its nodes.
1209 /// An ID is automatically affected to the created face.
1210 ///////////////////////////////////////////////////////////////////////////////
1212 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
1214 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1217 ///////////////////////////////////////////////////////////////////////////////
1218 /// Create a new polyhedral volume and add it to the mesh.
1219 /// @param ID The ID of the new volume
1220 /// @return The created volume or NULL if an element with this ID already exists
1221 /// or if input nodes are not found.
1222 ///////////////////////////////////////////////////////////////////////////////
1224 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1225 (vector<int> nodes_ids,
1226 vector<int> quantities,
1229 int nbNodes = nodes_ids.size();
1230 vector<const SMDS_MeshNode*> nodes (nbNodes);
1231 for (int i = 0; i < nbNodes; i++) {
1232 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1233 if (!nodes[i]) return NULL;
1235 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1238 ///////////////////////////////////////////////////////////////////////////////
1239 /// Create a new polyhedral volume and add it to the mesh.
1240 /// @param ID The ID of the new volume
1241 /// @return The created volume
1242 ///////////////////////////////////////////////////////////////////////////////
1244 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1245 (vector<const SMDS_MeshNode*> nodes,
1246 vector<int> quantities,
1249 SMDS_MeshVolume* volume;
1250 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1251 if (hasConstructionFaces())
1253 MESSAGE("Error : Not implemented");
1256 else if (hasConstructionEdges())
1258 MESSAGE("Error : Not implemented");
1263 //#ifdef VTK_HAVE_POLYHEDRON
1264 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1265 vector<vtkIdType> nodeIds;
1267 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1268 for (; it != nodes.end(); ++it)
1269 nodeIds.push_back((*it)->getVtkId());
1271 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1272 volvtk->initPoly(nodeIds, quantities, this);
1273 if (!this->registerElement(ID, volvtk))
1275 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1276 myVolumePool->destroy(volvtk);
1281 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1282 // for ( int i = 0; i < nodes.size(); ++i )
1283 // if ( !nodes[ i ] ) return 0;
1284 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1286 adjustmyCellsCapacity(ID);
1287 myCells[ID] = volume;
1288 myInfo.myNbPolyhedrons++;
1291 //#ifndef VTK_HAVE_POLYHEDRON
1292 // if (!registerElement(ID, volume))
1294 // registerElement(myElementIDFactory->GetFreeID(), volume);
1295 // //RemoveElement(volume, false);
1302 ///////////////////////////////////////////////////////////////////////////////
1303 /// Create a new polyhedral volume and add it to the mesh.
1304 /// @return The created volume
1305 ///////////////////////////////////////////////////////////////////////////////
1307 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1308 (vector<const SMDS_MeshNode*> nodes,
1309 vector<int> quantities)
1311 int ID = myElementIDFactory->GetFreeID();
1312 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1313 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1317 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1319 int ID = myElementIDFactory->GetFreeID();
1320 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1321 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1325 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1327 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1328 volvtk->init(vtkNodeIds, this);
1329 if (!this->registerElement(ID,volvtk))
1331 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1332 myVolumePool->destroy(volvtk);
1335 adjustmyCellsCapacity(ID);
1336 myCells[ID] = volvtk;
1337 vtkIdType aVtkType = volvtk->GetVtkType();
1341 myInfo.myNbTetras++;
1344 myInfo.myNbPyramids++;
1347 myInfo.myNbPrisms++;
1349 case VTK_HEXAHEDRON:
1352 case VTK_QUADRATIC_TETRA:
1353 myInfo.myNbQuadTetras++;
1355 case VTK_QUADRATIC_PYRAMID:
1356 myInfo.myNbQuadPyramids++;
1358 case VTK_QUADRATIC_WEDGE:
1359 myInfo.myNbQuadPrisms++;
1361 case VTK_QUADRATIC_HEXAHEDRON:
1362 myInfo.myNbQuadHexas++;
1364 //#ifdef VTK_HAVE_POLYHEDRON
1365 case VTK_POLYHEDRON:
1366 myInfo.myNbPolyhedrons++;
1370 myInfo.myNbPolyhedrons++;
1376 ///////////////////////////////////////////////////////////////////////////////
1377 /// Registers element with the given ID, maintains inverse connections
1378 ///////////////////////////////////////////////////////////////////////////////
1379 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1381 //MESSAGE("registerElement " << ID);
1382 if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1384 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1389 element->myMeshId = myMeshId;
1391 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1393 int vtkId = cell->getVtkId();
1395 vtkId = myElementIDFactory->SetInVtkGrid(element);
1397 if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1399 MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1400 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1402 myCellIdVtkToSmds[vtkId] = ID;
1404 myElementIDFactory->updateMinMax(ID);
1408 ///////////////////////////////////////////////////////////////////////////////
1409 /// Return the node whose SMDS ID is 'ID'.
1410 ///////////////////////////////////////////////////////////////////////////////
1411 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1413 if (ID < 1 || ID >= myNodes.size())
1415 MESSAGE("------------------------------------------------------------------------- ");
1416 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1417 MESSAGE("------------------------------------------------------------------------- ");
1420 return (const SMDS_MeshNode *)myNodes[ID];
1423 ///////////////////////////////////////////////////////////////////////////////
1424 /// Return the node whose VTK ID is 'vtkId'.
1425 ///////////////////////////////////////////////////////////////////////////////
1426 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1428 // TODO if needed use mesh->nodeIdFromVtkToSmds
1429 if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1431 MESSAGE("------------------------------------------------------------------------- ");
1432 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1433 MESSAGE("------------------------------------------------------------------------- ");
1436 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1439 ///////////////////////////////////////////////////////////////////////////////
1440 ///Create a triangle and add it to the current mesh. This method do not bind an
1441 ///ID to the create triangle.
1442 ///////////////////////////////////////////////////////////////////////////////
1443 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1444 const SMDS_MeshNode * node2,
1445 const SMDS_MeshNode * node3,
1448 if ( !node1 || !node2 || !node3) return 0;
1449 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1450 if(hasConstructionEdges())
1452 SMDS_MeshEdge *edge1, *edge2, *edge3;
1453 edge1=FindEdgeOrCreate(node1,node2);
1454 edge2=FindEdgeOrCreate(node2,node3);
1455 edge3=FindEdgeOrCreate(node3,node1);
1457 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1458 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1459 adjustmyCellsCapacity(ID);
1461 myInfo.myNbTriangles++;
1466 // --- retrieve nodes ID
1467 vector<vtkIdType> nodeIds;
1469 nodeIds.push_back(node1->getVtkId());
1470 nodeIds.push_back(node2->getVtkId());
1471 nodeIds.push_back(node3->getVtkId());
1473 SMDS_MeshFace * face = 0;
1474 SMDS_VtkFace *facevtk = myFacePool->getNew();
1475 facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1476 if (!this->registerElement(ID,facevtk))
1478 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1479 myFacePool->destroy(facevtk);
1483 adjustmyCellsCapacity(ID);
1485 //MESSAGE("createTriangle " << ID << " " << face);
1486 myInfo.myNbTriangles++;
1491 ///////////////////////////////////////////////////////////////////////////////
1492 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1493 ///a ID to the create triangle.
1494 ///////////////////////////////////////////////////////////////////////////////
1495 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1496 const SMDS_MeshNode * node2,
1497 const SMDS_MeshNode * node3,
1498 const SMDS_MeshNode * node4,
1501 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1502 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1503 if(hasConstructionEdges())
1505 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1506 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1507 edge1=FindEdgeOrCreate(node1,node2);
1508 edge2=FindEdgeOrCreate(node2,node3);
1509 edge3=FindEdgeOrCreate(node3,node4);
1510 edge4=FindEdgeOrCreate(node4,node1);
1512 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1513 adjustmyCellsCapacity(ID);
1515 myInfo.myNbQuadrangles++;
1520 // --- retrieve nodes ID
1521 vector<vtkIdType> nodeIds;
1523 nodeIds.push_back(node1->getVtkId());
1524 nodeIds.push_back(node2->getVtkId());
1525 nodeIds.push_back(node3->getVtkId());
1526 nodeIds.push_back(node4->getVtkId());
1528 SMDS_MeshFace * face = 0;
1529 SMDS_VtkFace *facevtk = myFacePool->getNew();
1530 facevtk->init(nodeIds, this);
1531 if (!this->registerElement(ID,facevtk))
1533 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1534 myFacePool->destroy(facevtk);
1538 adjustmyCellsCapacity(ID);
1540 myInfo.myNbQuadrangles++;
1545 ///////////////////////////////////////////////////////////////////////////////
1546 /// Remove a node and all the elements which own this node
1547 ///////////////////////////////////////////////////////////////////////////////
1549 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1551 MESSAGE("RemoveNode");
1552 RemoveElement(node, true);
1555 ///////////////////////////////////////////////////////////////////////////////
1556 /// Remove an edge and all the elements which own this edge
1557 ///////////////////////////////////////////////////////////////////////////////
1559 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1561 MESSAGE("Remove0DElement");
1562 RemoveElement(elem0d,true);
1565 ///////////////////////////////////////////////////////////////////////////////
1566 /// Remove an edge and all the elements which own this edge
1567 ///////////////////////////////////////////////////////////////////////////////
1569 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1571 MESSAGE("RemoveEdge");
1572 RemoveElement(edge,true);
1575 ///////////////////////////////////////////////////////////////////////////////
1576 /// Remove an face and all the elements which own this face
1577 ///////////////////////////////////////////////////////////////////////////////
1579 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1581 MESSAGE("RemoveFace");
1582 RemoveElement(face, true);
1585 ///////////////////////////////////////////////////////////////////////////////
1587 ///////////////////////////////////////////////////////////////////////////////
1589 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1591 MESSAGE("RemoveVolume");
1592 RemoveElement(volume, true);
1595 //=======================================================================
1596 //function : RemoveFromParent
1598 //=======================================================================
1600 bool SMDS_Mesh::RemoveFromParent()
1602 if (myParent==NULL) return false;
1603 else return (myParent->RemoveSubMesh(this));
1606 //=======================================================================
1607 //function : RemoveSubMesh
1609 //=======================================================================
1611 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1615 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1616 for (; itmsh!=myChildren.end() && !found; itmsh++)
1618 SMDS_Mesh * submesh = *itmsh;
1619 if (submesh == aMesh)
1622 myChildren.erase(itmsh);
1629 //=======================================================================
1630 //function : ChangeElementNodes
1632 //=======================================================================
1634 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1635 const SMDS_MeshNode * nodes[],
1638 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1639 // keep current nodes of elem
1640 set<const SMDS_MeshElement*> oldNodes;
1641 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1643 oldNodes.insert(itn->next());
1647 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1650 Ok = cell->vtkOrder(nodes, nbnodes);
1651 Ok = cell->ChangeNodes(nodes, nbnodes);
1654 if ( Ok ) { // update InverseElements
1656 set<const SMDS_MeshElement*>::iterator it;
1658 // AddInverseElement to new nodes
1659 for ( int i = 0; i < nbnodes; i++ ) {
1660 it = oldNodes.find( nodes[i] );
1661 if ( it == oldNodes.end() )
1663 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1665 // remove from oldNodes a node that remains in elem
1666 oldNodes.erase( it );
1668 // RemoveInverseElement from the nodes removed from elem
1669 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1671 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1672 (const_cast<SMDS_MeshElement *>( *it ));
1673 n->RemoveInverseElement( cell );
1680 //=======================================================================
1681 //function : ChangePolyhedronNodes
1682 //purpose : to change nodes of polyhedral volume
1683 //=======================================================================
1684 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1685 const vector<const SMDS_MeshNode*>& nodes,
1686 const vector<int> & quantities)
1688 if (elem->GetType() != SMDSAbs_Volume) {
1689 MESSAGE("WRONG ELEM TYPE");
1693 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1698 // keep current nodes of elem
1699 set<const SMDS_MeshElement*> oldNodes;
1700 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1701 while (itn->more()) {
1702 oldNodes.insert(itn->next());
1706 // TODO remove this function
1707 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1713 // update InverseElements
1715 // AddInverseElement to new nodes
1716 int nbnodes = nodes.size();
1717 set<const SMDS_MeshElement*>::iterator it;
1718 for (int i = 0; i < nbnodes; i++) {
1719 it = oldNodes.find(nodes[i]);
1720 if (it == oldNodes.end()) {
1722 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1724 // remove from oldNodes a node that remains in elem
1729 // RemoveInverseElement from the nodes removed from elem
1730 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1731 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1732 (const_cast<SMDS_MeshElement *>( *it ));
1733 n->RemoveInverseElement(elem);
1740 //=======================================================================
1741 //function : Find0DElement
1743 //=======================================================================
1744 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1746 const SMDS_MeshNode * node = FindNode(idnode);
1747 if(node == NULL) return NULL;
1748 return Find0DElement(node);
1751 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1753 if (!node) return 0;
1754 const SMDS_Mesh0DElement* toReturn = NULL;
1755 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1756 while (it1->more() && (toReturn == NULL)) {
1757 const SMDS_MeshElement* e = it1->next();
1758 if (e->NbNodes() == 1) {
1759 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1765 //=======================================================================
1766 //function : Find0DElementOrCreate
1768 //=======================================================================
1769 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1771 // if (!node) return 0;
1772 // SMDS_Mesh0DElement * toReturn = NULL;
1773 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1774 // if (toReturn == NULL) {
1775 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1776 // toReturn = new SMDS_Mesh0DElement(node);
1777 // my0DElements.Add(toReturn);
1778 // myInfo.myNb0DElements++;
1784 //=======================================================================
1785 //function : FindEdge
1787 //=======================================================================
1789 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1791 const SMDS_MeshNode * node1=FindNode(idnode1);
1792 const SMDS_MeshNode * node2=FindNode(idnode2);
1793 if((node1==NULL)||(node2==NULL)) return NULL;
1794 return FindEdge(node1,node2);
1797 //#include "Profiler.h"
1798 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1799 const SMDS_MeshNode * node2)
1801 if ( !node1 ) return 0;
1802 const SMDS_MeshEdge * toReturn=NULL;
1805 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1808 while(it1->more()) {
1809 const SMDS_MeshElement * e = it1->next();
1810 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1811 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1820 //=======================================================================
1821 //function : FindEdgeOrCreate
1823 //=======================================================================
1825 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1826 const SMDS_MeshNode * node2)
1828 if ( !node1 || !node2) return 0;
1829 SMDS_MeshEdge * toReturn=NULL;
1830 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1831 if(toReturn==NULL) {
1832 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1833 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1834 adjustmyCellsCapacity(ID);
1835 vector<vtkIdType> nodeIds;
1837 nodeIds.push_back(node1->getVtkId());
1838 nodeIds.push_back(node2->getVtkId());
1840 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1841 edgevtk->init(nodeIds, this);
1842 if (!this->registerElement(ID,edgevtk))
1844 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
1845 myEdgePool->destroy(edgevtk);
1849 myCells[ID] = toReturn;
1856 //=======================================================================
1857 //function : FindEdge
1859 //=======================================================================
1861 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1864 const SMDS_MeshNode * node1=FindNode(idnode1);
1865 const SMDS_MeshNode * node2=FindNode(idnode2);
1866 const SMDS_MeshNode * node3=FindNode(idnode3);
1867 return FindEdge(node1,node2,node3);
1870 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1871 const SMDS_MeshNode * node2,
1872 const SMDS_MeshNode * node3)
1874 if ( !node1 ) return 0;
1875 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1876 while(it1->more()) {
1877 const SMDS_MeshElement * e = it1->next();
1878 if ( e->NbNodes() == 3 ) {
1879 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1880 while(it2->more()) {
1881 const SMDS_MeshElement* n = it2->next();
1891 return static_cast<const SMDS_MeshEdge *> (e);
1898 //=======================================================================
1899 //function : FindFace
1901 //=======================================================================
1903 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1906 const SMDS_MeshNode * node1=FindNode(idnode1);
1907 const SMDS_MeshNode * node2=FindNode(idnode2);
1908 const SMDS_MeshNode * node3=FindNode(idnode3);
1909 return FindFace(node1, node2, node3);
1912 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1913 const SMDS_MeshNode *node2,
1914 const SMDS_MeshNode *node3)
1916 if ( !node1 ) return 0;
1917 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1918 while(it1->more()) {
1919 const SMDS_MeshElement * e = it1->next();
1920 if ( e->NbNodes() == 3 ) {
1921 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1922 while(it2->more()) {
1923 const SMDS_MeshElement* n = it2->next();
1933 return static_cast<const SMDS_MeshFace *> (e);
1939 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1940 const SMDS_MeshNode *node2,
1941 const SMDS_MeshNode *node3)
1943 SMDS_MeshFace * toReturn=NULL;
1944 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1945 if(toReturn==NULL) {
1946 int ID = myElementIDFactory->GetFreeID();
1947 toReturn = createTriangle(node1,node2,node3, ID);
1953 //=======================================================================
1954 //function : FindFace
1956 //=======================================================================
1958 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1959 int idnode3, int idnode4) const
1961 const SMDS_MeshNode * node1=FindNode(idnode1);
1962 const SMDS_MeshNode * node2=FindNode(idnode2);
1963 const SMDS_MeshNode * node3=FindNode(idnode3);
1964 const SMDS_MeshNode * node4=FindNode(idnode4);
1965 return FindFace(node1, node2, node3, node4);
1968 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1969 const SMDS_MeshNode *node2,
1970 const SMDS_MeshNode *node3,
1971 const SMDS_MeshNode *node4)
1973 if ( !node1 ) return 0;
1974 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1975 while(it1->more()) {
1976 const SMDS_MeshElement * e = it1->next();
1977 if ( e->NbNodes() == 4 ) {
1978 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1979 while(it2->more()) {
1980 const SMDS_MeshElement* n = it2->next();
1991 return static_cast<const SMDS_MeshFace *> (e);
1997 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1998 const SMDS_MeshNode *node2,
1999 const SMDS_MeshNode *node3,
2000 const SMDS_MeshNode *node4)
2002 SMDS_MeshFace * toReturn=NULL;
2003 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2004 if(toReturn==NULL) {
2005 int ID = myElementIDFactory->GetFreeID();
2006 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2012 //=======================================================================
2013 //function : FindFace
2014 //purpose :quadratic triangle
2015 //=======================================================================
2017 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2018 int idnode3, int idnode4,
2019 int idnode5, int idnode6) const
2021 const SMDS_MeshNode * node1 = FindNode(idnode1);
2022 const SMDS_MeshNode * node2 = FindNode(idnode2);
2023 const SMDS_MeshNode * node3 = FindNode(idnode3);
2024 const SMDS_MeshNode * node4 = FindNode(idnode4);
2025 const SMDS_MeshNode * node5 = FindNode(idnode5);
2026 const SMDS_MeshNode * node6 = FindNode(idnode6);
2027 return FindFace(node1, node2, node3, node4, node5, node6);
2030 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2031 const SMDS_MeshNode *node2,
2032 const SMDS_MeshNode *node3,
2033 const SMDS_MeshNode *node4,
2034 const SMDS_MeshNode *node5,
2035 const SMDS_MeshNode *node6)
2037 if ( !node1 ) return 0;
2038 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2039 while(it1->more()) {
2040 const SMDS_MeshElement * e = it1->next();
2041 if ( e->NbNodes() == 6 ) {
2042 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2043 while(it2->more()) {
2044 const SMDS_MeshElement* n = it2->next();
2057 return static_cast<const SMDS_MeshFace *> (e);
2064 //=======================================================================
2065 //function : FindFace
2066 //purpose : quadratic quadrangle
2067 //=======================================================================
2069 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2070 int idnode3, int idnode4,
2071 int idnode5, int idnode6,
2072 int idnode7, int idnode8) const
2074 const SMDS_MeshNode * node1 = FindNode(idnode1);
2075 const SMDS_MeshNode * node2 = FindNode(idnode2);
2076 const SMDS_MeshNode * node3 = FindNode(idnode3);
2077 const SMDS_MeshNode * node4 = FindNode(idnode4);
2078 const SMDS_MeshNode * node5 = FindNode(idnode5);
2079 const SMDS_MeshNode * node6 = FindNode(idnode6);
2080 const SMDS_MeshNode * node7 = FindNode(idnode7);
2081 const SMDS_MeshNode * node8 = FindNode(idnode8);
2082 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2085 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2086 const SMDS_MeshNode *node2,
2087 const SMDS_MeshNode *node3,
2088 const SMDS_MeshNode *node4,
2089 const SMDS_MeshNode *node5,
2090 const SMDS_MeshNode *node6,
2091 const SMDS_MeshNode *node7,
2092 const SMDS_MeshNode *node8)
2094 if ( !node1 ) return 0;
2095 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2096 while(it1->more()) {
2097 const SMDS_MeshElement * e = it1->next();
2098 if ( e->NbNodes() == 8 ) {
2099 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2100 while(it2->more()) {
2101 const SMDS_MeshElement* n = it2->next();
2116 return static_cast<const SMDS_MeshFace *> (e);
2123 //=======================================================================
2124 //function : FindElement
2126 //=======================================================================
2128 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2130 if ((IDelem <= 0) || IDelem >= myCells.size())
2132 MESSAGE("--------------------------------------------------------------------------------- ");
2133 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2134 MESSAGE("--------------------------------------------------------------------------------- ");
2135 // TODO raise an exception
2139 return myCells[IDelem];
2142 //=======================================================================
2143 //function : FindFace
2144 //purpose : find polygon
2145 //=======================================================================
2147 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2149 int nbnodes = nodes_ids.size();
2150 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2151 for (int inode = 0; inode < nbnodes; inode++) {
2152 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2153 if (node == NULL) return NULL;
2154 poly_nodes[inode] = node;
2156 return FindFace(poly_nodes);
2159 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2161 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2165 //================================================================================
2167 * \brief Return element based on all given nodes
2168 * \param nodes - node of element
2169 * \param type - type of element
2170 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2171 * \retval const SMDS_MeshElement* - found element or NULL
2173 //================================================================================
2175 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2176 const SMDSAbs_ElementType type,
2177 const bool noMedium)
2179 if ( nodes.size() > 0 && nodes[0] )
2181 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2184 const SMDS_MeshElement* e = itF->next();
2185 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2186 if ( nbNodesToCheck == nodes.size() )
2188 for ( int i = 1; e && i < nodes.size(); ++ i )
2190 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2191 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2195 return static_cast<const SMDS_MeshFace *> (e);
2202 //=======================================================================
2203 //function : DumpNodes
2205 //=======================================================================
2207 void SMDS_Mesh::DumpNodes() const
2209 MESSAGE("dump nodes of mesh : ");
2210 SMDS_NodeIteratorPtr itnode=nodesIterator();
2211 while(itnode->more()) ; //MESSAGE(itnode->next());
2214 //=======================================================================
2215 //function : Dump0DElements
2217 //=======================================================================
2218 void SMDS_Mesh::Dump0DElements() const
2220 MESSAGE("dump 0D elements of mesh : ");
2221 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2222 while(it0d->more()) ; //MESSAGE(it0d->next());
2225 //=======================================================================
2226 //function : DumpEdges
2228 //=======================================================================
2230 void SMDS_Mesh::DumpEdges() const
2232 MESSAGE("dump edges of mesh : ");
2233 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2234 while(itedge->more()) ; //MESSAGE(itedge->next());
2237 //=======================================================================
2238 //function : DumpFaces
2240 //=======================================================================
2242 void SMDS_Mesh::DumpFaces() const
2244 MESSAGE("dump faces of mesh : ");
2245 SMDS_FaceIteratorPtr itface=facesIterator();
2246 while(itface->more()) ; //MESSAGE(itface->next());
2249 //=======================================================================
2250 //function : DumpVolumes
2252 //=======================================================================
2254 void SMDS_Mesh::DumpVolumes() const
2256 MESSAGE("dump volumes of mesh : ");
2257 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2258 while(itvol->more()) ; //MESSAGE(itvol->next());
2261 //=======================================================================
2262 //function : DebugStats
2264 //=======================================================================
2266 void SMDS_Mesh::DebugStats() const
2268 MESSAGE("Debug stats of mesh : ");
2270 MESSAGE("===== NODES ====="<<NbNodes());
2271 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2272 MESSAGE("===== EDGES ====="<<NbEdges());
2273 MESSAGE("===== FACES ====="<<NbFaces());
2274 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2276 MESSAGE("End Debug stats of mesh ");
2280 SMDS_NodeIteratorPtr itnode=nodesIterator();
2281 int sizeofnodes = 0;
2282 int sizeoffaces = 0;
2284 while(itnode->more())
2286 const SMDS_MeshNode *node = itnode->next();
2288 sizeofnodes += sizeof(*node);
2290 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2293 const SMDS_MeshElement *me = it->next();
2294 sizeofnodes += sizeof(me);
2298 SMDS_FaceIteratorPtr itface=facesIterator();
2299 while(itface->more())
2301 const SMDS_MeshElement *face = itface->next();
2302 sizeoffaces += sizeof(*face);
2305 MESSAGE("total size of node elements = " << sizeofnodes);;
2306 MESSAGE("total size of face elements = " << sizeoffaces);;
2311 ///////////////////////////////////////////////////////////////////////////////
2312 /// Return the number of nodes
2313 ///////////////////////////////////////////////////////////////////////////////
2314 int SMDS_Mesh::NbNodes() const
2316 //MESSAGE(myGrid->GetNumberOfPoints());
2317 //MESSAGE(myInfo.NbNodes());
2318 //MESSAGE(myNodeMax);
2319 return myInfo.NbNodes();
2322 ///////////////////////////////////////////////////////////////////////////////
2323 /// Return the number of 0D elements
2324 ///////////////////////////////////////////////////////////////////////////////
2325 int SMDS_Mesh::Nb0DElements() const
2327 return myInfo.Nb0DElements(); // -PR- a verfier
2330 ///////////////////////////////////////////////////////////////////////////////
2331 /// Return the number of edges (including construction edges)
2332 ///////////////////////////////////////////////////////////////////////////////
2333 int SMDS_Mesh::NbEdges() const
2335 return myInfo.NbEdges(); // -PR- a verfier
2338 ///////////////////////////////////////////////////////////////////////////////
2339 /// Return the number of faces (including construction faces)
2340 ///////////////////////////////////////////////////////////////////////////////
2341 int SMDS_Mesh::NbFaces() const
2343 return myInfo.NbFaces(); // -PR- a verfier
2346 ///////////////////////////////////////////////////////////////////////////////
2347 /// Return the number of volumes
2348 ///////////////////////////////////////////////////////////////////////////////
2349 int SMDS_Mesh::NbVolumes() const
2351 return myInfo.NbVolumes(); // -PR- a verfier
2354 ///////////////////////////////////////////////////////////////////////////////
2355 /// Return the number of child mesh of this mesh.
2356 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2357 /// (2003-09-08) of SMESH
2358 ///////////////////////////////////////////////////////////////////////////////
2359 int SMDS_Mesh::NbSubMesh() const
2361 return myChildren.size();
2364 ///////////////////////////////////////////////////////////////////////////////
2365 /// Destroy the mesh and all its elements
2366 /// All pointer on elements owned by this mesh become illegals.
2367 ///////////////////////////////////////////////////////////////////////////////
2368 SMDS_Mesh::~SMDS_Mesh()
2370 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2371 while(itc!=myChildren.end())
2379 delete myNodeIDFactory;
2380 delete myElementIDFactory;
2384 SMDS_ElemIteratorPtr eIt = elementsIterator();
2385 while ( eIt->more() )
2387 const SMDS_MeshElement *elem = eIt->next();
2388 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2390 SMDS_NodeIteratorPtr itn = nodesIterator();
2393 const SMDS_MeshNode *node = itn->next();
2394 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2395 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2399 // SetOfNodes::Iterator itn(myNodes);
2400 // for (; itn.More(); itn.Next())
2401 // delete itn.Value();
2403 // SetOf0DElements::Iterator it0d (my0DElements);
2404 // for (; it0d.More(); it0d.Next())
2406 // SMDS_MeshElement* elem = it0d.Value();
2410 // SetOfEdges::Iterator ite(myEdges);
2411 // for (; ite.More(); ite.Next())
2413 // SMDS_MeshElement* elem = ite.Value();
2417 // SetOfFaces::Iterator itf(myFaces);
2418 // for (; itf.More(); itf.Next())
2420 // SMDS_MeshElement* elem = itf.Value();
2424 // SetOfVolumes::Iterator itv(myVolumes);
2425 // for (; itv.More(); itv.Next())
2427 // SMDS_MeshElement* elem = itv.Value();
2432 //================================================================================
2434 * \brief Clear all data
2436 //================================================================================
2438 void SMDS_Mesh::Clear()
2440 MESSAGE("SMDS_Mesh::Clear");
2443 SMDS_ElemIteratorPtr eIt = elementsIterator();
2444 while ( eIt->more() )
2446 const SMDS_MeshElement *elem = eIt->next();
2447 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2449 SMDS_NodeIteratorPtr itn = nodesIterator();
2452 const SMDS_MeshNode *node = itn->next();
2453 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2458 myNodeIDFactory->Clear();
2459 myElementIDFactory->Clear();
2462 SMDS_ElemIteratorPtr itv = elementsIterator();
2465 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2466 SMDSAbs_ElementType aType = elem->GetType();
2469 case SMDSAbs_0DElement:
2473 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2476 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2478 case SMDSAbs_Volume:
2479 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2486 myCellIdVtkToSmds.clear();
2487 //myCellIdSmdsToVtk.clear();
2489 SMDS_NodeIteratorPtr itn = nodesIterator();
2492 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2493 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2494 myNodePool->destroy(node);
2498 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2499 while(itc!=myChildren.end())
2509 myGrid->Initialize();
2511 vtkPoints* points = vtkPoints::New();
2512 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2513 // using double type for storing coordinates of nodes instead float.
2514 points->SetDataType(VTK_DOUBLE);
2515 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
2516 myGrid->SetPoints( points );
2518 myGrid->BuildLinks();
2521 ///////////////////////////////////////////////////////////////////////////////
2522 /// Return true if this mesh create faces with edges.
2523 /// A false returned value mean that faces are created with nodes. A concequence
2524 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2525 ///////////////////////////////////////////////////////////////////////////////
2526 bool SMDS_Mesh::hasConstructionEdges()
2528 return myHasConstructionEdges;
2531 ///////////////////////////////////////////////////////////////////////////////
2532 /// Return true if this mesh create volumes with faces
2533 /// A false returned value mean that volumes are created with nodes or edges.
2534 /// (see hasConstructionEdges)
2535 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2537 ///////////////////////////////////////////////////////////////////////////////
2538 bool SMDS_Mesh::hasConstructionFaces()
2540 return myHasConstructionFaces;
2543 ///////////////////////////////////////////////////////////////////////////////
2544 /// Return true if nodes are linked to the finit elements, they are belonging to.
2545 /// Currently, It always return true.
2546 ///////////////////////////////////////////////////////////////////////////////
2547 bool SMDS_Mesh::hasInverseElements()
2549 return myHasInverseElements;
2552 ///////////////////////////////////////////////////////////////////////////////
2553 /// Make this mesh creating construction edges (see hasConstructionEdges)
2554 /// @param b true to have construction edges, else false.
2555 ///////////////////////////////////////////////////////////////////////////////
2556 void SMDS_Mesh::setConstructionEdges(bool b)
2558 myHasConstructionEdges=b;
2561 ///////////////////////////////////////////////////////////////////////////////
2562 /// Make this mesh creating construction faces (see hasConstructionFaces)
2563 /// @param b true to have construction faces, else false.
2564 ///////////////////////////////////////////////////////////////////////////////
2565 void SMDS_Mesh::setConstructionFaces(bool b)
2567 myHasConstructionFaces=b;
2570 ///////////////////////////////////////////////////////////////////////////////
2571 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2572 /// @param b true to link nodes to elements, else false.
2573 ///////////////////////////////////////////////////////////////////////////////
2574 void SMDS_Mesh::setInverseElements(bool b)
2576 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2577 myHasInverseElements=b;
2582 ///////////////////////////////////////////////////////////////////////////////
2583 ///Iterator on NCollection_Map
2584 ///////////////////////////////////////////////////////////////////////////////
2585 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2586 struct MYNode_Map_Iterator: public FATHER
2590 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2597 while (_ctr < _map.size())
2608 ELEM current = _map[_ctr];
2614 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2615 struct MYElem_Map_Iterator: public FATHER
2620 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2624 while (_ctr < _map.size()) // go to the first valid element
2627 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2635 while (_ctr < _map.size())
2638 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2647 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2653 //================================================================================
2655 * \brief Iterator on elements in id increasing order
2657 //================================================================================
2659 template <typename ELEM=const SMDS_MeshElement*>
2660 class IdSortedIterator : public SMDS_Iterator<ELEM>
2662 const SMDS_MeshElementIDFactory& myIDFact;
2663 int myID, myMaxID, myNbFound, myTotalNb;
2664 SMDSAbs_ElementType myType;
2668 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2669 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2672 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2684 ELEM current = myElem;
2686 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2687 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2688 && myElem->GetType() != myType )
2691 myNbFound += bool(myElem);
2698 ///////////////////////////////////////////////////////////////////////////////
2699 /// Return an iterator on nodes of the current mesh factory
2700 ///////////////////////////////////////////////////////////////////////////////
2702 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2704 typedef MYNode_Map_Iterator
2705 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2706 return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2708 // typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2709 // return ( idInceasingOrder ?
2710 // SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2711 // SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2714 ///////////////////////////////////////////////////////////////////////////////
2715 ///Return an iterator on 0D elements of the current mesh.
2716 ///////////////////////////////////////////////////////////////////////////////
2718 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2720 typedef MYElem_Map_Iterator
2721 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2722 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2724 // typedef MYNCollection_Map_Iterator
2725 // < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2726 // typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator;
2727 // return ( idInceasingOrder ?
2728 // SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2729 // SMDSAbs_0DElement,
2730 // Nb0DElements() )) :
2731 // SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2734 ///////////////////////////////////////////////////////////////////////////////
2735 ///Return an iterator on edges of the current mesh.
2736 ///////////////////////////////////////////////////////////////////////////////
2738 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2740 typedef MYElem_Map_Iterator
2741 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2742 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2744 // typedef MYNCollection_Map_Iterator
2745 // < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2746 // typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator;
2747 // return ( idInceasingOrder ?
2748 // SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2751 // SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2754 ///////////////////////////////////////////////////////////////////////////////
2755 ///Return an iterator on faces of the current mesh.
2756 ///////////////////////////////////////////////////////////////////////////////
2758 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2760 typedef MYElem_Map_Iterator
2761 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2762 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2764 // typedef MYNCollection_Map_Iterator
2765 // < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2766 // typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator;
2767 // return ( idInceasingOrder ?
2768 // SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2771 // SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2774 ///////////////////////////////////////////////////////////////////////////////
2775 ///Return an iterator on volumes of the current mesh.
2776 ///////////////////////////////////////////////////////////////////////////////
2778 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2780 typedef MYElem_Map_Iterator
2781 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2782 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2784 // typedef MYNCollection_Map_Iterator
2785 // < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2786 // typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator;
2787 // return ( idInceasingOrder ?
2788 // SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2791 // SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2794 ///////////////////////////////////////////////////////////////////////////////
2795 /// Return an iterator on elements of the current mesh factory
2796 ///////////////////////////////////////////////////////////////////////////////
2797 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2801 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2803 case SMDSAbs_Volume:
2804 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2806 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2808 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2809 case SMDSAbs_0DElement:
2810 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2812 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2813 //return myNodeIDFactory->elementsIterator();
2816 return myElementIDFactory->elementsIterator();
2819 ///////////////////////////////////////////////////////////////////////////////
2820 /// Do intersection of sets (more than 2)
2821 ///////////////////////////////////////////////////////////////////////////////
2822 static set<const SMDS_MeshElement*> * intersectionOfSets(
2823 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2825 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2826 set<const SMDS_MeshElement*>* rsetB;
2828 for(int i=0; i<numberOfSets-1; i++)
2830 rsetB=new set<const SMDS_MeshElement*>();
2832 rsetA->begin(), rsetA->end(),
2833 vs[i+1].begin(), vs[i+1].end(),
2834 inserter(*rsetB, rsetB->begin()));
2841 ///////////////////////////////////////////////////////////////////////////////
2842 /// Return the list of finite elements owning the given element: elements
2843 /// containing all the nodes of the given element, for instance faces and
2844 /// volumes containing a given edge.
2845 ///////////////////////////////////////////////////////////////////////////////
2846 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2848 int numberOfSets=element->NbNodes();
2849 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2851 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2854 while(itNodes->more())
2856 const SMDS_MeshElement* node = itNodes->next();
2858 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2859 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2861 //initSet[i]=set<const SMDS_MeshElement*>();
2864 const SMDS_MeshElement* elem = itFe->next();
2866 initSet[i].insert(elem);
2872 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2873 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2878 ///////////////////////////////////////////////////////////////////////////////
2879 /// Return the list of nodes used only by the given elements
2880 ///////////////////////////////////////////////////////////////////////////////
2881 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2882 set<const SMDS_MeshElement*>& elements)
2884 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2885 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2887 while(itElements!=elements.end())
2889 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2892 while(itNodes->more())
2894 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2895 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2896 set<const SMDS_MeshElement*> s;
2898 s.insert(itFe->next());
2899 if(s==elements) toReturn->insert(n);
2905 ///////////////////////////////////////////////////////////////////////////////
2906 ///Find the children of an element that are made of given nodes
2907 ///@param setOfChildren The set in which matching children will be inserted
2908 ///@param element The element were to search matching children
2909 ///@param nodes The nodes that the children must have to be selected
2910 ///////////////////////////////////////////////////////////////////////////////
2911 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2912 const SMDS_MeshElement * element,
2913 set<const SMDS_MeshElement*>& nodes)
2915 switch(element->GetType())
2918 MESSAGE("Internal Error: This should not happen");
2920 case SMDSAbs_0DElement:
2926 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2929 const SMDS_MeshElement * e=itn->next();
2930 if(nodes.find(e)!=nodes.end())
2932 setOfChildren.insert(element);
2939 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2942 const SMDS_MeshElement * e=itn->next();
2943 if(nodes.find(e)!=nodes.end())
2945 setOfChildren.insert(element);
2949 if(hasConstructionEdges())
2951 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2953 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2956 case SMDSAbs_Volume:
2958 if(hasConstructionFaces())
2960 SMDS_ElemIteratorPtr ite=element->facesIterator();
2962 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2964 else if(hasConstructionEdges())
2966 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2968 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2974 ///////////////////////////////////////////////////////////////////////////////
2975 ///@param elem The element to delete
2976 ///@param removenodes if true remaining nodes will be removed
2977 ///////////////////////////////////////////////////////////////////////////////
2978 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2979 const bool removenodes)
2981 list<const SMDS_MeshElement *> removedElems;
2982 list<const SMDS_MeshElement *> removedNodes;
2983 RemoveElement( elem, removedElems, removedNodes, removenodes );
2986 ///////////////////////////////////////////////////////////////////////////////
2987 ///@param elem The element to delete
2988 ///@param removedElems to be filled with all removed elements
2989 ///@param removedNodes to be filled with all removed nodes
2990 ///@param removenodes if true remaining nodes will be removed
2991 ///////////////////////////////////////////////////////////////////////////////
2992 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2993 list<const SMDS_MeshElement *>& removedElems,
2994 list<const SMDS_MeshElement *>& removedNodes,
2997 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
2998 // get finite elements built on elem
2999 set<const SMDS_MeshElement*> * s1;
3000 if ( (elem->GetType() == SMDSAbs_0DElement)
3001 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3002 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3003 || (elem->GetType() == SMDSAbs_Volume) )
3005 s1 = new set<const SMDS_MeshElement*> ();
3009 s1 = getFinitElements(elem);
3011 // get exclusive nodes (which would become free afterwards)
3012 set<const SMDS_MeshElement*> * s2;
3013 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3015 // do not remove nodes except elem
3016 s2 = new set<const SMDS_MeshElement*> ();
3021 s2 = getExclusiveNodes(*s1);
3023 // form the set of finite and construction elements to remove
3024 set<const SMDS_MeshElement*> s3;
3025 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3026 while (it != s1->end())
3028 addChildrenWithNodes(s3, *it, *s2);
3032 if (elem->GetType() != SMDSAbs_Node)
3035 // remove finite and construction elements
3037 while (it != s3.end())
3039 // Remove element from <InverseElements> of its nodes
3040 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3043 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3044 n->RemoveInverseElement((*it));
3046 int IdToRemove = (*it)->GetID();
3047 int vtkid = (*it)->getVtkId();
3048 //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3049 // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3050 switch ((*it)->GetType())
3053 MYASSERT("Internal Error: This should not happen")
3056 case SMDSAbs_0DElement:
3057 if (IdToRemove >= 0)
3059 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3062 removedElems.push_back((*it));
3063 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3067 if (IdToRemove >= 0)
3069 myCells[IdToRemove] = 0;
3070 myInfo.RemoveEdge(*it);
3072 removedElems.push_back((*it));
3073 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3074 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3075 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3080 if (IdToRemove >= 0)
3082 myCells[IdToRemove] = 0;
3083 myInfo.RemoveFace(*it);
3085 removedElems.push_back((*it));
3086 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3087 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3088 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3092 case SMDSAbs_Volume:
3093 if (IdToRemove >= 0)
3095 myCells[IdToRemove] = 0;
3096 myInfo.RemoveVolume(*it);
3098 removedElems.push_back((*it));
3099 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3100 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3101 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3108 //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3109 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3114 // remove exclusive (free) nodes
3118 while (it != s2->end())
3120 int IdToRemove = (*it)->GetID();
3121 //MESSAGE( "SMDS: RM node " << IdToRemove);
3122 if (IdToRemove >= 0)
3124 myNodes[IdToRemove] = 0;
3127 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3128 removedNodes.push_back((*it));
3129 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3131 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3132 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3145 ///////////////////////////////////////////////////////////////////////////////
3146 ///@param elem The element to delete
3147 ///////////////////////////////////////////////////////////////////////////////
3148 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3150 int elemId = elem->GetID();
3151 int vtkId = elem->getVtkId();
3152 //MESSAGE("RemoveFreeElement " << elemId);
3153 SMDSAbs_ElementType aType = elem->GetType();
3154 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3155 if (aType == SMDSAbs_Node) {
3156 //MESSAGE("Remove free node " << elemId);
3157 // only free node can be removed by this method
3158 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3159 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3160 if (!itFe->more()) { // free node
3161 myNodes[elemId] = 0;
3163 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3164 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3165 myNodeIDFactory->ReleaseID(elemId, vtkId);
3168 if (hasConstructionEdges() || hasConstructionFaces())
3169 // this methods is only for meshes without descendants
3172 //MESSAGE("Remove free element " << elemId);
3173 // Remove element from <InverseElements> of its nodes
3174 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3175 while (itn->more()) {
3176 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3177 (const_cast<SMDS_MeshElement *>(itn->next()));
3178 n->RemoveInverseElement(elem);
3181 // in meshes without descendants elements are always free
3183 case SMDSAbs_0DElement:
3184 myCells[elemId] = 0;
3185 myInfo.remove(elem);
3189 myCells[elemId] = 0;
3190 myInfo.RemoveEdge(elem);
3191 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3194 myCells[elemId] = 0;
3195 myInfo.RemoveFace(elem);
3196 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3198 case SMDSAbs_Volume:
3199 myCells[elemId] = 0;
3200 myInfo.RemoveVolume(elem);
3201 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3206 myElementIDFactory->ReleaseID(elemId, vtkId);
3208 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3209 // --- to do: keep vtkid in a list of reusable cells
3214 * Checks if the element is present in mesh.
3215 * Useful to determine dead pointers.
3217 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3219 // we should not imply on validity of *elem, so iterate on containers
3220 // of all types in the hope of finding <elem> somewhere there
3221 SMDS_NodeIteratorPtr itn = nodesIterator();
3223 if (elem == itn->next())
3225 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3226 while (it0d->more())
3227 if (elem == it0d->next())
3229 SMDS_EdgeIteratorPtr ite = edgesIterator();
3231 if (elem == ite->next())
3233 SMDS_FaceIteratorPtr itf = facesIterator();
3235 if (elem == itf->next())
3237 SMDS_VolumeIteratorPtr itv = volumesIterator();
3239 if (elem == itv->next())
3244 //=======================================================================
3245 //function : MaxNodeID
3247 //=======================================================================
3249 int SMDS_Mesh::MaxNodeID() const
3254 //=======================================================================
3255 //function : MinNodeID
3257 //=======================================================================
3259 int SMDS_Mesh::MinNodeID() const
3264 //=======================================================================
3265 //function : MaxElementID
3267 //=======================================================================
3269 int SMDS_Mesh::MaxElementID() const
3271 return myElementIDFactory->GetMaxID();
3274 //=======================================================================
3275 //function : MinElementID
3277 //=======================================================================
3279 int SMDS_Mesh::MinElementID() const
3281 return myElementIDFactory->GetMinID();
3284 //=======================================================================
3285 //function : Renumber
3286 //purpose : Renumber all nodes or elements.
3287 //=======================================================================
3289 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3291 MESSAGE("Renumber");
3295 SMDS_MeshNodeIDFactory * idFactory =
3296 isNodes ? myNodeIDFactory : myElementIDFactory;
3298 // get existing elements in the order of ID increasing
3299 map<int,SMDS_MeshElement*> elemMap;
3300 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3301 while ( idElemIt->more() ) {
3302 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3303 int id = elem->GetID();
3304 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3306 // release their ids
3307 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3309 // for ( ; elemIt != elemMap.end(); elemIt++ )
3311 // int id = (*elemIt).first;
3312 // idFactory->ReleaseID( id );
3316 elemIt = elemMap.begin();
3317 for ( ; elemIt != elemMap.end(); elemIt++ )
3319 idFactory->BindID( ID, (*elemIt).second );
3324 //=======================================================================
3325 //function : GetElementType
3326 //purpose : Return type of element or node with id
3327 //=======================================================================
3329 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3331 SMDS_MeshElement* elem = 0;
3333 elem = myElementIDFactory->MeshElement( id );
3335 elem = myNodeIDFactory->MeshElement( id );
3339 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3343 return elem->GetType();
3348 //********************************************************************
3349 //********************************************************************
3350 //******** *********
3351 //***** Methods for addition of quadratic elements ******
3352 //******** *********
3353 //********************************************************************
3354 //********************************************************************
3356 //=======================================================================
3357 //function : AddEdgeWithID
3359 //=======================================================================
3360 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3362 return SMDS_Mesh::AddEdgeWithID
3363 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3364 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3365 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3369 //=======================================================================
3370 //function : AddEdge
3372 //=======================================================================
3373 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3374 const SMDS_MeshNode* n2,
3375 const SMDS_MeshNode* n12)
3377 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3380 //=======================================================================
3381 //function : AddEdgeWithID
3383 //=======================================================================
3384 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3385 const SMDS_MeshNode * n2,
3386 const SMDS_MeshNode * n12,
3389 if ( !n1 || !n2 || !n12 ) return 0;
3391 // --- retrieve nodes ID
3392 vector<vtkIdType> nodeIds;
3394 nodeIds.push_back(n1->getVtkId());
3395 nodeIds.push_back(n2->getVtkId());
3396 nodeIds.push_back(n12->getVtkId());
3398 SMDS_MeshEdge * edge = 0;
3399 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3400 edgevtk->init(nodeIds, this);
3401 if (!this->registerElement(ID,edgevtk))
3403 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3404 myEdgePool->destroy(edgevtk);
3408 adjustmyCellsCapacity(ID);
3410 myInfo.myNbQuadEdges++;
3412 // if (!registerElement(ID, edge)) {
3413 // RemoveElement(edge, false);
3421 //=======================================================================
3422 //function : AddFace
3424 //=======================================================================
3425 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3426 const SMDS_MeshNode * n2,
3427 const SMDS_MeshNode * n3,
3428 const SMDS_MeshNode * n12,
3429 const SMDS_MeshNode * n23,
3430 const SMDS_MeshNode * n31)
3432 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3433 myElementIDFactory->GetFreeID());
3436 //=======================================================================
3437 //function : AddFaceWithID
3439 //=======================================================================
3440 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3441 int n12,int n23,int n31, int ID)
3443 return SMDS_Mesh::AddFaceWithID
3444 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3445 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3446 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3447 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3448 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3449 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3453 //=======================================================================
3454 //function : AddFaceWithID
3456 //=======================================================================
3457 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3458 const SMDS_MeshNode * n2,
3459 const SMDS_MeshNode * n3,
3460 const SMDS_MeshNode * n12,
3461 const SMDS_MeshNode * n23,
3462 const SMDS_MeshNode * n31,
3465 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3466 if(hasConstructionEdges()) {
3467 // creation quadratic edges - not implemented
3472 // --- retrieve nodes ID
3473 vector<vtkIdType> nodeIds;
3475 nodeIds.push_back(n1->getVtkId());
3476 nodeIds.push_back(n2->getVtkId());
3477 nodeIds.push_back(n3->getVtkId());
3478 nodeIds.push_back(n12->getVtkId());
3479 nodeIds.push_back(n23->getVtkId());
3480 nodeIds.push_back(n31->getVtkId());
3482 SMDS_MeshFace * face = 0;
3483 SMDS_VtkFace *facevtk = myFacePool->getNew();
3484 facevtk->init(nodeIds, this);
3485 if (!this->registerElement(ID,facevtk))
3487 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3488 myFacePool->destroy(facevtk);
3492 adjustmyCellsCapacity(ID);
3494 myInfo.myNbQuadTriangles++;
3496 // if (!registerElement(ID, face)) {
3497 // RemoveElement(face, false);
3505 //=======================================================================
3506 //function : AddFace
3508 //=======================================================================
3509 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3510 const SMDS_MeshNode * n2,
3511 const SMDS_MeshNode * n3,
3512 const SMDS_MeshNode * n4,
3513 const SMDS_MeshNode * n12,
3514 const SMDS_MeshNode * n23,
3515 const SMDS_MeshNode * n34,
3516 const SMDS_MeshNode * n41)
3518 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3519 myElementIDFactory->GetFreeID());
3522 //=======================================================================
3523 //function : AddFaceWithID
3525 //=======================================================================
3526 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3527 int n12,int n23,int n34,int n41, int ID)
3529 return SMDS_Mesh::AddFaceWithID
3530 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3531 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3532 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3533 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3534 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3535 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3536 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3537 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3541 //=======================================================================
3542 //function : AddFaceWithID
3544 //=======================================================================
3545 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3546 const SMDS_MeshNode * n2,
3547 const SMDS_MeshNode * n3,
3548 const SMDS_MeshNode * n4,
3549 const SMDS_MeshNode * n12,
3550 const SMDS_MeshNode * n23,
3551 const SMDS_MeshNode * n34,
3552 const SMDS_MeshNode * n41,
3555 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3556 if(hasConstructionEdges()) {
3557 // creation quadratic edges - not implemented
3562 // --- retrieve nodes ID
3563 vector<vtkIdType> nodeIds;
3565 nodeIds.push_back(n1->getVtkId());
3566 nodeIds.push_back(n2->getVtkId());
3567 nodeIds.push_back(n3->getVtkId());
3568 nodeIds.push_back(n4->getVtkId());
3569 nodeIds.push_back(n12->getVtkId());
3570 nodeIds.push_back(n23->getVtkId());
3571 nodeIds.push_back(n34->getVtkId());
3572 nodeIds.push_back(n41->getVtkId());
3574 SMDS_MeshFace * face = 0;
3575 SMDS_VtkFace *facevtk = myFacePool->getNew();
3576 facevtk->init(nodeIds, this);
3577 if (!this->registerElement(ID,facevtk))
3579 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3580 myFacePool->destroy(facevtk);
3584 adjustmyCellsCapacity(ID);
3586 myInfo.myNbQuadQuadrangles++;
3588 // if (!registerElement(ID, face)) {
3589 // RemoveElement(face, false);
3597 //=======================================================================
3598 //function : AddVolume
3600 //=======================================================================
3601 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3602 const SMDS_MeshNode * n2,
3603 const SMDS_MeshNode * n3,
3604 const SMDS_MeshNode * n4,
3605 const SMDS_MeshNode * n12,
3606 const SMDS_MeshNode * n23,
3607 const SMDS_MeshNode * n31,
3608 const SMDS_MeshNode * n14,
3609 const SMDS_MeshNode * n24,
3610 const SMDS_MeshNode * n34)
3612 int ID = myElementIDFactory->GetFreeID();
3613 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3614 n31, n14, n24, n34, ID);
3615 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3619 //=======================================================================
3620 //function : AddVolumeWithID
3622 //=======================================================================
3623 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3624 int n12,int n23,int n31,
3625 int n14,int n24,int n34, int ID)
3627 return SMDS_Mesh::AddVolumeWithID
3628 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3629 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3630 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3631 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3632 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3633 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3634 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3635 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3636 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3637 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3641 //=======================================================================
3642 //function : AddVolumeWithID
3643 //purpose : 2d order tetrahedron of 10 nodes
3644 //=======================================================================
3645 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3646 const SMDS_MeshNode * n2,
3647 const SMDS_MeshNode * n3,
3648 const SMDS_MeshNode * n4,
3649 const SMDS_MeshNode * n12,
3650 const SMDS_MeshNode * n23,
3651 const SMDS_MeshNode * n31,
3652 const SMDS_MeshNode * n14,
3653 const SMDS_MeshNode * n24,
3654 const SMDS_MeshNode * n34,
3657 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3659 if(hasConstructionFaces()) {
3660 // creation quadratic faces - not implemented
3663 // --- retrieve nodes ID
3664 vector<vtkIdType> nodeIds;
3666 nodeIds.push_back(n1->getVtkId());
3667 nodeIds.push_back(n3->getVtkId());
3668 nodeIds.push_back(n2->getVtkId());
3669 nodeIds.push_back(n4->getVtkId());
3671 nodeIds.push_back(n31->getVtkId());
3672 nodeIds.push_back(n23->getVtkId());
3673 nodeIds.push_back(n12->getVtkId());
3675 nodeIds.push_back(n14->getVtkId());
3676 nodeIds.push_back(n34->getVtkId());
3677 nodeIds.push_back(n24->getVtkId());
3679 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3680 volvtk->init(nodeIds, this);
3681 if (!this->registerElement(ID,volvtk))
3683 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3684 myVolumePool->destroy(volvtk);
3687 adjustmyCellsCapacity(ID);
3688 myCells[ID] = volvtk;
3689 myInfo.myNbQuadTetras++;
3691 // if (!registerElement(ID, volvtk)) {
3692 // RemoveElement(volvtk, false);
3699 //=======================================================================
3700 //function : AddVolume
3702 //=======================================================================
3703 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3704 const SMDS_MeshNode * n2,
3705 const SMDS_MeshNode * n3,
3706 const SMDS_MeshNode * n4,
3707 const SMDS_MeshNode * n5,
3708 const SMDS_MeshNode * n12,
3709 const SMDS_MeshNode * n23,
3710 const SMDS_MeshNode * n34,
3711 const SMDS_MeshNode * n41,
3712 const SMDS_MeshNode * n15,
3713 const SMDS_MeshNode * n25,
3714 const SMDS_MeshNode * n35,
3715 const SMDS_MeshNode * n45)
3717 int ID = myElementIDFactory->GetFreeID();
3718 SMDS_MeshVolume * v =
3719 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3720 n15, n25, n35, n45, ID);
3721 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3725 //=======================================================================
3726 //function : AddVolumeWithID
3728 //=======================================================================
3729 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3730 int n12,int n23,int n34,int n41,
3731 int n15,int n25,int n35,int n45, int ID)
3733 return SMDS_Mesh::AddVolumeWithID
3734 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3735 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3736 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3737 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3738 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3739 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3740 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3741 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3742 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3743 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3744 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3745 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3746 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3750 //=======================================================================
3751 //function : AddVolumeWithID
3752 //purpose : 2d order pyramid of 13 nodes
3753 //=======================================================================
3754 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3755 const SMDS_MeshNode * n2,
3756 const SMDS_MeshNode * n3,
3757 const SMDS_MeshNode * n4,
3758 const SMDS_MeshNode * n5,
3759 const SMDS_MeshNode * n12,
3760 const SMDS_MeshNode * n23,
3761 const SMDS_MeshNode * n34,
3762 const SMDS_MeshNode * n41,
3763 const SMDS_MeshNode * n15,
3764 const SMDS_MeshNode * n25,
3765 const SMDS_MeshNode * n35,
3766 const SMDS_MeshNode * n45,
3769 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3770 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3772 if(hasConstructionFaces()) {
3773 // creation quadratic faces - not implemented
3776 // --- retrieve nodes ID
3777 vector<vtkIdType> nodeIds;
3779 nodeIds.push_back(n1->getVtkId());
3780 nodeIds.push_back(n4->getVtkId());
3781 nodeIds.push_back(n3->getVtkId());
3782 nodeIds.push_back(n2->getVtkId());
3783 nodeIds.push_back(n5->getVtkId());
3785 nodeIds.push_back(n41->getVtkId());
3786 nodeIds.push_back(n34->getVtkId());
3787 nodeIds.push_back(n23->getVtkId());
3788 nodeIds.push_back(n12->getVtkId());
3790 nodeIds.push_back(n15->getVtkId());
3791 nodeIds.push_back(n45->getVtkId());
3792 nodeIds.push_back(n35->getVtkId());
3793 nodeIds.push_back(n25->getVtkId());
3795 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3796 volvtk->init(nodeIds, this);
3797 if (!this->registerElement(ID,volvtk))
3799 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3800 myVolumePool->destroy(volvtk);
3803 adjustmyCellsCapacity(ID);
3804 myCells[ID] = volvtk;
3805 myInfo.myNbQuadPyramids++;
3807 // if (!registerElement(ID, volvtk)) {
3808 // RemoveElement(volvtk, false);
3815 //=======================================================================
3816 //function : AddVolume
3818 //=======================================================================
3819 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3820 const SMDS_MeshNode * n2,
3821 const SMDS_MeshNode * n3,
3822 const SMDS_MeshNode * n4,
3823 const SMDS_MeshNode * n5,
3824 const SMDS_MeshNode * n6,
3825 const SMDS_MeshNode * n12,
3826 const SMDS_MeshNode * n23,
3827 const SMDS_MeshNode * n31,
3828 const SMDS_MeshNode * n45,
3829 const SMDS_MeshNode * n56,
3830 const SMDS_MeshNode * n64,
3831 const SMDS_MeshNode * n14,
3832 const SMDS_MeshNode * n25,
3833 const SMDS_MeshNode * n36)
3835 int ID = myElementIDFactory->GetFreeID();
3836 SMDS_MeshVolume * v =
3837 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3838 n45, n56, n64, n14, n25, n36, ID);
3839 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3843 //=======================================================================
3844 //function : AddVolumeWithID
3846 //=======================================================================
3847 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3848 int n4, int n5, int n6,
3849 int n12,int n23,int n31,
3850 int n45,int n56,int n64,
3851 int n14,int n25,int n36, int ID)
3853 return SMDS_Mesh::AddVolumeWithID
3854 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3855 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3856 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3857 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3858 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3859 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3860 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3861 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3862 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3863 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3864 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3865 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3866 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3867 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3868 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3872 //=======================================================================
3873 //function : AddVolumeWithID
3874 //purpose : 2d order Pentahedron with 15 nodes
3875 //=======================================================================
3876 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3877 const SMDS_MeshNode * n2,
3878 const SMDS_MeshNode * n3,
3879 const SMDS_MeshNode * n4,
3880 const SMDS_MeshNode * n5,
3881 const SMDS_MeshNode * n6,
3882 const SMDS_MeshNode * n12,
3883 const SMDS_MeshNode * n23,
3884 const SMDS_MeshNode * n31,
3885 const SMDS_MeshNode * n45,
3886 const SMDS_MeshNode * n56,
3887 const SMDS_MeshNode * n64,
3888 const SMDS_MeshNode * n14,
3889 const SMDS_MeshNode * n25,
3890 const SMDS_MeshNode * n36,
3893 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3894 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3896 if(hasConstructionFaces()) {
3897 // creation quadratic faces - not implemented
3900 // --- retrieve nodes ID
3901 vector<vtkIdType> nodeIds;
3903 nodeIds.push_back(n1->getVtkId());
3904 nodeIds.push_back(n2->getVtkId());
3905 nodeIds.push_back(n3->getVtkId());
3907 nodeIds.push_back(n4->getVtkId());
3908 nodeIds.push_back(n5->getVtkId());
3909 nodeIds.push_back(n6->getVtkId());
3911 nodeIds.push_back(n12->getVtkId());
3912 nodeIds.push_back(n23->getVtkId());
3913 nodeIds.push_back(n31->getVtkId());
3915 nodeIds.push_back(n45->getVtkId());
3916 nodeIds.push_back(n56->getVtkId());
3917 nodeIds.push_back(n64->getVtkId());
3919 nodeIds.push_back(n14->getVtkId());
3920 nodeIds.push_back(n25->getVtkId());
3921 nodeIds.push_back(n36->getVtkId());
3923 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3924 volvtk->init(nodeIds, this);
3925 if (!this->registerElement(ID,volvtk))
3927 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3928 myVolumePool->destroy(volvtk);
3931 adjustmyCellsCapacity(ID);
3932 myCells[ID] = volvtk;
3933 myInfo.myNbQuadPrisms++;
3935 // if (!registerElement(ID, volvtk)) {
3936 // RemoveElement(volvtk, false);
3943 //=======================================================================
3944 //function : AddVolume
3946 //=======================================================================
3947 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3948 const SMDS_MeshNode * n2,
3949 const SMDS_MeshNode * n3,
3950 const SMDS_MeshNode * n4,
3951 const SMDS_MeshNode * n5,
3952 const SMDS_MeshNode * n6,
3953 const SMDS_MeshNode * n7,
3954 const SMDS_MeshNode * n8,
3955 const SMDS_MeshNode * n12,
3956 const SMDS_MeshNode * n23,
3957 const SMDS_MeshNode * n34,
3958 const SMDS_MeshNode * n41,
3959 const SMDS_MeshNode * n56,
3960 const SMDS_MeshNode * n67,
3961 const SMDS_MeshNode * n78,
3962 const SMDS_MeshNode * n85,
3963 const SMDS_MeshNode * n15,
3964 const SMDS_MeshNode * n26,
3965 const SMDS_MeshNode * n37,
3966 const SMDS_MeshNode * n48)
3968 int ID = myElementIDFactory->GetFreeID();
3969 SMDS_MeshVolume * v =
3970 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3971 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3972 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3976 //=======================================================================
3977 //function : AddVolumeWithID
3979 //=======================================================================
3980 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3981 int n5, int n6, int n7, int n8,
3982 int n12,int n23,int n34,int n41,
3983 int n56,int n67,int n78,int n85,
3984 int n15,int n26,int n37,int n48, int ID)
3986 return SMDS_Mesh::AddVolumeWithID
3987 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3988 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3989 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3997 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3999 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4000 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4001 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4002 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4003 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4004 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4005 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4006 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4010 //=======================================================================
4011 //function : AddVolumeWithID
4012 //purpose : 2d order Hexahedrons with 20 nodes
4013 //=======================================================================
4014 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4015 const SMDS_MeshNode * n2,
4016 const SMDS_MeshNode * n3,
4017 const SMDS_MeshNode * n4,
4018 const SMDS_MeshNode * n5,
4019 const SMDS_MeshNode * n6,
4020 const SMDS_MeshNode * n7,
4021 const SMDS_MeshNode * n8,
4022 const SMDS_MeshNode * n12,
4023 const SMDS_MeshNode * n23,
4024 const SMDS_MeshNode * n34,
4025 const SMDS_MeshNode * n41,
4026 const SMDS_MeshNode * n56,
4027 const SMDS_MeshNode * n67,
4028 const SMDS_MeshNode * n78,
4029 const SMDS_MeshNode * n85,
4030 const SMDS_MeshNode * n15,
4031 const SMDS_MeshNode * n26,
4032 const SMDS_MeshNode * n37,
4033 const SMDS_MeshNode * n48,
4036 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4037 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4039 if(hasConstructionFaces()) {
4041 // creation quadratic faces - not implemented
4043 // --- retrieve nodes ID
4044 vector<vtkIdType> nodeIds;
4046 nodeIds.push_back(n1->getVtkId());
4047 nodeIds.push_back(n4->getVtkId());
4048 nodeIds.push_back(n3->getVtkId());
4049 nodeIds.push_back(n2->getVtkId());
4051 nodeIds.push_back(n5->getVtkId());
4052 nodeIds.push_back(n8->getVtkId());
4053 nodeIds.push_back(n7->getVtkId());
4054 nodeIds.push_back(n6->getVtkId());
4056 nodeIds.push_back(n41->getVtkId());
4057 nodeIds.push_back(n34->getVtkId());
4058 nodeIds.push_back(n23->getVtkId());
4059 nodeIds.push_back(n12->getVtkId());
4061 nodeIds.push_back(n85->getVtkId());
4062 nodeIds.push_back(n78->getVtkId());
4063 nodeIds.push_back(n67->getVtkId());
4064 nodeIds.push_back(n56->getVtkId());
4066 nodeIds.push_back(n15->getVtkId());
4067 nodeIds.push_back(n48->getVtkId());
4068 nodeIds.push_back(n37->getVtkId());
4069 nodeIds.push_back(n26->getVtkId());
4071 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4072 volvtk->init(nodeIds, this);
4073 if (!this->registerElement(ID,volvtk))
4075 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4076 myVolumePool->destroy(volvtk);
4079 adjustmyCellsCapacity(ID);
4080 myCells[ID] = volvtk;
4081 myInfo.myNbQuadHexas++;
4083 // if (!registerElement(ID, volvtk)) {
4084 // RemoveElement(volvtk, false);
4090 void SMDS_Mesh::updateNodeMinMax()
4093 if (myNodes.size() == 0)
4098 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4100 myNodeMax=myNodes.size()-1;
4101 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4105 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4107 // int val = myCellIdSmdsToVtk.size();
4108 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4109 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4110 int val = myNodes.size();
4111 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4112 myNodes.resize(val +nbNodes, 0);
4115 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4117 int val = myCellIdVtkToSmds.size();
4118 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4119 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4120 val = myCells.size();
4121 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4122 myNodes.resize(val +nbCells, 0);
4125 void SMDS_Mesh::adjustStructure()
4127 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4130 void SMDS_Mesh::dumpGrid(string ficdump)
4132 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4133 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4134 // aWriter->SetFileName(ficdump.c_str());
4135 // aWriter->SetInput(myGrid);
4136 // if(myGrid->GetNumberOfCells())
4138 // aWriter->Write();
4140 // aWriter->Delete();
4141 ficdump = ficdump + "_connectivity";
4142 ofstream ficcon(ficdump.c_str(), ios::out);
4143 int nbPoints = myGrid->GetNumberOfPoints();
4144 ficcon << "-------------------------------- points " << nbPoints << endl;
4145 for (int i=0; i<nbPoints; i++)
4147 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4149 int nbCells = myGrid->GetNumberOfCells();
4150 ficcon << "-------------------------------- cells " << nbCells << endl;
4151 for (int i=0; i<nbCells; i++)
4153 // MESSAGE(i << " " << myGrid->GetCell(i));
4154 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4155 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4156 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4157 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4158 for (int j=0; j<nbptcell; j++)
4160 ficcon << " " << listid->GetId(j);
4164 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4165 vtkCellLinks *links = myGrid->GetCellLinks();
4166 for (int i=0; i<nbPoints; i++)
4168 int ncells = links->GetNcells(i);
4169 vtkIdType *cells = links->GetCells(i);
4170 ficcon << i << " - " << ncells << " -";
4171 for (int j=0; j<ncells; j++)
4173 ficcon << " " << cells[j];
4181 void SMDS_Mesh::compactMesh()
4183 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4186 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4188 if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4189 return myCellIdVtkToSmds[vtkid];
4190 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4193 void SMDS_Mesh::updateBoundingBox()
4198 vtkPoints *points = myGrid->GetPoints();
4199 int myNodesSize = this->myNodes.size();
4200 for (int i = 0; i < myNodesSize; i++)
4202 if (SMDS_MeshNode *n = myNodes[i])
4205 points->GetPoint(n->myVtkID, coords);
4206 if (coords[0] < xmin) xmin = coords[0];
4207 else if (coords[0] > xmax) xmax = coords[0];
4208 if (coords[1] < ymin) ymin = coords[1];
4209 else if (coords[1] > ymax) ymax = coords[1];
4210 if (coords[2] < zmin) zmin = coords[2];
4211 else if (coords[2] > zmax) zmax = coords[2];
4216 double SMDS_Mesh::getMaxDim()
4218 double dmax = 1.e-3;
4219 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4220 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4221 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4222 MESSAGE("getMaxDim " << dmax);
4226 //! modification that needs compact structure and redraw
4227 void SMDS_Mesh::Modified()
4229 if (this->myModified)
4231 this->myModifTime++;
4232 MESSAGE("modified");
4237 //! get last modification timeStamp
4238 unsigned long SMDS_Mesh::GetMTime()
4240 return this->myModifTime;
4243 bool SMDS_Mesh::isCompacted()
4245 if (this->myModifTime > this->myCompactTime)
4247 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4248 this->myCompactTime = this->myModifTime;