1 // Copyright (C) 2007-2011 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 100000
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 const unsigned long Mbyte = 1024 * 1024;
85 static int limit = -1;
87 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
89 limit = WEXITSTATUS(status);
92 double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
93 limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
98 limit = int ( limit * 1.5 );
99 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
102 // compute separately to avoid overflow
104 ( si.freeram * si.mem_unit ) / Mbyte +
105 ( si.freeswap * si.mem_unit ) / Mbyte;
106 //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
108 if ( freeMb > limit )
109 return freeMb - limit;
114 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
115 throw std::bad_alloc();
121 ///////////////////////////////////////////////////////////////////////////////
122 /// Create a new mesh object
123 ///////////////////////////////////////////////////////////////////////////////
124 SMDS_Mesh::SMDS_Mesh()
126 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
127 myElementIDFactory(new SMDS_MeshElementIDFactory()),
128 myHasConstructionEdges(false), myHasConstructionFaces(false),
129 myHasInverseElements(true),
130 myNodeMin(0), myNodeMax(0),
131 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),
132 myModified(false), myModifTime(0), myCompactTime(0),
133 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
135 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
136 MESSAGE("myMeshId=" << myMeshId);
137 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
138 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
139 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
140 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
141 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
142 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
143 myNodeIDFactory->SetMesh(this);
144 myElementIDFactory->SetMesh(this);
145 _meshList.push_back(this);
146 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
147 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
148 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
149 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
153 //myCellIdSmdsToVtk.clear();
154 myCellIdVtkToSmds.clear();
155 myGrid = SMDS_UnstructuredGrid::New();
156 myGrid->setSMDS_mesh(this);
157 myGrid->Initialize();
159 vtkPoints* points = vtkPoints::New();
160 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
161 // using double type for storing coordinates of nodes instead float.
162 points->SetDataType(VTK_DOUBLE);
163 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
164 myGrid->SetPoints( points );
166 myGrid->BuildLinks();
170 ///////////////////////////////////////////////////////////////////////////////
171 /// Create a new child mesh
172 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
173 /// (2003-09-08) of SMESH
174 ///////////////////////////////////////////////////////////////////////////////
175 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
176 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
177 myElementIDFactory(parent->myElementIDFactory),
178 myHasConstructionEdges(false), myHasConstructionFaces(false),
179 myHasInverseElements(true),
180 myNodePool(parent->myNodePool),
181 myEdgePool(parent->myEdgePool),
182 myFacePool(parent->myFacePool),
183 myVolumePool(parent->myVolumePool)
187 ///////////////////////////////////////////////////////////////////////////////
188 ///Create a submesh and add it to the current mesh
189 ///////////////////////////////////////////////////////////////////////////////
191 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
193 SMDS_Mesh *submesh = new SMDS_Mesh(this);
194 myChildren.insert(myChildren.end(), submesh);
198 ///////////////////////////////////////////////////////////////////////////////
199 ///create a MeshNode and add it to the current Mesh
200 ///An ID is automatically assigned to the node.
201 ///@return : The created node
202 ///////////////////////////////////////////////////////////////////////////////
204 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
206 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
209 ///////////////////////////////////////////////////////////////////////////////
210 ///create a MeshNode and add it to the current Mesh
211 ///@param ID : The ID of the MeshNode to create
212 ///@return : The created node or NULL if a node with this ID already exists
213 ///////////////////////////////////////////////////////////////////////////////
214 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
216 // find the MeshNode corresponding to ID
217 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
221 MESSAGE("=============> Bad Node Id: " << ID);
222 ID = myNodeIDFactory->GetFreeID();
224 myNodeIDFactory->adjustMaxId(ID);
225 SMDS_MeshNode * node = myNodePool->getNew();
226 node->init(ID, myMeshId, 0, x, y, z);
228 if (ID >= myNodes.size())
230 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
231 // MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
234 myNodeIDFactory->BindID(ID,node);
237 this->adjustBoundingBox(x, y, z);
243 ///////////////////////////////////////////////////////////////////////////////
244 /// create a Mesh0DElement and add it to the current Mesh
245 /// @return : The created Mesh0DElement
246 ///////////////////////////////////////////////////////////////////////////////
247 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
249 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
250 if (!node) return NULL;
251 return SMDS_Mesh::Add0DElementWithID(node, ID);
254 ///////////////////////////////////////////////////////////////////////////////
255 /// create a Mesh0DElement and add it to the current Mesh
256 /// @return : The created Mesh0DElement
257 ///////////////////////////////////////////////////////////////////////////////
258 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
260 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Create a new Mesh0DElement and at it to the mesh
265 /// @param idnode ID of the node
266 /// @param ID ID of the 0D element to create
267 /// @return The created 0D element or NULL if an element with this
268 /// ID already exists or if input node is not found.
269 ///////////////////////////////////////////////////////////////////////////////
270 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
274 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
275 //MESSAGE("Add0DElementWithID" << ID)
276 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
277 if (myElementIDFactory->BindID(ID, el0d)) {
278 //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
279 //node->AddInverseElement(el0d);// --- fait avec BindID
280 adjustmyCellsCapacity(ID);
282 myInfo.myNb0DElements++;
290 ///////////////////////////////////////////////////////////////////////////////
291 /// create a MeshEdge and add it to the current Mesh
292 /// @return : The created MeshEdge
293 ///////////////////////////////////////////////////////////////////////////////
295 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
297 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
298 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
299 if(!node1 || !node2) return NULL;
300 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
303 ///////////////////////////////////////////////////////////////////////////////
304 /// create a MeshEdge and add it to the current Mesh
305 /// @return : The created MeshEdge
306 ///////////////////////////////////////////////////////////////////////////////
308 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
309 const SMDS_MeshNode * node2)
311 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
314 ///////////////////////////////////////////////////////////////////////////////
315 /// Create a new edge and at it to the mesh
316 /// @param idnode1 ID of the first node
317 /// @param idnode2 ID of the second node
318 /// @param ID ID of the edge to create
319 /// @return The created edge or NULL if an element with this ID already exists or
320 /// if input nodes are not found.
321 ///////////////////////////////////////////////////////////////////////////////
323 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
324 const SMDS_MeshNode * n2,
327 if ( !n1 || !n2 ) return 0;
328 SMDS_MeshEdge * edge = 0;
330 // --- retreive nodes ID
331 vector<vtkIdType> nodeIds;
333 nodeIds.push_back(n1->getVtkId());
334 nodeIds.push_back(n2->getVtkId());
336 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
337 edgevtk->init(nodeIds, this);
338 if (!this->registerElement(ID,edgevtk))
340 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
341 myEdgePool->destroy(edgevtk);
345 adjustmyCellsCapacity(ID);
349 // if (edge && !registerElement(ID, edge))
351 // RemoveElement(edge, false);
357 ///////////////////////////////////////////////////////////////////////////////
358 /// Add a triangle defined by its nodes. An ID is automatically affected to the
360 ///////////////////////////////////////////////////////////////////////////////
362 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
363 const SMDS_MeshNode * n2,
364 const SMDS_MeshNode * n3)
366 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
369 ///////////////////////////////////////////////////////////////////////////////
370 /// Add a triangle defined by its nodes IDs
371 ///////////////////////////////////////////////////////////////////////////////
373 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
375 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
376 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
377 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
378 if(!node1 || !node2 || !node3) return NULL;
379 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
382 ///////////////////////////////////////////////////////////////////////////////
383 /// Add a triangle defined by its nodes
384 ///////////////////////////////////////////////////////////////////////////////
386 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
387 const SMDS_MeshNode * n2,
388 const SMDS_MeshNode * n3,
391 //MESSAGE("AddFaceWithID " << ID)
392 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
394 // if (face && !registerElement(ID, face)) {
395 // RemoveElement(face, false);
401 ///////////////////////////////////////////////////////////////////////////////
402 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
404 ///////////////////////////////////////////////////////////////////////////////
406 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
407 const SMDS_MeshNode * n2,
408 const SMDS_MeshNode * n3,
409 const SMDS_MeshNode * n4)
411 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
414 ///////////////////////////////////////////////////////////////////////////////
415 /// Add a quadrangle defined by its nodes IDs
416 ///////////////////////////////////////////////////////////////////////////////
418 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
424 SMDS_MeshNode *node1, *node2, *node3, *node4;
425 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
426 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
427 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
428 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
429 if(!node1 || !node2 || !node3 || !node4) return NULL;
430 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
433 ///////////////////////////////////////////////////////////////////////////////
434 /// Add a quadrangle defined by its nodes
435 ///////////////////////////////////////////////////////////////////////////////
437 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
438 const SMDS_MeshNode * n2,
439 const SMDS_MeshNode * n3,
440 const SMDS_MeshNode * n4,
443 //MESSAGE("AddFaceWithID " << ID);
444 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
446 // if (face && !registerElement(ID, face)) {
447 // RemoveElement(face, false);
453 ///////////////////////////////////////////////////////////////////////////////
454 /// Add a triangle defined by its edges. An ID is automatically assigned to the
456 ///////////////////////////////////////////////////////////////////////////////
458 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
459 const SMDS_MeshEdge * e2,
460 const SMDS_MeshEdge * e3)
462 if (!hasConstructionEdges())
464 //MESSAGE("AddFaceWithID");
465 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
468 ///////////////////////////////////////////////////////////////////////////////
469 /// Add a triangle defined by its edges
470 ///////////////////////////////////////////////////////////////////////////////
472 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
473 const SMDS_MeshEdge * e2,
474 const SMDS_MeshEdge * e3,
477 if (!hasConstructionEdges())
479 if ( !e1 || !e2 || !e3 ) return 0;
481 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
482 MESSAGE("AddFaceWithID" << ID);
484 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
485 adjustmyCellsCapacity(ID);
487 myInfo.myNbTriangles++;
489 if (!registerElement(ID, face)) {
490 registerElement(myElementIDFactory->GetFreeID(), face);
491 //RemoveElement(face, false);
497 ///////////////////////////////////////////////////////////////////////////////
498 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
500 ///////////////////////////////////////////////////////////////////////////////
502 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
503 const SMDS_MeshEdge * e2,
504 const SMDS_MeshEdge * e3,
505 const SMDS_MeshEdge * e4)
507 if (!hasConstructionEdges())
509 //MESSAGE("AddFaceWithID" );
510 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
513 ///////////////////////////////////////////////////////////////////////////////
514 /// Add a quadrangle defined by its edges
515 ///////////////////////////////////////////////////////////////////////////////
517 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
518 const SMDS_MeshEdge * e2,
519 const SMDS_MeshEdge * e3,
520 const SMDS_MeshEdge * e4,
523 if (!hasConstructionEdges())
525 MESSAGE("AddFaceWithID" << ID);
526 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
527 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
528 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
529 adjustmyCellsCapacity(ID);
531 myInfo.myNbQuadrangles++;
533 if (!registerElement(ID, face))
535 registerElement(myElementIDFactory->GetFreeID(), face);
536 //RemoveElement(face, false);
542 ///////////////////////////////////////////////////////////////////////////////
543 ///Create a new tetrahedron and add it to the mesh.
544 ///@return The created tetrahedron
545 ///////////////////////////////////////////////////////////////////////////////
547 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
548 const SMDS_MeshNode * n2,
549 const SMDS_MeshNode * n3,
550 const SMDS_MeshNode * n4)
552 int ID = myElementIDFactory->GetFreeID();
553 //MESSAGE("AddVolumeWithID " << ID);
554 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
555 if(v==NULL) myElementIDFactory->ReleaseID(ID);
559 ///////////////////////////////////////////////////////////////////////////////
560 ///Create a new tetrahedron and add it to the mesh.
561 ///@param ID The ID of the new volume
562 ///@return The created tetrahedron or NULL if an element with this ID already exists
563 ///or if input nodes are not found.
564 ///////////////////////////////////////////////////////////////////////////////
566 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
572 //MESSAGE("AddVolumeWithID" << ID);
573 SMDS_MeshNode *node1, *node2, *node3, *node4;
574 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
575 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
576 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
577 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
578 if(!node1 || !node2 || !node3 || !node4) return NULL;
579 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
582 ///////////////////////////////////////////////////////////////////////////////
583 ///Create a new tetrahedron and add it to the mesh.
584 ///@param ID The ID of the new volume
585 ///@return The created tetrahedron
586 ///////////////////////////////////////////////////////////////////////////////
588 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
589 const SMDS_MeshNode * n2,
590 const SMDS_MeshNode * n3,
591 const SMDS_MeshNode * n4,
594 //MESSAGE("AddVolumeWithID " << ID);
595 SMDS_MeshVolume* volume = 0;
596 if ( !n1 || !n2 || !n3 || !n4) return volume;
597 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
598 if(hasConstructionFaces()) {
599 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
600 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
601 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
602 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
603 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
604 adjustmyCellsCapacity(ID);
605 myCells[ID] = volume;
608 else if(hasConstructionEdges()) {
609 MESSAGE("Error : Not implemented");
613 // --- retrieve nodes ID
614 vector<vtkIdType> nodeIds;
616 nodeIds.push_back(n1->getVtkId());
617 nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
618 nodeIds.push_back(n2->getVtkId());
619 nodeIds.push_back(n4->getVtkId());
621 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
622 volvtk->init(nodeIds, this);
623 if (!this->registerElement(ID,volvtk))
625 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
626 myVolumePool->destroy(volvtk);
630 adjustmyCellsCapacity(ID);
631 myCells[ID] = volume;
635 // if (!registerElement(ID, volume)) {
636 // RemoveElement(volume, false);
642 ///////////////////////////////////////////////////////////////////////////////
643 ///Create a new pyramid and add it to the mesh.
644 ///Nodes 1,2,3 and 4 define the base of the pyramid
645 ///@return The created pyramid
646 ///////////////////////////////////////////////////////////////////////////////
648 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
649 const SMDS_MeshNode * n2,
650 const SMDS_MeshNode * n3,
651 const SMDS_MeshNode * n4,
652 const SMDS_MeshNode * n5)
654 int ID = myElementIDFactory->GetFreeID();
655 //MESSAGE("AddVolumeWithID " << ID);
656 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
657 if(v==NULL) myElementIDFactory->ReleaseID(ID);
661 ///////////////////////////////////////////////////////////////////////////////
662 ///Create a new pyramid and add it to the mesh.
663 ///Nodes 1,2,3 and 4 define the base of the pyramid
664 ///@param ID The ID of the new volume
665 ///@return The created pyramid or NULL if an element with this ID already exists
666 ///or if input nodes are not found.
667 ///////////////////////////////////////////////////////////////////////////////
669 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
676 //MESSAGE("AddVolumeWithID " << ID);
677 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
678 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
679 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
680 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
681 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
682 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
683 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
684 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
687 ///////////////////////////////////////////////////////////////////////////////
688 ///Create a new pyramid and add it to the mesh.
689 ///Nodes 1,2,3 and 4 define the base of the pyramid
690 ///@param ID The ID of the new volume
691 ///@return The created pyramid
692 ///////////////////////////////////////////////////////////////////////////////
694 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
695 const SMDS_MeshNode * n2,
696 const SMDS_MeshNode * n3,
697 const SMDS_MeshNode * n4,
698 const SMDS_MeshNode * n5,
701 //MESSAGE("AddVolumeWithID " << ID);
702 SMDS_MeshVolume* volume = 0;
703 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
704 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
705 if(hasConstructionFaces()) {
706 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
707 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
708 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
709 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
710 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
711 adjustmyCellsCapacity(ID);
712 myCells[ID] = volume;
713 myInfo.myNbPyramids++;
715 else if(hasConstructionEdges()) {
716 MESSAGE("Error : Not implemented");
720 // --- retrieve nodes ID
721 vector<vtkIdType> nodeIds;
723 nodeIds.push_back(n1->getVtkId());
724 nodeIds.push_back(n4->getVtkId());
725 nodeIds.push_back(n3->getVtkId());
726 nodeIds.push_back(n2->getVtkId());
727 nodeIds.push_back(n5->getVtkId());
729 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
730 volvtk->init(nodeIds, this);
731 if (!this->registerElement(ID,volvtk))
733 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
734 myVolumePool->destroy(volvtk);
738 adjustmyCellsCapacity(ID);
739 myCells[ID] = volume;
740 myInfo.myNbPyramids++;
743 // if (!registerElement(ID, volume)) {
744 // RemoveElement(volume, false);
750 ///////////////////////////////////////////////////////////////////////////////
751 ///Create a new prism and add it to the mesh.
752 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
753 ///@return The created prism
754 ///////////////////////////////////////////////////////////////////////////////
756 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
757 const SMDS_MeshNode * n2,
758 const SMDS_MeshNode * n3,
759 const SMDS_MeshNode * n4,
760 const SMDS_MeshNode * n5,
761 const SMDS_MeshNode * n6)
763 int ID = myElementIDFactory->GetFreeID();
764 //MESSAGE("AddVolumeWithID " << ID);
765 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
766 if(v==NULL) myElementIDFactory->ReleaseID(ID);
770 ///////////////////////////////////////////////////////////////////////////////
771 ///Create a new prism and add it to the mesh.
772 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
773 ///@param ID The ID of the new volume
774 ///@return The created prism or NULL if an element with this ID already exists
775 ///or if input nodes are not found.
776 ///////////////////////////////////////////////////////////////////////////////
778 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
786 //MESSAGE("AddVolumeWithID " << ID);
787 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
788 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
789 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
790 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
791 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
792 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
793 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
794 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
795 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
798 ///////////////////////////////////////////////////////////////////////////////
799 ///Create a new prism and add it to the mesh.
800 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
801 ///@param ID The ID of the new volume
802 ///@return The created prism
803 ///////////////////////////////////////////////////////////////////////////////
805 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
806 const SMDS_MeshNode * n2,
807 const SMDS_MeshNode * n3,
808 const SMDS_MeshNode * n4,
809 const SMDS_MeshNode * n5,
810 const SMDS_MeshNode * n6,
813 //MESSAGE("AddVolumeWithID " << ID);
814 SMDS_MeshVolume* volume = 0;
815 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
816 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
817 if(hasConstructionFaces()) {
818 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
819 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
820 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
821 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
822 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
823 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
824 adjustmyCellsCapacity(ID);
825 myCells[ID] = volume;
828 else if(hasConstructionEdges()) {
829 MESSAGE("Error : Not implemented");
833 // --- retrieve nodes ID
834 vector<vtkIdType> nodeIds;
836 nodeIds.push_back(n1->getVtkId());
837 nodeIds.push_back(n2->getVtkId());
838 nodeIds.push_back(n3->getVtkId());
839 nodeIds.push_back(n4->getVtkId());
840 nodeIds.push_back(n5->getVtkId());
841 nodeIds.push_back(n6->getVtkId());
843 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
844 volvtk->init(nodeIds, this);
845 if (!this->registerElement(ID,volvtk))
847 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
848 myVolumePool->destroy(volvtk);
852 adjustmyCellsCapacity(ID);
853 myCells[ID] = volume;
857 // if (!registerElement(ID, volume)) {
858 // RemoveElement(volume, false);
864 ///////////////////////////////////////////////////////////////////////////////
865 ///Create a new hexahedron and add it to the mesh.
866 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
867 ///@return The created hexahedron
868 ///////////////////////////////////////////////////////////////////////////////
870 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
871 const SMDS_MeshNode * n2,
872 const SMDS_MeshNode * n3,
873 const SMDS_MeshNode * n4,
874 const SMDS_MeshNode * n5,
875 const SMDS_MeshNode * n6,
876 const SMDS_MeshNode * n7,
877 const SMDS_MeshNode * n8)
879 int ID = myElementIDFactory->GetFreeID();
880 //MESSAGE("AddVolumeWithID " << ID);
881 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
882 if(v==NULL) myElementIDFactory->ReleaseID(ID);
886 ///////////////////////////////////////////////////////////////////////////////
887 ///Create a new hexahedron and add it to the mesh.
888 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
889 ///@param ID The ID of the new volume
890 ///@return The created hexahedron or NULL if an element with this ID already
891 ///exists or if input nodes are not found.
892 ///////////////////////////////////////////////////////////////////////////////
894 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
904 //MESSAGE("AddVolumeWithID " << ID);
905 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
906 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
907 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
908 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
909 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
910 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
911 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
912 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
913 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
914 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
916 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
920 ///////////////////////////////////////////////////////////////////////////////
921 ///Create a new hexahedron and add it to the mesh.
922 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
923 ///@param ID The ID of the new volume
924 ///@return The created prism or NULL if an element with this ID already exists
925 ///or if input nodes are not found.
926 ///////////////////////////////////////////////////////////////////////////////
928 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
929 const SMDS_MeshNode * n2,
930 const SMDS_MeshNode * n3,
931 const SMDS_MeshNode * n4,
932 const SMDS_MeshNode * n5,
933 const SMDS_MeshNode * n6,
934 const SMDS_MeshNode * n7,
935 const SMDS_MeshNode * n8,
938 //MESSAGE("AddVolumeWithID " << ID);
939 SMDS_MeshVolume* volume = 0;
940 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
941 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
942 if(hasConstructionFaces()) {
943 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
944 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
945 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
946 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
947 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
948 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
949 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
950 adjustmyCellsCapacity(ID);
951 myCells[ID] = volume;
954 else if(hasConstructionEdges()) {
955 MESSAGE("Error : Not implemented");
959 // --- retrieve nodes ID
960 vector<vtkIdType> nodeIds;
962 nodeIds.push_back(n1->getVtkId());
963 nodeIds.push_back(n4->getVtkId());
964 nodeIds.push_back(n3->getVtkId());
965 nodeIds.push_back(n2->getVtkId());
966 nodeIds.push_back(n5->getVtkId());
967 nodeIds.push_back(n8->getVtkId());
968 nodeIds.push_back(n7->getVtkId());
969 nodeIds.push_back(n6->getVtkId());
971 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
972 volvtk->init(nodeIds, this);
973 if (!this->registerElement(ID,volvtk))
975 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
976 myVolumePool->destroy(volvtk);
980 adjustmyCellsCapacity(ID);
981 myCells[ID] = volume;
985 // if (!registerElement(ID, volume)) {
986 // RemoveElement(volume, false);
992 ///////////////////////////////////////////////////////////////////////////////
993 ///Create a new tetrahedron defined by its faces and add it to the mesh.
994 ///@return The created tetrahedron
995 ///////////////////////////////////////////////////////////////////////////////
997 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
998 const SMDS_MeshFace * f2,
999 const SMDS_MeshFace * f3,
1000 const SMDS_MeshFace * f4)
1002 //MESSAGE("AddVolumeWithID");
1003 if (!hasConstructionFaces())
1005 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1008 ///////////////////////////////////////////////////////////////////////////////
1009 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1010 ///@param ID The ID of the new volume
1011 ///@return The created tetrahedron
1012 ///////////////////////////////////////////////////////////////////////////////
1014 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1015 const SMDS_MeshFace * f2,
1016 const SMDS_MeshFace * f3,
1017 const SMDS_MeshFace * f4,
1020 MESSAGE("AddVolumeWithID" << ID);
1021 if (!hasConstructionFaces())
1023 if ( !f1 || !f2 || !f3 || !f4) return 0;
1024 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1025 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1026 adjustmyCellsCapacity(ID);
1027 myCells[ID] = volume;
1028 myInfo.myNbTetras++;
1030 if (!registerElement(ID, volume)) {
1031 registerElement(myElementIDFactory->GetFreeID(), volume);
1032 //RemoveElement(volume, false);
1038 ///////////////////////////////////////////////////////////////////////////////
1039 ///Create a new pyramid defined by its faces and add it to the mesh.
1040 ///@return The created pyramid
1041 ///////////////////////////////////////////////////////////////////////////////
1043 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1044 const SMDS_MeshFace * f2,
1045 const SMDS_MeshFace * f3,
1046 const SMDS_MeshFace * f4,
1047 const SMDS_MeshFace * f5)
1049 //MESSAGE("AddVolumeWithID");
1050 if (!hasConstructionFaces())
1052 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1055 ///////////////////////////////////////////////////////////////////////////////
1056 ///Create a new pyramid defined by its faces and add it to the mesh.
1057 ///@param ID The ID of the new volume
1058 ///@return The created pyramid
1059 ///////////////////////////////////////////////////////////////////////////////
1061 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1062 const SMDS_MeshFace * f2,
1063 const SMDS_MeshFace * f3,
1064 const SMDS_MeshFace * f4,
1065 const SMDS_MeshFace * f5,
1068 MESSAGE("AddVolumeWithID" << ID);
1069 if (!hasConstructionFaces())
1071 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1072 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1073 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1074 adjustmyCellsCapacity(ID);
1075 myCells[ID] = volume;
1076 myInfo.myNbPyramids++;
1078 if (!registerElement(ID, volume)) {
1079 registerElement(myElementIDFactory->GetFreeID(), volume);
1080 //RemoveElement(volume, false);
1086 ///////////////////////////////////////////////////////////////////////////////
1087 ///Create a new prism defined by its faces and add it to the mesh.
1088 ///@return The created prism
1089 ///////////////////////////////////////////////////////////////////////////////
1091 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1092 const SMDS_MeshFace * f2,
1093 const SMDS_MeshFace * f3,
1094 const SMDS_MeshFace * f4,
1095 const SMDS_MeshFace * f5,
1096 const SMDS_MeshFace * f6)
1098 //MESSAGE("AddVolumeWithID" );
1099 if (!hasConstructionFaces())
1101 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1104 ///////////////////////////////////////////////////////////////////////////////
1105 ///Create a new prism defined by its faces and add it to the mesh.
1106 ///@param ID The ID of the new volume
1107 ///@return The created prism
1108 ///////////////////////////////////////////////////////////////////////////////
1110 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1111 const SMDS_MeshFace * f2,
1112 const SMDS_MeshFace * f3,
1113 const SMDS_MeshFace * f4,
1114 const SMDS_MeshFace * f5,
1115 const SMDS_MeshFace * f6,
1118 MESSAGE("AddVolumeWithID" << ID);
1119 if (!hasConstructionFaces())
1121 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1122 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1123 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1124 adjustmyCellsCapacity(ID);
1125 myCells[ID] = volume;
1126 myInfo.myNbPrisms++;
1128 if (!registerElement(ID, volume)) {
1129 registerElement(myElementIDFactory->GetFreeID(), volume);
1130 //RemoveElement(volume, false);
1136 ///////////////////////////////////////////////////////////////////////////////
1137 /// Add a polygon defined by its nodes IDs
1138 ///////////////////////////////////////////////////////////////////////////////
1140 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
1143 int nbNodes = nodes_ids.size();
1144 vector<const SMDS_MeshNode*> nodes (nbNodes);
1145 for (int i = 0; i < nbNodes; i++) {
1146 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1147 if (!nodes[i]) return NULL;
1149 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1152 ///////////////////////////////////////////////////////////////////////////////
1153 /// Add a polygon defined by its nodes
1154 ///////////////////////////////////////////////////////////////////////////////
1156 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1157 (vector<const SMDS_MeshNode*> nodes,
1160 SMDS_MeshFace * face;
1162 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1163 if (hasConstructionEdges())
1165 MESSAGE("Error : Not implemented");
1170 //#ifdef VTK_HAVE_POLYHEDRON
1171 //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
1172 vector<vtkIdType> nodeIds;
1174 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1175 for ( ; it != nodes.end(); ++it)
1176 nodeIds.push_back((*it)->getVtkId());
1178 SMDS_VtkFace *facevtk = myFacePool->getNew();
1179 facevtk->initPoly(nodeIds, this);
1180 if (!this->registerElement(ID,facevtk))
1182 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1183 myFacePool->destroy(facevtk);
1188 // MESSAGE("AddPolygonalFaceWithID smds " << ID);
1189 // for ( int i = 0; i < nodes.size(); ++i )
1190 // if ( !nodes[ i ] ) return 0;
1191 // face = new SMDS_PolygonalFaceOfNodes(nodes);
1193 adjustmyCellsCapacity(ID);
1195 myInfo.myNbPolygons++;
1198 //#ifndef VTK_HAVE_POLYHEDRON
1199 // if (!registerElement(ID, face))
1201 // registerElement(myElementIDFactory->GetFreeID(), face);
1202 // //RemoveElement(face, false);
1209 ///////////////////////////////////////////////////////////////////////////////
1210 /// Add a polygon defined by its nodes.
1211 /// An ID is automatically affected to the created face.
1212 ///////////////////////////////////////////////////////////////////////////////
1214 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
1216 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1219 ///////////////////////////////////////////////////////////////////////////////
1220 /// Create a new polyhedral volume and add it to the mesh.
1221 /// @param ID The ID of the new volume
1222 /// @return The created volume or NULL if an element with this ID already exists
1223 /// or if input nodes are not found.
1224 ///////////////////////////////////////////////////////////////////////////////
1226 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1227 (vector<int> nodes_ids,
1228 vector<int> quantities,
1231 int nbNodes = nodes_ids.size();
1232 vector<const SMDS_MeshNode*> nodes (nbNodes);
1233 for (int i = 0; i < nbNodes; i++) {
1234 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1235 if (!nodes[i]) return NULL;
1237 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1240 ///////////////////////////////////////////////////////////////////////////////
1241 /// Create a new polyhedral volume and add it to the mesh.
1242 /// @param ID The ID of the new volume
1243 /// @return The created volume
1244 ///////////////////////////////////////////////////////////////////////////////
1246 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1247 (vector<const SMDS_MeshNode*> nodes,
1248 vector<int> quantities,
1251 SMDS_MeshVolume* volume;
1252 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1253 if (hasConstructionFaces())
1255 MESSAGE("Error : Not implemented");
1258 else if (hasConstructionEdges())
1260 MESSAGE("Error : Not implemented");
1265 //#ifdef VTK_HAVE_POLYHEDRON
1266 //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1267 vector<vtkIdType> nodeIds;
1269 vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
1270 for (; it != nodes.end(); ++it)
1271 nodeIds.push_back((*it)->getVtkId());
1273 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1274 volvtk->initPoly(nodeIds, quantities, this);
1275 if (!this->registerElement(ID, volvtk))
1277 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1278 myVolumePool->destroy(volvtk);
1283 // MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1284 // for ( int i = 0; i < nodes.size(); ++i )
1285 // if ( !nodes[ i ] ) return 0;
1286 // volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1288 adjustmyCellsCapacity(ID);
1289 myCells[ID] = volume;
1290 myInfo.myNbPolyhedrons++;
1293 //#ifndef VTK_HAVE_POLYHEDRON
1294 // if (!registerElement(ID, volume))
1296 // registerElement(myElementIDFactory->GetFreeID(), volume);
1297 // //RemoveElement(volume, false);
1304 ///////////////////////////////////////////////////////////////////////////////
1305 /// Create a new polyhedral volume and add it to the mesh.
1306 /// @return The created volume
1307 ///////////////////////////////////////////////////////////////////////////////
1309 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1310 (vector<const SMDS_MeshNode*> nodes,
1311 vector<int> quantities)
1313 int ID = myElementIDFactory->GetFreeID();
1314 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1315 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1319 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1321 int ID = myElementIDFactory->GetFreeID();
1322 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1323 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1327 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1329 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1330 volvtk->init(vtkNodeIds, this);
1331 if (!this->registerElement(ID,volvtk))
1333 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1334 myVolumePool->destroy(volvtk);
1337 adjustmyCellsCapacity(ID);
1338 myCells[ID] = volvtk;
1339 vtkIdType aVtkType = volvtk->GetVtkType();
1343 myInfo.myNbTetras++;
1346 myInfo.myNbPyramids++;
1349 myInfo.myNbPrisms++;
1351 case VTK_HEXAHEDRON:
1354 case VTK_QUADRATIC_TETRA:
1355 myInfo.myNbQuadTetras++;
1357 case VTK_QUADRATIC_PYRAMID:
1358 myInfo.myNbQuadPyramids++;
1360 case VTK_QUADRATIC_WEDGE:
1361 myInfo.myNbQuadPrisms++;
1363 case VTK_QUADRATIC_HEXAHEDRON:
1364 myInfo.myNbQuadHexas++;
1366 //#ifdef VTK_HAVE_POLYHEDRON
1367 case VTK_POLYHEDRON:
1368 myInfo.myNbPolyhedrons++;
1372 myInfo.myNbPolyhedrons++;
1378 ///////////////////////////////////////////////////////////////////////////////
1379 /// Registers element with the given ID, maintains inverse connections
1380 ///////////////////////////////////////////////////////////////////////////////
1381 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1383 //MESSAGE("registerElement " << ID);
1384 if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1386 MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1391 element->myMeshId = myMeshId;
1393 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1395 int vtkId = cell->getVtkId();
1397 vtkId = myElementIDFactory->SetInVtkGrid(element);
1399 if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1401 // MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1402 myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1404 myCellIdVtkToSmds[vtkId] = ID;
1406 myElementIDFactory->updateMinMax(ID);
1410 ///////////////////////////////////////////////////////////////////////////////
1411 /// Return the node whose SMDS ID is 'ID'.
1412 ///////////////////////////////////////////////////////////////////////////////
1413 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1415 if (ID < 1 || ID >= myNodes.size())
1417 // MESSAGE("------------------------------------------------------------------------- ");
1418 // MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1419 // MESSAGE("------------------------------------------------------------------------- ");
1422 return (const SMDS_MeshNode *)myNodes[ID];
1425 ///////////////////////////////////////////////////////////////////////////////
1426 /// Return the node whose VTK ID is 'vtkId'.
1427 ///////////////////////////////////////////////////////////////////////////////
1428 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1430 // TODO if needed use mesh->nodeIdFromVtkToSmds
1431 if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1433 MESSAGE("------------------------------------------------------------------------- ");
1434 MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1435 MESSAGE("------------------------------------------------------------------------- ");
1438 return (const SMDS_MeshNode *)myNodes[vtkId+1];
1441 ///////////////////////////////////////////////////////////////////////////////
1442 ///Create a triangle and add it to the current mesh. This method do not bind an
1443 ///ID to the create triangle.
1444 ///////////////////////////////////////////////////////////////////////////////
1445 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1446 const SMDS_MeshNode * node2,
1447 const SMDS_MeshNode * node3,
1450 if ( !node1 || !node2 || !node3) return 0;
1451 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1452 if(hasConstructionEdges())
1454 SMDS_MeshEdge *edge1, *edge2, *edge3;
1455 edge1=FindEdgeOrCreate(node1,node2);
1456 edge2=FindEdgeOrCreate(node2,node3);
1457 edge3=FindEdgeOrCreate(node3,node1);
1459 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1460 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1461 adjustmyCellsCapacity(ID);
1463 myInfo.myNbTriangles++;
1468 // --- retrieve nodes ID
1469 vector<vtkIdType> nodeIds;
1471 nodeIds.push_back(node1->getVtkId());
1472 nodeIds.push_back(node2->getVtkId());
1473 nodeIds.push_back(node3->getVtkId());
1475 SMDS_MeshFace * face = 0;
1476 SMDS_VtkFace *facevtk = myFacePool->getNew();
1477 facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1478 if (!this->registerElement(ID,facevtk))
1480 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1481 myFacePool->destroy(facevtk);
1485 adjustmyCellsCapacity(ID);
1487 //MESSAGE("createTriangle " << ID << " " << face);
1488 myInfo.myNbTriangles++;
1493 ///////////////////////////////////////////////////////////////////////////////
1494 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1495 ///a ID to the create triangle.
1496 ///////////////////////////////////////////////////////////////////////////////
1497 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1498 const SMDS_MeshNode * node2,
1499 const SMDS_MeshNode * node3,
1500 const SMDS_MeshNode * node4,
1503 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1504 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1505 if(hasConstructionEdges())
1507 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1508 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1509 edge1=FindEdgeOrCreate(node1,node2);
1510 edge2=FindEdgeOrCreate(node2,node3);
1511 edge3=FindEdgeOrCreate(node3,node4);
1512 edge4=FindEdgeOrCreate(node4,node1);
1514 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1515 adjustmyCellsCapacity(ID);
1517 myInfo.myNbQuadrangles++;
1522 // --- retrieve nodes ID
1523 vector<vtkIdType> nodeIds;
1525 nodeIds.push_back(node1->getVtkId());
1526 nodeIds.push_back(node2->getVtkId());
1527 nodeIds.push_back(node3->getVtkId());
1528 nodeIds.push_back(node4->getVtkId());
1530 SMDS_MeshFace * face = 0;
1531 SMDS_VtkFace *facevtk = myFacePool->getNew();
1532 facevtk->init(nodeIds, this);
1533 if (!this->registerElement(ID,facevtk))
1535 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1536 myFacePool->destroy(facevtk);
1540 adjustmyCellsCapacity(ID);
1542 myInfo.myNbQuadrangles++;
1547 ///////////////////////////////////////////////////////////////////////////////
1548 /// Remove a node and all the elements which own this node
1549 ///////////////////////////////////////////////////////////////////////////////
1551 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1553 MESSAGE("RemoveNode");
1554 RemoveElement(node, true);
1557 ///////////////////////////////////////////////////////////////////////////////
1558 /// Remove an edge and all the elements which own this edge
1559 ///////////////////////////////////////////////////////////////////////////////
1561 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1563 MESSAGE("Remove0DElement");
1564 RemoveElement(elem0d,true);
1567 ///////////////////////////////////////////////////////////////////////////////
1568 /// Remove an edge and all the elements which own this edge
1569 ///////////////////////////////////////////////////////////////////////////////
1571 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1573 MESSAGE("RemoveEdge");
1574 RemoveElement(edge,true);
1577 ///////////////////////////////////////////////////////////////////////////////
1578 /// Remove an face and all the elements which own this face
1579 ///////////////////////////////////////////////////////////////////////////////
1581 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1583 MESSAGE("RemoveFace");
1584 RemoveElement(face, true);
1587 ///////////////////////////////////////////////////////////////////////////////
1589 ///////////////////////////////////////////////////////////////////////////////
1591 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1593 MESSAGE("RemoveVolume");
1594 RemoveElement(volume, true);
1597 //=======================================================================
1598 //function : RemoveFromParent
1600 //=======================================================================
1602 bool SMDS_Mesh::RemoveFromParent()
1604 if (myParent==NULL) return false;
1605 else return (myParent->RemoveSubMesh(this));
1608 //=======================================================================
1609 //function : RemoveSubMesh
1611 //=======================================================================
1613 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1617 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1618 for (; itmsh!=myChildren.end() && !found; itmsh++)
1620 SMDS_Mesh * submesh = *itmsh;
1621 if (submesh == aMesh)
1624 myChildren.erase(itmsh);
1631 //=======================================================================
1632 //function : ChangeElementNodes
1634 //=======================================================================
1636 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1637 const SMDS_MeshNode * nodes[],
1640 MESSAGE("SMDS_Mesh::ChangeElementNodes");
1641 // keep current nodes of elem
1642 set<const SMDS_MeshElement*> oldNodes;
1643 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1645 oldNodes.insert(itn->next());
1649 SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1652 Ok = cell->vtkOrder(nodes, nbnodes);
1653 Ok = cell->ChangeNodes(nodes, nbnodes);
1656 if ( Ok ) { // update InverseElements
1658 set<const SMDS_MeshElement*>::iterator it;
1660 // AddInverseElement to new nodes
1661 for ( int i = 0; i < nbnodes; i++ ) {
1662 it = oldNodes.find( nodes[i] );
1663 if ( it == oldNodes.end() )
1665 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1667 // remove from oldNodes a node that remains in elem
1668 oldNodes.erase( it );
1670 // RemoveInverseElement from the nodes removed from elem
1671 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1673 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1674 (const_cast<SMDS_MeshElement *>( *it ));
1675 n->RemoveInverseElement( cell );
1682 //=======================================================================
1683 //function : ChangePolyhedronNodes
1684 //purpose : to change nodes of polyhedral volume
1685 //=======================================================================
1686 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1687 const vector<const SMDS_MeshNode*>& nodes,
1688 const vector<int> & quantities)
1690 if (elem->GetType() != SMDSAbs_Volume) {
1691 MESSAGE("WRONG ELEM TYPE");
1695 const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1700 // keep current nodes of elem
1701 set<const SMDS_MeshElement*> oldNodes;
1702 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1703 while (itn->more()) {
1704 oldNodes.insert(itn->next());
1708 // TODO remove this function
1709 //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1715 // update InverseElements
1717 // AddInverseElement to new nodes
1718 int nbnodes = nodes.size();
1719 set<const SMDS_MeshElement*>::iterator it;
1720 for (int i = 0; i < nbnodes; i++) {
1721 it = oldNodes.find(nodes[i]);
1722 if (it == oldNodes.end()) {
1724 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1726 // remove from oldNodes a node that remains in elem
1731 // RemoveInverseElement from the nodes removed from elem
1732 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1733 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1734 (const_cast<SMDS_MeshElement *>( *it ));
1735 n->RemoveInverseElement(elem);
1742 //=======================================================================
1743 //function : Find0DElement
1745 //=======================================================================
1746 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1748 const SMDS_MeshNode * node = FindNode(idnode);
1749 if(node == NULL) return NULL;
1750 return Find0DElement(node);
1753 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1755 if (!node) return 0;
1756 const SMDS_Mesh0DElement* toReturn = NULL;
1757 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1758 while (it1->more() && (toReturn == NULL)) {
1759 const SMDS_MeshElement* e = it1->next();
1760 if (e->NbNodes() == 1) {
1761 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1767 //=======================================================================
1768 //function : Find0DElementOrCreate
1770 //=======================================================================
1771 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1773 // if (!node) return 0;
1774 // SMDS_Mesh0DElement * toReturn = NULL;
1775 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1776 // if (toReturn == NULL) {
1777 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1778 // toReturn = new SMDS_Mesh0DElement(node);
1779 // my0DElements.Add(toReturn);
1780 // myInfo.myNb0DElements++;
1786 //=======================================================================
1787 //function : FindEdge
1789 //=======================================================================
1791 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1793 const SMDS_MeshNode * node1=FindNode(idnode1);
1794 const SMDS_MeshNode * node2=FindNode(idnode2);
1795 if((node1==NULL)||(node2==NULL)) return NULL;
1796 return FindEdge(node1,node2);
1799 //#include "Profiler.h"
1800 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1801 const SMDS_MeshNode * node2)
1803 if ( !node1 ) return 0;
1804 const SMDS_MeshEdge * toReturn=NULL;
1807 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1810 while(it1->more()) {
1811 const SMDS_MeshElement * e = it1->next();
1812 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1813 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1822 //=======================================================================
1823 //function : FindEdgeOrCreate
1825 //=======================================================================
1827 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1828 const SMDS_MeshNode * node2)
1830 if ( !node1 || !node2) return 0;
1831 SMDS_MeshEdge * toReturn=NULL;
1832 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1833 if(toReturn==NULL) {
1834 if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1835 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1836 adjustmyCellsCapacity(ID);
1837 vector<vtkIdType> nodeIds;
1839 nodeIds.push_back(node1->getVtkId());
1840 nodeIds.push_back(node2->getVtkId());
1842 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1843 edgevtk->init(nodeIds, this);
1844 if (!this->registerElement(ID,edgevtk))
1846 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
1847 myEdgePool->destroy(edgevtk);
1851 myCells[ID] = toReturn;
1858 //=======================================================================
1859 //function : FindEdge
1861 //=======================================================================
1863 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1866 const SMDS_MeshNode * node1=FindNode(idnode1);
1867 const SMDS_MeshNode * node2=FindNode(idnode2);
1868 const SMDS_MeshNode * node3=FindNode(idnode3);
1869 return FindEdge(node1,node2,node3);
1872 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1873 const SMDS_MeshNode * node2,
1874 const SMDS_MeshNode * node3)
1876 if ( !node1 ) return 0;
1877 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1878 while(it1->more()) {
1879 const SMDS_MeshElement * e = it1->next();
1880 if ( e->NbNodes() == 3 ) {
1881 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1882 while(it2->more()) {
1883 const SMDS_MeshElement* n = it2->next();
1893 return static_cast<const SMDS_MeshEdge *> (e);
1900 //=======================================================================
1901 //function : FindFace
1903 //=======================================================================
1905 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1908 const SMDS_MeshNode * node1=FindNode(idnode1);
1909 const SMDS_MeshNode * node2=FindNode(idnode2);
1910 const SMDS_MeshNode * node3=FindNode(idnode3);
1911 return FindFace(node1, node2, node3);
1914 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1915 const SMDS_MeshNode *node2,
1916 const SMDS_MeshNode *node3)
1918 if ( !node1 ) return 0;
1919 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1920 while(it1->more()) {
1921 const SMDS_MeshElement * e = it1->next();
1922 if ( e->NbNodes() == 3 ) {
1923 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1924 while(it2->more()) {
1925 const SMDS_MeshElement* n = it2->next();
1935 return static_cast<const SMDS_MeshFace *> (e);
1941 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1942 const SMDS_MeshNode *node2,
1943 const SMDS_MeshNode *node3)
1945 SMDS_MeshFace * toReturn=NULL;
1946 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1947 if(toReturn==NULL) {
1948 int ID = myElementIDFactory->GetFreeID();
1949 toReturn = createTriangle(node1,node2,node3, ID);
1955 //=======================================================================
1956 //function : FindFace
1958 //=======================================================================
1960 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1961 int idnode3, int idnode4) const
1963 const SMDS_MeshNode * node1=FindNode(idnode1);
1964 const SMDS_MeshNode * node2=FindNode(idnode2);
1965 const SMDS_MeshNode * node3=FindNode(idnode3);
1966 const SMDS_MeshNode * node4=FindNode(idnode4);
1967 return FindFace(node1, node2, node3, node4);
1970 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1971 const SMDS_MeshNode *node2,
1972 const SMDS_MeshNode *node3,
1973 const SMDS_MeshNode *node4)
1975 if ( !node1 ) return 0;
1976 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1977 while(it1->more()) {
1978 const SMDS_MeshElement * e = it1->next();
1979 if ( e->NbNodes() == 4 ) {
1980 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1981 while(it2->more()) {
1982 const SMDS_MeshElement* n = it2->next();
1993 return static_cast<const SMDS_MeshFace *> (e);
1999 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2000 const SMDS_MeshNode *node2,
2001 const SMDS_MeshNode *node3,
2002 const SMDS_MeshNode *node4)
2004 SMDS_MeshFace * toReturn=NULL;
2005 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2006 if(toReturn==NULL) {
2007 int ID = myElementIDFactory->GetFreeID();
2008 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2014 //=======================================================================
2015 //function : FindFace
2016 //purpose :quadratic triangle
2017 //=======================================================================
2019 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2020 int idnode3, int idnode4,
2021 int idnode5, int idnode6) const
2023 const SMDS_MeshNode * node1 = FindNode(idnode1);
2024 const SMDS_MeshNode * node2 = FindNode(idnode2);
2025 const SMDS_MeshNode * node3 = FindNode(idnode3);
2026 const SMDS_MeshNode * node4 = FindNode(idnode4);
2027 const SMDS_MeshNode * node5 = FindNode(idnode5);
2028 const SMDS_MeshNode * node6 = FindNode(idnode6);
2029 return FindFace(node1, node2, node3, node4, node5, node6);
2032 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2033 const SMDS_MeshNode *node2,
2034 const SMDS_MeshNode *node3,
2035 const SMDS_MeshNode *node4,
2036 const SMDS_MeshNode *node5,
2037 const SMDS_MeshNode *node6)
2039 if ( !node1 ) return 0;
2040 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2041 while(it1->more()) {
2042 const SMDS_MeshElement * e = it1->next();
2043 if ( e->NbNodes() == 6 ) {
2044 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2045 while(it2->more()) {
2046 const SMDS_MeshElement* n = it2->next();
2059 return static_cast<const SMDS_MeshFace *> (e);
2066 //=======================================================================
2067 //function : FindFace
2068 //purpose : quadratic quadrangle
2069 //=======================================================================
2071 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2072 int idnode3, int idnode4,
2073 int idnode5, int idnode6,
2074 int idnode7, int idnode8) const
2076 const SMDS_MeshNode * node1 = FindNode(idnode1);
2077 const SMDS_MeshNode * node2 = FindNode(idnode2);
2078 const SMDS_MeshNode * node3 = FindNode(idnode3);
2079 const SMDS_MeshNode * node4 = FindNode(idnode4);
2080 const SMDS_MeshNode * node5 = FindNode(idnode5);
2081 const SMDS_MeshNode * node6 = FindNode(idnode6);
2082 const SMDS_MeshNode * node7 = FindNode(idnode7);
2083 const SMDS_MeshNode * node8 = FindNode(idnode8);
2084 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2087 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2088 const SMDS_MeshNode *node2,
2089 const SMDS_MeshNode *node3,
2090 const SMDS_MeshNode *node4,
2091 const SMDS_MeshNode *node5,
2092 const SMDS_MeshNode *node6,
2093 const SMDS_MeshNode *node7,
2094 const SMDS_MeshNode *node8)
2096 if ( !node1 ) return 0;
2097 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2098 while(it1->more()) {
2099 const SMDS_MeshElement * e = it1->next();
2100 if ( e->NbNodes() == 8 ) {
2101 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2102 while(it2->more()) {
2103 const SMDS_MeshElement* n = it2->next();
2118 return static_cast<const SMDS_MeshFace *> (e);
2125 //=======================================================================
2126 //function : FindElement
2128 //=======================================================================
2130 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2132 if ((IDelem <= 0) || IDelem >= myCells.size())
2134 MESSAGE("--------------------------------------------------------------------------------- ");
2135 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2136 MESSAGE("--------------------------------------------------------------------------------- ");
2137 // TODO raise an exception
2141 return myCells[IDelem];
2144 //=======================================================================
2145 //function : FindFace
2146 //purpose : find polygon
2147 //=======================================================================
2149 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2151 int nbnodes = nodes_ids.size();
2152 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2153 for (int inode = 0; inode < nbnodes; inode++) {
2154 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2155 if (node == NULL) return NULL;
2156 poly_nodes[inode] = node;
2158 return FindFace(poly_nodes);
2161 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2163 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2167 //================================================================================
2169 * \brief Return element based on all given nodes
2170 * \param nodes - node of element
2171 * \param type - type of element
2172 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2173 * \retval const SMDS_MeshElement* - found element or NULL
2175 //================================================================================
2177 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2178 const SMDSAbs_ElementType type,
2179 const bool noMedium)
2181 if ( nodes.size() > 0 && nodes[0] )
2183 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2186 const SMDS_MeshElement* e = itF->next();
2187 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2188 if ( nbNodesToCheck == nodes.size() )
2190 for ( int i = 1; e && i < nodes.size(); ++ i )
2192 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2193 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2197 return static_cast<const SMDS_MeshFace *> (e);
2204 //=======================================================================
2205 //function : DumpNodes
2207 //=======================================================================
2209 void SMDS_Mesh::DumpNodes() const
2211 MESSAGE("dump nodes of mesh : ");
2212 SMDS_NodeIteratorPtr itnode=nodesIterator();
2213 while(itnode->more()) ; //MESSAGE(itnode->next());
2216 //=======================================================================
2217 //function : Dump0DElements
2219 //=======================================================================
2220 void SMDS_Mesh::Dump0DElements() const
2222 MESSAGE("dump 0D elements of mesh : ");
2223 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2224 while(it0d->more()) ; //MESSAGE(it0d->next());
2227 //=======================================================================
2228 //function : DumpEdges
2230 //=======================================================================
2232 void SMDS_Mesh::DumpEdges() const
2234 MESSAGE("dump edges of mesh : ");
2235 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2236 while(itedge->more()) ; //MESSAGE(itedge->next());
2239 //=======================================================================
2240 //function : DumpFaces
2242 //=======================================================================
2244 void SMDS_Mesh::DumpFaces() const
2246 MESSAGE("dump faces of mesh : ");
2247 SMDS_FaceIteratorPtr itface=facesIterator();
2248 while(itface->more()) ; //MESSAGE(itface->next());
2251 //=======================================================================
2252 //function : DumpVolumes
2254 //=======================================================================
2256 void SMDS_Mesh::DumpVolumes() const
2258 MESSAGE("dump volumes of mesh : ");
2259 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2260 while(itvol->more()) ; //MESSAGE(itvol->next());
2263 //=======================================================================
2264 //function : DebugStats
2266 //=======================================================================
2268 void SMDS_Mesh::DebugStats() const
2270 MESSAGE("Debug stats of mesh : ");
2272 MESSAGE("===== NODES ====="<<NbNodes());
2273 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2274 MESSAGE("===== EDGES ====="<<NbEdges());
2275 MESSAGE("===== FACES ====="<<NbFaces());
2276 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2278 MESSAGE("End Debug stats of mesh ");
2282 SMDS_NodeIteratorPtr itnode=nodesIterator();
2283 int sizeofnodes = 0;
2284 int sizeoffaces = 0;
2286 while(itnode->more())
2288 const SMDS_MeshNode *node = itnode->next();
2290 sizeofnodes += sizeof(*node);
2292 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2295 const SMDS_MeshElement *me = it->next();
2296 sizeofnodes += sizeof(me);
2300 SMDS_FaceIteratorPtr itface=facesIterator();
2301 while(itface->more())
2303 const SMDS_MeshElement *face = itface->next();
2304 sizeoffaces += sizeof(*face);
2307 MESSAGE("total size of node elements = " << sizeofnodes);;
2308 MESSAGE("total size of face elements = " << sizeoffaces);;
2313 ///////////////////////////////////////////////////////////////////////////////
2314 /// Return the number of nodes
2315 ///////////////////////////////////////////////////////////////////////////////
2316 int SMDS_Mesh::NbNodes() const
2318 //MESSAGE(myGrid->GetNumberOfPoints());
2319 //MESSAGE(myInfo.NbNodes());
2320 //MESSAGE(myNodeMax);
2321 return myInfo.NbNodes();
2324 ///////////////////////////////////////////////////////////////////////////////
2325 /// Return the number of 0D elements
2326 ///////////////////////////////////////////////////////////////////////////////
2327 int SMDS_Mesh::Nb0DElements() const
2329 return myInfo.Nb0DElements(); // -PR- a verfier
2332 ///////////////////////////////////////////////////////////////////////////////
2333 /// Return the number of edges (including construction edges)
2334 ///////////////////////////////////////////////////////////////////////////////
2335 int SMDS_Mesh::NbEdges() const
2337 return myInfo.NbEdges(); // -PR- a verfier
2340 ///////////////////////////////////////////////////////////////////////////////
2341 /// Return the number of faces (including construction faces)
2342 ///////////////////////////////////////////////////////////////////////////////
2343 int SMDS_Mesh::NbFaces() const
2345 return myInfo.NbFaces(); // -PR- a verfier
2348 ///////////////////////////////////////////////////////////////////////////////
2349 /// Return the number of volumes
2350 ///////////////////////////////////////////////////////////////////////////////
2351 int SMDS_Mesh::NbVolumes() const
2353 return myInfo.NbVolumes(); // -PR- a verfier
2356 ///////////////////////////////////////////////////////////////////////////////
2357 /// Return the number of child mesh of this mesh.
2358 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2359 /// (2003-09-08) of SMESH
2360 ///////////////////////////////////////////////////////////////////////////////
2361 int SMDS_Mesh::NbSubMesh() const
2363 return myChildren.size();
2366 ///////////////////////////////////////////////////////////////////////////////
2367 /// Destroy the mesh and all its elements
2368 /// All pointer on elements owned by this mesh become illegals.
2369 ///////////////////////////////////////////////////////////////////////////////
2370 SMDS_Mesh::~SMDS_Mesh()
2372 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2373 while(itc!=myChildren.end())
2381 delete myNodeIDFactory;
2382 delete myElementIDFactory;
2386 SMDS_ElemIteratorPtr eIt = elementsIterator();
2387 while ( eIt->more() )
2389 const SMDS_MeshElement *elem = eIt->next();
2390 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2392 SMDS_NodeIteratorPtr itn = nodesIterator();
2395 const SMDS_MeshNode *node = itn->next();
2396 ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2397 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2401 // SetOfNodes::Iterator itn(myNodes);
2402 // for (; itn.More(); itn.Next())
2403 // delete itn.Value();
2405 // SetOf0DElements::Iterator it0d (my0DElements);
2406 // for (; it0d.More(); it0d.Next())
2408 // SMDS_MeshElement* elem = it0d.Value();
2412 // SetOfEdges::Iterator ite(myEdges);
2413 // for (; ite.More(); ite.Next())
2415 // SMDS_MeshElement* elem = ite.Value();
2419 // SetOfFaces::Iterator itf(myFaces);
2420 // for (; itf.More(); itf.Next())
2422 // SMDS_MeshElement* elem = itf.Value();
2426 // SetOfVolumes::Iterator itv(myVolumes);
2427 // for (; itv.More(); itv.Next())
2429 // SMDS_MeshElement* elem = itv.Value();
2434 //================================================================================
2436 * \brief Clear all data
2438 //================================================================================
2440 void SMDS_Mesh::Clear()
2442 MESSAGE("SMDS_Mesh::Clear");
2445 SMDS_ElemIteratorPtr eIt = elementsIterator();
2446 while ( eIt->more() )
2448 const SMDS_MeshElement *elem = eIt->next();
2449 myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2451 SMDS_NodeIteratorPtr itn = nodesIterator();
2454 const SMDS_MeshNode *node = itn->next();
2455 myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2460 myNodeIDFactory->Clear();
2461 myElementIDFactory->Clear();
2464 SMDS_ElemIteratorPtr itv = elementsIterator();
2467 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2468 SMDSAbs_ElementType aType = elem->GetType();
2471 case SMDSAbs_0DElement:
2475 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2478 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2480 case SMDSAbs_Volume:
2481 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2488 myCellIdVtkToSmds.clear();
2489 //myCellIdSmdsToVtk.clear();
2491 SMDS_NodeIteratorPtr itn = nodesIterator();
2494 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2495 node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2496 myNodePool->destroy(node);
2500 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2501 while(itc!=myChildren.end())
2511 myGrid->Initialize();
2513 vtkPoints* points = vtkPoints::New();
2514 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2515 // using double type for storing coordinates of nodes instead float.
2516 points->SetDataType(VTK_DOUBLE);
2517 points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2518 myGrid->SetPoints( points );
2520 myGrid->BuildLinks();
2523 ///////////////////////////////////////////////////////////////////////////////
2524 /// Return true if this mesh create faces with edges.
2525 /// A false returned value mean that faces are created with nodes. A concequence
2526 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2527 ///////////////////////////////////////////////////////////////////////////////
2528 bool SMDS_Mesh::hasConstructionEdges()
2530 return myHasConstructionEdges;
2533 ///////////////////////////////////////////////////////////////////////////////
2534 /// Return true if this mesh create volumes with faces
2535 /// A false returned value mean that volumes are created with nodes or edges.
2536 /// (see hasConstructionEdges)
2537 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2539 ///////////////////////////////////////////////////////////////////////////////
2540 bool SMDS_Mesh::hasConstructionFaces()
2542 return myHasConstructionFaces;
2545 ///////////////////////////////////////////////////////////////////////////////
2546 /// Return true if nodes are linked to the finit elements, they are belonging to.
2547 /// Currently, It always return true.
2548 ///////////////////////////////////////////////////////////////////////////////
2549 bool SMDS_Mesh::hasInverseElements()
2551 return myHasInverseElements;
2554 ///////////////////////////////////////////////////////////////////////////////
2555 /// Make this mesh creating construction edges (see hasConstructionEdges)
2556 /// @param b true to have construction edges, else false.
2557 ///////////////////////////////////////////////////////////////////////////////
2558 void SMDS_Mesh::setConstructionEdges(bool b)
2560 myHasConstructionEdges=b;
2563 ///////////////////////////////////////////////////////////////////////////////
2564 /// Make this mesh creating construction faces (see hasConstructionFaces)
2565 /// @param b true to have construction faces, else false.
2566 ///////////////////////////////////////////////////////////////////////////////
2567 void SMDS_Mesh::setConstructionFaces(bool b)
2569 myHasConstructionFaces=b;
2572 ///////////////////////////////////////////////////////////////////////////////
2573 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2574 /// @param b true to link nodes to elements, else false.
2575 ///////////////////////////////////////////////////////////////////////////////
2576 void SMDS_Mesh::setInverseElements(bool b)
2578 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2579 myHasInverseElements=b;
2584 ///////////////////////////////////////////////////////////////////////////////
2585 ///Iterator on NCollection_Map
2586 ///////////////////////////////////////////////////////////////////////////////
2587 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2588 struct MYNode_Map_Iterator: public FATHER
2592 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2599 while (_ctr < _map.size())
2610 ELEM current = _map[_ctr];
2616 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2617 struct MYElem_Map_Iterator: public FATHER
2622 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2626 while (_ctr < _map.size()) // go to the first valid element
2629 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2637 while (_ctr < _map.size())
2640 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2649 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2655 //================================================================================
2657 * \brief Iterator on elements in id increasing order
2659 //================================================================================
2661 template <typename ELEM=const SMDS_MeshElement*>
2662 class IdSortedIterator : public SMDS_Iterator<ELEM>
2664 const SMDS_MeshElementIDFactory& myIDFact;
2665 int myID, myMaxID, myNbFound, myTotalNb;
2666 SMDSAbs_ElementType myType;
2670 IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2671 const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
2674 myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2686 ELEM current = myElem;
2688 for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2689 if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2690 && myElem->GetType() != myType )
2693 myNbFound += bool(myElem);
2700 ///////////////////////////////////////////////////////////////////////////////
2701 /// Return an iterator on nodes of the current mesh factory
2702 ///////////////////////////////////////////////////////////////////////////////
2704 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2706 typedef MYNode_Map_Iterator
2707 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2708 return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2710 // typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2711 // return ( idInceasingOrder ?
2712 // SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2713 // SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2716 ///////////////////////////////////////////////////////////////////////////////
2717 ///Return an iterator on 0D elements of the current mesh.
2718 ///////////////////////////////////////////////////////////////////////////////
2720 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2722 typedef MYElem_Map_Iterator
2723 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2724 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2726 // typedef MYNCollection_Map_Iterator
2727 // < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2728 // typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator;
2729 // return ( idInceasingOrder ?
2730 // SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2731 // SMDSAbs_0DElement,
2732 // Nb0DElements() )) :
2733 // SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2736 ///////////////////////////////////////////////////////////////////////////////
2737 ///Return an iterator on edges of the current mesh.
2738 ///////////////////////////////////////////////////////////////////////////////
2740 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2742 typedef MYElem_Map_Iterator
2743 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2744 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2746 // typedef MYNCollection_Map_Iterator
2747 // < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2748 // typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator;
2749 // return ( idInceasingOrder ?
2750 // SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2753 // SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2756 ///////////////////////////////////////////////////////////////////////////////
2757 ///Return an iterator on faces of the current mesh.
2758 ///////////////////////////////////////////////////////////////////////////////
2760 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2762 typedef MYElem_Map_Iterator
2763 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2764 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2766 // typedef MYNCollection_Map_Iterator
2767 // < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2768 // typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator;
2769 // return ( idInceasingOrder ?
2770 // SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2773 // SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2776 ///////////////////////////////////////////////////////////////////////////////
2777 ///Return an iterator on volumes of the current mesh.
2778 ///////////////////////////////////////////////////////////////////////////////
2780 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2782 typedef MYElem_Map_Iterator
2783 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2784 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2786 // typedef MYNCollection_Map_Iterator
2787 // < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2788 // typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator;
2789 // return ( idInceasingOrder ?
2790 // SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2793 // SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2796 ///////////////////////////////////////////////////////////////////////////////
2797 /// Return an iterator on elements of the current mesh factory
2798 ///////////////////////////////////////////////////////////////////////////////
2799 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2803 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2805 case SMDSAbs_Volume:
2806 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2808 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2810 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2811 case SMDSAbs_0DElement:
2812 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2814 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2815 //return myNodeIDFactory->elementsIterator();
2818 return myElementIDFactory->elementsIterator();
2821 ///////////////////////////////////////////////////////////////////////////////
2822 /// Do intersection of sets (more than 2)
2823 ///////////////////////////////////////////////////////////////////////////////
2824 static set<const SMDS_MeshElement*> * intersectionOfSets(
2825 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2827 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2828 set<const SMDS_MeshElement*>* rsetB;
2830 for(int i=0; i<numberOfSets-1; i++)
2832 rsetB=new set<const SMDS_MeshElement*>();
2834 rsetA->begin(), rsetA->end(),
2835 vs[i+1].begin(), vs[i+1].end(),
2836 inserter(*rsetB, rsetB->begin()));
2843 ///////////////////////////////////////////////////////////////////////////////
2844 /// Return the list of finite elements owning the given element: elements
2845 /// containing all the nodes of the given element, for instance faces and
2846 /// volumes containing a given edge.
2847 ///////////////////////////////////////////////////////////////////////////////
2848 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2850 int numberOfSets=element->NbNodes();
2851 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2853 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2856 while(itNodes->more())
2858 const SMDS_MeshElement* node = itNodes->next();
2860 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2861 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2863 //initSet[i]=set<const SMDS_MeshElement*>();
2866 const SMDS_MeshElement* elem = itFe->next();
2868 initSet[i].insert(elem);
2874 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2875 // MESSAGE("nb elems " << i << " intersection " << retSet->size());
2880 ///////////////////////////////////////////////////////////////////////////////
2881 /// Return the list of nodes used only by the given elements
2882 ///////////////////////////////////////////////////////////////////////////////
2883 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2884 set<const SMDS_MeshElement*>& elements)
2886 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2887 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2889 while(itElements!=elements.end())
2891 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2894 while(itNodes->more())
2896 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2897 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2898 set<const SMDS_MeshElement*> s;
2900 s.insert(itFe->next());
2901 if(s==elements) toReturn->insert(n);
2907 ///////////////////////////////////////////////////////////////////////////////
2908 ///Find the children of an element that are made of given nodes
2909 ///@param setOfChildren The set in which matching children will be inserted
2910 ///@param element The element were to search matching children
2911 ///@param nodes The nodes that the children must have to be selected
2912 ///////////////////////////////////////////////////////////////////////////////
2913 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2914 const SMDS_MeshElement * element,
2915 set<const SMDS_MeshElement*>& nodes)
2917 switch(element->GetType())
2920 MESSAGE("Internal Error: This should not happen");
2922 case SMDSAbs_0DElement:
2928 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2931 const SMDS_MeshElement * e=itn->next();
2932 if(nodes.find(e)!=nodes.end())
2934 setOfChildren.insert(element);
2941 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2944 const SMDS_MeshElement * e=itn->next();
2945 if(nodes.find(e)!=nodes.end())
2947 setOfChildren.insert(element);
2951 if(hasConstructionEdges())
2953 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2955 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2958 case SMDSAbs_Volume:
2960 if(hasConstructionFaces())
2962 SMDS_ElemIteratorPtr ite=element->facesIterator();
2964 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2966 else if(hasConstructionEdges())
2968 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2970 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2976 ///////////////////////////////////////////////////////////////////////////////
2977 ///@param elem The element to delete
2978 ///@param removenodes if true remaining nodes will be removed
2979 ///////////////////////////////////////////////////////////////////////////////
2980 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2981 const bool removenodes)
2983 list<const SMDS_MeshElement *> removedElems;
2984 list<const SMDS_MeshElement *> removedNodes;
2985 RemoveElement( elem, removedElems, removedNodes, removenodes );
2988 ///////////////////////////////////////////////////////////////////////////////
2989 ///@param elem The element to delete
2990 ///@param removedElems to be filled with all removed elements
2991 ///@param removedNodes to be filled with all removed nodes
2992 ///@param removenodes if true remaining nodes will be removed
2993 ///////////////////////////////////////////////////////////////////////////////
2994 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2995 list<const SMDS_MeshElement *>& removedElems,
2996 list<const SMDS_MeshElement *>& removedNodes,
2999 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
3000 // get finite elements built on elem
3001 set<const SMDS_MeshElement*> * s1;
3002 if ( (elem->GetType() == SMDSAbs_0DElement)
3003 || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3004 || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3005 || (elem->GetType() == SMDSAbs_Volume) )
3007 s1 = new set<const SMDS_MeshElement*> ();
3011 s1 = getFinitElements(elem);
3013 // get exclusive nodes (which would become free afterwards)
3014 set<const SMDS_MeshElement*> * s2;
3015 if (elem->GetType() == SMDSAbs_Node) // a node is removed
3017 // do not remove nodes except elem
3018 s2 = new set<const SMDS_MeshElement*> ();
3023 s2 = getExclusiveNodes(*s1);
3025 // form the set of finite and construction elements to remove
3026 set<const SMDS_MeshElement*> s3;
3027 set<const SMDS_MeshElement*>::iterator it = s1->begin();
3028 while (it != s1->end())
3030 addChildrenWithNodes(s3, *it, *s2);
3034 if (elem->GetType() != SMDSAbs_Node)
3037 // remove finite and construction elements
3039 while (it != s3.end())
3041 // Remove element from <InverseElements> of its nodes
3042 SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3045 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3046 n->RemoveInverseElement((*it));
3048 int IdToRemove = (*it)->GetID();
3049 int vtkid = (*it)->getVtkId();
3050 //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3051 // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3052 switch ((*it)->GetType())
3055 MYASSERT("Internal Error: This should not happen")
3058 case SMDSAbs_0DElement:
3059 if (IdToRemove >= 0)
3061 myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3064 removedElems.push_back((*it));
3065 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3069 if (IdToRemove >= 0)
3071 myCells[IdToRemove] = 0;
3072 myInfo.RemoveEdge(*it);
3074 removedElems.push_back((*it));
3075 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3076 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3077 myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3082 if (IdToRemove >= 0)
3084 myCells[IdToRemove] = 0;
3085 myInfo.RemoveFace(*it);
3087 removedElems.push_back((*it));
3088 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3089 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3090 myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3094 case SMDSAbs_Volume:
3095 if (IdToRemove >= 0)
3097 myCells[IdToRemove] = 0;
3098 myInfo.RemoveVolume(*it);
3100 removedElems.push_back((*it));
3101 myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3102 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3103 myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3110 //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3111 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3116 // remove exclusive (free) nodes
3120 while (it != s2->end())
3122 int IdToRemove = (*it)->GetID();
3123 //MESSAGE( "SMDS: RM node " << IdToRemove);
3124 if (IdToRemove >= 0)
3126 myNodes[IdToRemove] = 0;
3129 myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3130 removedNodes.push_back((*it));
3131 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3133 ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3134 myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3147 ///////////////////////////////////////////////////////////////////////////////
3148 ///@param elem The element to delete
3149 ///////////////////////////////////////////////////////////////////////////////
3150 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3152 int elemId = elem->GetID();
3153 int vtkId = elem->getVtkId();
3154 //MESSAGE("RemoveFreeElement " << elemId);
3155 SMDSAbs_ElementType aType = elem->GetType();
3156 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3157 if (aType == SMDSAbs_Node) {
3158 //MESSAGE("Remove free node " << elemId);
3159 // only free node can be removed by this method
3160 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3161 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3162 if (!itFe->more()) { // free node
3163 myNodes[elemId] = 0;
3165 ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3166 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3167 myNodeIDFactory->ReleaseID(elemId, vtkId);
3170 if (hasConstructionEdges() || hasConstructionFaces())
3171 // this methods is only for meshes without descendants
3174 //MESSAGE("Remove free element " << elemId);
3175 // Remove element from <InverseElements> of its nodes
3176 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3177 while (itn->more()) {
3178 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3179 (const_cast<SMDS_MeshElement *>(itn->next()));
3180 n->RemoveInverseElement(elem);
3183 // in meshes without descendants elements are always free
3185 case SMDSAbs_0DElement:
3186 myCells[elemId] = 0;
3187 myInfo.remove(elem);
3191 myCells[elemId] = 0;
3192 myInfo.RemoveEdge(elem);
3193 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3196 myCells[elemId] = 0;
3197 myInfo.RemoveFace(elem);
3198 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3200 case SMDSAbs_Volume:
3201 myCells[elemId] = 0;
3202 myInfo.RemoveVolume(elem);
3203 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3208 myElementIDFactory->ReleaseID(elemId, vtkId);
3210 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3211 // --- to do: keep vtkid in a list of reusable cells
3216 * Checks if the element is present in mesh.
3217 * Useful to determine dead pointers.
3219 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3221 // we should not imply on validity of *elem, so iterate on containers
3222 // of all types in the hope of finding <elem> somewhere there
3223 SMDS_NodeIteratorPtr itn = nodesIterator();
3225 if (elem == itn->next())
3227 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3228 while (it0d->more())
3229 if (elem == it0d->next())
3231 SMDS_EdgeIteratorPtr ite = edgesIterator();
3233 if (elem == ite->next())
3235 SMDS_FaceIteratorPtr itf = facesIterator();
3237 if (elem == itf->next())
3239 SMDS_VolumeIteratorPtr itv = volumesIterator();
3241 if (elem == itv->next())
3246 //=======================================================================
3247 //function : MaxNodeID
3249 //=======================================================================
3251 int SMDS_Mesh::MaxNodeID() const
3256 //=======================================================================
3257 //function : MinNodeID
3259 //=======================================================================
3261 int SMDS_Mesh::MinNodeID() const
3266 //=======================================================================
3267 //function : MaxElementID
3269 //=======================================================================
3271 int SMDS_Mesh::MaxElementID() const
3273 return myElementIDFactory->GetMaxID();
3276 //=======================================================================
3277 //function : MinElementID
3279 //=======================================================================
3281 int SMDS_Mesh::MinElementID() const
3283 return myElementIDFactory->GetMinID();
3286 //=======================================================================
3287 //function : Renumber
3288 //purpose : Renumber all nodes or elements.
3289 //=======================================================================
3291 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3293 MESSAGE("Renumber");
3297 SMDS_MeshNodeIDFactory * idFactory =
3298 isNodes ? myNodeIDFactory : myElementIDFactory;
3300 // get existing elements in the order of ID increasing
3301 map<int,SMDS_MeshElement*> elemMap;
3302 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3303 while ( idElemIt->more() ) {
3304 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3305 int id = elem->GetID();
3306 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3308 // release their ids
3309 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3311 // for ( ; elemIt != elemMap.end(); elemIt++ )
3313 // int id = (*elemIt).first;
3314 // idFactory->ReleaseID( id );
3318 elemIt = elemMap.begin();
3319 for ( ; elemIt != elemMap.end(); elemIt++ )
3321 idFactory->BindID( ID, (*elemIt).second );
3326 //=======================================================================
3327 //function : GetElementType
3328 //purpose : Return type of element or node with id
3329 //=======================================================================
3331 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3333 SMDS_MeshElement* elem = 0;
3335 elem = myElementIDFactory->MeshElement( id );
3337 elem = myNodeIDFactory->MeshElement( id );
3341 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3345 return elem->GetType();
3350 //********************************************************************
3351 //********************************************************************
3352 //******** *********
3353 //***** Methods for addition of quadratic elements ******
3354 //******** *********
3355 //********************************************************************
3356 //********************************************************************
3358 //=======================================================================
3359 //function : AddEdgeWithID
3361 //=======================================================================
3362 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3364 return SMDS_Mesh::AddEdgeWithID
3365 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3366 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3367 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3371 //=======================================================================
3372 //function : AddEdge
3374 //=======================================================================
3375 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3376 const SMDS_MeshNode* n2,
3377 const SMDS_MeshNode* n12)
3379 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3382 //=======================================================================
3383 //function : AddEdgeWithID
3385 //=======================================================================
3386 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3387 const SMDS_MeshNode * n2,
3388 const SMDS_MeshNode * n12,
3391 if ( !n1 || !n2 || !n12 ) return 0;
3393 // --- retrieve nodes ID
3394 vector<vtkIdType> nodeIds;
3396 nodeIds.push_back(n1->getVtkId());
3397 nodeIds.push_back(n2->getVtkId());
3398 nodeIds.push_back(n12->getVtkId());
3400 SMDS_MeshEdge * edge = 0;
3401 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3402 edgevtk->init(nodeIds, this);
3403 if (!this->registerElement(ID,edgevtk))
3405 this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3406 myEdgePool->destroy(edgevtk);
3410 adjustmyCellsCapacity(ID);
3412 myInfo.myNbQuadEdges++;
3414 // if (!registerElement(ID, edge)) {
3415 // RemoveElement(edge, false);
3423 //=======================================================================
3424 //function : AddFace
3426 //=======================================================================
3427 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3428 const SMDS_MeshNode * n2,
3429 const SMDS_MeshNode * n3,
3430 const SMDS_MeshNode * n12,
3431 const SMDS_MeshNode * n23,
3432 const SMDS_MeshNode * n31)
3434 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3435 myElementIDFactory->GetFreeID());
3438 //=======================================================================
3439 //function : AddFaceWithID
3441 //=======================================================================
3442 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3443 int n12,int n23,int n31, int ID)
3445 return SMDS_Mesh::AddFaceWithID
3446 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3447 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3448 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3449 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3450 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3451 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3455 //=======================================================================
3456 //function : AddFaceWithID
3458 //=======================================================================
3459 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3460 const SMDS_MeshNode * n2,
3461 const SMDS_MeshNode * n3,
3462 const SMDS_MeshNode * n12,
3463 const SMDS_MeshNode * n23,
3464 const SMDS_MeshNode * n31,
3467 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3468 if(hasConstructionEdges()) {
3469 // creation quadratic edges - not implemented
3474 // --- retrieve nodes ID
3475 vector<vtkIdType> nodeIds;
3477 nodeIds.push_back(n1->getVtkId());
3478 nodeIds.push_back(n2->getVtkId());
3479 nodeIds.push_back(n3->getVtkId());
3480 nodeIds.push_back(n12->getVtkId());
3481 nodeIds.push_back(n23->getVtkId());
3482 nodeIds.push_back(n31->getVtkId());
3484 SMDS_MeshFace * face = 0;
3485 SMDS_VtkFace *facevtk = myFacePool->getNew();
3486 facevtk->init(nodeIds, this);
3487 if (!this->registerElement(ID,facevtk))
3489 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3490 myFacePool->destroy(facevtk);
3494 adjustmyCellsCapacity(ID);
3496 myInfo.myNbQuadTriangles++;
3498 // if (!registerElement(ID, face)) {
3499 // RemoveElement(face, false);
3507 //=======================================================================
3508 //function : AddFace
3510 //=======================================================================
3511 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3512 const SMDS_MeshNode * n2,
3513 const SMDS_MeshNode * n3,
3514 const SMDS_MeshNode * n4,
3515 const SMDS_MeshNode * n12,
3516 const SMDS_MeshNode * n23,
3517 const SMDS_MeshNode * n34,
3518 const SMDS_MeshNode * n41)
3520 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3521 myElementIDFactory->GetFreeID());
3524 //=======================================================================
3525 //function : AddFaceWithID
3527 //=======================================================================
3528 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3529 int n12,int n23,int n34,int n41, int ID)
3531 return SMDS_Mesh::AddFaceWithID
3532 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3533 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3534 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3535 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3536 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3537 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3538 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3539 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3543 //=======================================================================
3544 //function : AddFaceWithID
3546 //=======================================================================
3547 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3548 const SMDS_MeshNode * n2,
3549 const SMDS_MeshNode * n3,
3550 const SMDS_MeshNode * n4,
3551 const SMDS_MeshNode * n12,
3552 const SMDS_MeshNode * n23,
3553 const SMDS_MeshNode * n34,
3554 const SMDS_MeshNode * n41,
3557 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3558 if(hasConstructionEdges()) {
3559 // creation quadratic edges - not implemented
3564 // --- retrieve nodes ID
3565 vector<vtkIdType> nodeIds;
3567 nodeIds.push_back(n1->getVtkId());
3568 nodeIds.push_back(n2->getVtkId());
3569 nodeIds.push_back(n3->getVtkId());
3570 nodeIds.push_back(n4->getVtkId());
3571 nodeIds.push_back(n12->getVtkId());
3572 nodeIds.push_back(n23->getVtkId());
3573 nodeIds.push_back(n34->getVtkId());
3574 nodeIds.push_back(n41->getVtkId());
3576 SMDS_MeshFace * face = 0;
3577 SMDS_VtkFace *facevtk = myFacePool->getNew();
3578 facevtk->init(nodeIds, this);
3579 if (!this->registerElement(ID,facevtk))
3581 this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3582 myFacePool->destroy(facevtk);
3586 adjustmyCellsCapacity(ID);
3588 myInfo.myNbQuadQuadrangles++;
3590 // if (!registerElement(ID, face)) {
3591 // RemoveElement(face, false);
3599 //=======================================================================
3600 //function : AddVolume
3602 //=======================================================================
3603 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3604 const SMDS_MeshNode * n2,
3605 const SMDS_MeshNode * n3,
3606 const SMDS_MeshNode * n4,
3607 const SMDS_MeshNode * n12,
3608 const SMDS_MeshNode * n23,
3609 const SMDS_MeshNode * n31,
3610 const SMDS_MeshNode * n14,
3611 const SMDS_MeshNode * n24,
3612 const SMDS_MeshNode * n34)
3614 int ID = myElementIDFactory->GetFreeID();
3615 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3616 n31, n14, n24, n34, ID);
3617 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3621 //=======================================================================
3622 //function : AddVolumeWithID
3624 //=======================================================================
3625 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3626 int n12,int n23,int n31,
3627 int n14,int n24,int n34, int ID)
3629 return SMDS_Mesh::AddVolumeWithID
3630 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3631 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3632 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3633 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3634 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3635 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3636 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3637 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3638 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3639 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3643 //=======================================================================
3644 //function : AddVolumeWithID
3645 //purpose : 2d order tetrahedron of 10 nodes
3646 //=======================================================================
3647 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3648 const SMDS_MeshNode * n2,
3649 const SMDS_MeshNode * n3,
3650 const SMDS_MeshNode * n4,
3651 const SMDS_MeshNode * n12,
3652 const SMDS_MeshNode * n23,
3653 const SMDS_MeshNode * n31,
3654 const SMDS_MeshNode * n14,
3655 const SMDS_MeshNode * n24,
3656 const SMDS_MeshNode * n34,
3659 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3661 if(hasConstructionFaces()) {
3662 // creation quadratic faces - not implemented
3665 // --- retrieve nodes ID
3666 vector<vtkIdType> nodeIds;
3668 nodeIds.push_back(n1->getVtkId());
3669 nodeIds.push_back(n3->getVtkId());
3670 nodeIds.push_back(n2->getVtkId());
3671 nodeIds.push_back(n4->getVtkId());
3673 nodeIds.push_back(n31->getVtkId());
3674 nodeIds.push_back(n23->getVtkId());
3675 nodeIds.push_back(n12->getVtkId());
3677 nodeIds.push_back(n14->getVtkId());
3678 nodeIds.push_back(n34->getVtkId());
3679 nodeIds.push_back(n24->getVtkId());
3681 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3682 volvtk->init(nodeIds, this);
3683 if (!this->registerElement(ID,volvtk))
3685 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3686 myVolumePool->destroy(volvtk);
3689 adjustmyCellsCapacity(ID);
3690 myCells[ID] = volvtk;
3691 myInfo.myNbQuadTetras++;
3693 // if (!registerElement(ID, volvtk)) {
3694 // RemoveElement(volvtk, false);
3701 //=======================================================================
3702 //function : AddVolume
3704 //=======================================================================
3705 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3706 const SMDS_MeshNode * n2,
3707 const SMDS_MeshNode * n3,
3708 const SMDS_MeshNode * n4,
3709 const SMDS_MeshNode * n5,
3710 const SMDS_MeshNode * n12,
3711 const SMDS_MeshNode * n23,
3712 const SMDS_MeshNode * n34,
3713 const SMDS_MeshNode * n41,
3714 const SMDS_MeshNode * n15,
3715 const SMDS_MeshNode * n25,
3716 const SMDS_MeshNode * n35,
3717 const SMDS_MeshNode * n45)
3719 int ID = myElementIDFactory->GetFreeID();
3720 SMDS_MeshVolume * v =
3721 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3722 n15, n25, n35, n45, ID);
3723 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3727 //=======================================================================
3728 //function : AddVolumeWithID
3730 //=======================================================================
3731 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3732 int n12,int n23,int n34,int n41,
3733 int n15,int n25,int n35,int n45, int ID)
3735 return SMDS_Mesh::AddVolumeWithID
3736 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3737 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3738 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3739 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3740 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3741 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3742 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3743 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3744 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3745 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3746 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3747 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3748 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3752 //=======================================================================
3753 //function : AddVolumeWithID
3754 //purpose : 2d order pyramid of 13 nodes
3755 //=======================================================================
3756 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3757 const SMDS_MeshNode * n2,
3758 const SMDS_MeshNode * n3,
3759 const SMDS_MeshNode * n4,
3760 const SMDS_MeshNode * n5,
3761 const SMDS_MeshNode * n12,
3762 const SMDS_MeshNode * n23,
3763 const SMDS_MeshNode * n34,
3764 const SMDS_MeshNode * n41,
3765 const SMDS_MeshNode * n15,
3766 const SMDS_MeshNode * n25,
3767 const SMDS_MeshNode * n35,
3768 const SMDS_MeshNode * n45,
3771 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3772 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3774 if(hasConstructionFaces()) {
3775 // creation quadratic faces - not implemented
3778 // --- retrieve nodes ID
3779 vector<vtkIdType> nodeIds;
3781 nodeIds.push_back(n1->getVtkId());
3782 nodeIds.push_back(n4->getVtkId());
3783 nodeIds.push_back(n3->getVtkId());
3784 nodeIds.push_back(n2->getVtkId());
3785 nodeIds.push_back(n5->getVtkId());
3787 nodeIds.push_back(n41->getVtkId());
3788 nodeIds.push_back(n34->getVtkId());
3789 nodeIds.push_back(n23->getVtkId());
3790 nodeIds.push_back(n12->getVtkId());
3792 nodeIds.push_back(n15->getVtkId());
3793 nodeIds.push_back(n45->getVtkId());
3794 nodeIds.push_back(n35->getVtkId());
3795 nodeIds.push_back(n25->getVtkId());
3797 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3798 volvtk->init(nodeIds, this);
3799 if (!this->registerElement(ID,volvtk))
3801 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3802 myVolumePool->destroy(volvtk);
3805 adjustmyCellsCapacity(ID);
3806 myCells[ID] = volvtk;
3807 myInfo.myNbQuadPyramids++;
3809 // if (!registerElement(ID, volvtk)) {
3810 // RemoveElement(volvtk, false);
3817 //=======================================================================
3818 //function : AddVolume
3820 //=======================================================================
3821 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3822 const SMDS_MeshNode * n2,
3823 const SMDS_MeshNode * n3,
3824 const SMDS_MeshNode * n4,
3825 const SMDS_MeshNode * n5,
3826 const SMDS_MeshNode * n6,
3827 const SMDS_MeshNode * n12,
3828 const SMDS_MeshNode * n23,
3829 const SMDS_MeshNode * n31,
3830 const SMDS_MeshNode * n45,
3831 const SMDS_MeshNode * n56,
3832 const SMDS_MeshNode * n64,
3833 const SMDS_MeshNode * n14,
3834 const SMDS_MeshNode * n25,
3835 const SMDS_MeshNode * n36)
3837 int ID = myElementIDFactory->GetFreeID();
3838 SMDS_MeshVolume * v =
3839 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3840 n45, n56, n64, n14, n25, n36, ID);
3841 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3845 //=======================================================================
3846 //function : AddVolumeWithID
3848 //=======================================================================
3849 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3850 int n4, int n5, int n6,
3851 int n12,int n23,int n31,
3852 int n45,int n56,int n64,
3853 int n14,int n25,int n36, int ID)
3855 return SMDS_Mesh::AddVolumeWithID
3856 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3857 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3858 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3859 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3860 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3861 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3862 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3863 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3864 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3865 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3866 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3867 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3868 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3869 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3870 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3874 //=======================================================================
3875 //function : AddVolumeWithID
3876 //purpose : 2d order Pentahedron with 15 nodes
3877 //=======================================================================
3878 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3879 const SMDS_MeshNode * n2,
3880 const SMDS_MeshNode * n3,
3881 const SMDS_MeshNode * n4,
3882 const SMDS_MeshNode * n5,
3883 const SMDS_MeshNode * n6,
3884 const SMDS_MeshNode * n12,
3885 const SMDS_MeshNode * n23,
3886 const SMDS_MeshNode * n31,
3887 const SMDS_MeshNode * n45,
3888 const SMDS_MeshNode * n56,
3889 const SMDS_MeshNode * n64,
3890 const SMDS_MeshNode * n14,
3891 const SMDS_MeshNode * n25,
3892 const SMDS_MeshNode * n36,
3895 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3896 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3898 if(hasConstructionFaces()) {
3899 // creation quadratic faces - not implemented
3902 // --- retrieve nodes ID
3903 vector<vtkIdType> nodeIds;
3905 nodeIds.push_back(n1->getVtkId());
3906 nodeIds.push_back(n2->getVtkId());
3907 nodeIds.push_back(n3->getVtkId());
3909 nodeIds.push_back(n4->getVtkId());
3910 nodeIds.push_back(n5->getVtkId());
3911 nodeIds.push_back(n6->getVtkId());
3913 nodeIds.push_back(n12->getVtkId());
3914 nodeIds.push_back(n23->getVtkId());
3915 nodeIds.push_back(n31->getVtkId());
3917 nodeIds.push_back(n45->getVtkId());
3918 nodeIds.push_back(n56->getVtkId());
3919 nodeIds.push_back(n64->getVtkId());
3921 nodeIds.push_back(n14->getVtkId());
3922 nodeIds.push_back(n25->getVtkId());
3923 nodeIds.push_back(n36->getVtkId());
3925 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3926 volvtk->init(nodeIds, this);
3927 if (!this->registerElement(ID,volvtk))
3929 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3930 myVolumePool->destroy(volvtk);
3933 adjustmyCellsCapacity(ID);
3934 myCells[ID] = volvtk;
3935 myInfo.myNbQuadPrisms++;
3937 // if (!registerElement(ID, volvtk)) {
3938 // RemoveElement(volvtk, false);
3945 //=======================================================================
3946 //function : AddVolume
3948 //=======================================================================
3949 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3950 const SMDS_MeshNode * n2,
3951 const SMDS_MeshNode * n3,
3952 const SMDS_MeshNode * n4,
3953 const SMDS_MeshNode * n5,
3954 const SMDS_MeshNode * n6,
3955 const SMDS_MeshNode * n7,
3956 const SMDS_MeshNode * n8,
3957 const SMDS_MeshNode * n12,
3958 const SMDS_MeshNode * n23,
3959 const SMDS_MeshNode * n34,
3960 const SMDS_MeshNode * n41,
3961 const SMDS_MeshNode * n56,
3962 const SMDS_MeshNode * n67,
3963 const SMDS_MeshNode * n78,
3964 const SMDS_MeshNode * n85,
3965 const SMDS_MeshNode * n15,
3966 const SMDS_MeshNode * n26,
3967 const SMDS_MeshNode * n37,
3968 const SMDS_MeshNode * n48)
3970 int ID = myElementIDFactory->GetFreeID();
3971 SMDS_MeshVolume * v =
3972 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3973 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3974 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3978 //=======================================================================
3979 //function : AddVolumeWithID
3981 //=======================================================================
3982 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3983 int n5, int n6, int n7, int n8,
3984 int n12,int n23,int n34,int n41,
3985 int n56,int n67,int n78,int n85,
3986 int n15,int n26,int n37,int n48, int ID)
3988 return SMDS_Mesh::AddVolumeWithID
3989 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3990 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3991 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3992 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3993 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3994 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3995 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3996 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3997 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3998 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3999 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4000 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4001 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4002 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4003 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4004 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4005 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4006 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4007 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4008 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4012 //=======================================================================
4013 //function : AddVolumeWithID
4014 //purpose : 2d order Hexahedrons with 20 nodes
4015 //=======================================================================
4016 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4017 const SMDS_MeshNode * n2,
4018 const SMDS_MeshNode * n3,
4019 const SMDS_MeshNode * n4,
4020 const SMDS_MeshNode * n5,
4021 const SMDS_MeshNode * n6,
4022 const SMDS_MeshNode * n7,
4023 const SMDS_MeshNode * n8,
4024 const SMDS_MeshNode * n12,
4025 const SMDS_MeshNode * n23,
4026 const SMDS_MeshNode * n34,
4027 const SMDS_MeshNode * n41,
4028 const SMDS_MeshNode * n56,
4029 const SMDS_MeshNode * n67,
4030 const SMDS_MeshNode * n78,
4031 const SMDS_MeshNode * n85,
4032 const SMDS_MeshNode * n15,
4033 const SMDS_MeshNode * n26,
4034 const SMDS_MeshNode * n37,
4035 const SMDS_MeshNode * n48,
4038 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4039 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4041 if(hasConstructionFaces()) {
4043 // creation quadratic faces - not implemented
4045 // --- retrieve nodes ID
4046 vector<vtkIdType> nodeIds;
4048 nodeIds.push_back(n1->getVtkId());
4049 nodeIds.push_back(n4->getVtkId());
4050 nodeIds.push_back(n3->getVtkId());
4051 nodeIds.push_back(n2->getVtkId());
4053 nodeIds.push_back(n5->getVtkId());
4054 nodeIds.push_back(n8->getVtkId());
4055 nodeIds.push_back(n7->getVtkId());
4056 nodeIds.push_back(n6->getVtkId());
4058 nodeIds.push_back(n41->getVtkId());
4059 nodeIds.push_back(n34->getVtkId());
4060 nodeIds.push_back(n23->getVtkId());
4061 nodeIds.push_back(n12->getVtkId());
4063 nodeIds.push_back(n85->getVtkId());
4064 nodeIds.push_back(n78->getVtkId());
4065 nodeIds.push_back(n67->getVtkId());
4066 nodeIds.push_back(n56->getVtkId());
4068 nodeIds.push_back(n15->getVtkId());
4069 nodeIds.push_back(n48->getVtkId());
4070 nodeIds.push_back(n37->getVtkId());
4071 nodeIds.push_back(n26->getVtkId());
4073 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4074 volvtk->init(nodeIds, this);
4075 if (!this->registerElement(ID,volvtk))
4077 this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4078 myVolumePool->destroy(volvtk);
4081 adjustmyCellsCapacity(ID);
4082 myCells[ID] = volvtk;
4083 myInfo.myNbQuadHexas++;
4085 // if (!registerElement(ID, volvtk)) {
4086 // RemoveElement(volvtk, false);
4092 void SMDS_Mesh::updateNodeMinMax()
4095 if (myNodes.size() == 0)
4100 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4102 myNodeMax=myNodes.size()-1;
4103 while (!myNodes[myNodeMax] && (myNodeMin>=0))
4107 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4109 // int val = myCellIdSmdsToVtk.size();
4110 // MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4111 // myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4112 int val = myNodes.size();
4113 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4114 myNodes.resize(val +nbNodes, 0);
4117 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4119 int val = myCellIdVtkToSmds.size();
4120 MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4121 myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4122 val = myCells.size();
4123 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4124 myNodes.resize(val +nbCells, 0);
4127 void SMDS_Mesh::adjustStructure()
4129 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4132 void SMDS_Mesh::dumpGrid(string ficdump)
4134 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4135 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4136 // aWriter->SetFileName(ficdump.c_str());
4137 // aWriter->SetInput(myGrid);
4138 // if(myGrid->GetNumberOfCells())
4140 // aWriter->Write();
4142 // aWriter->Delete();
4143 ficdump = ficdump + "_connectivity";
4144 ofstream ficcon(ficdump.c_str(), ios::out);
4145 int nbPoints = myGrid->GetNumberOfPoints();
4146 ficcon << "-------------------------------- points " << nbPoints << endl;
4147 for (int i=0; i<nbPoints; i++)
4149 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4151 int nbCells = myGrid->GetNumberOfCells();
4152 ficcon << "-------------------------------- cells " << nbCells << endl;
4153 for (int i=0; i<nbCells; i++)
4155 // MESSAGE(i << " " << myGrid->GetCell(i));
4156 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
4157 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4158 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4159 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4160 for (int j=0; j<nbptcell; j++)
4162 ficcon << " " << listid->GetId(j);
4166 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
4167 vtkCellLinks *links = myGrid->GetCellLinks();
4168 for (int i=0; i<nbPoints; i++)
4170 int ncells = links->GetNcells(i);
4171 vtkIdType *cells = links->GetCells(i);
4172 ficcon << i << " - " << ncells << " -";
4173 for (int j=0; j<ncells; j++)
4175 ficcon << " " << cells[j];
4183 void SMDS_Mesh::compactMesh()
4185 MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4188 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4190 if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4191 return myCellIdVtkToSmds[vtkid];
4192 throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4195 void SMDS_Mesh::updateBoundingBox()
4200 vtkPoints *points = myGrid->GetPoints();
4201 int myNodesSize = this->myNodes.size();
4202 for (int i = 0; i < myNodesSize; i++)
4204 if (SMDS_MeshNode *n = myNodes[i])
4207 points->GetPoint(n->myVtkID, coords);
4208 if (coords[0] < xmin) xmin = coords[0];
4209 else if (coords[0] > xmax) xmax = coords[0];
4210 if (coords[1] < ymin) ymin = coords[1];
4211 else if (coords[1] > ymax) ymax = coords[1];
4212 if (coords[2] < zmin) zmin = coords[2];
4213 else if (coords[2] > zmax) zmax = coords[2];
4218 double SMDS_Mesh::getMaxDim()
4220 double dmax = 1.e-3;
4221 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4222 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4223 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4224 MESSAGE("getMaxDim " << dmax);
4228 //! modification that needs compact structure and redraw
4229 void SMDS_Mesh::Modified()
4231 if (this->myModified)
4233 this->myModifTime++;
4234 MESSAGE("modified");
4239 //! get last modification timeStamp
4240 unsigned long SMDS_Mesh::GetMTime() const
4242 return this->myModifTime;
4245 bool SMDS_Mesh::isCompacted()
4247 if (this->myModifTime > this->myCompactTime)
4249 MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4250 this->myCompactTime = this->myModifTime;