1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementaion of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "utilities.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_VolumeOfNodes.hxx"
32 #include "SMDS_VolumeOfFaces.hxx"
33 #include "SMDS_FaceOfNodes.hxx"
34 #include "SMDS_FaceOfEdges.hxx"
35 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
36 #include "SMDS_PolygonalFaceOfNodes.hxx"
37 #include "SMDS_QuadraticEdge.hxx"
38 #include "SMDS_QuadraticFaceOfNodes.hxx"
39 #include "SMDS_QuadraticVolumeOfNodes.hxx"
40 #include "SMDS_SpacePosition.hxx"
41 #include "SMDS_UnstructuredGrid.hxx"
43 #include <vtkUnstructuredGrid.h>
44 #include <vtkUnstructuredGridWriter.h>
45 #include <vtkUnsignedCharArray.h>
47 #include <vtkCellLinks.h>
48 #include <vtkIdList.h>
57 #include <sys/sysinfo.h>
60 // number of added entities to check memory after
61 #define CHECKMEMORY_INTERVAL 1000
63 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
64 int SMDS_Mesh::chunkSize = 1024;
67 //================================================================================
69 * \brief Raise an exception if free memory (ram+swap) too low
70 * \param doNotRaise - if true, suppres exception, just return free memory size
71 * \retval int - amount of available memory in MB or negative number in failure case
73 //================================================================================
75 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
79 int err = sysinfo( &si );
83 static int limit = -1;
85 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
87 limit = WEXITSTATUS(status);
92 limit = int( limit * 1.5 );
94 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
98 const unsigned long Mbyte = 1024 * 1024;
99 // compute separately to avoid overflow
101 ( si.freeram * si.mem_unit ) / Mbyte +
102 ( si.freeswap * si.mem_unit ) / Mbyte;
104 if ( freeMb > limit )
105 return freeMb - limit;
110 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
112 throw std::bad_alloc();
118 ///////////////////////////////////////////////////////////////////////////////
119 /// Create a new mesh object
120 ///////////////////////////////////////////////////////////////////////////////
121 SMDS_Mesh::SMDS_Mesh()
123 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
124 myElementIDFactory(new SMDS_MeshElementIDFactory()),
125 myHasConstructionEdges(false), myHasConstructionFaces(false),
126 myHasInverseElements(true),
127 myNodeMin(0), myNodeMax(0),
128 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
130 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
131 MESSAGE("myMeshId=" << myMeshId);
132 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
133 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
134 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
135 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
136 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
137 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
138 myNodeIDFactory->SetMesh(this);
139 myElementIDFactory->SetMesh(this);
140 _meshList.push_back(this);
141 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
142 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
143 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
144 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
148 myIDElements.clear();
150 myGrid = SMDS_UnstructuredGrid::New();
151 myGrid->Initialize();
153 vtkPoints* points = vtkPoints::New();
154 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
155 myGrid->SetPoints( points );
157 myGrid->BuildLinks();
160 ///////////////////////////////////////////////////////////////////////////////
161 /// Create a new child mesh
162 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
163 /// (2003-09-08) of SMESH
164 ///////////////////////////////////////////////////////////////////////////////
165 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
166 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
167 myElementIDFactory(parent->myElementIDFactory),
168 myHasConstructionEdges(false), myHasConstructionFaces(false),
169 myHasInverseElements(true),
170 myNodePool(parent->myNodePool),
171 myEdgePool(parent->myEdgePool),
172 myFacePool(parent->myFacePool),
173 myVolumePool(parent->myVolumePool)
177 ///////////////////////////////////////////////////////////////////////////////
178 ///Create a submesh and add it to the current mesh
179 ///////////////////////////////////////////////////////////////////////////////
181 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
183 SMDS_Mesh *submesh = new SMDS_Mesh(this);
184 myChildren.insert(myChildren.end(), submesh);
188 ///////////////////////////////////////////////////////////////////////////////
189 ///create a MeshNode and add it to the current Mesh
190 ///An ID is automatically assigned to the node.
191 ///@return : The created node
192 ///////////////////////////////////////////////////////////////////////////////
194 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
196 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
199 ///////////////////////////////////////////////////////////////////////////////
200 ///create a MeshNode and add it to the current Mesh
201 ///@param ID : The ID of the MeshNode to create
202 ///@return : The created node or NULL if a node with this ID already exists
203 ///////////////////////////////////////////////////////////////////////////////
204 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
206 // find the MeshNode corresponding to ID
207 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
209 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
210 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
211 SMDS_MeshNode * node = myNodePool->getNew();
212 node->init(ID, myMeshId, -1, x, y, z);
213 if (ID >= myNodes.size())
215 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
216 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
219 myNodeIDFactory->BindID(ID,node);
226 ///////////////////////////////////////////////////////////////////////////////
227 /// create a Mesh0DElement and add it to the current Mesh
228 /// @return : The created Mesh0DElement
229 ///////////////////////////////////////////////////////////////////////////////
230 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
232 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
233 if (!node) return NULL;
234 return SMDS_Mesh::Add0DElementWithID(node, ID);
237 ///////////////////////////////////////////////////////////////////////////////
238 /// create a Mesh0DElement and add it to the current Mesh
239 /// @return : The created Mesh0DElement
240 ///////////////////////////////////////////////////////////////////////////////
241 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
243 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
246 ///////////////////////////////////////////////////////////////////////////////
247 /// Create a new Mesh0DElement and at it to the mesh
248 /// @param idnode ID of the node
249 /// @param ID ID of the 0D element to create
250 /// @return The created 0D element or NULL if an element with this
251 /// ID already exists or if input node is not found.
252 ///////////////////////////////////////////////////////////////////////////////
253 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
257 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
258 //MESSAGE("Add0DElementWithID" << ID)
259 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
260 if (myElementIDFactory->BindID(ID, el0d)) {
261 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
262 //node->AddInverseElement(el0d);// --- fait avec BindID
263 adjustmyCellsCapacity(ID);
265 myInfo.myNb0DElements++;
273 ///////////////////////////////////////////////////////////////////////////////
274 /// create a MeshEdge and add it to the current Mesh
275 /// @return : The created MeshEdge
276 ///////////////////////////////////////////////////////////////////////////////
278 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
280 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
281 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
282 if(!node1 || !node2) return NULL;
283 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
286 ///////////////////////////////////////////////////////////////////////////////
287 /// create a MeshEdge and add it to the current Mesh
288 /// @return : The created MeshEdge
289 ///////////////////////////////////////////////////////////////////////////////
291 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
292 const SMDS_MeshNode * node2)
294 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
297 ///////////////////////////////////////////////////////////////////////////////
298 /// Create a new edge and at it to the mesh
299 /// @param idnode1 ID of the first node
300 /// @param idnode2 ID of the second node
301 /// @param ID ID of the edge to create
302 /// @return The created edge or NULL if an element with this ID already exists or
303 /// if input nodes are not found.
304 ///////////////////////////////////////////////////////////////////////////////
306 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
307 const SMDS_MeshNode * n2,
310 if ( !n1 || !n2 ) return 0;
311 SMDS_MeshEdge * edge = 0;
313 // --- retreive nodes ID
314 vector<vtkIdType> nodeIds;
316 nodeIds.push_back(n1->getId());
317 nodeIds.push_back(n2->getId());
319 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
320 edgevtk->init(nodeIds, this);
322 adjustmyCellsCapacity(ID);
326 if (edge && !registerElement(ID, edge))
328 RemoveElement(edge, false);
334 ///////////////////////////////////////////////////////////////////////////////
335 /// Add a triangle defined by its nodes. An ID is automatically affected to the
337 ///////////////////////////////////////////////////////////////////////////////
339 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
340 const SMDS_MeshNode * n2,
341 const SMDS_MeshNode * n3)
343 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
346 ///////////////////////////////////////////////////////////////////////////////
347 /// Add a triangle defined by its nodes IDs
348 ///////////////////////////////////////////////////////////////////////////////
350 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
352 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
353 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
354 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
355 if(!node1 || !node2 || !node3) return NULL;
356 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
359 ///////////////////////////////////////////////////////////////////////////////
360 /// Add a triangle defined by its nodes
361 ///////////////////////////////////////////////////////////////////////////////
363 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
364 const SMDS_MeshNode * n2,
365 const SMDS_MeshNode * n3,
368 //MESSAGE("AddFaceWithID " << ID)
369 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
371 if (face && !registerElement(ID, face)) {
372 RemoveElement(face, false);
378 ///////////////////////////////////////////////////////////////////////////////
379 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
381 ///////////////////////////////////////////////////////////////////////////////
383 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
384 const SMDS_MeshNode * n2,
385 const SMDS_MeshNode * n3,
386 const SMDS_MeshNode * n4)
388 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
391 ///////////////////////////////////////////////////////////////////////////////
392 /// Add a quadrangle defined by its nodes IDs
393 ///////////////////////////////////////////////////////////////////////////////
395 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
401 SMDS_MeshNode *node1, *node2, *node3, *node4;
402 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
403 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
404 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
405 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
406 if(!node1 || !node2 || !node3 || !node4) return NULL;
407 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
410 ///////////////////////////////////////////////////////////////////////////////
411 /// Add a quadrangle defined by its nodes
412 ///////////////////////////////////////////////////////////////////////////////
414 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
415 const SMDS_MeshNode * n2,
416 const SMDS_MeshNode * n3,
417 const SMDS_MeshNode * n4,
420 //MESSAGE("AddFaceWithID " << ID);
421 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
423 if (face && !registerElement(ID, face)) {
424 RemoveElement(face, false);
430 ///////////////////////////////////////////////////////////////////////////////
431 /// Add a triangle defined by its edges. An ID is automatically assigned to the
433 ///////////////////////////////////////////////////////////////////////////////
435 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
436 const SMDS_MeshEdge * e2,
437 const SMDS_MeshEdge * e3)
439 if (!hasConstructionEdges())
441 //MESSAGE("AddFaceWithID");
442 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
445 ///////////////////////////////////////////////////////////////////////////////
446 /// Add a triangle defined by its edges
447 ///////////////////////////////////////////////////////////////////////////////
449 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
450 const SMDS_MeshEdge * e2,
451 const SMDS_MeshEdge * e3,
454 if (!hasConstructionEdges())
456 if ( !e1 || !e2 || !e3 ) return 0;
458 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
459 //MESSAGE("AddFaceWithID" << ID);
461 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
462 adjustmyCellsCapacity(ID);
464 myInfo.myNbTriangles++;
466 if (!registerElement(ID, face)) {
467 RemoveElement(face, false);
473 ///////////////////////////////////////////////////////////////////////////////
474 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
476 ///////////////////////////////////////////////////////////////////////////////
478 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
479 const SMDS_MeshEdge * e2,
480 const SMDS_MeshEdge * e3,
481 const SMDS_MeshEdge * e4)
483 if (!hasConstructionEdges())
485 //MESSAGE("AddFaceWithID" );
486 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
489 ///////////////////////////////////////////////////////////////////////////////
490 /// Add a quadrangle defined by its edges
491 ///////////////////////////////////////////////////////////////////////////////
493 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
494 const SMDS_MeshEdge * e2,
495 const SMDS_MeshEdge * e3,
496 const SMDS_MeshEdge * e4,
499 if (!hasConstructionEdges())
501 //MESSAGE("AddFaceWithID" << ID);
502 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
503 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
504 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
505 adjustmyCellsCapacity(ID);
507 myInfo.myNbQuadrangles++;
509 if (!registerElement(ID, face))
511 RemoveElement(face, false);
517 ///////////////////////////////////////////////////////////////////////////////
518 ///Create a new tetrahedron and add it to the mesh.
519 ///@return The created tetrahedron
520 ///////////////////////////////////////////////////////////////////////////////
522 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
523 const SMDS_MeshNode * n2,
524 const SMDS_MeshNode * n3,
525 const SMDS_MeshNode * n4)
527 int ID = myElementIDFactory->GetFreeID();
528 //MESSAGE("AddVolumeWithID " << ID);
529 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
530 if(v==NULL) myElementIDFactory->ReleaseID(ID);
534 ///////////////////////////////////////////////////////////////////////////////
535 ///Create a new tetrahedron and add it to the mesh.
536 ///@param ID The ID of the new volume
537 ///@return The created tetrahedron or NULL if an element with this ID already exists
538 ///or if input nodes are not found.
539 ///////////////////////////////////////////////////////////////////////////////
541 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
547 //MESSAGE("AddVolumeWithID" << ID);
548 SMDS_MeshNode *node1, *node2, *node3, *node4;
549 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
550 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
551 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
552 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
553 if(!node1 || !node2 || !node3 || !node4) return NULL;
554 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
557 ///////////////////////////////////////////////////////////////////////////////
558 ///Create a new tetrahedron and add it to the mesh.
559 ///@param ID The ID of the new volume
560 ///@return The created tetrahedron
561 ///////////////////////////////////////////////////////////////////////////////
563 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
564 const SMDS_MeshNode * n2,
565 const SMDS_MeshNode * n3,
566 const SMDS_MeshNode * n4,
569 //MESSAGE("AddVolumeWithID " << ID);
570 SMDS_MeshVolume* volume = 0;
571 if ( !n1 || !n2 || !n3 || !n4) return volume;
572 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
573 if(hasConstructionFaces()) {
574 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
575 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
576 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
577 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
578 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
579 adjustmyCellsCapacity(ID);
580 myCells[ID] = volume;
583 else if(hasConstructionEdges()) {
584 MESSAGE("Error : Not implemented");
588 // --- retrieve nodes ID
589 vector<vtkIdType> nodeIds;
591 nodeIds.push_back(n1->getId());
592 nodeIds.push_back(n3->getId()); // order SMDS-->VTK
593 nodeIds.push_back(n2->getId());
594 nodeIds.push_back(n4->getId());
596 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
597 volvtk->init(nodeIds, this);
599 adjustmyCellsCapacity(ID);
600 myCells[ID] = volume;
604 if (!registerElement(ID, volume)) {
605 RemoveElement(volume, false);
611 ///////////////////////////////////////////////////////////////////////////////
612 ///Create a new pyramid and add it to the mesh.
613 ///Nodes 1,2,3 and 4 define the base of the pyramid
614 ///@return The created pyramid
615 ///////////////////////////////////////////////////////////////////////////////
617 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
618 const SMDS_MeshNode * n2,
619 const SMDS_MeshNode * n3,
620 const SMDS_MeshNode * n4,
621 const SMDS_MeshNode * n5)
623 int ID = myElementIDFactory->GetFreeID();
624 //MESSAGE("AddVolumeWithID " << ID);
625 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
626 if(v==NULL) myElementIDFactory->ReleaseID(ID);
630 ///////////////////////////////////////////////////////////////////////////////
631 ///Create a new pyramid and add it to the mesh.
632 ///Nodes 1,2,3 and 4 define the base of the pyramid
633 ///@param ID The ID of the new volume
634 ///@return The created pyramid or NULL if an element with this ID already exists
635 ///or if input nodes are not found.
636 ///////////////////////////////////////////////////////////////////////////////
638 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
645 //MESSAGE("AddVolumeWithID " << ID);
646 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
647 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
648 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
649 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
650 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
651 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
652 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
653 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
656 ///////////////////////////////////////////////////////////////////////////////
657 ///Create a new pyramid and add it to the mesh.
658 ///Nodes 1,2,3 and 4 define the base of the pyramid
659 ///@param ID The ID of the new volume
660 ///@return The created pyramid
661 ///////////////////////////////////////////////////////////////////////////////
663 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
664 const SMDS_MeshNode * n2,
665 const SMDS_MeshNode * n3,
666 const SMDS_MeshNode * n4,
667 const SMDS_MeshNode * n5,
670 //MESSAGE("AddVolumeWithID " << ID);
671 SMDS_MeshVolume* volume = 0;
672 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
673 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
674 if(hasConstructionFaces()) {
675 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
676 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
677 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
678 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
679 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
680 adjustmyCellsCapacity(ID);
681 myCells[ID] = volume;
682 myInfo.myNbPyramids++;
684 else if(hasConstructionEdges()) {
685 MESSAGE("Error : Not implemented");
689 // --- retrieve nodes ID
690 vector<vtkIdType> nodeIds;
692 nodeIds.push_back(n1->getId());
693 nodeIds.push_back(n4->getId());
694 nodeIds.push_back(n3->getId());
695 nodeIds.push_back(n2->getId());
696 nodeIds.push_back(n5->getId());
698 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
699 volvtk->init(nodeIds, this);
701 adjustmyCellsCapacity(ID);
702 myCells[ID] = volume;
703 myInfo.myNbPyramids++;
706 if (!registerElement(ID, volume)) {
707 RemoveElement(volume, false);
713 ///////////////////////////////////////////////////////////////////////////////
714 ///Create a new prism and add it to the mesh.
715 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
716 ///@return The created prism
717 ///////////////////////////////////////////////////////////////////////////////
719 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
720 const SMDS_MeshNode * n2,
721 const SMDS_MeshNode * n3,
722 const SMDS_MeshNode * n4,
723 const SMDS_MeshNode * n5,
724 const SMDS_MeshNode * n6)
726 int ID = myElementIDFactory->GetFreeID();
727 //MESSAGE("AddVolumeWithID " << ID);
728 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
729 if(v==NULL) myElementIDFactory->ReleaseID(ID);
733 ///////////////////////////////////////////////////////////////////////////////
734 ///Create a new prism and add it to the mesh.
735 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
736 ///@param ID The ID of the new volume
737 ///@return The created prism or NULL if an element with this ID already exists
738 ///or if input nodes are not found.
739 ///////////////////////////////////////////////////////////////////////////////
741 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
749 //MESSAGE("AddVolumeWithID " << ID);
750 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
751 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
752 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
753 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
754 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
755 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
756 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
757 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
758 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
761 ///////////////////////////////////////////////////////////////////////////////
762 ///Create a new prism and add it to the mesh.
763 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
764 ///@param ID The ID of the new volume
765 ///@return The created prism
766 ///////////////////////////////////////////////////////////////////////////////
768 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
769 const SMDS_MeshNode * n2,
770 const SMDS_MeshNode * n3,
771 const SMDS_MeshNode * n4,
772 const SMDS_MeshNode * n5,
773 const SMDS_MeshNode * n6,
776 //MESSAGE("AddVolumeWithID " << ID);
777 SMDS_MeshVolume* volume = 0;
778 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
779 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
780 if(hasConstructionFaces()) {
781 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
782 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
783 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
784 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
785 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
786 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
787 adjustmyCellsCapacity(ID);
788 myCells[ID] = volume;
791 else if(hasConstructionEdges()) {
792 MESSAGE("Error : Not implemented");
796 // --- retrieve nodes ID
797 vector<vtkIdType> nodeIds;
799 nodeIds.push_back(n1->getId());
800 nodeIds.push_back(n2->getId());
801 nodeIds.push_back(n3->getId());
802 nodeIds.push_back(n4->getId());
803 nodeIds.push_back(n5->getId());
804 nodeIds.push_back(n6->getId());
806 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
807 volvtk->init(nodeIds, this);
809 adjustmyCellsCapacity(ID);
810 myCells[ID] = volume;
814 if (!registerElement(ID, volume)) {
815 RemoveElement(volume, false);
821 ///////////////////////////////////////////////////////////////////////////////
822 ///Create a new hexahedron and add it to the mesh.
823 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
824 ///@return The created hexahedron
825 ///////////////////////////////////////////////////////////////////////////////
827 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
828 const SMDS_MeshNode * n2,
829 const SMDS_MeshNode * n3,
830 const SMDS_MeshNode * n4,
831 const SMDS_MeshNode * n5,
832 const SMDS_MeshNode * n6,
833 const SMDS_MeshNode * n7,
834 const SMDS_MeshNode * n8)
836 int ID = myElementIDFactory->GetFreeID();
837 //MESSAGE("AddVolumeWithID " << ID);
838 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
839 if(v==NULL) myElementIDFactory->ReleaseID(ID);
843 ///////////////////////////////////////////////////////////////////////////////
844 ///Create a new hexahedron and add it to the mesh.
845 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
846 ///@param ID The ID of the new volume
847 ///@return The created hexahedron or NULL if an element with this ID already
848 ///exists or if input nodes are not found.
849 ///////////////////////////////////////////////////////////////////////////////
851 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
861 //MESSAGE("AddVolumeWithID " << ID);
862 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
863 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
864 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
865 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
866 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
867 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
868 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
869 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
870 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
871 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
873 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
877 ///////////////////////////////////////////////////////////////////////////////
878 ///Create a new hexahedron and add it to the mesh.
879 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
880 ///@param ID The ID of the new volume
881 ///@return The created prism or NULL if an element with this ID already exists
882 ///or if input nodes are not found.
883 ///////////////////////////////////////////////////////////////////////////////
885 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
886 const SMDS_MeshNode * n2,
887 const SMDS_MeshNode * n3,
888 const SMDS_MeshNode * n4,
889 const SMDS_MeshNode * n5,
890 const SMDS_MeshNode * n6,
891 const SMDS_MeshNode * n7,
892 const SMDS_MeshNode * n8,
895 //MESSAGE("AddVolumeWithID " << ID);
896 SMDS_MeshVolume* volume = 0;
897 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
898 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
899 if(hasConstructionFaces()) {
900 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
901 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
902 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
903 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
904 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
905 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
906 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
907 adjustmyCellsCapacity(ID);
908 myCells[ID] = volume;
911 else if(hasConstructionEdges()) {
912 MESSAGE("Error : Not implemented");
916 // --- retrieve nodes ID
917 vector<vtkIdType> nodeIds;
919 nodeIds.push_back(n1->getId());
920 nodeIds.push_back(n4->getId());
921 nodeIds.push_back(n3->getId());
922 nodeIds.push_back(n2->getId());
923 nodeIds.push_back(n5->getId());
924 nodeIds.push_back(n8->getId());
925 nodeIds.push_back(n7->getId());
926 nodeIds.push_back(n6->getId());
928 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
929 volvtk->init(nodeIds, this);
931 adjustmyCellsCapacity(ID);
932 myCells[ID] = volume;
936 if (!registerElement(ID, volume)) {
937 RemoveElement(volume, false);
943 ///////////////////////////////////////////////////////////////////////////////
944 ///Create a new tetrahedron defined by its faces and add it to the mesh.
945 ///@return The created tetrahedron
946 ///////////////////////////////////////////////////////////////////////////////
948 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
949 const SMDS_MeshFace * f2,
950 const SMDS_MeshFace * f3,
951 const SMDS_MeshFace * f4)
953 //MESSAGE("AddVolumeWithID");
954 if (!hasConstructionFaces())
956 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
959 ///////////////////////////////////////////////////////////////////////////////
960 ///Create a new tetrahedron defined by its faces and add it to the mesh.
961 ///@param ID The ID of the new volume
962 ///@return The created tetrahedron
963 ///////////////////////////////////////////////////////////////////////////////
965 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
966 const SMDS_MeshFace * f2,
967 const SMDS_MeshFace * f3,
968 const SMDS_MeshFace * f4,
971 //MESSAGE("AddVolumeWithID" << ID);
972 if (!hasConstructionFaces())
974 if ( !f1 || !f2 || !f3 || !f4) return 0;
975 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
976 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
977 adjustmyCellsCapacity(ID);
978 myCells[ID] = volume;
981 if (!registerElement(ID, volume)) {
982 RemoveElement(volume, false);
988 ///////////////////////////////////////////////////////////////////////////////
989 ///Create a new pyramid defined by its faces and add it to the mesh.
990 ///@return The created pyramid
991 ///////////////////////////////////////////////////////////////////////////////
993 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
994 const SMDS_MeshFace * f2,
995 const SMDS_MeshFace * f3,
996 const SMDS_MeshFace * f4,
997 const SMDS_MeshFace * f5)
999 //MESSAGE("AddVolumeWithID");
1000 if (!hasConstructionFaces())
1002 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1005 ///////////////////////////////////////////////////////////////////////////////
1006 ///Create a new pyramid defined by its faces and add it to the mesh.
1007 ///@param ID The ID of the new volume
1008 ///@return The created pyramid
1009 ///////////////////////////////////////////////////////////////////////////////
1011 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1012 const SMDS_MeshFace * f2,
1013 const SMDS_MeshFace * f3,
1014 const SMDS_MeshFace * f4,
1015 const SMDS_MeshFace * f5,
1018 //MESSAGE("AddVolumeWithID" << ID);
1019 if (!hasConstructionFaces())
1021 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1022 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1023 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1024 adjustmyCellsCapacity(ID);
1025 myCells[ID] = volume;
1026 myInfo.myNbPyramids++;
1028 if (!registerElement(ID, volume)) {
1029 RemoveElement(volume, false);
1035 ///////////////////////////////////////////////////////////////////////////////
1036 ///Create a new prism defined by its faces and add it to the mesh.
1037 ///@return The created prism
1038 ///////////////////////////////////////////////////////////////////////////////
1040 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1041 const SMDS_MeshFace * f2,
1042 const SMDS_MeshFace * f3,
1043 const SMDS_MeshFace * f4,
1044 const SMDS_MeshFace * f5,
1045 const SMDS_MeshFace * f6)
1047 //MESSAGE("AddVolumeWithID" );
1048 if (!hasConstructionFaces())
1050 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1053 ///////////////////////////////////////////////////////////////////////////////
1054 ///Create a new prism defined by its faces and add it to the mesh.
1055 ///@param ID The ID of the new volume
1056 ///@return The created prism
1057 ///////////////////////////////////////////////////////////////////////////////
1059 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1060 const SMDS_MeshFace * f2,
1061 const SMDS_MeshFace * f3,
1062 const SMDS_MeshFace * f4,
1063 const SMDS_MeshFace * f5,
1064 const SMDS_MeshFace * f6,
1067 //MESSAGE("AddVolumeWithID" << ID);
1068 if (!hasConstructionFaces())
1070 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1071 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1072 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1073 adjustmyCellsCapacity(ID);
1074 myCells[ID] = volume;
1075 myInfo.myNbPrisms++;
1077 if (!registerElement(ID, volume)) {
1078 RemoveElement(volume, false);
1084 ///////////////////////////////////////////////////////////////////////////////
1085 /// Add a polygon defined by its nodes IDs
1086 ///////////////////////////////////////////////////////////////////////////////
1088 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
1091 int nbNodes = nodes_ids.size();
1092 vector<const SMDS_MeshNode*> nodes (nbNodes);
1093 for (int i = 0; i < nbNodes; i++) {
1094 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1095 if (!nodes[i]) return NULL;
1097 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1100 ///////////////////////////////////////////////////////////////////////////////
1101 /// Add a polygon defined by its nodes
1102 ///////////////////////////////////////////////////////////////////////////////
1104 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1105 (vector<const SMDS_MeshNode*> nodes,
1108 SMDS_MeshFace * face;
1110 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1111 if (hasConstructionEdges())
1113 MESSAGE("Error : Not implemented");
1118 for ( int i = 0; i < nodes.size(); ++i )
1119 if ( !nodes[ i ] ) return 0;
1120 face = new SMDS_PolygonalFaceOfNodes(nodes);
1121 adjustmyCellsCapacity(ID);
1123 myInfo.myNbPolygons++;
1126 if (!registerElement(ID, face)) {
1127 RemoveElement(face, false);
1133 ///////////////////////////////////////////////////////////////////////////////
1134 /// Add a polygon defined by its nodes.
1135 /// An ID is automatically affected to the created face.
1136 ///////////////////////////////////////////////////////////////////////////////
1138 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
1140 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1143 ///////////////////////////////////////////////////////////////////////////////
1144 /// Create a new polyhedral volume and add it to the mesh.
1145 /// @param ID The ID of the new volume
1146 /// @return The created volume or NULL if an element with this ID already exists
1147 /// or if input nodes are not found.
1148 ///////////////////////////////////////////////////////////////////////////////
1150 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1151 (vector<int> nodes_ids,
1152 vector<int> quantities,
1155 int nbNodes = nodes_ids.size();
1156 vector<const SMDS_MeshNode*> nodes (nbNodes);
1157 for (int i = 0; i < nbNodes; i++) {
1158 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1159 if (!nodes[i]) return NULL;
1161 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1164 ///////////////////////////////////////////////////////////////////////////////
1165 /// Create a new polyhedral volume and add it to the mesh.
1166 /// @param ID The ID of the new volume
1167 /// @return The created volume
1168 ///////////////////////////////////////////////////////////////////////////////
1170 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1171 (vector<const SMDS_MeshNode*> nodes,
1172 vector<int> quantities,
1175 SMDS_MeshVolume* volume;
1176 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1177 if (hasConstructionFaces()) {
1178 MESSAGE("Error : Not implemented");
1180 } else if (hasConstructionEdges()) {
1181 MESSAGE("Error : Not implemented");
1184 for ( int i = 0; i < nodes.size(); ++i )
1185 if ( !nodes[ i ] ) return 0;
1186 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1187 adjustmyCellsCapacity(ID);
1188 myCells[ID] = volume;
1189 myInfo.myNbPolyhedrons++;
1192 if (!registerElement(ID, volume)) {
1193 RemoveElement(volume, false);
1199 ///////////////////////////////////////////////////////////////////////////////
1200 /// Create a new polyhedral volume and add it to the mesh.
1201 /// @return The created volume
1202 ///////////////////////////////////////////////////////////////////////////////
1204 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1205 (vector<const SMDS_MeshNode*> nodes,
1206 vector<int> quantities)
1208 int ID = myElementIDFactory->GetFreeID();
1209 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1210 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1214 ///////////////////////////////////////////////////////////////////////////////
1215 /// Registers element with the given ID, maintains inverse connections
1216 ///////////////////////////////////////////////////////////////////////////////
1217 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1219 //MESSAGE("registerElement " << ID);
1220 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1222 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1227 element->myMeshId = myMeshId;
1229 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1231 int vtkId = cell->getVtkId();
1233 vtkId = myElementIDFactory->SetInVtkGrid(element);
1235 if (ID >= myIDElements.size()) // --- resize local vector
1237 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1238 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1241 myIDElements[ID] = vtkId;
1242 //MESSAGE("smds:" << ID << " vtk:" << vtkId );
1244 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1246 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1247 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1249 myVtkIndex[vtkId] = ID;
1251 myElementIDFactory->updateMinMax(ID);
1255 ///////////////////////////////////////////////////////////////////////////////
1256 /// Return the node whose ID is 'ID'.
1257 ///////////////////////////////////////////////////////////////////////////////
1258 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1260 if (ID < 0 || ID >= myNodes.size())
1262 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1265 return (const SMDS_MeshNode *)myNodes[ID];
1268 ///////////////////////////////////////////////////////////////////////////////
1269 ///Create a triangle and add it to the current mesh. This method do not bind an
1270 ///ID to the create triangle.
1271 ///////////////////////////////////////////////////////////////////////////////
1272 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1273 const SMDS_MeshNode * node2,
1274 const SMDS_MeshNode * node3,
1277 if ( !node1 || !node2 || !node3) return 0;
1278 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1279 if(hasConstructionEdges())
1281 SMDS_MeshEdge *edge1, *edge2, *edge3;
1282 edge1=FindEdgeOrCreate(node1,node2);
1283 edge2=FindEdgeOrCreate(node2,node3);
1284 edge3=FindEdgeOrCreate(node3,node1);
1286 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1287 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1288 adjustmyCellsCapacity(ID);
1290 myInfo.myNbTriangles++;
1295 // --- retrieve nodes ID
1296 vector<vtkIdType> nodeIds;
1298 nodeIds.push_back(node1->getId());
1299 nodeIds.push_back(node2->getId());
1300 nodeIds.push_back(node3->getId());
1302 SMDS_MeshFace * face = 0;
1303 SMDS_VtkFace *facevtk = myFacePool->getNew();
1304 facevtk->init(nodeIds, this);
1306 adjustmyCellsCapacity(ID);
1308 //MESSAGE("createTriangle " << ID << " " << face);
1309 myInfo.myNbTriangles++;
1314 ///////////////////////////////////////////////////////////////////////////////
1315 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1316 ///a ID to the create triangle.
1317 ///////////////////////////////////////////////////////////////////////////////
1318 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1319 const SMDS_MeshNode * node2,
1320 const SMDS_MeshNode * node3,
1321 const SMDS_MeshNode * node4,
1324 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1325 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1326 if(hasConstructionEdges())
1328 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1329 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1330 edge1=FindEdgeOrCreate(node1,node2);
1331 edge2=FindEdgeOrCreate(node2,node3);
1332 edge3=FindEdgeOrCreate(node3,node4);
1333 edge4=FindEdgeOrCreate(node4,node1);
1335 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1336 adjustmyCellsCapacity(ID);
1338 myInfo.myNbQuadrangles++;
1343 // --- retrieve nodes ID
1344 vector<vtkIdType> nodeIds;
1346 nodeIds.push_back(node1->getId());
1347 nodeIds.push_back(node2->getId());
1348 nodeIds.push_back(node3->getId());
1349 nodeIds.push_back(node4->getId());
1351 SMDS_MeshFace * face = 0;
1352 SMDS_VtkFace *facevtk = myFacePool->getNew();
1353 facevtk->init(nodeIds, this);
1355 adjustmyCellsCapacity(ID);
1357 myInfo.myNbQuadrangles++;
1362 ///////////////////////////////////////////////////////////////////////////////
1363 /// Remove a node and all the elements which own this node
1364 ///////////////////////////////////////////////////////////////////////////////
1366 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1368 MESSAGE("RemoveNode");
1369 RemoveElement(node, true);
1372 ///////////////////////////////////////////////////////////////////////////////
1373 /// Remove an edge and all the elements which own this edge
1374 ///////////////////////////////////////////////////////////////////////////////
1376 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1378 MESSAGE("Remove0DElement");
1379 RemoveElement(elem0d,true);
1382 ///////////////////////////////////////////////////////////////////////////////
1383 /// Remove an edge and all the elements which own this edge
1384 ///////////////////////////////////////////////////////////////////////////////
1386 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1388 MESSAGE("RemoveEdge");
1389 RemoveElement(edge,true);
1392 ///////////////////////////////////////////////////////////////////////////////
1393 /// Remove an face and all the elements which own this face
1394 ///////////////////////////////////////////////////////////////////////////////
1396 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1398 MESSAGE("RemoveFace");
1399 RemoveElement(face, true);
1402 ///////////////////////////////////////////////////////////////////////////////
1404 ///////////////////////////////////////////////////////////////////////////////
1406 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1408 MESSAGE("RemoveVolume");
1409 RemoveElement(volume, true);
1412 //=======================================================================
1413 //function : RemoveFromParent
1415 //=======================================================================
1417 bool SMDS_Mesh::RemoveFromParent()
1419 if (myParent==NULL) return false;
1420 else return (myParent->RemoveSubMesh(this));
1423 //=======================================================================
1424 //function : RemoveSubMesh
1426 //=======================================================================
1428 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1432 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1433 for (; itmsh!=myChildren.end() && !found; itmsh++)
1435 SMDS_Mesh * submesh = *itmsh;
1436 if (submesh == aMesh)
1439 myChildren.erase(itmsh);
1446 //=======================================================================
1447 //function : ChangeElementNodes
1449 //=======================================================================
1451 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1452 const SMDS_MeshNode * nodes[],
1455 MYASSERT(0); // REVOIR LES TYPES
1456 // keep current nodes of elem
1457 set<const SMDS_MeshElement*> oldNodes;
1458 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1460 oldNodes.insert( itn->next() );
1462 if ( !element->IsPoly() )
1463 myInfo.remove( element ); // element may change type
1467 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1468 switch ( elem->GetType() )
1470 case SMDSAbs_0DElement: {
1471 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1472 Ok = elem0d->ChangeNode( nodes[0] );
1475 case SMDSAbs_Edge: {
1476 if ( nbnodes == 2 ) {
1477 if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
1478 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1480 else if ( nbnodes == 3 ) {
1481 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1482 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1486 case SMDSAbs_Face: {
1487 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1488 Ok = face->ChangeNodes( nodes, nbnodes );
1490 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1491 Ok = QF->ChangeNodes( nodes, nbnodes );
1493 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1494 Ok = face->ChangeNodes(nodes, nbnodes);
1497 case SMDSAbs_Volume: {
1498 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1499 Ok = vol->ChangeNodes( nodes, nbnodes );
1501 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1502 Ok = QV->ChangeNodes( nodes, nbnodes );
1506 MESSAGE ( "WRONG ELEM TYPE");
1509 if ( Ok ) { // update InverseElements
1511 set<const SMDS_MeshElement*>::iterator it;
1513 // AddInverseElement to new nodes
1514 for ( int i = 0; i < nbnodes; i++ ) {
1515 it = oldNodes.find( nodes[i] );
1516 if ( it == oldNodes.end() )
1518 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1520 // remove from oldNodes a node that remains in elem
1521 oldNodes.erase( it );
1523 // RemoveInverseElement from the nodes removed from elem
1524 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1526 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1527 (const_cast<SMDS_MeshElement *>( *it ));
1528 n->RemoveInverseElement( elem );
1532 if ( !element->IsPoly() )
1533 myInfo.add( element ); // element may change type
1538 //=======================================================================
1539 //function : ChangePolyhedronNodes
1540 //purpose : to change nodes of polyhedral volume
1541 //=======================================================================
1542 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1543 const vector<const SMDS_MeshNode*>& nodes,
1544 const vector<int> & quantities)
1546 if (elem->GetType() != SMDSAbs_Volume) {
1547 MESSAGE("WRONG ELEM TYPE");
1551 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1556 // keep current nodes of elem
1557 set<const SMDS_MeshElement*> oldNodes;
1558 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1559 while (itn->more()) {
1560 oldNodes.insert(itn->next());
1564 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1569 // update InverseElements
1571 // AddInverseElement to new nodes
1572 int nbnodes = nodes.size();
1573 set<const SMDS_MeshElement*>::iterator it;
1574 for (int i = 0; i < nbnodes; i++) {
1575 it = oldNodes.find(nodes[i]);
1576 if (it == oldNodes.end()) {
1578 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1580 // remove from oldNodes a node that remains in elem
1585 // RemoveInverseElement from the nodes removed from elem
1586 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1587 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1588 (const_cast<SMDS_MeshElement *>( *it ));
1589 n->RemoveInverseElement(elem);
1596 //=======================================================================
1597 //function : Find0DElement
1599 //=======================================================================
1600 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1602 const SMDS_MeshNode * node = FindNode(idnode);
1603 if(node == NULL) return NULL;
1604 return Find0DElement(node);
1607 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1609 if (!node) return 0;
1610 const SMDS_Mesh0DElement* toReturn = NULL;
1611 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1612 while (it1->more() && (toReturn == NULL)) {
1613 const SMDS_MeshElement* e = it1->next();
1614 if (e->NbNodes() == 1) {
1615 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1621 //=======================================================================
1622 //function : Find0DElementOrCreate
1624 //=======================================================================
1625 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1627 // if (!node) return 0;
1628 // SMDS_Mesh0DElement * toReturn = NULL;
1629 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1630 // if (toReturn == NULL) {
1631 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1632 // toReturn = new SMDS_Mesh0DElement(node);
1633 // my0DElements.Add(toReturn);
1634 // myInfo.myNb0DElements++;
1640 //=======================================================================
1641 //function : FindEdge
1643 //=======================================================================
1645 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1647 const SMDS_MeshNode * node1=FindNode(idnode1);
1648 const SMDS_MeshNode * node2=FindNode(idnode2);
1649 if((node1==NULL)||(node2==NULL)) return NULL;
1650 return FindEdge(node1,node2);
1653 //#include "Profiler.h"
1654 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1655 const SMDS_MeshNode * node2)
1657 if ( !node1 ) return 0;
1658 const SMDS_MeshEdge * toReturn=NULL;
1661 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1664 while(it1->more()) {
1665 const SMDS_MeshElement * e = it1->next();
1666 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1667 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1676 //=======================================================================
1677 //function : FindEdgeOrCreate
1679 //=======================================================================
1681 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1682 const SMDS_MeshNode * node2)
1684 if ( !node1 || !node2) return 0;
1685 SMDS_MeshEdge * toReturn=NULL;
1686 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1687 if(toReturn==NULL) {
1688 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1689 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1690 adjustmyCellsCapacity(ID);
1691 vector<vtkIdType> nodeIds;
1693 nodeIds.push_back(node1->getId());
1694 nodeIds.push_back(node2->getId());
1696 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1697 edgevtk->init(nodeIds, this);
1699 myCells[ID] = toReturn;
1706 //=======================================================================
1707 //function : FindEdge
1709 //=======================================================================
1711 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1714 const SMDS_MeshNode * node1=FindNode(idnode1);
1715 const SMDS_MeshNode * node2=FindNode(idnode2);
1716 const SMDS_MeshNode * node3=FindNode(idnode3);
1717 return FindEdge(node1,node2,node3);
1720 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1721 const SMDS_MeshNode * node2,
1722 const SMDS_MeshNode * node3)
1724 if ( !node1 ) return 0;
1725 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1726 while(it1->more()) {
1727 const SMDS_MeshElement * e = it1->next();
1728 if ( e->NbNodes() == 3 ) {
1729 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1730 while(it2->more()) {
1731 const SMDS_MeshElement* n = it2->next();
1741 return static_cast<const SMDS_MeshEdge *> (e);
1748 //=======================================================================
1749 //function : FindFace
1751 //=======================================================================
1753 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1756 const SMDS_MeshNode * node1=FindNode(idnode1);
1757 const SMDS_MeshNode * node2=FindNode(idnode2);
1758 const SMDS_MeshNode * node3=FindNode(idnode3);
1759 return FindFace(node1, node2, node3);
1762 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1763 const SMDS_MeshNode *node2,
1764 const SMDS_MeshNode *node3)
1766 if ( !node1 ) return 0;
1767 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1768 while(it1->more()) {
1769 const SMDS_MeshElement * e = it1->next();
1770 if ( e->NbNodes() == 3 ) {
1771 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1772 while(it2->more()) {
1773 const SMDS_MeshElement* n = it2->next();
1783 return static_cast<const SMDS_MeshFace *> (e);
1789 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1790 const SMDS_MeshNode *node2,
1791 const SMDS_MeshNode *node3)
1793 SMDS_MeshFace * toReturn=NULL;
1794 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1795 if(toReturn==NULL) {
1796 int ID = myElementIDFactory->GetFreeID();
1797 toReturn = createTriangle(node1,node2,node3, ID);
1803 //=======================================================================
1804 //function : FindFace
1806 //=======================================================================
1808 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1809 int idnode3, int idnode4) const
1811 const SMDS_MeshNode * node1=FindNode(idnode1);
1812 const SMDS_MeshNode * node2=FindNode(idnode2);
1813 const SMDS_MeshNode * node3=FindNode(idnode3);
1814 const SMDS_MeshNode * node4=FindNode(idnode4);
1815 return FindFace(node1, node2, node3, node4);
1818 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1819 const SMDS_MeshNode *node2,
1820 const SMDS_MeshNode *node3,
1821 const SMDS_MeshNode *node4)
1823 if ( !node1 ) return 0;
1824 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1825 while(it1->more()) {
1826 const SMDS_MeshElement * e = it1->next();
1827 if ( e->NbNodes() == 4 ) {
1828 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1829 while(it2->more()) {
1830 const SMDS_MeshElement* n = it2->next();
1841 return static_cast<const SMDS_MeshFace *> (e);
1847 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1848 const SMDS_MeshNode *node2,
1849 const SMDS_MeshNode *node3,
1850 const SMDS_MeshNode *node4)
1852 SMDS_MeshFace * toReturn=NULL;
1853 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1854 if(toReturn==NULL) {
1855 int ID = myElementIDFactory->GetFreeID();
1856 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1862 //=======================================================================
1863 //function : FindFace
1864 //purpose :quadratic triangle
1865 //=======================================================================
1867 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1868 int idnode3, int idnode4,
1869 int idnode5, int idnode6) const
1871 const SMDS_MeshNode * node1 = FindNode(idnode1);
1872 const SMDS_MeshNode * node2 = FindNode(idnode2);
1873 const SMDS_MeshNode * node3 = FindNode(idnode3);
1874 const SMDS_MeshNode * node4 = FindNode(idnode4);
1875 const SMDS_MeshNode * node5 = FindNode(idnode5);
1876 const SMDS_MeshNode * node6 = FindNode(idnode6);
1877 return FindFace(node1, node2, node3, node4, node5, node6);
1880 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1881 const SMDS_MeshNode *node2,
1882 const SMDS_MeshNode *node3,
1883 const SMDS_MeshNode *node4,
1884 const SMDS_MeshNode *node5,
1885 const SMDS_MeshNode *node6)
1887 if ( !node1 ) return 0;
1888 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1889 while(it1->more()) {
1890 const SMDS_MeshElement * e = it1->next();
1891 if ( e->NbNodes() == 6 ) {
1892 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1893 while(it2->more()) {
1894 const SMDS_MeshElement* n = it2->next();
1907 return static_cast<const SMDS_MeshFace *> (e);
1914 //=======================================================================
1915 //function : FindFace
1916 //purpose : quadratic quadrangle
1917 //=======================================================================
1919 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1920 int idnode3, int idnode4,
1921 int idnode5, int idnode6,
1922 int idnode7, int idnode8) const
1924 const SMDS_MeshNode * node1 = FindNode(idnode1);
1925 const SMDS_MeshNode * node2 = FindNode(idnode2);
1926 const SMDS_MeshNode * node3 = FindNode(idnode3);
1927 const SMDS_MeshNode * node4 = FindNode(idnode4);
1928 const SMDS_MeshNode * node5 = FindNode(idnode5);
1929 const SMDS_MeshNode * node6 = FindNode(idnode6);
1930 const SMDS_MeshNode * node7 = FindNode(idnode7);
1931 const SMDS_MeshNode * node8 = FindNode(idnode8);
1932 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1935 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1936 const SMDS_MeshNode *node2,
1937 const SMDS_MeshNode *node3,
1938 const SMDS_MeshNode *node4,
1939 const SMDS_MeshNode *node5,
1940 const SMDS_MeshNode *node6,
1941 const SMDS_MeshNode *node7,
1942 const SMDS_MeshNode *node8)
1944 if ( !node1 ) return 0;
1945 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1946 while(it1->more()) {
1947 const SMDS_MeshElement * e = it1->next();
1948 if ( e->NbNodes() == 8 ) {
1949 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1950 while(it2->more()) {
1951 const SMDS_MeshElement* n = it2->next();
1966 return static_cast<const SMDS_MeshFace *> (e);
1973 //=======================================================================
1974 //function : FindElement
1976 //=======================================================================
1978 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1980 if ((IDelem < 0) || IDelem >= myCells.size())
1982 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
1986 return myCells[IDelem];
1989 //=======================================================================
1990 //function : FindFace
1991 //purpose : find polygon
1992 //=======================================================================
1994 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
1996 int nbnodes = nodes_ids.size();
1997 vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1998 for (int inode = 0; inode < nbnodes; inode++) {
1999 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2000 if (node == NULL) return NULL;
2001 poly_nodes[inode] = node;
2003 return FindFace(poly_nodes);
2006 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2008 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2012 //================================================================================
2014 * \brief Return element based on all given nodes
2015 * \param nodes - node of element
2016 * \param type - type of element
2017 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2018 * \retval const SMDS_MeshElement* - found element or NULL
2020 //================================================================================
2022 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2023 const SMDSAbs_ElementType type,
2024 const bool noMedium)
2026 if ( nodes.size() > 0 && nodes[0] )
2028 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2031 const SMDS_MeshElement* e = itF->next();
2032 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2033 if ( nbNodesToCheck == nodes.size() )
2035 for ( int i = 1; e && i < nodes.size(); ++ i )
2037 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2038 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2042 return static_cast<const SMDS_MeshFace *> (e);
2049 //=======================================================================
2050 //function : DumpNodes
2052 //=======================================================================
2054 void SMDS_Mesh::DumpNodes() const
2056 MESSAGE("dump nodes of mesh : ");
2057 SMDS_NodeIteratorPtr itnode=nodesIterator();
2058 while(itnode->more()) ; //MESSAGE(itnode->next());
2061 //=======================================================================
2062 //function : Dump0DElements
2064 //=======================================================================
2065 void SMDS_Mesh::Dump0DElements() const
2067 MESSAGE("dump 0D elements of mesh : ");
2068 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2069 while(it0d->more()) ; //MESSAGE(it0d->next());
2072 //=======================================================================
2073 //function : DumpEdges
2075 //=======================================================================
2077 void SMDS_Mesh::DumpEdges() const
2079 MESSAGE("dump edges of mesh : ");
2080 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2081 while(itedge->more()) ; //MESSAGE(itedge->next());
2084 //=======================================================================
2085 //function : DumpFaces
2087 //=======================================================================
2089 void SMDS_Mesh::DumpFaces() const
2091 MESSAGE("dump faces of mesh : ");
2092 SMDS_FaceIteratorPtr itface=facesIterator();
2093 while(itface->more()) ; //MESSAGE(itface->next());
2096 //=======================================================================
2097 //function : DumpVolumes
2099 //=======================================================================
2101 void SMDS_Mesh::DumpVolumes() const
2103 MESSAGE("dump volumes of mesh : ");
2104 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2105 while(itvol->more()) ; //MESSAGE(itvol->next());
2108 //=======================================================================
2109 //function : DebugStats
2111 //=======================================================================
2113 void SMDS_Mesh::DebugStats() const
2115 MESSAGE("Debug stats of mesh : ");
2117 MESSAGE("===== NODES ====="<<NbNodes());
2118 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2119 MESSAGE("===== EDGES ====="<<NbEdges());
2120 MESSAGE("===== FACES ====="<<NbFaces());
2121 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2123 MESSAGE("End Debug stats of mesh ");
2127 SMDS_NodeIteratorPtr itnode=nodesIterator();
2128 int sizeofnodes = 0;
2129 int sizeoffaces = 0;
2131 while(itnode->more())
2133 const SMDS_MeshNode *node = itnode->next();
2135 sizeofnodes += sizeof(*node);
2137 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2140 const SMDS_MeshElement *me = it->next();
2141 sizeofnodes += sizeof(me);
2145 SMDS_FaceIteratorPtr itface=facesIterator();
2146 while(itface->more())
2148 const SMDS_MeshElement *face = itface->next();
2149 sizeoffaces += sizeof(*face);
2152 MESSAGE("total size of node elements = " << sizeofnodes);;
2153 MESSAGE("total size of face elements = " << sizeoffaces);;
2158 ///////////////////////////////////////////////////////////////////////////////
2159 /// Return the number of nodes
2160 ///////////////////////////////////////////////////////////////////////////////
2161 int SMDS_Mesh::NbNodes() const
2163 //MESSAGE(myGrid->GetNumberOfPoints());
2164 //MESSAGE(myInfo.NbNodes());
2165 //MESSAGE(myNodeMax);
2166 return myInfo.NbNodes();
2169 ///////////////////////////////////////////////////////////////////////////////
2170 /// Return the number of 0D elements
2171 ///////////////////////////////////////////////////////////////////////////////
2172 int SMDS_Mesh::Nb0DElements() const
2174 return myInfo.Nb0DElements(); // -PR- a verfier
2177 ///////////////////////////////////////////////////////////////////////////////
2178 /// Return the number of edges (including construction edges)
2179 ///////////////////////////////////////////////////////////////////////////////
2180 int SMDS_Mesh::NbEdges() const
2182 return myInfo.NbEdges(); // -PR- a verfier
2185 ///////////////////////////////////////////////////////////////////////////////
2186 /// Return the number of faces (including construction faces)
2187 ///////////////////////////////////////////////////////////////////////////////
2188 int SMDS_Mesh::NbFaces() const
2190 return myInfo.NbFaces(); // -PR- a verfier
2193 ///////////////////////////////////////////////////////////////////////////////
2194 /// Return the number of volumes
2195 ///////////////////////////////////////////////////////////////////////////////
2196 int SMDS_Mesh::NbVolumes() const
2198 return myInfo.NbVolumes(); // -PR- a verfier
2201 ///////////////////////////////////////////////////////////////////////////////
2202 /// Return the number of child mesh of this mesh.
2203 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2204 /// (2003-09-08) of SMESH
2205 ///////////////////////////////////////////////////////////////////////////////
2206 int SMDS_Mesh::NbSubMesh() const
2208 return myChildren.size();
2211 ///////////////////////////////////////////////////////////////////////////////
2212 /// Destroy the mesh and all its elements
2213 /// All pointer on elements owned by this mesh become illegals.
2214 ///////////////////////////////////////////////////////////////////////////////
2215 SMDS_Mesh::~SMDS_Mesh()
2217 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2218 while(itc!=myChildren.end())
2226 delete myNodeIDFactory;
2227 delete myElementIDFactory;
2231 SMDS_ElemIteratorPtr eIt = elementsIterator();
2232 while ( eIt->more() )
2233 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2234 SMDS_NodeIteratorPtr itn = nodesIterator();
2236 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2239 // SetOfNodes::Iterator itn(myNodes);
2240 // for (; itn.More(); itn.Next())
2241 // delete itn.Value();
2243 // SetOf0DElements::Iterator it0d (my0DElements);
2244 // for (; it0d.More(); it0d.Next())
2246 // SMDS_MeshElement* elem = it0d.Value();
2250 // SetOfEdges::Iterator ite(myEdges);
2251 // for (; ite.More(); ite.Next())
2253 // SMDS_MeshElement* elem = ite.Value();
2257 // SetOfFaces::Iterator itf(myFaces);
2258 // for (; itf.More(); itf.Next())
2260 // SMDS_MeshElement* elem = itf.Value();
2264 // SetOfVolumes::Iterator itv(myVolumes);
2265 // for (; itv.More(); itv.Next())
2267 // SMDS_MeshElement* elem = itv.Value();
2272 //================================================================================
2274 * \brief Clear all data
2276 //================================================================================
2278 void SMDS_Mesh::Clear()
2282 SMDS_ElemIteratorPtr eIt = elementsIterator();
2283 while ( eIt->more() )
2284 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2285 SMDS_NodeIteratorPtr itn = nodesIterator();
2287 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2291 myNodeIDFactory->Clear();
2292 myElementIDFactory->Clear();
2295 SMDS_ElemIteratorPtr itv = elementsIterator();
2298 SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2299 SMDSAbs_ElementType aType = elem->GetType();
2302 case SMDSAbs_0DElement:
2306 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2309 myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2311 case SMDSAbs_Volume:
2312 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2320 SMDS_NodeIteratorPtr itn = nodesIterator();
2323 SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2324 myNodePool->destroy(node);
2328 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2329 while(itc!=myChildren.end())
2334 myGrid->Initialize();
2336 vtkPoints* points = vtkPoints::New();
2337 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
2338 myGrid->SetPoints( points );
2340 myGrid->BuildLinks();
2343 ///////////////////////////////////////////////////////////////////////////////
2344 /// Return true if this mesh create faces with edges.
2345 /// A false returned value mean that faces are created with nodes. A concequence
2346 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2347 ///////////////////////////////////////////////////////////////////////////////
2348 bool SMDS_Mesh::hasConstructionEdges()
2350 return myHasConstructionEdges;
2353 ///////////////////////////////////////////////////////////////////////////////
2354 /// Return true if this mesh create volumes with faces
2355 /// A false returned value mean that volumes are created with nodes or edges.
2356 /// (see hasConstructionEdges)
2357 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2359 ///////////////////////////////////////////////////////////////////////////////
2360 bool SMDS_Mesh::hasConstructionFaces()
2362 return myHasConstructionFaces;
2365 ///////////////////////////////////////////////////////////////////////////////
2366 /// Return true if nodes are linked to the finit elements, they are belonging to.
2367 /// Currently, It always return true.
2368 ///////////////////////////////////////////////////////////////////////////////
2369 bool SMDS_Mesh::hasInverseElements()
2371 return myHasInverseElements;
2374 ///////////////////////////////////////////////////////////////////////////////
2375 /// Make this mesh creating construction edges (see hasConstructionEdges)
2376 /// @param b true to have construction edges, else false.
2377 ///////////////////////////////////////////////////////////////////////////////
2378 void SMDS_Mesh::setConstructionEdges(bool b)
2380 myHasConstructionEdges=b;
2383 ///////////////////////////////////////////////////////////////////////////////
2384 /// Make this mesh creating construction faces (see hasConstructionFaces)
2385 /// @param b true to have construction faces, else false.
2386 ///////////////////////////////////////////////////////////////////////////////
2387 void SMDS_Mesh::setConstructionFaces(bool b)
2389 myHasConstructionFaces=b;
2392 ///////////////////////////////////////////////////////////////////////////////
2393 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2394 /// @param b true to link nodes to elements, else false.
2395 ///////////////////////////////////////////////////////////////////////////////
2396 void SMDS_Mesh::setInverseElements(bool b)
2398 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2399 myHasInverseElements=b;
2404 ///////////////////////////////////////////////////////////////////////////////
2405 ///Iterator on NCollection_Map
2406 ///////////////////////////////////////////////////////////////////////////////
2407 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2408 struct MYNode_Map_Iterator: public FATHER
2412 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2419 while (_ctr < _map.size())
2430 ELEM current = _map[_ctr];
2436 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2437 struct MYElem_Map_Iterator: public FATHER
2442 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2450 while (_ctr < _map.size())
2453 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2462 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2468 //================================================================================
2470 * \brief Iterator on elements in id increasing order
2472 //================================================================================
2474 template <typename ELEM=const SMDS_MeshElement*>
2475 class IdSortedIterator : public SMDS_Iterator<ELEM>
2477 const SMDS_MeshElementIDFactory& myIDFact;
2482 IdSortedIterator(const SMDS_MeshElementIDFactory& fact)
2483 :myIDFact( fact ), myID(1), myMaxID( myIDFact.GetMaxID() ), myElem(0)
2493 ELEM current = myElem;
2494 for ( myElem = 0; myID <= myMaxID && !myElem; ++myID )
2495 myElem = (ELEM) myIDFact.MeshElement( myID );
2501 ///////////////////////////////////////////////////////////////////////////////
2502 /// Return an iterator on nodes of the current mesh factory
2503 ///////////////////////////////////////////////////////////////////////////////
2505 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2507 typedef MYNode_Map_Iterator
2508 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2509 typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator;
2510 /* return ( idInceasingOrder ?
2511 SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory )) :
2512 SMDS_NodeIteratorPtr( new TIterator(myNodes)));*/
2513 return ( SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2516 ///////////////////////////////////////////////////////////////////////////////
2517 ///Return an iterator on 0D elements of the current mesh.
2518 ///////////////////////////////////////////////////////////////////////////////
2520 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2522 typedef MYElem_Map_Iterator
2523 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2524 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2527 ///////////////////////////////////////////////////////////////////////////////
2528 ///Return an iterator on edges of the current mesh.
2529 ///////////////////////////////////////////////////////////////////////////////
2531 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2533 typedef MYElem_Map_Iterator
2534 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2535 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2538 ///////////////////////////////////////////////////////////////////////////////
2539 ///Return an iterator on faces of the current mesh.
2540 ///////////////////////////////////////////////////////////////////////////////
2542 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2544 typedef MYElem_Map_Iterator
2545 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2546 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2549 ///////////////////////////////////////////////////////////////////////////////
2550 ///Return an iterator on volumes of the current mesh.
2551 ///////////////////////////////////////////////////////////////////////////////
2553 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2555 typedef MYElem_Map_Iterator
2556 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2557 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2560 ///////////////////////////////////////////////////////////////////////////////
2561 /// Return an iterator on elements of the current mesh factory
2562 ///////////////////////////////////////////////////////////////////////////////
2563 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2567 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2569 case SMDSAbs_Volume:
2570 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2572 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2574 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2575 case SMDSAbs_0DElement:
2576 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2578 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2579 //return myNodeIDFactory->elementsIterator();
2582 return myElementIDFactory->elementsIterator();
2585 ///////////////////////////////////////////////////////////////////////////////
2586 /// Do intersection of sets (more than 2)
2587 ///////////////////////////////////////////////////////////////////////////////
2588 static set<const SMDS_MeshElement*> * intersectionOfSets(
2589 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2591 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2592 set<const SMDS_MeshElement*>* rsetB;
2594 for(int i=0; i<numberOfSets-1; i++)
2596 rsetB=new set<const SMDS_MeshElement*>();
2598 rsetA->begin(), rsetA->end(),
2599 vs[i+1].begin(), vs[i+1].end(),
2600 inserter(*rsetB, rsetB->begin()));
2607 ///////////////////////////////////////////////////////////////////////////////
2608 /// Return the list of finite elements owning the given element: elements
2609 /// containing all the nodes of the given element, for instance faces and
2610 /// volumes containing a given edge.
2611 ///////////////////////////////////////////////////////////////////////////////
2612 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2614 int numberOfSets=element->NbNodes();
2615 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2617 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2620 while(itNodes->more())
2622 const SMDS_MeshElement* node = itNodes->next();
2624 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2625 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2627 //initSet[i]=set<const SMDS_MeshElement*>();
2630 const SMDS_MeshElement* elem = itFe->next();
2632 initSet[i].insert(elem);
2638 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2639 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2644 ///////////////////////////////////////////////////////////////////////////////
2645 /// Return the list of nodes used only by the given elements
2646 ///////////////////////////////////////////////////////////////////////////////
2647 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2648 set<const SMDS_MeshElement*>& elements)
2650 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2651 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2653 while(itElements!=elements.end())
2655 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2658 while(itNodes->more())
2660 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2661 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2662 set<const SMDS_MeshElement*> s;
2664 s.insert(itFe->next());
2665 if(s==elements) toReturn->insert(n);
2671 ///////////////////////////////////////////////////////////////////////////////
2672 ///Find the children of an element that are made of given nodes
2673 ///@param setOfChildren The set in which matching children will be inserted
2674 ///@param element The element were to search matching children
2675 ///@param nodes The nodes that the children must have to be selected
2676 ///////////////////////////////////////////////////////////////////////////////
2677 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2678 const SMDS_MeshElement * element,
2679 set<const SMDS_MeshElement*>& nodes)
2681 switch(element->GetType())
2684 MESSAGE("Internal Error: This should not happend");
2686 case SMDSAbs_0DElement:
2692 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2695 const SMDS_MeshElement * e=itn->next();
2696 if(nodes.find(e)!=nodes.end())
2698 setOfChildren.insert(element);
2705 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2708 const SMDS_MeshElement * e=itn->next();
2709 if(nodes.find(e)!=nodes.end())
2711 setOfChildren.insert(element);
2715 if(hasConstructionEdges())
2717 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2719 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2722 case SMDSAbs_Volume:
2724 if(hasConstructionFaces())
2726 SMDS_ElemIteratorPtr ite=element->facesIterator();
2728 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2730 else if(hasConstructionEdges())
2732 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2734 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2740 ///////////////////////////////////////////////////////////////////////////////
2741 ///@param elem The element to delete
2742 ///@param removenodes if true remaining nodes will be removed
2743 ///////////////////////////////////////////////////////////////////////////////
2744 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2745 const bool removenodes)
2747 list<const SMDS_MeshElement *> removedElems;
2748 list<const SMDS_MeshElement *> removedNodes;
2749 RemoveElement( elem, removedElems, removedNodes, removenodes );
2752 ///////////////////////////////////////////////////////////////////////////////
2753 ///@param elem The element to delete
2754 ///@param removedElems to be filled with all removed elements
2755 ///@param removedNodes to be filled with all removed nodes
2756 ///@param removenodes if true remaining nodes will be removed
2757 ///////////////////////////////////////////////////////////////////////////////
2758 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2759 list<const SMDS_MeshElement *>& removedElems,
2760 list<const SMDS_MeshElement *>& removedNodes,
2763 //MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2764 // get finite elements built on elem
2765 set<const SMDS_MeshElement*> * s1;
2766 if (elem->GetType() == SMDSAbs_0DElement ||
2767 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2768 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2769 elem->GetType() == SMDSAbs_Volume)
2771 s1 = new set<const SMDS_MeshElement*>();
2775 s1 = getFinitElements(elem);
2777 // get exclusive nodes (which would become free afterwards)
2778 set<const SMDS_MeshElement*> * s2;
2779 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2781 // do not remove nodes except elem
2782 s2 = new set<const SMDS_MeshElement*>();
2787 s2 = getExclusiveNodes(*s1);
2789 // form the set of finite and construction elements to remove
2790 set<const SMDS_MeshElement*> s3;
2791 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2792 while(it!=s1->end())
2794 addChildrenWithNodes(s3, *it ,*s2);
2798 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2800 // remove finite and construction elements
2804 // Remove element from <InverseElements> of its nodes
2805 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2808 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2809 (const_cast<SMDS_MeshElement *>(itn->next()));
2810 n->RemoveInverseElement( (*it) );
2813 switch((*it)->GetType())
2816 MYASSERT("Internal Error: This should not happen");
2818 case SMDSAbs_0DElement:
2819 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2821 removedElems.push_back( (*it) );
2822 myElementIDFactory->ReleaseID((*it)->GetID());
2826 myCells[(*it)->GetID()] = 0;
2827 myInfo.RemoveEdge(*it);
2828 removedElems.push_back( (*it) );
2829 myElementIDFactory->ReleaseID((*it)->GetID());
2830 if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
2831 myEdgePool->destroy((SMDS_VtkEdge*)vtkElem);
2835 myCells[(*it)->GetID()] = 0;
2836 myInfo.RemoveFace(*it);
2837 removedElems.push_back( (*it) );
2838 myElementIDFactory->ReleaseID((*it)->GetID());
2839 if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
2840 myFacePool->destroy((SMDS_VtkFace*)vtkElem);
2843 case SMDSAbs_Volume:
2844 myCells[(*it)->GetID()] = 0;
2845 myInfo.RemoveVolume(*it);
2846 removedElems.push_back( (*it) );
2847 myElementIDFactory->ReleaseID((*it)->GetID());
2848 if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
2849 myVolumePool->destroy((SMDS_VtkVolume*)vtkElem);
2856 // remove exclusive (free) nodes
2860 while(it!=s2->end())
2862 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2863 myNodes[(*it)->GetID()] = 0;
2865 myNodeIDFactory->ReleaseID((*it)->GetID());
2866 removedNodes.push_back( (*it) );
2867 if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
2868 myNodePool->destroy((SMDS_MeshNode*)vtkElem);
2879 ///////////////////////////////////////////////////////////////////////////////
2880 ///@param elem The element to delete
2881 ///////////////////////////////////////////////////////////////////////////////
2882 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2884 int elemId = elem->GetID();
2885 //MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2886 SMDSAbs_ElementType aType = elem->GetType();
2887 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2888 if (aType == SMDSAbs_Node) {
2889 // only free node can be removed by this method
2890 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2891 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2892 if (!itFe->more()) { // free node
2893 myNodes[elemId] = 0;
2895 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2896 myNodeIDFactory->ReleaseID(elemId);
2899 if (hasConstructionEdges() || hasConstructionFaces())
2900 // this methods is only for meshes without descendants
2903 int vtkid = this->fromSmdsToVtk(elemId);
2905 // Remove element from <InverseElements> of its nodes
2906 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2907 while (itn->more()) {
2908 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2909 (const_cast<SMDS_MeshElement *>(itn->next()));
2910 n->RemoveInverseElement(elem);
2913 // in meshes without descendants elements are always free
2915 case SMDSAbs_0DElement:
2916 myCells[elemId] = 0;
2917 myInfo.remove(elem);
2921 myCells[elemId] = 0;
2922 myInfo.RemoveEdge(elem);
2923 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2926 myCells[elemId] = 0;
2927 myInfo.RemoveFace(elem);
2928 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2930 case SMDSAbs_Volume:
2931 myCells[elemId] = 0;
2932 myInfo.RemoveVolume(elem);
2933 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2938 myElementIDFactory->ReleaseID(elemId);
2940 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2941 // --- to do: keep vtkid in a list of reusable cells
2946 * Checks if the element is present in mesh.
2947 * Useful to determine dead pointers.
2949 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2951 // we should not imply on validity of *elem, so iterate on containers
2952 // of all types in the hope of finding <elem> somewhere there
2953 SMDS_NodeIteratorPtr itn = nodesIterator();
2955 if (elem == itn->next())
2957 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2958 while (it0d->more())
2959 if (elem == it0d->next())
2961 SMDS_EdgeIteratorPtr ite = edgesIterator();
2963 if (elem == ite->next())
2965 SMDS_FaceIteratorPtr itf = facesIterator();
2967 if (elem == itf->next())
2969 SMDS_VolumeIteratorPtr itv = volumesIterator();
2971 if (elem == itv->next())
2976 //=======================================================================
2977 //function : MaxNodeID
2979 //=======================================================================
2981 int SMDS_Mesh::MaxNodeID() const
2986 //=======================================================================
2987 //function : MinNodeID
2989 //=======================================================================
2991 int SMDS_Mesh::MinNodeID() const
2996 //=======================================================================
2997 //function : MaxElementID
2999 //=======================================================================
3001 int SMDS_Mesh::MaxElementID() const
3003 return myElementIDFactory->GetMaxID();
3006 //=======================================================================
3007 //function : MinElementID
3009 //=======================================================================
3011 int SMDS_Mesh::MinElementID() const
3013 return myElementIDFactory->GetMinID();
3016 //=======================================================================
3017 //function : Renumber
3018 //purpose : Renumber all nodes or elements.
3019 //=======================================================================
3021 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
3023 MESSAGE("Renumber");
3027 SMDS_MeshNodeIDFactory * idFactory =
3028 isNodes ? myNodeIDFactory : myElementIDFactory;
3030 // get existing elements in the order of ID increasing
3031 map<int,SMDS_MeshElement*> elemMap;
3032 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3033 while ( idElemIt->more() ) {
3034 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3035 int id = elem->GetID();
3036 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3038 // release their ids
3039 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3041 // for ( ; elemIt != elemMap.end(); elemIt++ )
3043 // int id = (*elemIt).first;
3044 // idFactory->ReleaseID( id );
3048 elemIt = elemMap.begin();
3049 for ( ; elemIt != elemMap.end(); elemIt++ )
3051 idFactory->BindID( ID, (*elemIt).second );
3056 //=======================================================================
3057 //function : GetElementType
3058 //purpose : Return type of element or node with id
3059 //=======================================================================
3061 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3063 SMDS_MeshElement* elem = 0;
3065 elem = myElementIDFactory->MeshElement( id );
3067 elem = myNodeIDFactory->MeshElement( id );
3071 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3075 return elem->GetType();
3080 //********************************************************************
3081 //********************************************************************
3082 //******** *********
3083 //***** Methods for addition of quadratic elements ******
3084 //******** *********
3085 //********************************************************************
3086 //********************************************************************
3088 //=======================================================================
3089 //function : AddEdgeWithID
3091 //=======================================================================
3092 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3094 return SMDS_Mesh::AddEdgeWithID
3095 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3096 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3097 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3101 //=======================================================================
3102 //function : AddEdge
3104 //=======================================================================
3105 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3106 const SMDS_MeshNode* n2,
3107 const SMDS_MeshNode* n12)
3109 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3112 //=======================================================================
3113 //function : AddEdgeWithID
3115 //=======================================================================
3116 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3117 const SMDS_MeshNode * n2,
3118 const SMDS_MeshNode * n12,
3121 if ( !n1 || !n2 || !n12 ) return 0;
3123 // --- retrieve nodes ID
3124 vector<vtkIdType> nodeIds;
3126 nodeIds.push_back(n1->getId());
3127 nodeIds.push_back(n2->getId());
3128 nodeIds.push_back(n12->getId());
3130 SMDS_MeshEdge * edge = 0;
3131 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3132 edgevtk->init(nodeIds, this);
3134 adjustmyCellsCapacity(ID);
3136 myInfo.myNbQuadEdges++;
3138 if (!registerElement(ID, edge)) {
3139 RemoveElement(edge, false);
3147 //=======================================================================
3148 //function : AddFace
3150 //=======================================================================
3151 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3152 const SMDS_MeshNode * n2,
3153 const SMDS_MeshNode * n3,
3154 const SMDS_MeshNode * n12,
3155 const SMDS_MeshNode * n23,
3156 const SMDS_MeshNode * n31)
3158 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3159 myElementIDFactory->GetFreeID());
3162 //=======================================================================
3163 //function : AddFaceWithID
3165 //=======================================================================
3166 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3167 int n12,int n23,int n31, int ID)
3169 return SMDS_Mesh::AddFaceWithID
3170 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3171 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3172 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3173 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3174 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3175 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3179 //=======================================================================
3180 //function : AddFaceWithID
3182 //=======================================================================
3183 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3184 const SMDS_MeshNode * n2,
3185 const SMDS_MeshNode * n3,
3186 const SMDS_MeshNode * n12,
3187 const SMDS_MeshNode * n23,
3188 const SMDS_MeshNode * n31,
3191 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3192 if(hasConstructionEdges()) {
3193 // creation quadratic edges - not implemented
3198 // --- retrieve nodes ID
3199 vector<vtkIdType> nodeIds;
3201 nodeIds.push_back(n1->getId());
3202 nodeIds.push_back(n2->getId());
3203 nodeIds.push_back(n3->getId());
3204 nodeIds.push_back(n12->getId());
3205 nodeIds.push_back(n23->getId());
3206 nodeIds.push_back(n31->getId());
3208 SMDS_MeshFace * face = 0;
3209 SMDS_VtkFace *facevtk = myFacePool->getNew();
3210 facevtk->init(nodeIds, this);
3212 adjustmyCellsCapacity(ID);
3214 myInfo.myNbQuadTriangles++;
3216 if (!registerElement(ID, face)) {
3217 RemoveElement(face, false);
3225 //=======================================================================
3226 //function : AddFace
3228 //=======================================================================
3229 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3230 const SMDS_MeshNode * n2,
3231 const SMDS_MeshNode * n3,
3232 const SMDS_MeshNode * n4,
3233 const SMDS_MeshNode * n12,
3234 const SMDS_MeshNode * n23,
3235 const SMDS_MeshNode * n34,
3236 const SMDS_MeshNode * n41)
3238 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3239 myElementIDFactory->GetFreeID());
3242 //=======================================================================
3243 //function : AddFaceWithID
3245 //=======================================================================
3246 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3247 int n12,int n23,int n34,int n41, int ID)
3249 return SMDS_Mesh::AddFaceWithID
3250 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3251 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3252 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3253 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3254 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3255 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3256 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3257 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3261 //=======================================================================
3262 //function : AddFaceWithID
3264 //=======================================================================
3265 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3266 const SMDS_MeshNode * n2,
3267 const SMDS_MeshNode * n3,
3268 const SMDS_MeshNode * n4,
3269 const SMDS_MeshNode * n12,
3270 const SMDS_MeshNode * n23,
3271 const SMDS_MeshNode * n34,
3272 const SMDS_MeshNode * n41,
3275 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3276 if(hasConstructionEdges()) {
3277 // creation quadratic edges - not implemented
3282 // --- retrieve nodes ID
3283 vector<vtkIdType> nodeIds;
3285 nodeIds.push_back(n1->getId());
3286 nodeIds.push_back(n2->getId());
3287 nodeIds.push_back(n3->getId());
3288 nodeIds.push_back(n4->getId());
3289 nodeIds.push_back(n12->getId());
3290 nodeIds.push_back(n23->getId());
3291 nodeIds.push_back(n34->getId());
3292 nodeIds.push_back(n41->getId());
3294 SMDS_MeshFace * face = 0;
3295 SMDS_VtkFace *facevtk = myFacePool->getNew();
3296 facevtk->init(nodeIds, this);
3298 adjustmyCellsCapacity(ID);
3300 myInfo.myNbQuadQuadrangles++;
3302 if (!registerElement(ID, face)) {
3303 RemoveElement(face, false);
3311 //=======================================================================
3312 //function : AddVolume
3314 //=======================================================================
3315 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3316 const SMDS_MeshNode * n2,
3317 const SMDS_MeshNode * n3,
3318 const SMDS_MeshNode * n4,
3319 const SMDS_MeshNode * n12,
3320 const SMDS_MeshNode * n23,
3321 const SMDS_MeshNode * n31,
3322 const SMDS_MeshNode * n14,
3323 const SMDS_MeshNode * n24,
3324 const SMDS_MeshNode * n34)
3326 int ID = myElementIDFactory->GetFreeID();
3327 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3328 n31, n14, n24, n34, ID);
3329 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3333 //=======================================================================
3334 //function : AddVolumeWithID
3336 //=======================================================================
3337 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3338 int n12,int n23,int n31,
3339 int n14,int n24,int n34, int ID)
3341 return SMDS_Mesh::AddVolumeWithID
3342 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3343 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3344 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3345 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3346 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3347 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3348 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3349 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3350 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3351 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3355 //=======================================================================
3356 //function : AddVolumeWithID
3357 //purpose : 2d order tetrahedron of 10 nodes
3358 //=======================================================================
3359 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3360 const SMDS_MeshNode * n2,
3361 const SMDS_MeshNode * n3,
3362 const SMDS_MeshNode * n4,
3363 const SMDS_MeshNode * n12,
3364 const SMDS_MeshNode * n23,
3365 const SMDS_MeshNode * n31,
3366 const SMDS_MeshNode * n14,
3367 const SMDS_MeshNode * n24,
3368 const SMDS_MeshNode * n34,
3371 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3373 if(hasConstructionFaces()) {
3374 // creation quadratic faces - not implemented
3377 // --- retrieve nodes ID
3378 vector<vtkIdType> nodeIds;
3380 nodeIds.push_back(n1->getId());
3381 nodeIds.push_back(n3->getId());
3382 nodeIds.push_back(n2->getId());
3383 nodeIds.push_back(n4->getId());
3385 nodeIds.push_back(n31->getId());
3386 nodeIds.push_back(n23->getId());
3387 nodeIds.push_back(n12->getId());
3389 nodeIds.push_back(n14->getId());
3390 nodeIds.push_back(n34->getId());
3391 nodeIds.push_back(n24->getId());
3393 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3394 volvtk->init(nodeIds, this);
3395 adjustmyCellsCapacity(ID);
3396 myCells[ID] = volvtk;
3397 myInfo.myNbQuadTetras++;
3399 if (!registerElement(ID, volvtk)) {
3400 RemoveElement(volvtk, false);
3407 //=======================================================================
3408 //function : AddVolume
3410 //=======================================================================
3411 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3412 const SMDS_MeshNode * n2,
3413 const SMDS_MeshNode * n3,
3414 const SMDS_MeshNode * n4,
3415 const SMDS_MeshNode * n5,
3416 const SMDS_MeshNode * n12,
3417 const SMDS_MeshNode * n23,
3418 const SMDS_MeshNode * n34,
3419 const SMDS_MeshNode * n41,
3420 const SMDS_MeshNode * n15,
3421 const SMDS_MeshNode * n25,
3422 const SMDS_MeshNode * n35,
3423 const SMDS_MeshNode * n45)
3425 int ID = myElementIDFactory->GetFreeID();
3426 SMDS_MeshVolume * v =
3427 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3428 n15, n25, n35, n45, ID);
3429 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3433 //=======================================================================
3434 //function : AddVolumeWithID
3436 //=======================================================================
3437 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3438 int n12,int n23,int n34,int n41,
3439 int n15,int n25,int n35,int n45, int ID)
3441 return SMDS_Mesh::AddVolumeWithID
3442 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3443 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3444 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3445 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3446 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3447 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3448 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3449 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3450 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3451 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3452 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3453 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3454 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3458 //=======================================================================
3459 //function : AddVolumeWithID
3460 //purpose : 2d order pyramid of 13 nodes
3461 //=======================================================================
3462 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3463 const SMDS_MeshNode * n2,
3464 const SMDS_MeshNode * n3,
3465 const SMDS_MeshNode * n4,
3466 const SMDS_MeshNode * n5,
3467 const SMDS_MeshNode * n12,
3468 const SMDS_MeshNode * n23,
3469 const SMDS_MeshNode * n34,
3470 const SMDS_MeshNode * n41,
3471 const SMDS_MeshNode * n15,
3472 const SMDS_MeshNode * n25,
3473 const SMDS_MeshNode * n35,
3474 const SMDS_MeshNode * n45,
3477 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3478 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3480 if(hasConstructionFaces()) {
3481 // creation quadratic faces - not implemented
3484 // --- retrieve nodes ID
3485 vector<vtkIdType> nodeIds;
3487 nodeIds.push_back(n1->getId());
3488 nodeIds.push_back(n4->getId());
3489 nodeIds.push_back(n3->getId());
3490 nodeIds.push_back(n2->getId());
3491 nodeIds.push_back(n5->getId());
3493 nodeIds.push_back(n41->getId());
3494 nodeIds.push_back(n34->getId());
3495 nodeIds.push_back(n23->getId());
3496 nodeIds.push_back(n12->getId());
3498 nodeIds.push_back(n15->getId());
3499 nodeIds.push_back(n45->getId());
3500 nodeIds.push_back(n35->getId());
3501 nodeIds.push_back(n25->getId());
3503 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3504 volvtk->init(nodeIds, this);
3505 adjustmyCellsCapacity(ID);
3506 myCells[ID] = volvtk;
3507 myInfo.myNbQuadPyramids++;
3509 if (!registerElement(ID, volvtk)) {
3510 RemoveElement(volvtk, false);
3517 //=======================================================================
3518 //function : AddVolume
3520 //=======================================================================
3521 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3522 const SMDS_MeshNode * n2,
3523 const SMDS_MeshNode * n3,
3524 const SMDS_MeshNode * n4,
3525 const SMDS_MeshNode * n5,
3526 const SMDS_MeshNode * n6,
3527 const SMDS_MeshNode * n12,
3528 const SMDS_MeshNode * n23,
3529 const SMDS_MeshNode * n31,
3530 const SMDS_MeshNode * n45,
3531 const SMDS_MeshNode * n56,
3532 const SMDS_MeshNode * n64,
3533 const SMDS_MeshNode * n14,
3534 const SMDS_MeshNode * n25,
3535 const SMDS_MeshNode * n36)
3537 int ID = myElementIDFactory->GetFreeID();
3538 SMDS_MeshVolume * v =
3539 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3540 n45, n56, n64, n14, n25, n36, ID);
3541 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3545 //=======================================================================
3546 //function : AddVolumeWithID
3548 //=======================================================================
3549 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3550 int n4, int n5, int n6,
3551 int n12,int n23,int n31,
3552 int n45,int n56,int n64,
3553 int n14,int n25,int n36, int ID)
3555 return SMDS_Mesh::AddVolumeWithID
3556 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3557 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3558 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3559 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3560 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3561 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3562 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3563 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3564 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3565 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3566 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3567 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3568 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3569 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3570 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3574 //=======================================================================
3575 //function : AddVolumeWithID
3576 //purpose : 2d order Pentahedron with 15 nodes
3577 //=======================================================================
3578 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3579 const SMDS_MeshNode * n2,
3580 const SMDS_MeshNode * n3,
3581 const SMDS_MeshNode * n4,
3582 const SMDS_MeshNode * n5,
3583 const SMDS_MeshNode * n6,
3584 const SMDS_MeshNode * n12,
3585 const SMDS_MeshNode * n23,
3586 const SMDS_MeshNode * n31,
3587 const SMDS_MeshNode * n45,
3588 const SMDS_MeshNode * n56,
3589 const SMDS_MeshNode * n64,
3590 const SMDS_MeshNode * n14,
3591 const SMDS_MeshNode * n25,
3592 const SMDS_MeshNode * n36,
3595 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3596 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3598 if(hasConstructionFaces()) {
3599 // creation quadratic faces - not implemented
3602 // --- retrieve nodes ID
3603 vector<vtkIdType> nodeIds;
3605 nodeIds.push_back(n1->getId());
3606 nodeIds.push_back(n2->getId());
3607 nodeIds.push_back(n3->getId());
3609 nodeIds.push_back(n4->getId());
3610 nodeIds.push_back(n5->getId());
3611 nodeIds.push_back(n6->getId());
3613 nodeIds.push_back(n12->getId());
3614 nodeIds.push_back(n23->getId());
3615 nodeIds.push_back(n31->getId());
3617 nodeIds.push_back(n45->getId());
3618 nodeIds.push_back(n56->getId());
3619 nodeIds.push_back(n64->getId());
3621 nodeIds.push_back(n14->getId());
3622 nodeIds.push_back(n25->getId());
3623 nodeIds.push_back(n36->getId());
3625 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3626 volvtk->init(nodeIds, this);
3627 adjustmyCellsCapacity(ID);
3628 myCells[ID] = volvtk;
3629 myInfo.myNbQuadPrisms++;
3631 if (!registerElement(ID, volvtk)) {
3632 RemoveElement(volvtk, false);
3639 //=======================================================================
3640 //function : AddVolume
3642 //=======================================================================
3643 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3644 const SMDS_MeshNode * n2,
3645 const SMDS_MeshNode * n3,
3646 const SMDS_MeshNode * n4,
3647 const SMDS_MeshNode * n5,
3648 const SMDS_MeshNode * n6,
3649 const SMDS_MeshNode * n7,
3650 const SMDS_MeshNode * n8,
3651 const SMDS_MeshNode * n12,
3652 const SMDS_MeshNode * n23,
3653 const SMDS_MeshNode * n34,
3654 const SMDS_MeshNode * n41,
3655 const SMDS_MeshNode * n56,
3656 const SMDS_MeshNode * n67,
3657 const SMDS_MeshNode * n78,
3658 const SMDS_MeshNode * n85,
3659 const SMDS_MeshNode * n15,
3660 const SMDS_MeshNode * n26,
3661 const SMDS_MeshNode * n37,
3662 const SMDS_MeshNode * n48)
3664 int ID = myElementIDFactory->GetFreeID();
3665 SMDS_MeshVolume * v =
3666 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3667 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3668 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3672 //=======================================================================
3673 //function : AddVolumeWithID
3675 //=======================================================================
3676 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3677 int n5, int n6, int n7, int n8,
3678 int n12,int n23,int n34,int n41,
3679 int n56,int n67,int n78,int n85,
3680 int n15,int n26,int n37,int n48, int ID)
3682 return SMDS_Mesh::AddVolumeWithID
3683 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3684 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3685 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3686 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3687 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3688 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3689 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3690 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3691 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3692 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3693 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3694 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3695 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3696 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3697 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3698 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3699 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3700 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3701 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3702 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3706 //=======================================================================
3707 //function : AddVolumeWithID
3708 //purpose : 2d order Hexahedrons with 20 nodes
3709 //=======================================================================
3710 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3711 const SMDS_MeshNode * n2,
3712 const SMDS_MeshNode * n3,
3713 const SMDS_MeshNode * n4,
3714 const SMDS_MeshNode * n5,
3715 const SMDS_MeshNode * n6,
3716 const SMDS_MeshNode * n7,
3717 const SMDS_MeshNode * n8,
3718 const SMDS_MeshNode * n12,
3719 const SMDS_MeshNode * n23,
3720 const SMDS_MeshNode * n34,
3721 const SMDS_MeshNode * n41,
3722 const SMDS_MeshNode * n56,
3723 const SMDS_MeshNode * n67,
3724 const SMDS_MeshNode * n78,
3725 const SMDS_MeshNode * n85,
3726 const SMDS_MeshNode * n15,
3727 const SMDS_MeshNode * n26,
3728 const SMDS_MeshNode * n37,
3729 const SMDS_MeshNode * n48,
3732 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3733 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3735 if(hasConstructionFaces()) {
3737 // creation quadratic faces - not implemented
3739 // --- retrieve nodes ID
3740 vector<vtkIdType> nodeIds;
3742 nodeIds.push_back(n1->getId());
3743 nodeIds.push_back(n4->getId());
3744 nodeIds.push_back(n3->getId());
3745 nodeIds.push_back(n2->getId());
3747 nodeIds.push_back(n5->getId());
3748 nodeIds.push_back(n8->getId());
3749 nodeIds.push_back(n7->getId());
3750 nodeIds.push_back(n6->getId());
3752 nodeIds.push_back(n41->getId());
3753 nodeIds.push_back(n34->getId());
3754 nodeIds.push_back(n23->getId());
3755 nodeIds.push_back(n12->getId());
3757 nodeIds.push_back(n85->getId());
3758 nodeIds.push_back(n78->getId());
3759 nodeIds.push_back(n67->getId());
3760 nodeIds.push_back(n56->getId());
3762 nodeIds.push_back(n15->getId());
3763 nodeIds.push_back(n48->getId());
3764 nodeIds.push_back(n37->getId());
3765 nodeIds.push_back(n26->getId());
3767 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3768 volvtk->init(nodeIds, this);
3769 adjustmyCellsCapacity(ID);
3770 myCells[ID] = volvtk;
3771 myInfo.myNbQuadHexas++;
3773 if (!registerElement(ID, volvtk)) {
3774 RemoveElement(volvtk, false);
3780 void SMDS_Mesh::updateNodeMinMax()
3783 if (myNodes.size() == 0)
3788 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3790 myNodeMax=myNodes.size()-1;
3791 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3795 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3797 int val = myIDElements.size();
3798 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3799 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3800 val = myNodes.size();
3801 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3802 myNodes.resize(val +nbNodes, 0);
3805 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3807 int val = myVtkIndex.size();
3808 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3809 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3810 val = myCells.size();
3811 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3812 myNodes.resize(val +nbCells, 0);
3815 void SMDS_Mesh::adjustStructure()
3817 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3820 void SMDS_Mesh::dumpGrid(string ficdump)
3822 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
3823 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
3824 // aWriter->SetFileName(ficdump.c_str());
3825 // aWriter->SetInput(myGrid);
3826 // if(myGrid->GetNumberOfCells())
3828 // aWriter->Write();
3830 // aWriter->Delete();
3831 ficdump = ficdump + "_connectivity";
3832 ofstream ficcon(ficdump.c_str(), ios::out);
3833 int nbPoints = myGrid->GetNumberOfPoints();
3834 ficcon << "-------------------------------- points " << nbPoints << endl;
3835 for (int i=0; i<nbPoints; i++)
3837 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
3839 int nbCells = myGrid->GetNumberOfCells();
3840 ficcon << "-------------------------------- cells " << nbCells << endl;
3841 for (int i=0; i<nbCells; i++)
3843 // MESSAGE(i << " " << myGrid->GetCell(i));
3844 // MESSAGE(" " << myGrid->GetCell(i)->GetCellType());
3845 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
3846 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
3847 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
3848 for (int j=0; j<nbptcell; j++)
3850 ficcon << " " << listid->GetId(j);
3854 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
3855 vtkCellLinks *links = myGrid->GetCellLinks();
3856 for (int i=0; i<nbPoints; i++)
3858 int ncells = links->GetNcells(i);
3859 vtkIdType *cells = links->GetCells(i);
3860 ficcon << i << " - " << ncells << " -";
3861 for (int j=0; j<ncells; j++)
3863 ficcon << " " << cells[j];