1 // Copyright (C) 2007-2008 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
22 // SMESH SMDS : implementaion of Salome mesh data structure
25 #pragma warning(disable:4786)
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
39 #include "SMDS_SpacePosition.hxx"
41 #include <vtkUnstructuredGrid.h>
42 #include <vtkUnstructuredGridWriter.h>
43 #include <vtkUnsignedCharArray.h>
45 #include <vtkCellLinks.h>
46 #include <vtkIdList.h>
55 #include <sys/sysinfo.h>
58 // number of added entities to check memory after
59 #define CHECKMEMORY_INTERVAL 1000
61 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
62 int SMDS_Mesh::chunkSize = 1024;
65 //================================================================================
67 * \brief Raise an exception if free memory (ram+swap) too low
68 * \param doNotRaise - if true, suppres exception, just return free memory size
69 * \retval int - amount of available memory in MB or negative number in failure case
71 //================================================================================
73 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
77 int err = sysinfo( &si );
81 static int limit = -1;
83 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
85 limit = WEXITSTATUS(status);
90 limit = int( limit * 1.5 );
92 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
96 const unsigned long Mbyte = 1024 * 1024;
97 // compute separately to avoid overflow
99 ( si.freeram * si.mem_unit ) / Mbyte +
100 ( si.freeswap * si.mem_unit ) / Mbyte;
102 if ( freeMb > limit )
103 return freeMb - limit;
108 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
110 throw std::bad_alloc();
116 ///////////////////////////////////////////////////////////////////////////////
117 /// Create a new mesh object
118 ///////////////////////////////////////////////////////////////////////////////
119 SMDS_Mesh::SMDS_Mesh()
121 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
122 myElementIDFactory(new SMDS_MeshElementIDFactory()),
123 myHasConstructionEdges(false), myHasConstructionFaces(false),
124 myHasInverseElements(true),
125 myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
126 myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
128 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
129 MESSAGE("myMeshId=" << myMeshId);
130 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
131 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
132 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
133 MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
134 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
135 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
136 myNodeIDFactory->SetMesh(this);
137 myElementIDFactory->SetMesh(this);
138 _meshList.push_back(this);
139 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
140 myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
141 myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
142 myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
146 myIDElements.clear();
148 myGrid = vtkUnstructuredGrid::New();
149 myGrid->Initialize();
151 vtkPoints* points = vtkPoints::New();
152 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
153 myGrid->SetPoints( points );
155 myGrid->BuildLinks();
158 ///////////////////////////////////////////////////////////////////////////////
159 /// Create a new child mesh
160 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
161 /// (2003-09-08) of SMESH
162 ///////////////////////////////////////////////////////////////////////////////
163 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
164 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
165 myElementIDFactory(parent->myElementIDFactory),
166 myHasConstructionEdges(false), myHasConstructionFaces(false),
167 myHasInverseElements(true),
168 myNodePool(parent->myNodePool),
169 myEdgePool(parent->myEdgePool),
170 myFacePool(parent->myFacePool),
171 myVolumePool(parent->myVolumePool)
175 ///////////////////////////////////////////////////////////////////////////////
176 ///Create a submesh and add it to the current mesh
177 ///////////////////////////////////////////////////////////////////////////////
179 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
181 SMDS_Mesh *submesh = new SMDS_Mesh(this);
182 myChildren.insert(myChildren.end(), submesh);
186 ///////////////////////////////////////////////////////////////////////////////
187 ///create a MeshNode and add it to the current Mesh
188 ///An ID is automatically assigned to the node.
189 ///@return : The created node
190 ///////////////////////////////////////////////////////////////////////////////
192 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
194 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
197 ///////////////////////////////////////////////////////////////////////////////
198 ///create a MeshNode and add it to the current Mesh
199 ///@param ID : The ID of the MeshNode to create
200 ///@return : The created node or NULL if a node with this ID already exists
201 ///////////////////////////////////////////////////////////////////////////////
202 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
204 // find the MeshNode corresponding to ID
205 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
207 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
208 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
209 SMDS_MeshNode * node = myNodePool->getNew();
210 node->init(ID, myMeshId, -1, x, y, z);
211 if (ID >= myNodes.size())
213 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
214 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
217 myNodeIDFactory->BindID(ID,node);
224 ///////////////////////////////////////////////////////////////////////////////
225 /// create a Mesh0DElement and add it to the current Mesh
226 /// @return : The created Mesh0DElement
227 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
230 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
231 if (!node) return NULL;
232 return SMDS_Mesh::Add0DElementWithID(node, ID);
235 ///////////////////////////////////////////////////////////////////////////////
236 /// create a Mesh0DElement and add it to the current Mesh
237 /// @return : The created Mesh0DElement
238 ///////////////////////////////////////////////////////////////////////////////
239 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
241 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
244 ///////////////////////////////////////////////////////////////////////////////
245 /// Create a new Mesh0DElement and at it to the mesh
246 /// @param idnode ID of the node
247 /// @param ID ID of the 0D element to create
248 /// @return The created 0D element or NULL if an element with this
249 /// ID already exists or if input node is not found.
250 ///////////////////////////////////////////////////////////////////////////////
251 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
255 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
256 //MESSAGE("Add0DElementWithID" << ID)
257 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
258 if (myElementIDFactory->BindID(ID, el0d)) {
259 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
260 //node->AddInverseElement(el0d);// --- fait avec BindID
261 adjustmyCellsCapacity(ID);
263 myInfo.myNb0DElements++;
271 ///////////////////////////////////////////////////////////////////////////////
272 /// create a MeshEdge and add it to the current Mesh
273 /// @return : The created MeshEdge
274 ///////////////////////////////////////////////////////////////////////////////
276 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
278 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
279 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
280 if(!node1 || !node2) return NULL;
281 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
284 ///////////////////////////////////////////////////////////////////////////////
285 /// create a MeshEdge and add it to the current Mesh
286 /// @return : The created MeshEdge
287 ///////////////////////////////////////////////////////////////////////////////
289 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
290 const SMDS_MeshNode * node2)
292 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
295 ///////////////////////////////////////////////////////////////////////////////
296 /// Create a new edge and at it to the mesh
297 /// @param idnode1 ID of the first node
298 /// @param idnode2 ID of the second node
299 /// @param ID ID of the edge to create
300 /// @return The created edge or NULL if an element with this ID already exists or
301 /// if input nodes are not found.
302 ///////////////////////////////////////////////////////////////////////////////
304 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
305 const SMDS_MeshNode * n2,
308 if ( !n1 || !n2 ) return 0;
309 SMDS_MeshEdge * edge = 0;
311 // --- retreive nodes ID
312 vector<vtkIdType> nodeIds;
314 nodeIds.push_back(n1->getId());
315 nodeIds.push_back(n2->getId());
317 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
318 edgevtk->init(nodeIds, this);
320 adjustmyCellsCapacity(ID);
324 if (edge && !registerElement(ID, edge))
326 RemoveElement(edge, false);
332 ///////////////////////////////////////////////////////////////////////////////
333 /// Add a triangle defined by its nodes. An ID is automatically affected to the
335 ///////////////////////////////////////////////////////////////////////////////
337 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
338 const SMDS_MeshNode * n2,
339 const SMDS_MeshNode * n3)
341 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
344 ///////////////////////////////////////////////////////////////////////////////
345 /// Add a triangle defined by its nodes IDs
346 ///////////////////////////////////////////////////////////////////////////////
348 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
350 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
351 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
352 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
353 if(!node1 || !node2 || !node3) return NULL;
354 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
357 ///////////////////////////////////////////////////////////////////////////////
358 /// Add a triangle defined by its nodes
359 ///////////////////////////////////////////////////////////////////////////////
361 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
362 const SMDS_MeshNode * n2,
363 const SMDS_MeshNode * n3,
366 //MESSAGE("AddFaceWithID " << ID)
367 SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
369 if (face && !registerElement(ID, face)) {
370 RemoveElement(face, false);
376 ///////////////////////////////////////////////////////////////////////////////
377 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
379 ///////////////////////////////////////////////////////////////////////////////
381 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
382 const SMDS_MeshNode * n2,
383 const SMDS_MeshNode * n3,
384 const SMDS_MeshNode * n4)
386 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
389 ///////////////////////////////////////////////////////////////////////////////
390 /// Add a quadrangle defined by its nodes IDs
391 ///////////////////////////////////////////////////////////////////////////////
393 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
399 SMDS_MeshNode *node1, *node2, *node3, *node4;
400 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
401 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
402 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
403 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
404 if(!node1 || !node2 || !node3 || !node4) return NULL;
405 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
408 ///////////////////////////////////////////////////////////////////////////////
409 /// Add a quadrangle defined by its nodes
410 ///////////////////////////////////////////////////////////////////////////////
412 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
413 const SMDS_MeshNode * n2,
414 const SMDS_MeshNode * n3,
415 const SMDS_MeshNode * n4,
418 //MESSAGE("AddFaceWithID " << ID);
419 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
421 if (face && !registerElement(ID, face)) {
422 RemoveElement(face, false);
428 ///////////////////////////////////////////////////////////////////////////////
429 /// Add a triangle defined by its edges. An ID is automatically assigned to the
431 ///////////////////////////////////////////////////////////////////////////////
433 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
434 const SMDS_MeshEdge * e2,
435 const SMDS_MeshEdge * e3)
437 if (!hasConstructionEdges())
439 //MESSAGE("AddFaceWithID");
440 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
443 ///////////////////////////////////////////////////////////////////////////////
444 /// Add a triangle defined by its edges
445 ///////////////////////////////////////////////////////////////////////////////
447 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
448 const SMDS_MeshEdge * e2,
449 const SMDS_MeshEdge * e3,
452 if (!hasConstructionEdges())
454 if ( !e1 || !e2 || !e3 ) return 0;
456 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
457 //MESSAGE("AddFaceWithID" << ID);
459 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
460 adjustmyCellsCapacity(ID);
462 myInfo.myNbTriangles++;
464 if (!registerElement(ID, face)) {
465 RemoveElement(face, false);
471 ///////////////////////////////////////////////////////////////////////////////
472 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
474 ///////////////////////////////////////////////////////////////////////////////
476 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
477 const SMDS_MeshEdge * e2,
478 const SMDS_MeshEdge * e3,
479 const SMDS_MeshEdge * e4)
481 if (!hasConstructionEdges())
483 //MESSAGE("AddFaceWithID" );
484 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
487 ///////////////////////////////////////////////////////////////////////////////
488 /// Add a quadrangle defined by its edges
489 ///////////////////////////////////////////////////////////////////////////////
491 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
492 const SMDS_MeshEdge * e2,
493 const SMDS_MeshEdge * e3,
494 const SMDS_MeshEdge * e4,
497 if (!hasConstructionEdges())
499 //MESSAGE("AddFaceWithID" << ID);
500 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
501 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
502 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
503 adjustmyCellsCapacity(ID);
505 myInfo.myNbQuadrangles++;
507 if (!registerElement(ID, face))
509 RemoveElement(face, false);
515 ///////////////////////////////////////////////////////////////////////////////
516 ///Create a new tetrahedron and add it to the mesh.
517 ///@return The created tetrahedron
518 ///////////////////////////////////////////////////////////////////////////////
520 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
521 const SMDS_MeshNode * n2,
522 const SMDS_MeshNode * n3,
523 const SMDS_MeshNode * n4)
525 int ID = myElementIDFactory->GetFreeID();
526 //MESSAGE("AddVolumeWithID " << ID);
527 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
528 if(v==NULL) myElementIDFactory->ReleaseID(ID);
532 ///////////////////////////////////////////////////////////////////////////////
533 ///Create a new tetrahedron and add it to the mesh.
534 ///@param ID The ID of the new volume
535 ///@return The created tetrahedron or NULL if an element with this ID already exists
536 ///or if input nodes are not found.
537 ///////////////////////////////////////////////////////////////////////////////
539 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
545 //MESSAGE("AddVolumeWithID" << ID);
546 SMDS_MeshNode *node1, *node2, *node3, *node4;
547 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
548 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
549 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
550 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
551 if(!node1 || !node2 || !node3 || !node4) return NULL;
552 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
555 ///////////////////////////////////////////////////////////////////////////////
556 ///Create a new tetrahedron and add it to the mesh.
557 ///@param ID The ID of the new volume
558 ///@return The created tetrahedron
559 ///////////////////////////////////////////////////////////////////////////////
561 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
562 const SMDS_MeshNode * n2,
563 const SMDS_MeshNode * n3,
564 const SMDS_MeshNode * n4,
567 //MESSAGE("AddVolumeWithID " << ID);
568 SMDS_MeshVolume* volume = 0;
569 if ( !n1 || !n2 || !n3 || !n4) return volume;
570 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
571 if(hasConstructionFaces()) {
572 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
573 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
574 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
575 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
576 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
577 adjustmyCellsCapacity(ID);
578 myCells[ID] = volume;
581 else if(hasConstructionEdges()) {
582 MESSAGE("Error : Not implemented");
586 // --- retrieve nodes ID
587 vector<vtkIdType> nodeIds;
589 nodeIds.push_back(n1->getId());
590 nodeIds.push_back(n3->getId()); // order SMDS-->VTK
591 nodeIds.push_back(n2->getId());
592 nodeIds.push_back(n4->getId());
594 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
595 volvtk->init(nodeIds, this);
597 adjustmyCellsCapacity(ID);
598 myCells[ID] = volume;
602 if (!registerElement(ID, volume)) {
603 RemoveElement(volume, false);
609 ///////////////////////////////////////////////////////////////////////////////
610 ///Create a new pyramid and add it to the mesh.
611 ///Nodes 1,2,3 and 4 define the base of the pyramid
612 ///@return The created pyramid
613 ///////////////////////////////////////////////////////////////////////////////
615 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
616 const SMDS_MeshNode * n2,
617 const SMDS_MeshNode * n3,
618 const SMDS_MeshNode * n4,
619 const SMDS_MeshNode * n5)
621 int ID = myElementIDFactory->GetFreeID();
622 //MESSAGE("AddVolumeWithID " << ID);
623 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
624 if(v==NULL) myElementIDFactory->ReleaseID(ID);
628 ///////////////////////////////////////////////////////////////////////////////
629 ///Create a new pyramid and add it to the mesh.
630 ///Nodes 1,2,3 and 4 define the base of the pyramid
631 ///@param ID The ID of the new volume
632 ///@return The created pyramid or NULL if an element with this ID already exists
633 ///or if input nodes are not found.
634 ///////////////////////////////////////////////////////////////////////////////
636 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
643 //MESSAGE("AddVolumeWithID " << ID);
644 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
645 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
646 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
647 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
648 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
649 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
650 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
651 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
654 ///////////////////////////////////////////////////////////////////////////////
655 ///Create a new pyramid and add it to the mesh.
656 ///Nodes 1,2,3 and 4 define the base of the pyramid
657 ///@param ID The ID of the new volume
658 ///@return The created pyramid
659 ///////////////////////////////////////////////////////////////////////////////
661 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
662 const SMDS_MeshNode * n2,
663 const SMDS_MeshNode * n3,
664 const SMDS_MeshNode * n4,
665 const SMDS_MeshNode * n5,
668 //MESSAGE("AddVolumeWithID " << ID);
669 SMDS_MeshVolume* volume = 0;
670 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
671 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
672 if(hasConstructionFaces()) {
673 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
674 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
675 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
676 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
677 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
678 adjustmyCellsCapacity(ID);
679 myCells[ID] = volume;
680 myInfo.myNbPyramids++;
682 else if(hasConstructionEdges()) {
683 MESSAGE("Error : Not implemented");
687 // --- retrieve nodes ID
688 vector<vtkIdType> nodeIds;
690 nodeIds.push_back(n1->getId());
691 nodeIds.push_back(n4->getId());
692 nodeIds.push_back(n3->getId());
693 nodeIds.push_back(n2->getId());
694 nodeIds.push_back(n5->getId());
696 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
697 volvtk->init(nodeIds, this);
699 adjustmyCellsCapacity(ID);
700 myCells[ID] = volume;
701 myInfo.myNbPyramids++;
704 if (!registerElement(ID, volume)) {
705 RemoveElement(volume, false);
711 ///////////////////////////////////////////////////////////////////////////////
712 ///Create a new prism and add it to the mesh.
713 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
714 ///@return The created prism
715 ///////////////////////////////////////////////////////////////////////////////
717 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
718 const SMDS_MeshNode * n2,
719 const SMDS_MeshNode * n3,
720 const SMDS_MeshNode * n4,
721 const SMDS_MeshNode * n5,
722 const SMDS_MeshNode * n6)
724 int ID = myElementIDFactory->GetFreeID();
725 //MESSAGE("AddVolumeWithID " << ID);
726 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
727 if(v==NULL) myElementIDFactory->ReleaseID(ID);
731 ///////////////////////////////////////////////////////////////////////////////
732 ///Create a new prism and add it to the mesh.
733 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
734 ///@param ID The ID of the new volume
735 ///@return The created prism or NULL if an element with this ID already exists
736 ///or if input nodes are not found.
737 ///////////////////////////////////////////////////////////////////////////////
739 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
747 //MESSAGE("AddVolumeWithID " << ID);
748 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
749 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
750 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
751 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
752 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
753 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
754 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
755 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
756 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
759 ///////////////////////////////////////////////////////////////////////////////
760 ///Create a new prism and add it to the mesh.
761 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
762 ///@param ID The ID of the new volume
763 ///@return The created prism
764 ///////////////////////////////////////////////////////////////////////////////
766 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
767 const SMDS_MeshNode * n2,
768 const SMDS_MeshNode * n3,
769 const SMDS_MeshNode * n4,
770 const SMDS_MeshNode * n5,
771 const SMDS_MeshNode * n6,
774 //MESSAGE("AddVolumeWithID " << ID);
775 SMDS_MeshVolume* volume = 0;
776 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
777 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
778 if(hasConstructionFaces()) {
779 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
780 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
781 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
782 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
783 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
784 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
785 adjustmyCellsCapacity(ID);
786 myCells[ID] = volume;
789 else if(hasConstructionEdges()) {
790 MESSAGE("Error : Not implemented");
794 // --- retrieve nodes ID
795 vector<vtkIdType> nodeIds;
797 nodeIds.push_back(n1->getId());
798 nodeIds.push_back(n3->getId());
799 nodeIds.push_back(n2->getId());
800 nodeIds.push_back(n4->getId());
801 nodeIds.push_back(n6->getId());
802 nodeIds.push_back(n5->getId());
804 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
805 volvtk->init(nodeIds, this);
807 adjustmyCellsCapacity(ID);
808 myCells[ID] = volume;
812 if (!registerElement(ID, volume)) {
813 RemoveElement(volume, false);
819 ///////////////////////////////////////////////////////////////////////////////
820 ///Create a new hexahedron and add it to the mesh.
821 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
822 ///@return The created hexahedron
823 ///////////////////////////////////////////////////////////////////////////////
825 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
826 const SMDS_MeshNode * n2,
827 const SMDS_MeshNode * n3,
828 const SMDS_MeshNode * n4,
829 const SMDS_MeshNode * n5,
830 const SMDS_MeshNode * n6,
831 const SMDS_MeshNode * n7,
832 const SMDS_MeshNode * n8)
834 int ID = myElementIDFactory->GetFreeID();
835 //MESSAGE("AddVolumeWithID " << ID);
836 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
837 if(v==NULL) myElementIDFactory->ReleaseID(ID);
841 ///////////////////////////////////////////////////////////////////////////////
842 ///Create a new hexahedron and add it to the mesh.
843 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
844 ///@param ID The ID of the new volume
845 ///@return The created hexahedron or NULL if an element with this ID already
846 ///exists or if input nodes are not found.
847 ///////////////////////////////////////////////////////////////////////////////
849 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
859 //MESSAGE("AddVolumeWithID " << ID);
860 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
861 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
862 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
863 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
864 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
865 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
866 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
867 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
868 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
869 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
871 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
875 ///////////////////////////////////////////////////////////////////////////////
876 ///Create a new hexahedron and add it to the mesh.
877 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
878 ///@param ID The ID of the new volume
879 ///@return The created prism or NULL if an element with this ID already exists
880 ///or if input nodes are not found.
881 ///////////////////////////////////////////////////////////////////////////////
883 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
884 const SMDS_MeshNode * n2,
885 const SMDS_MeshNode * n3,
886 const SMDS_MeshNode * n4,
887 const SMDS_MeshNode * n5,
888 const SMDS_MeshNode * n6,
889 const SMDS_MeshNode * n7,
890 const SMDS_MeshNode * n8,
893 //MESSAGE("AddVolumeWithID " << ID);
894 SMDS_MeshVolume* volume = 0;
895 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
896 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
897 if(hasConstructionFaces()) {
898 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
899 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
900 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
901 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
902 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
903 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
904 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
905 adjustmyCellsCapacity(ID);
906 myCells[ID] = volume;
909 else if(hasConstructionEdges()) {
910 MESSAGE("Error : Not implemented");
914 // --- retrieve nodes ID
915 vector<vtkIdType> nodeIds;
917 nodeIds.push_back(n1->getId());
918 nodeIds.push_back(n4->getId());
919 nodeIds.push_back(n3->getId());
920 nodeIds.push_back(n2->getId());
921 nodeIds.push_back(n5->getId());
922 nodeIds.push_back(n8->getId());
923 nodeIds.push_back(n7->getId());
924 nodeIds.push_back(n6->getId());
926 SMDS_VtkVolume *volvtk = myVolumePool->getNew();
927 volvtk->init(nodeIds, this);
929 adjustmyCellsCapacity(ID);
930 myCells[ID] = volume;
934 if (!registerElement(ID, volume)) {
935 RemoveElement(volume, false);
941 ///////////////////////////////////////////////////////////////////////////////
942 ///Create a new tetrahedron defined by its faces and add it to the mesh.
943 ///@return The created tetrahedron
944 ///////////////////////////////////////////////////////////////////////////////
946 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
947 const SMDS_MeshFace * f2,
948 const SMDS_MeshFace * f3,
949 const SMDS_MeshFace * f4)
951 //MESSAGE("AddVolumeWithID");
952 if (!hasConstructionFaces())
954 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
957 ///////////////////////////////////////////////////////////////////////////////
958 ///Create a new tetrahedron defined by its faces and add it to the mesh.
959 ///@param ID The ID of the new volume
960 ///@return The created tetrahedron
961 ///////////////////////////////////////////////////////////////////////////////
963 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
964 const SMDS_MeshFace * f2,
965 const SMDS_MeshFace * f3,
966 const SMDS_MeshFace * f4,
969 //MESSAGE("AddVolumeWithID" << ID);
970 if (!hasConstructionFaces())
972 if ( !f1 || !f2 || !f3 || !f4) return 0;
973 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
974 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
975 adjustmyCellsCapacity(ID);
976 myCells[ID] = volume;
979 if (!registerElement(ID, volume)) {
980 RemoveElement(volume, false);
986 ///////////////////////////////////////////////////////////////////////////////
987 ///Create a new pyramid defined by its faces and add it to the mesh.
988 ///@return The created pyramid
989 ///////////////////////////////////////////////////////////////////////////////
991 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
992 const SMDS_MeshFace * f2,
993 const SMDS_MeshFace * f3,
994 const SMDS_MeshFace * f4,
995 const SMDS_MeshFace * f5)
997 //MESSAGE("AddVolumeWithID");
998 if (!hasConstructionFaces())
1000 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1003 ///////////////////////////////////////////////////////////////////////////////
1004 ///Create a new pyramid defined by its faces and add it to the mesh.
1005 ///@param ID The ID of the new volume
1006 ///@return The created pyramid
1007 ///////////////////////////////////////////////////////////////////////////////
1009 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1010 const SMDS_MeshFace * f2,
1011 const SMDS_MeshFace * f3,
1012 const SMDS_MeshFace * f4,
1013 const SMDS_MeshFace * f5,
1016 //MESSAGE("AddVolumeWithID" << ID);
1017 if (!hasConstructionFaces())
1019 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1020 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1021 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1022 adjustmyCellsCapacity(ID);
1023 myCells[ID] = volume;
1024 myInfo.myNbPyramids++;
1026 if (!registerElement(ID, volume)) {
1027 RemoveElement(volume, false);
1033 ///////////////////////////////////////////////////////////////////////////////
1034 ///Create a new prism defined by its faces and add it to the mesh.
1035 ///@return The created prism
1036 ///////////////////////////////////////////////////////////////////////////////
1038 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1039 const SMDS_MeshFace * f2,
1040 const SMDS_MeshFace * f3,
1041 const SMDS_MeshFace * f4,
1042 const SMDS_MeshFace * f5,
1043 const SMDS_MeshFace * f6)
1045 //MESSAGE("AddVolumeWithID" );
1046 if (!hasConstructionFaces())
1048 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1051 ///////////////////////////////////////////////////////////////////////////////
1052 ///Create a new prism defined by its faces and add it to the mesh.
1053 ///@param ID The ID of the new volume
1054 ///@return The created prism
1055 ///////////////////////////////////////////////////////////////////////////////
1057 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1058 const SMDS_MeshFace * f2,
1059 const SMDS_MeshFace * f3,
1060 const SMDS_MeshFace * f4,
1061 const SMDS_MeshFace * f5,
1062 const SMDS_MeshFace * f6,
1065 //MESSAGE("AddVolumeWithID" << ID);
1066 if (!hasConstructionFaces())
1068 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1069 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1070 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1071 adjustmyCellsCapacity(ID);
1072 myCells[ID] = volume;
1073 myInfo.myNbPrisms++;
1075 if (!registerElement(ID, volume)) {
1076 RemoveElement(volume, false);
1082 ///////////////////////////////////////////////////////////////////////////////
1083 /// Add a polygon defined by its nodes IDs
1084 ///////////////////////////////////////////////////////////////////////////////
1086 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1089 int nbNodes = nodes_ids.size();
1090 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1091 for (int i = 0; i < nbNodes; i++) {
1092 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1093 if (!nodes[i]) return NULL;
1095 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1098 ///////////////////////////////////////////////////////////////////////////////
1099 /// Add a polygon defined by its nodes
1100 ///////////////////////////////////////////////////////////////////////////////
1102 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1103 (std::vector<const SMDS_MeshNode*> nodes,
1106 SMDS_MeshFace * face;
1108 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1109 if (hasConstructionEdges())
1111 MESSAGE("Error : Not implemented");
1116 for ( int i = 0; i < nodes.size(); ++i )
1117 if ( !nodes[ i ] ) return 0;
1118 face = new SMDS_PolygonalFaceOfNodes(nodes);
1119 adjustmyCellsCapacity(ID);
1121 myInfo.myNbPolygons++;
1124 if (!registerElement(ID, face)) {
1125 RemoveElement(face, false);
1131 ///////////////////////////////////////////////////////////////////////////////
1132 /// Add a polygon defined by its nodes.
1133 /// An ID is automatically affected to the created face.
1134 ///////////////////////////////////////////////////////////////////////////////
1136 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1138 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1141 ///////////////////////////////////////////////////////////////////////////////
1142 /// Create a new polyhedral volume and add it to the mesh.
1143 /// @param ID The ID of the new volume
1144 /// @return The created volume or NULL if an element with this ID already exists
1145 /// or if input nodes are not found.
1146 ///////////////////////////////////////////////////////////////////////////////
1148 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1149 (std::vector<int> nodes_ids,
1150 std::vector<int> quantities,
1153 int nbNodes = nodes_ids.size();
1154 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1155 for (int i = 0; i < nbNodes; i++) {
1156 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1157 if (!nodes[i]) return NULL;
1159 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1162 ///////////////////////////////////////////////////////////////////////////////
1163 /// Create a new polyhedral volume and add it to the mesh.
1164 /// @param ID The ID of the new volume
1165 /// @return The created volume
1166 ///////////////////////////////////////////////////////////////////////////////
1168 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1169 (std::vector<const SMDS_MeshNode*> nodes,
1170 std::vector<int> quantities,
1173 SMDS_MeshVolume* volume;
1174 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1175 if (hasConstructionFaces()) {
1176 MESSAGE("Error : Not implemented");
1178 } else if (hasConstructionEdges()) {
1179 MESSAGE("Error : Not implemented");
1182 for ( int i = 0; i < nodes.size(); ++i )
1183 if ( !nodes[ i ] ) return 0;
1184 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1185 adjustmyCellsCapacity(ID);
1186 myCells[ID] = volume;
1187 myInfo.myNbPolyhedrons++;
1190 if (!registerElement(ID, volume)) {
1191 RemoveElement(volume, false);
1197 ///////////////////////////////////////////////////////////////////////////////
1198 /// Create a new polyhedral volume and add it to the mesh.
1199 /// @return The created volume
1200 ///////////////////////////////////////////////////////////////////////////////
1202 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1203 (std::vector<const SMDS_MeshNode*> nodes,
1204 std::vector<int> quantities)
1206 int ID = myElementIDFactory->GetFreeID();
1207 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1208 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1212 ///////////////////////////////////////////////////////////////////////////////
1213 /// Registers element with the given ID, maintains inverse connections
1214 ///////////////////////////////////////////////////////////////////////////////
1215 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1217 //MESSAGE("registerElement " << ID);
1218 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1220 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1225 element->myMeshId = myMeshId;
1227 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1229 int vtkId = cell->getVtkId();
1231 vtkId = myElementIDFactory->SetInVtkGrid(element);
1233 if (ID >= myIDElements.size()) // --- resize local vector
1235 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1236 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1239 myIDElements[ID] = vtkId;
1240 //MESSAGE("smds:" << ID << " vtk:" << vtkId );
1242 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1244 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1245 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1247 myVtkIndex[vtkId] = ID;
1249 myElementIDFactory->updateMinMax(ID);
1253 ///////////////////////////////////////////////////////////////////////////////
1254 /// Return the node whose ID is 'ID'.
1255 ///////////////////////////////////////////////////////////////////////////////
1256 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1258 if (ID < 0 || ID >= myNodes.size())
1260 MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1263 return (const SMDS_MeshNode *)myNodes[ID];
1266 ///////////////////////////////////////////////////////////////////////////////
1267 ///Create a triangle and add it to the current mesh. This method do not bind an
1268 ///ID to the create triangle.
1269 ///////////////////////////////////////////////////////////////////////////////
1270 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1271 const SMDS_MeshNode * node2,
1272 const SMDS_MeshNode * node3,
1275 if ( !node1 || !node2 || !node3) return 0;
1276 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1277 if(hasConstructionEdges())
1279 SMDS_MeshEdge *edge1, *edge2, *edge3;
1280 edge1=FindEdgeOrCreate(node1,node2);
1281 edge2=FindEdgeOrCreate(node2,node3);
1282 edge3=FindEdgeOrCreate(node3,node1);
1284 //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1285 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1286 adjustmyCellsCapacity(ID);
1288 myInfo.myNbTriangles++;
1293 // --- retrieve nodes ID
1294 vector<vtkIdType> nodeIds;
1296 nodeIds.push_back(node1->getId());
1297 nodeIds.push_back(node2->getId());
1298 nodeIds.push_back(node3->getId());
1300 SMDS_MeshFace * face = 0;
1301 SMDS_VtkFace *facevtk = myFacePool->getNew();
1302 facevtk->init(nodeIds, this);
1304 adjustmyCellsCapacity(ID);
1306 //MESSAGE("createTriangle " << ID << " " << face);
1307 myInfo.myNbTriangles++;
1312 ///////////////////////////////////////////////////////////////////////////////
1313 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1314 ///a ID to the create triangle.
1315 ///////////////////////////////////////////////////////////////////////////////
1316 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1317 const SMDS_MeshNode * node2,
1318 const SMDS_MeshNode * node3,
1319 const SMDS_MeshNode * node4,
1322 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1323 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1324 if(hasConstructionEdges())
1326 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1327 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1328 edge1=FindEdgeOrCreate(node1,node2);
1329 edge2=FindEdgeOrCreate(node2,node3);
1330 edge3=FindEdgeOrCreate(node3,node4);
1331 edge4=FindEdgeOrCreate(node4,node1);
1333 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1334 adjustmyCellsCapacity(ID);
1336 myInfo.myNbQuadrangles++;
1341 // --- retrieve nodes ID
1342 vector<vtkIdType> nodeIds;
1344 nodeIds.push_back(node1->getId());
1345 nodeIds.push_back(node2->getId());
1346 nodeIds.push_back(node3->getId());
1347 nodeIds.push_back(node4->getId());
1349 SMDS_MeshFace * face = 0;
1350 SMDS_VtkFace *facevtk = myFacePool->getNew();
1351 facevtk->init(nodeIds, this);
1353 adjustmyCellsCapacity(ID);
1355 myInfo.myNbQuadrangles++;
1360 ///////////////////////////////////////////////////////////////////////////////
1361 /// Remove a node and all the elements which own this node
1362 ///////////////////////////////////////////////////////////////////////////////
1364 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1366 MESSAGE("RemoveNode");
1367 RemoveElement(node, true);
1370 ///////////////////////////////////////////////////////////////////////////////
1371 /// Remove an edge and all the elements which own this edge
1372 ///////////////////////////////////////////////////////////////////////////////
1374 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1376 MESSAGE("Remove0DElement");
1377 RemoveElement(elem0d,true);
1380 ///////////////////////////////////////////////////////////////////////////////
1381 /// Remove an edge and all the elements which own this edge
1382 ///////////////////////////////////////////////////////////////////////////////
1384 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1386 MESSAGE("RemoveEdge");
1387 RemoveElement(edge,true);
1390 ///////////////////////////////////////////////////////////////////////////////
1391 /// Remove an face and all the elements which own this face
1392 ///////////////////////////////////////////////////////////////////////////////
1394 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1396 MESSAGE("RemoveFace");
1397 RemoveElement(face, true);
1400 ///////////////////////////////////////////////////////////////////////////////
1402 ///////////////////////////////////////////////////////////////////////////////
1404 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1406 MESSAGE("RemoveVolume");
1407 RemoveElement(volume, true);
1410 //=======================================================================
1411 //function : RemoveFromParent
1413 //=======================================================================
1415 bool SMDS_Mesh::RemoveFromParent()
1417 if (myParent==NULL) return false;
1418 else return (myParent->RemoveSubMesh(this));
1421 //=======================================================================
1422 //function : RemoveSubMesh
1424 //=======================================================================
1426 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1430 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1431 for (; itmsh!=myChildren.end() && !found; itmsh++)
1433 SMDS_Mesh * submesh = *itmsh;
1434 if (submesh == aMesh)
1437 myChildren.erase(itmsh);
1444 //=======================================================================
1445 //function : ChangeElementNodes
1447 //=======================================================================
1449 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1450 const SMDS_MeshNode * nodes[],
1453 MYASSERT(0); // REVOIR LES TYPES
1454 // keep current nodes of elem
1455 set<const SMDS_MeshElement*> oldNodes;
1456 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1458 oldNodes.insert( itn->next() );
1460 if ( !element->IsPoly() )
1461 myInfo.remove( element ); // element may change type
1465 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1466 switch ( elem->GetType() )
1468 case SMDSAbs_0DElement: {
1469 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1470 Ok = elem0d->ChangeNode( nodes[0] );
1473 case SMDSAbs_Edge: {
1474 if ( nbnodes == 2 ) {
1475 if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
1476 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1478 else if ( nbnodes == 3 ) {
1479 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1480 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1484 case SMDSAbs_Face: {
1485 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1486 Ok = face->ChangeNodes( nodes, nbnodes );
1488 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1489 Ok = QF->ChangeNodes( nodes, nbnodes );
1491 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1492 Ok = face->ChangeNodes(nodes, nbnodes);
1495 case SMDSAbs_Volume: {
1496 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1497 Ok = vol->ChangeNodes( nodes, nbnodes );
1499 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1500 Ok = QV->ChangeNodes( nodes, nbnodes );
1504 MESSAGE ( "WRONG ELEM TYPE");
1507 if ( Ok ) { // update InverseElements
1509 set<const SMDS_MeshElement*>::iterator it;
1511 // AddInverseElement to new nodes
1512 for ( int i = 0; i < nbnodes; i++ ) {
1513 it = oldNodes.find( nodes[i] );
1514 if ( it == oldNodes.end() )
1516 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1518 // remove from oldNodes a node that remains in elem
1519 oldNodes.erase( it );
1521 // RemoveInverseElement from the nodes removed from elem
1522 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1524 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1525 (const_cast<SMDS_MeshElement *>( *it ));
1526 n->RemoveInverseElement( elem );
1530 if ( !element->IsPoly() )
1531 myInfo.add( element ); // element may change type
1536 //=======================================================================
1537 //function : ChangePolyhedronNodes
1538 //purpose : to change nodes of polyhedral volume
1539 //=======================================================================
1540 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1541 const vector<const SMDS_MeshNode*>& nodes,
1542 const vector<int> & quantities)
1544 if (elem->GetType() != SMDSAbs_Volume) {
1545 MESSAGE("WRONG ELEM TYPE");
1549 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1554 // keep current nodes of elem
1555 set<const SMDS_MeshElement*> oldNodes;
1556 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1557 while (itn->more()) {
1558 oldNodes.insert(itn->next());
1562 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1567 // update InverseElements
1569 // AddInverseElement to new nodes
1570 int nbnodes = nodes.size();
1571 set<const SMDS_MeshElement*>::iterator it;
1572 for (int i = 0; i < nbnodes; i++) {
1573 it = oldNodes.find(nodes[i]);
1574 if (it == oldNodes.end()) {
1576 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1578 // remove from oldNodes a node that remains in elem
1583 // RemoveInverseElement from the nodes removed from elem
1584 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1585 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1586 (const_cast<SMDS_MeshElement *>( *it ));
1587 n->RemoveInverseElement(elem);
1594 //=======================================================================
1595 //function : Find0DElement
1597 //=======================================================================
1598 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1600 const SMDS_MeshNode * node = FindNode(idnode);
1601 if(node == NULL) return NULL;
1602 return Find0DElement(node);
1605 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1607 if (!node) return 0;
1608 const SMDS_Mesh0DElement* toReturn = NULL;
1609 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1610 while (it1->more() && (toReturn == NULL)) {
1611 const SMDS_MeshElement* e = it1->next();
1612 if (e->NbNodes() == 1) {
1613 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1619 //=======================================================================
1620 //function : Find0DElementOrCreate
1622 //=======================================================================
1623 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1625 // if (!node) return 0;
1626 // SMDS_Mesh0DElement * toReturn = NULL;
1627 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1628 // if (toReturn == NULL) {
1629 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1630 // toReturn = new SMDS_Mesh0DElement(node);
1631 // my0DElements.Add(toReturn);
1632 // myInfo.myNb0DElements++;
1638 //=======================================================================
1639 //function : FindEdge
1641 //=======================================================================
1643 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1645 const SMDS_MeshNode * node1=FindNode(idnode1);
1646 const SMDS_MeshNode * node2=FindNode(idnode2);
1647 if((node1==NULL)||(node2==NULL)) return NULL;
1648 return FindEdge(node1,node2);
1651 //#include "Profiler.h"
1652 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1653 const SMDS_MeshNode * node2)
1655 if ( !node1 ) return 0;
1656 const SMDS_MeshEdge * toReturn=NULL;
1659 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1662 while(it1->more()) {
1663 const SMDS_MeshElement * e = it1->next();
1664 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1665 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1674 //=======================================================================
1675 //function : FindEdgeOrCreate
1677 //=======================================================================
1679 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1680 const SMDS_MeshNode * node2)
1682 if ( !node1 || !node2) return 0;
1683 SMDS_MeshEdge * toReturn=NULL;
1684 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1685 if(toReturn==NULL) {
1686 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1687 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1688 adjustmyCellsCapacity(ID);
1689 vector<vtkIdType> nodeIds;
1691 nodeIds.push_back(node1->getId());
1692 nodeIds.push_back(node2->getId());
1694 SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1695 edgevtk->init(nodeIds, this);
1697 myCells[ID] = toReturn;
1704 //=======================================================================
1705 //function : FindEdge
1707 //=======================================================================
1709 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1712 const SMDS_MeshNode * node1=FindNode(idnode1);
1713 const SMDS_MeshNode * node2=FindNode(idnode2);
1714 const SMDS_MeshNode * node3=FindNode(idnode3);
1715 return FindEdge(node1,node2,node3);
1718 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1719 const SMDS_MeshNode * node2,
1720 const SMDS_MeshNode * node3)
1722 if ( !node1 ) return 0;
1723 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1724 while(it1->more()) {
1725 const SMDS_MeshElement * e = it1->next();
1726 if ( e->NbNodes() == 3 ) {
1727 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1728 while(it2->more()) {
1729 const SMDS_MeshElement* n = it2->next();
1739 return static_cast<const SMDS_MeshEdge *> (e);
1746 //=======================================================================
1747 //function : FindFace
1749 //=======================================================================
1751 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1754 const SMDS_MeshNode * node1=FindNode(idnode1);
1755 const SMDS_MeshNode * node2=FindNode(idnode2);
1756 const SMDS_MeshNode * node3=FindNode(idnode3);
1757 return FindFace(node1, node2, node3);
1760 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1761 const SMDS_MeshNode *node2,
1762 const SMDS_MeshNode *node3)
1764 if ( !node1 ) return 0;
1765 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1766 while(it1->more()) {
1767 const SMDS_MeshElement * e = it1->next();
1768 if ( e->NbNodes() == 3 ) {
1769 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1770 while(it2->more()) {
1771 const SMDS_MeshElement* n = it2->next();
1781 return static_cast<const SMDS_MeshFace *> (e);
1787 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1788 const SMDS_MeshNode *node2,
1789 const SMDS_MeshNode *node3)
1791 SMDS_MeshFace * toReturn=NULL;
1792 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1793 if(toReturn==NULL) {
1794 int ID = myElementIDFactory->GetFreeID();
1795 toReturn = createTriangle(node1,node2,node3, ID);
1801 //=======================================================================
1802 //function : FindFace
1804 //=======================================================================
1806 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1807 int idnode3, int idnode4) const
1809 const SMDS_MeshNode * node1=FindNode(idnode1);
1810 const SMDS_MeshNode * node2=FindNode(idnode2);
1811 const SMDS_MeshNode * node3=FindNode(idnode3);
1812 const SMDS_MeshNode * node4=FindNode(idnode4);
1813 return FindFace(node1, node2, node3, node4);
1816 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1817 const SMDS_MeshNode *node2,
1818 const SMDS_MeshNode *node3,
1819 const SMDS_MeshNode *node4)
1821 if ( !node1 ) return 0;
1822 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1823 while(it1->more()) {
1824 const SMDS_MeshElement * e = it1->next();
1825 if ( e->NbNodes() == 4 ) {
1826 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1827 while(it2->more()) {
1828 const SMDS_MeshElement* n = it2->next();
1839 return static_cast<const SMDS_MeshFace *> (e);
1845 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1846 const SMDS_MeshNode *node2,
1847 const SMDS_MeshNode *node3,
1848 const SMDS_MeshNode *node4)
1850 SMDS_MeshFace * toReturn=NULL;
1851 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1852 if(toReturn==NULL) {
1853 int ID = myElementIDFactory->GetFreeID();
1854 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1860 //=======================================================================
1861 //function : FindFace
1862 //purpose :quadratic triangle
1863 //=======================================================================
1865 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1866 int idnode3, int idnode4,
1867 int idnode5, int idnode6) const
1869 const SMDS_MeshNode * node1 = FindNode(idnode1);
1870 const SMDS_MeshNode * node2 = FindNode(idnode2);
1871 const SMDS_MeshNode * node3 = FindNode(idnode3);
1872 const SMDS_MeshNode * node4 = FindNode(idnode4);
1873 const SMDS_MeshNode * node5 = FindNode(idnode5);
1874 const SMDS_MeshNode * node6 = FindNode(idnode6);
1875 return FindFace(node1, node2, node3, node4, node5, node6);
1878 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1879 const SMDS_MeshNode *node2,
1880 const SMDS_MeshNode *node3,
1881 const SMDS_MeshNode *node4,
1882 const SMDS_MeshNode *node5,
1883 const SMDS_MeshNode *node6)
1885 if ( !node1 ) return 0;
1886 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1887 while(it1->more()) {
1888 const SMDS_MeshElement * e = it1->next();
1889 if ( e->NbNodes() == 6 ) {
1890 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1891 while(it2->more()) {
1892 const SMDS_MeshElement* n = it2->next();
1905 return static_cast<const SMDS_MeshFace *> (e);
1912 //=======================================================================
1913 //function : FindFace
1914 //purpose : quadratic quadrangle
1915 //=======================================================================
1917 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1918 int idnode3, int idnode4,
1919 int idnode5, int idnode6,
1920 int idnode7, int idnode8) const
1922 const SMDS_MeshNode * node1 = FindNode(idnode1);
1923 const SMDS_MeshNode * node2 = FindNode(idnode2);
1924 const SMDS_MeshNode * node3 = FindNode(idnode3);
1925 const SMDS_MeshNode * node4 = FindNode(idnode4);
1926 const SMDS_MeshNode * node5 = FindNode(idnode5);
1927 const SMDS_MeshNode * node6 = FindNode(idnode6);
1928 const SMDS_MeshNode * node7 = FindNode(idnode7);
1929 const SMDS_MeshNode * node8 = FindNode(idnode8);
1930 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1933 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1934 const SMDS_MeshNode *node2,
1935 const SMDS_MeshNode *node3,
1936 const SMDS_MeshNode *node4,
1937 const SMDS_MeshNode *node5,
1938 const SMDS_MeshNode *node6,
1939 const SMDS_MeshNode *node7,
1940 const SMDS_MeshNode *node8)
1942 if ( !node1 ) return 0;
1943 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1944 while(it1->more()) {
1945 const SMDS_MeshElement * e = it1->next();
1946 if ( e->NbNodes() == 8 ) {
1947 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1948 while(it2->more()) {
1949 const SMDS_MeshElement* n = it2->next();
1964 return static_cast<const SMDS_MeshFace *> (e);
1971 //=======================================================================
1972 //function : FindElement
1974 //=======================================================================
1976 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1978 if ((IDelem < 0) || IDelem >= myCells.size())
1980 MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
1983 return myCells[IDelem];
1986 //=======================================================================
1987 //function : FindFace
1988 //purpose : find polygon
1989 //=======================================================================
1991 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1993 int nbnodes = nodes_ids.size();
1994 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1995 for (int inode = 0; inode < nbnodes; inode++) {
1996 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1997 if (node == NULL) return NULL;
1998 poly_nodes[inode] = node;
2000 return FindFace(poly_nodes);
2003 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
2005 if ( nodes.size() > 2 && nodes[0] ) {
2006 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
2007 while (itF->more()) {
2008 const SMDS_MeshElement* f = itF->next();
2009 if ( f->NbNodes() == nodes.size() ) {
2010 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
2011 while(it2->more()) {
2012 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
2018 return static_cast<const SMDS_MeshFace *> (f);
2025 //=======================================================================
2026 //function : DumpNodes
2028 //=======================================================================
2030 void SMDS_Mesh::DumpNodes() const
2032 MESSAGE("dump nodes of mesh : ");
2033 SMDS_NodeIteratorPtr itnode=nodesIterator();
2034 while(itnode->more()) ; //MESSAGE(itnode->next());
2037 //=======================================================================
2038 //function : Dump0DElements
2040 //=======================================================================
2041 void SMDS_Mesh::Dump0DElements() const
2043 MESSAGE("dump 0D elements of mesh : ");
2044 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2045 while(it0d->more()) ; //MESSAGE(it0d->next());
2048 //=======================================================================
2049 //function : DumpEdges
2051 //=======================================================================
2053 void SMDS_Mesh::DumpEdges() const
2055 MESSAGE("dump edges of mesh : ");
2056 SMDS_EdgeIteratorPtr itedge=edgesIterator();
2057 while(itedge->more()) ; //MESSAGE(itedge->next());
2060 //=======================================================================
2061 //function : DumpFaces
2063 //=======================================================================
2065 void SMDS_Mesh::DumpFaces() const
2067 MESSAGE("dump faces of mesh : ");
2068 SMDS_FaceIteratorPtr itface=facesIterator();
2069 while(itface->more()) ; //MESSAGE(itface->next());
2072 //=======================================================================
2073 //function : DumpVolumes
2075 //=======================================================================
2077 void SMDS_Mesh::DumpVolumes() const
2079 MESSAGE("dump volumes of mesh : ");
2080 SMDS_VolumeIteratorPtr itvol=volumesIterator();
2081 while(itvol->more()) ; //MESSAGE(itvol->next());
2084 //=======================================================================
2085 //function : DebugStats
2087 //=======================================================================
2089 void SMDS_Mesh::DebugStats() const
2091 MESSAGE("Debug stats of mesh : ");
2093 MESSAGE("===== NODES ====="<<NbNodes());
2094 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2095 MESSAGE("===== EDGES ====="<<NbEdges());
2096 MESSAGE("===== FACES ====="<<NbFaces());
2097 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2099 MESSAGE("End Debug stats of mesh ");
2103 SMDS_NodeIteratorPtr itnode=nodesIterator();
2104 int sizeofnodes = 0;
2105 int sizeoffaces = 0;
2107 while(itnode->more())
2109 const SMDS_MeshNode *node = itnode->next();
2111 sizeofnodes += sizeof(*node);
2113 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2116 const SMDS_MeshElement *me = it->next();
2117 sizeofnodes += sizeof(me);
2121 SMDS_FaceIteratorPtr itface=facesIterator();
2122 while(itface->more())
2124 const SMDS_MeshElement *face = itface->next();
2125 sizeoffaces += sizeof(*face);
2128 MESSAGE("total size of node elements = " << sizeofnodes);;
2129 MESSAGE("total size of face elements = " << sizeoffaces);;
2134 ///////////////////////////////////////////////////////////////////////////////
2135 /// Return the number of nodes
2136 ///////////////////////////////////////////////////////////////////////////////
2137 int SMDS_Mesh::NbNodes() const
2139 //MESSAGE(myGrid->GetNumberOfPoints());
2140 //MESSAGE(myInfo.NbNodes());
2141 //MESSAGE(myNodeMax);
2142 return myInfo.NbNodes();
2145 ///////////////////////////////////////////////////////////////////////////////
2146 /// Return the number of 0D elements
2147 ///////////////////////////////////////////////////////////////////////////////
2148 int SMDS_Mesh::Nb0DElements() const
2150 return myInfo.Nb0DElements(); // -PR- a verfier
2153 ///////////////////////////////////////////////////////////////////////////////
2154 /// Return the number of edges (including construction edges)
2155 ///////////////////////////////////////////////////////////////////////////////
2156 int SMDS_Mesh::NbEdges() const
2158 return myInfo.NbEdges(); // -PR- a verfier
2161 ///////////////////////////////////////////////////////////////////////////////
2162 /// Return the number of faces (including construction faces)
2163 ///////////////////////////////////////////////////////////////////////////////
2164 int SMDS_Mesh::NbFaces() const
2166 return myInfo.NbFaces(); // -PR- a verfier
2169 ///////////////////////////////////////////////////////////////////////////////
2170 /// Return the number of volumes
2171 ///////////////////////////////////////////////////////////////////////////////
2172 int SMDS_Mesh::NbVolumes() const
2174 return myInfo.NbVolumes(); // -PR- a verfier
2177 ///////////////////////////////////////////////////////////////////////////////
2178 /// Return the number of child mesh of this mesh.
2179 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2180 /// (2003-09-08) of SMESH
2181 ///////////////////////////////////////////////////////////////////////////////
2182 int SMDS_Mesh::NbSubMesh() const
2184 return myChildren.size();
2187 ///////////////////////////////////////////////////////////////////////////////
2188 /// Destroy the mesh and all its elements
2189 /// All pointer on elements owned by this mesh become illegals.
2190 ///////////////////////////////////////////////////////////////////////////////
2191 SMDS_Mesh::~SMDS_Mesh()
2193 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2194 while(itc!=myChildren.end())
2202 delete myNodeIDFactory;
2203 delete myElementIDFactory;
2207 SMDS_ElemIteratorPtr eIt = elementsIterator();
2208 while ( eIt->more() )
2209 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2210 SMDS_NodeIteratorPtr itn = nodesIterator();
2212 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2215 // SetOfNodes::Iterator itn(myNodes);
2216 // for (; itn.More(); itn.Next())
2217 // delete itn.Value();
2219 // SetOf0DElements::Iterator it0d (my0DElements);
2220 // for (; it0d.More(); it0d.Next())
2222 // SMDS_MeshElement* elem = it0d.Value();
2226 // SetOfEdges::Iterator ite(myEdges);
2227 // for (; ite.More(); ite.Next())
2229 // SMDS_MeshElement* elem = ite.Value();
2233 // SetOfFaces::Iterator itf(myFaces);
2234 // for (; itf.More(); itf.Next())
2236 // SMDS_MeshElement* elem = itf.Value();
2240 // SetOfVolumes::Iterator itv(myVolumes);
2241 // for (; itv.More(); itv.Next())
2243 // SMDS_MeshElement* elem = itv.Value();
2248 //================================================================================
2250 * \brief Clear all data
2252 //================================================================================
2254 void SMDS_Mesh::Clear()
2256 if (myParent!=NULL) {
2257 SMDS_ElemIteratorPtr eIt = elementsIterator();
2258 while ( eIt->more() )
2259 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2260 SMDS_NodeIteratorPtr itn = nodesIterator();
2262 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2265 myNodeIDFactory->Clear();
2266 myElementIDFactory->Clear();
2269 SMDS_ElemIteratorPtr itv = elementsIterator();
2274 // SMDS_VolumeIteratorPtr itv = volumesIterator();
2275 // while (itv->more())
2276 // delete itv->next();
2277 // myVolumes.Clear();
2279 // SMDS_FaceIteratorPtr itf = facesIterator();
2280 // while (itf->more())
2281 // delete itf->next();
2284 // SMDS_EdgeIteratorPtr ite = edgesIterator();
2285 // while (ite->more())
2286 // delete ite->next();
2289 // SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2290 // while (it0d->more())
2291 // delete it0d->next();
2292 // my0DElements.Clear();
2294 SMDS_NodeIteratorPtr itn = nodesIterator();
2299 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2300 while(itc!=myChildren.end())
2306 ///////////////////////////////////////////////////////////////////////////////
2307 /// Return true if this mesh create faces with edges.
2308 /// A false returned value mean that faces are created with nodes. A concequence
2309 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2310 ///////////////////////////////////////////////////////////////////////////////
2311 bool SMDS_Mesh::hasConstructionEdges()
2313 return myHasConstructionEdges;
2316 ///////////////////////////////////////////////////////////////////////////////
2317 /// Return true if this mesh create volumes with faces
2318 /// A false returned value mean that volumes are created with nodes or edges.
2319 /// (see hasConstructionEdges)
2320 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2322 ///////////////////////////////////////////////////////////////////////////////
2323 bool SMDS_Mesh::hasConstructionFaces()
2325 return myHasConstructionFaces;
2328 ///////////////////////////////////////////////////////////////////////////////
2329 /// Return true if nodes are linked to the finit elements, they are belonging to.
2330 /// Currently, It always return true.
2331 ///////////////////////////////////////////////////////////////////////////////
2332 bool SMDS_Mesh::hasInverseElements()
2334 return myHasInverseElements;
2337 ///////////////////////////////////////////////////////////////////////////////
2338 /// Make this mesh creating construction edges (see hasConstructionEdges)
2339 /// @param b true to have construction edges, else false.
2340 ///////////////////////////////////////////////////////////////////////////////
2341 void SMDS_Mesh::setConstructionEdges(bool b)
2343 myHasConstructionEdges=b;
2346 ///////////////////////////////////////////////////////////////////////////////
2347 /// Make this mesh creating construction faces (see hasConstructionFaces)
2348 /// @param b true to have construction faces, else false.
2349 ///////////////////////////////////////////////////////////////////////////////
2350 void SMDS_Mesh::setConstructionFaces(bool b)
2352 myHasConstructionFaces=b;
2355 ///////////////////////////////////////////////////////////////////////////////
2356 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2357 /// @param b true to link nodes to elements, else false.
2358 ///////////////////////////////////////////////////////////////////////////////
2359 void SMDS_Mesh::setInverseElements(bool b)
2361 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2362 myHasInverseElements=b;
2365 ///////////////////////////////////////////////////////////////////////////////
2366 ///Iterator on NCollection_Map
2367 ///////////////////////////////////////////////////////////////////////////////
2368 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2369 struct MYNode_Map_Iterator: public FATHER
2373 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2380 while (_ctr < _map.size())
2391 ELEM current = _map[_ctr];
2397 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2398 struct MYElem_Map_Iterator: public FATHER
2403 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2411 while (_ctr < _map.size())
2414 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2423 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2429 ///////////////////////////////////////////////////////////////////////////////
2430 /// Return an iterator on nodes of the current mesh factory
2431 ///////////////////////////////////////////////////////////////////////////////
2433 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2435 //return SMDS_NodeIteratorPtr
2436 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2437 typedef MYNode_Map_Iterator
2438 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2439 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2442 ///////////////////////////////////////////////////////////////////////////////
2443 ///Return an iterator on 0D elements of the current mesh.
2444 ///////////////////////////////////////////////////////////////////////////////
2446 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2448 typedef MYElem_Map_Iterator
2449 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2450 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2453 ///////////////////////////////////////////////////////////////////////////////
2454 ///Return an iterator on edges of the current mesh.
2455 ///////////////////////////////////////////////////////////////////////////////
2457 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2459 typedef MYElem_Map_Iterator
2460 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2461 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2464 ///////////////////////////////////////////////////////////////////////////////
2465 ///Return an iterator on faces of the current mesh.
2466 ///////////////////////////////////////////////////////////////////////////////
2468 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2470 typedef MYElem_Map_Iterator
2471 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2472 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2475 ///////////////////////////////////////////////////////////////////////////////
2476 ///Return an iterator on volumes of the current mesh.
2477 ///////////////////////////////////////////////////////////////////////////////
2479 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2481 typedef MYElem_Map_Iterator
2482 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2483 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2486 ///////////////////////////////////////////////////////////////////////////////
2487 /// Return an iterator on elements of the current mesh factory
2488 ///////////////////////////////////////////////////////////////////////////////
2489 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2493 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2495 case SMDSAbs_Volume:
2496 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2498 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2500 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2501 case SMDSAbs_0DElement:
2502 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2504 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2505 //return myNodeIDFactory->elementsIterator();
2508 return myElementIDFactory->elementsIterator();
2511 ///////////////////////////////////////////////////////////////////////////////
2512 /// Do intersection of sets (more than 2)
2513 ///////////////////////////////////////////////////////////////////////////////
2514 static set<const SMDS_MeshElement*> * intersectionOfSets(
2515 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2517 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2518 set<const SMDS_MeshElement*>* rsetB;
2520 for(int i=0; i<numberOfSets-1; i++)
2522 rsetB=new set<const SMDS_MeshElement*>();
2524 rsetA->begin(), rsetA->end(),
2525 vs[i+1].begin(), vs[i+1].end(),
2526 inserter(*rsetB, rsetB->begin()));
2533 ///////////////////////////////////////////////////////////////////////////////
2534 /// Return the list of finite elements owning the given element: elements
2535 /// containing all the nodes of the given element, for instance faces and
2536 /// volumes containing a given edge.
2537 ///////////////////////////////////////////////////////////////////////////////
2538 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2540 int numberOfSets=element->NbNodes();
2541 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2543 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2546 while(itNodes->more())
2548 const SMDS_MeshElement* node = itNodes->next();
2550 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2551 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2553 //initSet[i]=set<const SMDS_MeshElement*>();
2556 const SMDS_MeshElement* elem = itFe->next();
2558 initSet[i].insert(elem);
2564 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2565 MESSAGE("nb elems " << i << " intersection " << retSet->size());
2570 ///////////////////////////////////////////////////////////////////////////////
2571 /// Return the list of nodes used only by the given elements
2572 ///////////////////////////////////////////////////////////////////////////////
2573 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2574 set<const SMDS_MeshElement*>& elements)
2576 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2577 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2579 while(itElements!=elements.end())
2581 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2584 while(itNodes->more())
2586 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2587 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2588 set<const SMDS_MeshElement*> s;
2590 s.insert(itFe->next());
2591 if(s==elements) toReturn->insert(n);
2597 ///////////////////////////////////////////////////////////////////////////////
2598 ///Find the children of an element that are made of given nodes
2599 ///@param setOfChildren The set in which matching children will be inserted
2600 ///@param element The element were to search matching children
2601 ///@param nodes The nodes that the children must have to be selected
2602 ///////////////////////////////////////////////////////////////////////////////
2603 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2604 const SMDS_MeshElement * element,
2605 set<const SMDS_MeshElement*>& nodes)
2607 switch(element->GetType())
2610 MESSAGE("Internal Error: This should not happend");
2612 case SMDSAbs_0DElement:
2618 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2621 const SMDS_MeshElement * e=itn->next();
2622 if(nodes.find(e)!=nodes.end())
2624 setOfChildren.insert(element);
2631 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2634 const SMDS_MeshElement * e=itn->next();
2635 if(nodes.find(e)!=nodes.end())
2637 setOfChildren.insert(element);
2641 if(hasConstructionEdges())
2643 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2645 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2648 case SMDSAbs_Volume:
2650 if(hasConstructionFaces())
2652 SMDS_ElemIteratorPtr ite=element->facesIterator();
2654 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2656 else if(hasConstructionEdges())
2658 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2660 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2666 ///////////////////////////////////////////////////////////////////////////////
2667 ///@param elem The element to delete
2668 ///@param removenodes if true remaining nodes will be removed
2669 ///////////////////////////////////////////////////////////////////////////////
2670 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2671 const bool removenodes)
2673 list<const SMDS_MeshElement *> removedElems;
2674 list<const SMDS_MeshElement *> removedNodes;
2675 RemoveElement( elem, removedElems, removedNodes, removenodes );
2678 ///////////////////////////////////////////////////////////////////////////////
2679 ///@param elem The element to delete
2680 ///@param removedElems to be filled with all removed elements
2681 ///@param removedNodes to be filled with all removed nodes
2682 ///@param removenodes if true remaining nodes will be removed
2683 ///////////////////////////////////////////////////////////////////////////////
2684 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2685 list<const SMDS_MeshElement *>& removedElems,
2686 list<const SMDS_MeshElement *>& removedNodes,
2689 MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2690 // get finite elements built on elem
2691 set<const SMDS_MeshElement*> * s1;
2692 if (elem->GetType() == SMDSAbs_0DElement ||
2693 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2694 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2695 elem->GetType() == SMDSAbs_Volume)
2697 s1 = new set<const SMDS_MeshElement*>();
2701 s1 = getFinitElements(elem);
2703 // get exclusive nodes (which would become free afterwards)
2704 set<const SMDS_MeshElement*> * s2;
2705 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2707 // do not remove nodes except elem
2708 s2 = new set<const SMDS_MeshElement*>();
2713 s2 = getExclusiveNodes(*s1);
2715 // form the set of finite and construction elements to remove
2716 set<const SMDS_MeshElement*> s3;
2717 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2718 while(it!=s1->end())
2720 addChildrenWithNodes(s3, *it ,*s2);
2724 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2726 // remove finite and construction elements
2730 // Remove element from <InverseElements> of its nodes
2731 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2734 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2735 (const_cast<SMDS_MeshElement *>(itn->next()));
2736 n->RemoveInverseElement( (*it) );
2739 switch((*it)->GetType())
2742 MYASSERT("Internal Error: This should not happen");
2744 case SMDSAbs_0DElement:
2745 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2749 myCells[(*it)->GetID()] = 0;
2750 myInfo.RemoveEdge(*it);
2753 myCells[(*it)->GetID()] = 0;
2754 myInfo.RemoveFace(*it);
2756 case SMDSAbs_Volume:
2757 myCells[(*it)->GetID()] = 0;
2758 myInfo.RemoveVolume(*it);
2761 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2762 removedElems.push_back( (*it) );
2763 myElementIDFactory->ReleaseID((*it)->GetID());
2764 MYASSERT("problem delete elem")
2769 // remove exclusive (free) nodes
2773 while(it!=s2->end())
2775 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2776 myNodes[(*it)->GetID()] = 0;
2778 myNodeIDFactory->ReleaseID((*it)->GetID());
2779 removedNodes.push_back( (*it) );
2780 MYASSERT("problem delete node")
2791 ///////////////////////////////////////////////////////////////////////////////
2792 ///@param elem The element to delete
2793 ///////////////////////////////////////////////////////////////////////////////
2794 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2796 int elemId = elem->GetID();
2797 MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2798 SMDSAbs_ElementType aType = elem->GetType();
2799 SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2800 if (aType == SMDSAbs_Node) {
2801 // only free node can be removed by this method
2802 const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2803 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2804 if (!itFe->more()) { // free node
2805 myNodes[elemId] = 0;
2807 myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2808 myNodeIDFactory->ReleaseID(elemId);
2811 if (hasConstructionEdges() || hasConstructionFaces())
2812 // this methods is only for meshes without descendants
2815 int vtkid = this->fromSmdsToVtk(elemId);
2817 // Remove element from <InverseElements> of its nodes
2818 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2819 while (itn->more()) {
2820 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2821 (const_cast<SMDS_MeshElement *>(itn->next()));
2822 n->RemoveInverseElement(elem);
2825 // in meshes without descendants elements are always free
2827 case SMDSAbs_0DElement:
2828 myCells[elemId] = 0;
2829 myInfo.remove(elem);
2833 myCells[elemId] = 0;
2834 myInfo.RemoveEdge(elem);
2835 myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2838 myCells[elemId] = 0;
2839 myInfo.RemoveFace(elem);
2840 myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2842 case SMDSAbs_Volume:
2843 myCells[elemId] = 0;
2844 myInfo.RemoveVolume(elem);
2845 myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2850 myElementIDFactory->ReleaseID(elemId);
2852 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2853 // --- to do: keep vtkid in a list of reusable cells
2858 * Checks if the element is present in mesh.
2859 * Useful to determine dead pointers.
2861 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2863 // we should not imply on validity of *elem, so iterate on containers
2864 // of all types in the hope of finding <elem> somewhere there
2865 SMDS_NodeIteratorPtr itn = nodesIterator();
2867 if (elem == itn->next())
2869 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2870 while (it0d->more())
2871 if (elem == it0d->next())
2873 SMDS_EdgeIteratorPtr ite = edgesIterator();
2875 if (elem == ite->next())
2877 SMDS_FaceIteratorPtr itf = facesIterator();
2879 if (elem == itf->next())
2881 SMDS_VolumeIteratorPtr itv = volumesIterator();
2883 if (elem == itv->next())
2888 //=======================================================================
2889 //function : MaxNodeID
2891 //=======================================================================
2893 int SMDS_Mesh::MaxNodeID() const
2898 //=======================================================================
2899 //function : MinNodeID
2901 //=======================================================================
2903 int SMDS_Mesh::MinNodeID() const
2908 //=======================================================================
2909 //function : MaxElementID
2911 //=======================================================================
2913 int SMDS_Mesh::MaxElementID() const
2915 return myElementIDFactory->GetMaxID();
2918 //=======================================================================
2919 //function : MinElementID
2921 //=======================================================================
2923 int SMDS_Mesh::MinElementID() const
2925 return myElementIDFactory->GetMinID();
2928 //=======================================================================
2929 //function : Renumber
2930 //purpose : Renumber all nodes or elements.
2931 //=======================================================================
2933 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2935 MESSAGE("Renumber");
2939 SMDS_MeshNodeIDFactory * idFactory =
2940 isNodes ? myNodeIDFactory : myElementIDFactory;
2942 // get existing elements in the order of ID increasing
2943 map<int,SMDS_MeshElement*> elemMap;
2944 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2945 while ( idElemIt->more() ) {
2946 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2947 int id = elem->GetID();
2948 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2950 // release their ids
2951 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2953 // for ( ; elemIt != elemMap.end(); elemIt++ )
2955 // int id = (*elemIt).first;
2956 // idFactory->ReleaseID( id );
2960 elemIt = elemMap.begin();
2961 for ( ; elemIt != elemMap.end(); elemIt++ )
2963 idFactory->BindID( ID, (*elemIt).second );
2968 //=======================================================================
2969 //function : GetElementType
2970 //purpose : Return type of element or node with id
2971 //=======================================================================
2973 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2975 SMDS_MeshElement* elem = 0;
2977 elem = myElementIDFactory->MeshElement( id );
2979 elem = myNodeIDFactory->MeshElement( id );
2983 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2987 return elem->GetType();
2992 //********************************************************************
2993 //********************************************************************
2994 //******** *********
2995 //***** Methods for addition of quadratic elements ******
2996 //******** *********
2997 //********************************************************************
2998 //********************************************************************
3000 //=======================================================================
3001 //function : AddEdgeWithID
3003 //=======================================================================
3004 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3006 return SMDS_Mesh::AddEdgeWithID
3007 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3008 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3009 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3013 //=======================================================================
3014 //function : AddEdge
3016 //=======================================================================
3017 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3018 const SMDS_MeshNode* n2,
3019 const SMDS_MeshNode* n12)
3021 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3024 //=======================================================================
3025 //function : AddEdgeWithID
3027 //=======================================================================
3028 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3029 const SMDS_MeshNode * n2,
3030 const SMDS_MeshNode * n12,
3033 if ( !n1 || !n2 || !n12 ) return 0;
3034 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
3035 if(myElementIDFactory->BindID(ID, edge)) {
3036 SMDS_MeshNode *node1,*node2, *node12;
3037 //node1 = const_cast<SMDS_MeshNode*>(n1);
3038 //node2 = const_cast<SMDS_MeshNode*>(n2);
3039 //node12 = const_cast<SMDS_MeshNode*>(n12);
3040 //node1->AddInverseElement(edge); // --- fait avec BindID
3041 //node2->AddInverseElement(edge);
3042 //node12->AddInverseElement(edge);
3043 adjustmyCellsCapacity(ID);
3045 myInfo.myNbQuadEdges++;
3055 //=======================================================================
3056 //function : AddFace
3058 //=======================================================================
3059 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3060 const SMDS_MeshNode * n2,
3061 const SMDS_MeshNode * n3,
3062 const SMDS_MeshNode * n12,
3063 const SMDS_MeshNode * n23,
3064 const SMDS_MeshNode * n31)
3066 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3067 myElementIDFactory->GetFreeID());
3070 //=======================================================================
3071 //function : AddFaceWithID
3073 //=======================================================================
3074 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3075 int n12,int n23,int n31, int ID)
3077 return SMDS_Mesh::AddFaceWithID
3078 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3079 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3080 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3081 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3082 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3083 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3087 //=======================================================================
3088 //function : AddFaceWithID
3090 //=======================================================================
3091 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3092 const SMDS_MeshNode * n2,
3093 const SMDS_MeshNode * n3,
3094 const SMDS_MeshNode * n12,
3095 const SMDS_MeshNode * n23,
3096 const SMDS_MeshNode * n31,
3099 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3100 if(hasConstructionEdges()) {
3101 // creation quadratic edges - not implemented
3104 SMDS_QuadraticFaceOfNodes* face =
3105 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
3106 adjustmyCellsCapacity(ID);
3108 myInfo.myNbQuadTriangles++;
3110 if (!registerElement(ID, face)) {
3111 RemoveElement(face, false);
3118 //=======================================================================
3119 //function : AddFace
3121 //=======================================================================
3122 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3123 const SMDS_MeshNode * n2,
3124 const SMDS_MeshNode * n3,
3125 const SMDS_MeshNode * n4,
3126 const SMDS_MeshNode * n12,
3127 const SMDS_MeshNode * n23,
3128 const SMDS_MeshNode * n34,
3129 const SMDS_MeshNode * n41)
3131 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3132 myElementIDFactory->GetFreeID());
3135 //=======================================================================
3136 //function : AddFaceWithID
3138 //=======================================================================
3139 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3140 int n12,int n23,int n34,int n41, int ID)
3142 return SMDS_Mesh::AddFaceWithID
3143 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3144 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3145 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3146 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3147 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3148 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3149 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3150 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3154 //=======================================================================
3155 //function : AddFaceWithID
3157 //=======================================================================
3158 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3159 const SMDS_MeshNode * n2,
3160 const SMDS_MeshNode * n3,
3161 const SMDS_MeshNode * n4,
3162 const SMDS_MeshNode * n12,
3163 const SMDS_MeshNode * n23,
3164 const SMDS_MeshNode * n34,
3165 const SMDS_MeshNode * n41,
3168 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3169 if(hasConstructionEdges()) {
3170 // creation quadratic edges - not implemented
3172 SMDS_QuadraticFaceOfNodes* face =
3173 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
3174 adjustmyCellsCapacity(ID);
3176 myInfo.myNbQuadQuadrangles++;
3178 if (!registerElement(ID, face)) {
3179 RemoveElement(face, false);
3186 //=======================================================================
3187 //function : AddVolume
3189 //=======================================================================
3190 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3191 const SMDS_MeshNode * n2,
3192 const SMDS_MeshNode * n3,
3193 const SMDS_MeshNode * n4,
3194 const SMDS_MeshNode * n12,
3195 const SMDS_MeshNode * n23,
3196 const SMDS_MeshNode * n31,
3197 const SMDS_MeshNode * n14,
3198 const SMDS_MeshNode * n24,
3199 const SMDS_MeshNode * n34)
3201 int ID = myElementIDFactory->GetFreeID();
3202 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3203 n31, n14, n24, n34, ID);
3204 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3208 //=======================================================================
3209 //function : AddVolumeWithID
3211 //=======================================================================
3212 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3213 int n12,int n23,int n31,
3214 int n14,int n24,int n34, int ID)
3216 return SMDS_Mesh::AddVolumeWithID
3217 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3218 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3219 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3220 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3221 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3222 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3223 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3224 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3225 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3226 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3230 //=======================================================================
3231 //function : AddVolumeWithID
3232 //purpose : 2d order tetrahedron of 10 nodes
3233 //=======================================================================
3234 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3235 const SMDS_MeshNode * n2,
3236 const SMDS_MeshNode * n3,
3237 const SMDS_MeshNode * n4,
3238 const SMDS_MeshNode * n12,
3239 const SMDS_MeshNode * n23,
3240 const SMDS_MeshNode * n31,
3241 const SMDS_MeshNode * n14,
3242 const SMDS_MeshNode * n24,
3243 const SMDS_MeshNode * n34,
3246 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3248 if(hasConstructionFaces()) {
3249 // creation quadratic faces - not implemented
3252 SMDS_QuadraticVolumeOfNodes * volume =
3253 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3254 adjustmyCellsCapacity(ID);
3255 myCells[ID] = volume;
3256 myInfo.myNbQuadTetras++;
3258 if (!registerElement(ID, volume)) {
3259 RemoveElement(volume, false);
3266 //=======================================================================
3267 //function : AddVolume
3269 //=======================================================================
3270 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3271 const SMDS_MeshNode * n2,
3272 const SMDS_MeshNode * n3,
3273 const SMDS_MeshNode * n4,
3274 const SMDS_MeshNode * n5,
3275 const SMDS_MeshNode * n12,
3276 const SMDS_MeshNode * n23,
3277 const SMDS_MeshNode * n34,
3278 const SMDS_MeshNode * n41,
3279 const SMDS_MeshNode * n15,
3280 const SMDS_MeshNode * n25,
3281 const SMDS_MeshNode * n35,
3282 const SMDS_MeshNode * n45)
3284 int ID = myElementIDFactory->GetFreeID();
3285 SMDS_MeshVolume * v =
3286 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3287 n15, n25, n35, n45, ID);
3288 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3292 //=======================================================================
3293 //function : AddVolumeWithID
3295 //=======================================================================
3296 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3297 int n12,int n23,int n34,int n41,
3298 int n15,int n25,int n35,int n45, int ID)
3300 return SMDS_Mesh::AddVolumeWithID
3301 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3302 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3303 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3304 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3305 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3306 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3307 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3308 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3309 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3310 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3311 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3312 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3313 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3317 //=======================================================================
3318 //function : AddVolumeWithID
3319 //purpose : 2d order pyramid of 13 nodes
3320 //=======================================================================
3321 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3322 const SMDS_MeshNode * n2,
3323 const SMDS_MeshNode * n3,
3324 const SMDS_MeshNode * n4,
3325 const SMDS_MeshNode * n5,
3326 const SMDS_MeshNode * n12,
3327 const SMDS_MeshNode * n23,
3328 const SMDS_MeshNode * n34,
3329 const SMDS_MeshNode * n41,
3330 const SMDS_MeshNode * n15,
3331 const SMDS_MeshNode * n25,
3332 const SMDS_MeshNode * n35,
3333 const SMDS_MeshNode * n45,
3336 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3337 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3339 if(hasConstructionFaces()) {
3340 // creation quadratic faces - not implemented
3343 SMDS_QuadraticVolumeOfNodes * volume =
3344 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3345 n34,n41,n15,n25,n35,n45);
3346 adjustmyCellsCapacity(ID);
3347 myCells[ID] = volume;
3348 myInfo.myNbQuadPyramids++;
3350 if (!registerElement(ID, volume)) {
3351 RemoveElement(volume, false);
3358 //=======================================================================
3359 //function : AddVolume
3361 //=======================================================================
3362 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3363 const SMDS_MeshNode * n2,
3364 const SMDS_MeshNode * n3,
3365 const SMDS_MeshNode * n4,
3366 const SMDS_MeshNode * n5,
3367 const SMDS_MeshNode * n6,
3368 const SMDS_MeshNode * n12,
3369 const SMDS_MeshNode * n23,
3370 const SMDS_MeshNode * n31,
3371 const SMDS_MeshNode * n45,
3372 const SMDS_MeshNode * n56,
3373 const SMDS_MeshNode * n64,
3374 const SMDS_MeshNode * n14,
3375 const SMDS_MeshNode * n25,
3376 const SMDS_MeshNode * n36)
3378 int ID = myElementIDFactory->GetFreeID();
3379 SMDS_MeshVolume * v =
3380 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3381 n45, n56, n64, n14, n25, n36, ID);
3382 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3386 //=======================================================================
3387 //function : AddVolumeWithID
3389 //=======================================================================
3390 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3391 int n4, int n5, int n6,
3392 int n12,int n23,int n31,
3393 int n45,int n56,int n64,
3394 int n14,int n25,int n36, int ID)
3396 return SMDS_Mesh::AddVolumeWithID
3397 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3398 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3399 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3400 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3401 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3402 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3403 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3404 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3405 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3406 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3407 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3408 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3409 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3410 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3411 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3415 //=======================================================================
3416 //function : AddVolumeWithID
3417 //purpose : 2d order Pentahedron with 15 nodes
3418 //=======================================================================
3419 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3420 const SMDS_MeshNode * n2,
3421 const SMDS_MeshNode * n3,
3422 const SMDS_MeshNode * n4,
3423 const SMDS_MeshNode * n5,
3424 const SMDS_MeshNode * n6,
3425 const SMDS_MeshNode * n12,
3426 const SMDS_MeshNode * n23,
3427 const SMDS_MeshNode * n31,
3428 const SMDS_MeshNode * n45,
3429 const SMDS_MeshNode * n56,
3430 const SMDS_MeshNode * n64,
3431 const SMDS_MeshNode * n14,
3432 const SMDS_MeshNode * n25,
3433 const SMDS_MeshNode * n36,
3436 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3437 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3439 if(hasConstructionFaces()) {
3440 // creation quadratic faces - not implemented
3443 SMDS_QuadraticVolumeOfNodes * volume =
3444 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3445 n45,n56,n64,n14,n25,n36);
3446 adjustmyCellsCapacity(ID);
3447 myCells[ID] = volume;
3448 myInfo.myNbQuadPrisms++;
3450 if (!registerElement(ID, volume)) {
3451 RemoveElement(volume, false);
3458 //=======================================================================
3459 //function : AddVolume
3461 //=======================================================================
3462 SMDS_MeshVolume* SMDS_Mesh::AddVolume(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 * n6,
3468 const SMDS_MeshNode * n7,
3469 const SMDS_MeshNode * n8,
3470 const SMDS_MeshNode * n12,
3471 const SMDS_MeshNode * n23,
3472 const SMDS_MeshNode * n34,
3473 const SMDS_MeshNode * n41,
3474 const SMDS_MeshNode * n56,
3475 const SMDS_MeshNode * n67,
3476 const SMDS_MeshNode * n78,
3477 const SMDS_MeshNode * n85,
3478 const SMDS_MeshNode * n15,
3479 const SMDS_MeshNode * n26,
3480 const SMDS_MeshNode * n37,
3481 const SMDS_MeshNode * n48)
3483 int ID = myElementIDFactory->GetFreeID();
3484 SMDS_MeshVolume * v =
3485 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3486 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3487 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3491 //=======================================================================
3492 //function : AddVolumeWithID
3494 //=======================================================================
3495 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3496 int n5, int n6, int n7, int n8,
3497 int n12,int n23,int n34,int n41,
3498 int n56,int n67,int n78,int n85,
3499 int n15,int n26,int n37,int n48, int ID)
3501 return SMDS_Mesh::AddVolumeWithID
3502 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3503 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3504 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3505 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3506 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3507 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3508 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3509 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3510 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3511 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3512 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3513 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3514 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3515 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3516 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3517 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3518 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3519 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3520 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3521 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3525 //=======================================================================
3526 //function : AddVolumeWithID
3527 //purpose : 2d order Hexahedrons with 20 nodes
3528 //=======================================================================
3529 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3530 const SMDS_MeshNode * n2,
3531 const SMDS_MeshNode * n3,
3532 const SMDS_MeshNode * n4,
3533 const SMDS_MeshNode * n5,
3534 const SMDS_MeshNode * n6,
3535 const SMDS_MeshNode * n7,
3536 const SMDS_MeshNode * n8,
3537 const SMDS_MeshNode * n12,
3538 const SMDS_MeshNode * n23,
3539 const SMDS_MeshNode * n34,
3540 const SMDS_MeshNode * n41,
3541 const SMDS_MeshNode * n56,
3542 const SMDS_MeshNode * n67,
3543 const SMDS_MeshNode * n78,
3544 const SMDS_MeshNode * n85,
3545 const SMDS_MeshNode * n15,
3546 const SMDS_MeshNode * n26,
3547 const SMDS_MeshNode * n37,
3548 const SMDS_MeshNode * n48,
3551 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3552 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3554 if(hasConstructionFaces()) {
3556 // creation quadratic faces - not implemented
3558 SMDS_QuadraticVolumeOfNodes * volume =
3559 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3560 n56,n67,n78,n85,n15,n26,n37,n48);
3561 adjustmyCellsCapacity(ID);
3562 myCells[ID] = volume;
3563 myInfo.myNbQuadHexas++;
3565 if (!registerElement(ID, volume)) {
3566 RemoveElement(volume, false);
3572 void SMDS_Mesh::updateNodeMinMax()
3575 if (myNodes.size() == 0)
3580 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3582 myNodeMax=myNodes.size()-1;
3583 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3587 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3589 int val = myIDElements.size();
3590 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3591 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3592 val = myNodes.size();
3593 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3594 myNodes.resize(val +nbNodes, 0);
3597 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3599 int val = myVtkIndex.size();
3600 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3601 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3602 val = myCells.size();
3603 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3604 myNodes.resize(val +nbCells, 0);
3607 void SMDS_Mesh::adjustStructure()
3609 myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3612 void SMDS_Mesh::dumpGrid(string ficdump)
3614 MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
3615 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
3616 aWriter->SetFileName(ficdump.c_str());
3617 aWriter->SetInput(myGrid);
3618 if(myGrid->GetNumberOfCells())
3623 ficdump = ficdump + "_connectivity";
3624 ofstream ficcon(ficdump.c_str(), ios::out);
3625 int nbPoints = myGrid->GetNumberOfPoints();
3626 ficcon << "-------------------------------- points " << nbPoints << endl;
3627 for (int i=0; i<nbPoints; i++)
3629 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
3631 int nbCells = myGrid->GetNumberOfCells();
3632 ficcon << "-------------------------------- cells " << nbCells << endl;
3633 for (int i=0; i<nbCells; i++)
3635 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
3636 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
3637 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
3638 for (int j=0; j<nbptcell; j++)
3640 ficcon << " " << listid->GetId(j);
3644 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
3645 vtkCellLinks *links = myGrid->GetCellLinks();
3646 for (int i=0; i<nbPoints; i++)
3648 int ncells = links->GetNcells(i);
3649 vtkIdType *cells = links->GetCells(i);
3650 ficcon << i << " - " << ncells << " -";
3651 for (int j=0; j<ncells; j++)
3653 ficcon << " " << cells[j];