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>
48 #include <sys/sysinfo.h>
51 // number of added entitis to check memory after
52 #define CHECKMEMORY_INTERVAL 1000
54 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
55 int SMDS_Mesh::chunkSize = 1024;
58 //================================================================================
60 * \brief Raise an exception if free memory (ram+swap) too low
61 * \param doNotRaise - if true, suppres exception, just return free memory size
62 * \retval int - amount of available memory in MB or negative number in failure case
64 //================================================================================
66 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
70 int err = sysinfo( &si );
74 static int limit = -1;
76 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
78 limit = WEXITSTATUS(status);
83 limit = int( limit * 1.5 );
85 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
89 const unsigned long Mbyte = 1024 * 1024;
90 // compute separately to avoid overflow
92 ( si.freeram * si.mem_unit ) / Mbyte +
93 ( si.freeswap * si.mem_unit ) / Mbyte;
96 return freeMb - limit;
101 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
103 throw std::bad_alloc();
109 ///////////////////////////////////////////////////////////////////////////////
110 /// Create a new mesh object
111 ///////////////////////////////////////////////////////////////////////////////
112 SMDS_Mesh::SMDS_Mesh()
114 myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
115 myElementIDFactory(new SMDS_MeshElementIDFactory()),
116 myHasConstructionEdges(false), myHasConstructionFaces(false),
117 myHasInverseElements(true),
118 myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
119 myNodePool(0), myVolumePool(0)
121 myMeshId = _meshList.size(); // --- index of the mesh to push back in the vector
122 MESSAGE("myMeshId=" << myMeshId);
123 MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
124 MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
125 MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
126 MESSAGE("sizeof(SMDS_VolumeVtkNodes) " << sizeof(SMDS_VolumeVtkNodes) );
127 MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
128 MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
129 myNodeIDFactory->SetMesh(this);
130 myElementIDFactory->SetMesh(this);
131 _meshList.push_back(this);
132 myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
133 myVolumePool = new ObjectPool<SMDS_VolumeVtkNodes>(SMDS_Mesh::chunkSize);
137 myIDElements.clear();
139 myGrid = vtkUnstructuredGrid::New();
140 myGrid->Initialize();
142 vtkPoints* points = vtkPoints::New();
143 points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
144 myGrid->SetPoints( points );
146 myGrid->BuildLinks();
149 ///////////////////////////////////////////////////////////////////////////////
150 /// Create a new child mesh
151 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
152 /// (2003-09-08) of SMESH
153 ///////////////////////////////////////////////////////////////////////////////
154 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
155 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
156 myElementIDFactory(parent->myElementIDFactory),
157 myHasConstructionEdges(false), myHasConstructionFaces(false),
158 myHasInverseElements(true),
159 myNodePool(parent->myNodePool),
160 myVolumePool(parent->myVolumePool)
164 ///////////////////////////////////////////////////////////////////////////////
165 ///Create a submesh and add it to the current mesh
166 ///////////////////////////////////////////////////////////////////////////////
168 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
170 SMDS_Mesh *submesh = new SMDS_Mesh(this);
171 myChildren.insert(myChildren.end(), submesh);
175 ///////////////////////////////////////////////////////////////////////////////
176 ///create a MeshNode and add it to the current Mesh
177 ///An ID is automatically assigned to the node.
178 ///@return : The created node
179 ///////////////////////////////////////////////////////////////////////////////
181 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
183 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
186 ///////////////////////////////////////////////////////////////////////////////
187 ///create a MeshNode and add it to the current Mesh
188 ///@param ID : The ID of the MeshNode to create
189 ///@return : The created node or NULL if a node with this ID already exists
190 ///////////////////////////////////////////////////////////////////////////////
191 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
193 // find the MeshNode corresponding to ID
194 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
196 //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
197 //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
198 SMDS_MeshNode * node = myNodePool->getNew();
199 node->init(ID, myMeshId, -1, x, y, z);
200 if (ID >= myNodes.size())
202 myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
203 //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
206 myNodeIDFactory->BindID(ID,node);
213 ///////////////////////////////////////////////////////////////////////////////
214 /// create a Mesh0DElement and add it to the current Mesh
215 /// @return : The created Mesh0DElement
216 ///////////////////////////////////////////////////////////////////////////////
217 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
219 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
220 if (!node) return NULL;
221 return SMDS_Mesh::Add0DElementWithID(node, ID);
224 ///////////////////////////////////////////////////////////////////////////////
225 /// create a Mesh0DElement and add it to the current Mesh
226 /// @return : The created Mesh0DElement
227 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
230 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
233 ///////////////////////////////////////////////////////////////////////////////
234 /// Create a new Mesh0DElement and at it to the mesh
235 /// @param idnode ID of the node
236 /// @param ID ID of the 0D element to create
237 /// @return The created 0D element or NULL if an element with this
238 /// ID already exists or if input node is not found.
239 ///////////////////////////////////////////////////////////////////////////////
240 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
244 //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
245 //MESSAGE("Add0DElementWithID" << ID)
246 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
247 if (myElementIDFactory->BindID(ID, el0d)) {
248 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
249 //node->AddInverseElement(el0d);// --- fait avec BindID
250 adjustmyCellsCapacity(ID);
252 myInfo.myNb0DElements++;
260 ///////////////////////////////////////////////////////////////////////////////
261 /// create a MeshEdge and add it to the current Mesh
262 /// @return : The created MeshEdge
263 ///////////////////////////////////////////////////////////////////////////////
265 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
267 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
268 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
269 if(!node1 || !node2) return NULL;
270 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
273 ///////////////////////////////////////////////////////////////////////////////
274 /// create a MeshEdge and add it to the current Mesh
275 /// @return : The created MeshEdge
276 ///////////////////////////////////////////////////////////////////////////////
278 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
279 const SMDS_MeshNode * node2)
281 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
284 ///////////////////////////////////////////////////////////////////////////////
285 /// Create a new edge and at it to the mesh
286 /// @param idnode1 ID of the first node
287 /// @param idnode2 ID of the second node
288 /// @param ID ID of the edge to create
289 /// @return The created edge or NULL if an element with this ID already exists or
290 /// if input nodes are not found.
291 ///////////////////////////////////////////////////////////////////////////////
293 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
294 const SMDS_MeshNode * n2,
297 if ( !n1 || !n2 ) return 0;
299 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
300 //MESSAGE("AddEdgeWithID " << ID)
301 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
302 adjustmyCellsCapacity(ID);
306 if (edge && !registerElement(ID, edge))
308 RemoveElement(edge, false);
314 ///////////////////////////////////////////////////////////////////////////////
315 /// Add a triangle defined by its nodes. An ID is automatically affected to the
317 ///////////////////////////////////////////////////////////////////////////////
319 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
320 const SMDS_MeshNode * n2,
321 const SMDS_MeshNode * n3)
323 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
326 ///////////////////////////////////////////////////////////////////////////////
327 /// Add a triangle defined by its nodes IDs
328 ///////////////////////////////////////////////////////////////////////////////
330 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
332 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
333 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
334 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
335 if(!node1 || !node2 || !node3) return NULL;
336 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
339 ///////////////////////////////////////////////////////////////////////////////
340 /// Add a triangle defined by its nodes
341 ///////////////////////////////////////////////////////////////////////////////
343 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
344 const SMDS_MeshNode * n2,
345 const SMDS_MeshNode * n3,
348 //MESSAGE("AddFaceWithID " << ID)
349 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
351 if (face && !registerElement(ID, face)) {
352 RemoveElement(face, false);
358 ///////////////////////////////////////////////////////////////////////////////
359 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
361 ///////////////////////////////////////////////////////////////////////////////
363 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
364 const SMDS_MeshNode * n2,
365 const SMDS_MeshNode * n3,
366 const SMDS_MeshNode * n4)
368 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
371 ///////////////////////////////////////////////////////////////////////////////
372 /// Add a quadrangle defined by its nodes IDs
373 ///////////////////////////////////////////////////////////////////////////////
375 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
381 SMDS_MeshNode *node1, *node2, *node3, *node4;
382 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
383 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
384 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
385 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
386 if(!node1 || !node2 || !node3 || !node4) return NULL;
387 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
390 ///////////////////////////////////////////////////////////////////////////////
391 /// Add a quadrangle defined by its nodes
392 ///////////////////////////////////////////////////////////////////////////////
394 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
395 const SMDS_MeshNode * n2,
396 const SMDS_MeshNode * n3,
397 const SMDS_MeshNode * n4,
400 //MESSAGE("AddFaceWithID " << ID);
401 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
403 if (face && !registerElement(ID, face)) {
404 RemoveElement(face, false);
410 ///////////////////////////////////////////////////////////////////////////////
411 /// Add a triangle defined by its edges. An ID is automatically assigned to the
413 ///////////////////////////////////////////////////////////////////////////////
415 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
416 const SMDS_MeshEdge * e2,
417 const SMDS_MeshEdge * e3)
419 if (!hasConstructionEdges())
421 //MESSAGE("AddFaceWithID");
422 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
425 ///////////////////////////////////////////////////////////////////////////////
426 /// Add a triangle defined by its edges
427 ///////////////////////////////////////////////////////////////////////////////
429 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
430 const SMDS_MeshEdge * e2,
431 const SMDS_MeshEdge * e3,
434 if (!hasConstructionEdges())
436 if ( !e1 || !e2 || !e3 ) return 0;
438 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
439 //MESSAGE("AddFaceWithID" << ID);
441 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
442 adjustmyCellsCapacity(ID);
444 myInfo.myNbTriangles++;
446 if (!registerElement(ID, face)) {
447 RemoveElement(face, false);
453 ///////////////////////////////////////////////////////////////////////////////
454 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
456 ///////////////////////////////////////////////////////////////////////////////
458 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
459 const SMDS_MeshEdge * e2,
460 const SMDS_MeshEdge * e3,
461 const SMDS_MeshEdge * e4)
463 if (!hasConstructionEdges())
465 //MESSAGE("AddFaceWithID" );
466 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
469 ///////////////////////////////////////////////////////////////////////////////
470 /// Add a quadrangle defined by its edges
471 ///////////////////////////////////////////////////////////////////////////////
473 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
474 const SMDS_MeshEdge * e2,
475 const SMDS_MeshEdge * e3,
476 const SMDS_MeshEdge * e4,
479 if (!hasConstructionEdges())
481 //MESSAGE("AddFaceWithID" << ID);
482 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
483 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
484 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
485 adjustmyCellsCapacity(ID);
487 myInfo.myNbQuadrangles++;
489 if (!registerElement(ID, face))
491 RemoveElement(face, false);
497 ///////////////////////////////////////////////////////////////////////////////
498 ///Create a new tetrahedron and add it to the mesh.
499 ///@return The created tetrahedron
500 ///////////////////////////////////////////////////////////////////////////////
502 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
503 const SMDS_MeshNode * n2,
504 const SMDS_MeshNode * n3,
505 const SMDS_MeshNode * n4)
507 int ID = myElementIDFactory->GetFreeID();
508 //MESSAGE("AddVolumeWithID " << ID);
509 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
510 if(v==NULL) myElementIDFactory->ReleaseID(ID);
514 ///////////////////////////////////////////////////////////////////////////////
515 ///Create a new tetrahedron and add it to the mesh.
516 ///@param ID The ID of the new volume
517 ///@return The created tetrahedron or NULL if an element with this ID already exists
518 ///or if input nodes are not found.
519 ///////////////////////////////////////////////////////////////////////////////
521 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
527 //MESSAGE("AddVolumeWithID" << ID);
528 SMDS_MeshNode *node1, *node2, *node3, *node4;
529 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
530 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
531 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
532 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
533 if(!node1 || !node2 || !node3 || !node4) return NULL;
534 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
537 ///////////////////////////////////////////////////////////////////////////////
538 ///Create a new tetrahedron and add it to the mesh.
539 ///@param ID The ID of the new volume
540 ///@return The created tetrahedron
541 ///////////////////////////////////////////////////////////////////////////////
543 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
544 const SMDS_MeshNode * n2,
545 const SMDS_MeshNode * n3,
546 const SMDS_MeshNode * n4,
549 //MESSAGE("AddVolumeWithID " << ID);
550 SMDS_MeshVolume* volume = 0;
551 if ( !n1 || !n2 || !n3 || !n4) return volume;
552 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
553 if(hasConstructionFaces()) {
554 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
555 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
556 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
557 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
558 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
559 adjustmyCellsCapacity(ID);
560 myCells[ID] = volume;
563 else if(hasConstructionEdges()) {
564 MESSAGE("Error : Not implemented");
568 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
569 adjustmyCellsCapacity(ID);
570 myCells[ID] = volume;
574 if (!registerElement(ID, volume)) {
575 RemoveElement(volume, false);
581 ///////////////////////////////////////////////////////////////////////////////
582 ///Create a new pyramid and add it to the mesh.
583 ///Nodes 1,2,3 and 4 define the base of the pyramid
584 ///@return The created pyramid
585 ///////////////////////////////////////////////////////////////////////////////
587 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
588 const SMDS_MeshNode * n2,
589 const SMDS_MeshNode * n3,
590 const SMDS_MeshNode * n4,
591 const SMDS_MeshNode * n5)
593 int ID = myElementIDFactory->GetFreeID();
594 //MESSAGE("AddVolumeWithID " << ID);
595 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
596 if(v==NULL) myElementIDFactory->ReleaseID(ID);
600 ///////////////////////////////////////////////////////////////////////////////
601 ///Create a new pyramid and add it to the mesh.
602 ///Nodes 1,2,3 and 4 define the base of the pyramid
603 ///@param ID The ID of the new volume
604 ///@return The created pyramid or NULL if an element with this ID already exists
605 ///or if input nodes are not found.
606 ///////////////////////////////////////////////////////////////////////////////
608 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
615 //MESSAGE("AddVolumeWithID " << ID);
616 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
617 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
618 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
619 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
620 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
621 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
622 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
623 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
626 ///////////////////////////////////////////////////////////////////////////////
627 ///Create a new pyramid and add it to the mesh.
628 ///Nodes 1,2,3 and 4 define the base of the pyramid
629 ///@param ID The ID of the new volume
630 ///@return The created pyramid
631 ///////////////////////////////////////////////////////////////////////////////
633 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
634 const SMDS_MeshNode * n2,
635 const SMDS_MeshNode * n3,
636 const SMDS_MeshNode * n4,
637 const SMDS_MeshNode * n5,
640 //MESSAGE("AddVolumeWithID " << ID);
641 SMDS_MeshVolume* volume = 0;
642 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
643 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
644 if(hasConstructionFaces()) {
645 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
646 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
647 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
648 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
649 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
650 adjustmyCellsCapacity(ID);
651 myCells[ID] = volume;
652 myInfo.myNbPyramids++;
654 else if(hasConstructionEdges()) {
655 MESSAGE("Error : Not implemented");
659 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
660 adjustmyCellsCapacity(ID);
661 myCells[ID] = volume;
662 myInfo.myNbPyramids++;
665 if (!registerElement(ID, volume)) {
666 RemoveElement(volume, false);
672 ///////////////////////////////////////////////////////////////////////////////
673 ///Create a new prism and add it to the mesh.
674 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
675 ///@return The created prism
676 ///////////////////////////////////////////////////////////////////////////////
678 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
679 const SMDS_MeshNode * n2,
680 const SMDS_MeshNode * n3,
681 const SMDS_MeshNode * n4,
682 const SMDS_MeshNode * n5,
683 const SMDS_MeshNode * n6)
685 int ID = myElementIDFactory->GetFreeID();
686 //MESSAGE("AddVolumeWithID " << ID);
687 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
688 if(v==NULL) myElementIDFactory->ReleaseID(ID);
692 ///////////////////////////////////////////////////////////////////////////////
693 ///Create a new prism and add it to the mesh.
694 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
695 ///@param ID The ID of the new volume
696 ///@return The created prism or NULL if an element with this ID already exists
697 ///or if input nodes are not found.
698 ///////////////////////////////////////////////////////////////////////////////
700 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
708 //MESSAGE("AddVolumeWithID " << ID);
709 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
710 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
711 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
712 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
713 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
714 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
715 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
716 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
717 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
720 ///////////////////////////////////////////////////////////////////////////////
721 ///Create a new prism and add it to the mesh.
722 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
723 ///@param ID The ID of the new volume
724 ///@return The created prism
725 ///////////////////////////////////////////////////////////////////////////////
727 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
728 const SMDS_MeshNode * n2,
729 const SMDS_MeshNode * n3,
730 const SMDS_MeshNode * n4,
731 const SMDS_MeshNode * n5,
732 const SMDS_MeshNode * n6,
735 //MESSAGE("AddVolumeWithID " << ID);
736 SMDS_MeshVolume* volume = 0;
737 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
738 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
739 if(hasConstructionFaces()) {
740 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
741 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
742 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
743 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
744 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
745 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
746 adjustmyCellsCapacity(ID);
747 myCells[ID] = volume;
750 else if(hasConstructionEdges()) {
751 MESSAGE("Error : Not implemented");
755 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
756 adjustmyCellsCapacity(ID);
757 myCells[ID] = volume;
761 if (!registerElement(ID, volume)) {
762 RemoveElement(volume, false);
768 ///////////////////////////////////////////////////////////////////////////////
769 ///Create a new hexahedron and add it to the mesh.
770 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
771 ///@return The created hexahedron
772 ///////////////////////////////////////////////////////////////////////////////
774 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
775 const SMDS_MeshNode * n2,
776 const SMDS_MeshNode * n3,
777 const SMDS_MeshNode * n4,
778 const SMDS_MeshNode * n5,
779 const SMDS_MeshNode * n6,
780 const SMDS_MeshNode * n7,
781 const SMDS_MeshNode * n8)
783 int ID = myElementIDFactory->GetFreeID();
784 //MESSAGE("AddVolumeWithID " << ID);
785 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
786 if(v==NULL) myElementIDFactory->ReleaseID(ID);
790 ///////////////////////////////////////////////////////////////////////////////
791 ///Create a new hexahedron and add it to the mesh.
792 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
793 ///@param ID The ID of the new volume
794 ///@return The created hexahedron or NULL if an element with this ID already
795 ///exists or if input nodes are not found.
796 ///////////////////////////////////////////////////////////////////////////////
798 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
808 //MESSAGE("AddVolumeWithID " << ID);
809 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
810 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
811 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
812 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
813 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
814 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
815 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
816 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
817 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
818 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
820 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
824 ///////////////////////////////////////////////////////////////////////////////
825 ///Create a new hexahedron and add it to the mesh.
826 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
827 ///@param ID The ID of the new volume
828 ///@return The created prism or NULL if an element with this ID already exists
829 ///or if input nodes are not found.
830 ///////////////////////////////////////////////////////////////////////////////
832 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
833 const SMDS_MeshNode * n2,
834 const SMDS_MeshNode * n3,
835 const SMDS_MeshNode * n4,
836 const SMDS_MeshNode * n5,
837 const SMDS_MeshNode * n6,
838 const SMDS_MeshNode * n7,
839 const SMDS_MeshNode * n8,
842 //MESSAGE("AddVolumeWithID " << ID);
843 SMDS_MeshVolume* volume = 0;
844 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
845 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
846 if(hasConstructionFaces()) {
847 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
848 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
849 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
850 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
851 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
852 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
853 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
854 adjustmyCellsCapacity(ID);
855 myCells[ID] = volume;
858 else if(hasConstructionEdges()) {
859 MESSAGE("Error : Not implemented");
863 // --- retreive nodes ID
864 vector<vtkIdType> nodeIds;
866 nodeIds.push_back(n1->getId());
867 nodeIds.push_back(n2->getId());
868 nodeIds.push_back(n3->getId());
869 nodeIds.push_back(n4->getId());
870 nodeIds.push_back(n5->getId());
871 nodeIds.push_back(n6->getId());
872 nodeIds.push_back(n7->getId());
873 nodeIds.push_back(n8->getId());
875 //volume = new SMDS_VolumeVtkNodes(nodeIds, this);
876 SMDS_VolumeVtkNodes *volvtk = myVolumePool->getNew();
877 volvtk->init(nodeIds, this);
879 adjustmyCellsCapacity(ID);
880 myCells[ID] = volume;
884 if (!registerElement(ID, volume)) {
885 RemoveElement(volume, false);
891 ///////////////////////////////////////////////////////////////////////////////
892 ///Create a new tetrahedron defined by its faces and add it to the mesh.
893 ///@return The created tetrahedron
894 ///////////////////////////////////////////////////////////////////////////////
896 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
897 const SMDS_MeshFace * f2,
898 const SMDS_MeshFace * f3,
899 const SMDS_MeshFace * f4)
901 //MESSAGE("AddVolumeWithID");
902 if (!hasConstructionFaces())
904 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
907 ///////////////////////////////////////////////////////////////////////////////
908 ///Create a new tetrahedron defined by its faces and add it to the mesh.
909 ///@param ID The ID of the new volume
910 ///@return The created tetrahedron
911 ///////////////////////////////////////////////////////////////////////////////
913 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
914 const SMDS_MeshFace * f2,
915 const SMDS_MeshFace * f3,
916 const SMDS_MeshFace * f4,
919 //MESSAGE("AddVolumeWithID" << ID);
920 if (!hasConstructionFaces())
922 if ( !f1 || !f2 || !f3 || !f4) return 0;
923 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
924 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
925 adjustmyCellsCapacity(ID);
926 myCells[ID] = volume;
929 if (!registerElement(ID, volume)) {
930 RemoveElement(volume, false);
936 ///////////////////////////////////////////////////////////////////////////////
937 ///Create a new pyramid defined by its faces and add it to the mesh.
938 ///@return The created pyramid
939 ///////////////////////////////////////////////////////////////////////////////
941 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
942 const SMDS_MeshFace * f2,
943 const SMDS_MeshFace * f3,
944 const SMDS_MeshFace * f4,
945 const SMDS_MeshFace * f5)
947 //MESSAGE("AddVolumeWithID");
948 if (!hasConstructionFaces())
950 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
953 ///////////////////////////////////////////////////////////////////////////////
954 ///Create a new pyramid defined by its faces and add it to the mesh.
955 ///@param ID The ID of the new volume
956 ///@return The created pyramid
957 ///////////////////////////////////////////////////////////////////////////////
959 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
960 const SMDS_MeshFace * f2,
961 const SMDS_MeshFace * f3,
962 const SMDS_MeshFace * f4,
963 const SMDS_MeshFace * f5,
966 //MESSAGE("AddVolumeWithID" << ID);
967 if (!hasConstructionFaces())
969 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
970 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
971 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
972 adjustmyCellsCapacity(ID);
973 myCells[ID] = volume;
974 myInfo.myNbPyramids++;
976 if (!registerElement(ID, volume)) {
977 RemoveElement(volume, false);
983 ///////////////////////////////////////////////////////////////////////////////
984 ///Create a new prism defined by its faces and add it to the mesh.
985 ///@return The created prism
986 ///////////////////////////////////////////////////////////////////////////////
988 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
989 const SMDS_MeshFace * f2,
990 const SMDS_MeshFace * f3,
991 const SMDS_MeshFace * f4,
992 const SMDS_MeshFace * f5,
993 const SMDS_MeshFace * f6)
995 //MESSAGE("AddVolumeWithID" );
996 if (!hasConstructionFaces())
998 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1001 ///////////////////////////////////////////////////////////////////////////////
1002 ///Create a new prism defined by its faces and add it to the mesh.
1003 ///@param ID The ID of the new volume
1004 ///@return The created prism
1005 ///////////////////////////////////////////////////////////////////////////////
1007 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1008 const SMDS_MeshFace * f2,
1009 const SMDS_MeshFace * f3,
1010 const SMDS_MeshFace * f4,
1011 const SMDS_MeshFace * f5,
1012 const SMDS_MeshFace * f6,
1015 //MESSAGE("AddVolumeWithID" << ID);
1016 if (!hasConstructionFaces())
1018 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1019 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1020 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1021 adjustmyCellsCapacity(ID);
1022 myCells[ID] = volume;
1023 myInfo.myNbPrisms++;
1025 if (!registerElement(ID, volume)) {
1026 RemoveElement(volume, false);
1032 ///////////////////////////////////////////////////////////////////////////////
1033 /// Add a polygon defined by its nodes IDs
1034 ///////////////////////////////////////////////////////////////////////////////
1036 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1039 int nbNodes = nodes_ids.size();
1040 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1041 for (int i = 0; i < nbNodes; i++) {
1042 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1043 if (!nodes[i]) return NULL;
1045 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1048 ///////////////////////////////////////////////////////////////////////////////
1049 /// Add a polygon defined by its nodes
1050 ///////////////////////////////////////////////////////////////////////////////
1052 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1053 (std::vector<const SMDS_MeshNode*> nodes,
1056 SMDS_MeshFace * face;
1058 //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1059 if (hasConstructionEdges())
1061 MESSAGE("Error : Not implemented");
1066 for ( int i = 0; i < nodes.size(); ++i )
1067 if ( !nodes[ i ] ) return 0;
1068 face = new SMDS_PolygonalFaceOfNodes(nodes);
1069 adjustmyCellsCapacity(ID);
1071 myInfo.myNbPolygons++;
1074 if (!registerElement(ID, face)) {
1075 RemoveElement(face, false);
1081 ///////////////////////////////////////////////////////////////////////////////
1082 /// Add a polygon defined by its nodes.
1083 /// An ID is automatically affected to the created face.
1084 ///////////////////////////////////////////////////////////////////////////////
1086 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1088 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1091 ///////////////////////////////////////////////////////////////////////////////
1092 /// Create a new polyhedral volume and add it to the mesh.
1093 /// @param ID The ID of the new volume
1094 /// @return The created volume or NULL if an element with this ID already exists
1095 /// or if input nodes are not found.
1096 ///////////////////////////////////////////////////////////////////////////////
1098 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1099 (std::vector<int> nodes_ids,
1100 std::vector<int> quantities,
1103 int nbNodes = nodes_ids.size();
1104 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1105 for (int i = 0; i < nbNodes; i++) {
1106 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1107 if (!nodes[i]) return NULL;
1109 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1112 ///////////////////////////////////////////////////////////////////////////////
1113 /// Create a new polyhedral volume and add it to the mesh.
1114 /// @param ID The ID of the new volume
1115 /// @return The created volume
1116 ///////////////////////////////////////////////////////////////////////////////
1118 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1119 (std::vector<const SMDS_MeshNode*> nodes,
1120 std::vector<int> quantities,
1123 SMDS_MeshVolume* volume;
1124 //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1125 if (hasConstructionFaces()) {
1126 MESSAGE("Error : Not implemented");
1128 } else if (hasConstructionEdges()) {
1129 MESSAGE("Error : Not implemented");
1132 for ( int i = 0; i < nodes.size(); ++i )
1133 if ( !nodes[ i ] ) return 0;
1134 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1135 adjustmyCellsCapacity(ID);
1136 myCells[ID] = volume;
1137 myInfo.myNbPolyhedrons++;
1140 if (!registerElement(ID, volume)) {
1141 RemoveElement(volume, false);
1147 ///////////////////////////////////////////////////////////////////////////////
1148 /// Create a new polyhedral volume and add it to the mesh.
1149 /// @return The created volume
1150 ///////////////////////////////////////////////////////////////////////////////
1152 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1153 (std::vector<const SMDS_MeshNode*> nodes,
1154 std::vector<int> quantities)
1156 int ID = myElementIDFactory->GetFreeID();
1157 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1158 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1162 ///////////////////////////////////////////////////////////////////////////////
1163 /// Registers element with the given ID, maintains inverse connections
1164 ///////////////////////////////////////////////////////////////////////////////
1165 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1167 //MESSAGE("registerElement " << ID)
1168 if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1170 MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1175 element->myMeshId = myMeshId;
1177 SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1179 int vtkId = cell->getVtkId();
1181 vtkId = myElementIDFactory->SetInVtkGrid(element);
1183 if (ID >= myIDElements.size()) // --- resize local vector
1185 MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1186 myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1189 myIDElements[ID] = vtkId;
1190 //MESSAGE("smds:" << ID << " vtk:" << cellId );
1192 if (vtkId >= myVtkIndex.size()) // --- resize local vector
1194 MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1195 myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1197 myVtkIndex[vtkId] = ID;
1199 myElementIDFactory->updateMinMax(ID);
1203 ///////////////////////////////////////////////////////////////////////////////
1204 /// Return the node whose ID is 'ID'.
1205 ///////////////////////////////////////////////////////////////////////////////
1206 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1208 if (ID <0 || ID >= myNodes.size())
1210 return (const SMDS_MeshNode *)myNodes[ID];
1213 ///////////////////////////////////////////////////////////////////////////////
1214 ///Create a triangle and add it to the current mesh. This methode do not bind a
1215 ///ID to the create triangle.
1216 ///////////////////////////////////////////////////////////////////////////////
1217 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1218 const SMDS_MeshNode * node2,
1219 const SMDS_MeshNode * node3)
1221 if ( !node1 || !node2 || !node3) return 0;
1222 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1223 if(hasConstructionEdges())
1225 SMDS_MeshEdge *edge1, *edge2, *edge3;
1226 edge1=FindEdgeOrCreate(node1,node2);
1227 edge2=FindEdgeOrCreate(node2,node3);
1228 edge3=FindEdgeOrCreate(node3,node1);
1230 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1231 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1232 adjustmyCellsCapacity(ID);
1234 myInfo.myNbTriangles++;
1239 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1240 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1241 adjustmyCellsCapacity(ID);
1243 myInfo.myNbTriangles++;
1248 ///////////////////////////////////////////////////////////////////////////////
1249 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1250 ///a ID to the create triangle.
1251 ///////////////////////////////////////////////////////////////////////////////
1252 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1253 const SMDS_MeshNode * node2,
1254 const SMDS_MeshNode * node3,
1255 const SMDS_MeshNode * node4,
1258 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1259 // if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1260 if(hasConstructionEdges())
1262 //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1263 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1264 edge1=FindEdgeOrCreate(node1,node2);
1265 edge2=FindEdgeOrCreate(node2,node3);
1266 edge3=FindEdgeOrCreate(node3,node4);
1267 edge4=FindEdgeOrCreate(node4,node1);
1269 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1270 adjustmyCellsCapacity(ID);
1272 myInfo.myNbQuadrangles++;
1277 //MESSAGE("createQuadrangle " << ID);
1278 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1279 adjustmyCellsCapacity(ID);
1281 myInfo.myNbQuadrangles++;
1286 ///////////////////////////////////////////////////////////////////////////////
1287 /// Remove a node and all the elements which own this node
1288 ///////////////////////////////////////////////////////////////////////////////
1290 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1292 MESSAGE("RemoveNode");
1293 RemoveElement(node, true);
1296 ///////////////////////////////////////////////////////////////////////////////
1297 /// Remove an edge and all the elements which own this edge
1298 ///////////////////////////////////////////////////////////////////////////////
1300 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1302 MESSAGE("Remove0DElement");
1303 RemoveElement(elem0d,true);
1306 ///////////////////////////////////////////////////////////////////////////////
1307 /// Remove an edge and all the elements which own this edge
1308 ///////////////////////////////////////////////////////////////////////////////
1310 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1312 MESSAGE("RemoveEdge");
1313 RemoveElement(edge,true);
1316 ///////////////////////////////////////////////////////////////////////////////
1317 /// Remove an face and all the elements which own this face
1318 ///////////////////////////////////////////////////////////////////////////////
1320 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1322 MESSAGE("RemoveFace");
1323 RemoveElement(face, true);
1326 ///////////////////////////////////////////////////////////////////////////////
1328 ///////////////////////////////////////////////////////////////////////////////
1330 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1332 MESSAGE("RemoveVolume");
1333 RemoveElement(volume, true);
1336 //=======================================================================
1337 //function : RemoveFromParent
1339 //=======================================================================
1341 bool SMDS_Mesh::RemoveFromParent()
1343 if (myParent==NULL) return false;
1344 else return (myParent->RemoveSubMesh(this));
1347 //=======================================================================
1348 //function : RemoveSubMesh
1350 //=======================================================================
1352 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1356 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1357 for (; itmsh!=myChildren.end() && !found; itmsh++)
1359 SMDS_Mesh * submesh = *itmsh;
1360 if (submesh == aMesh)
1363 myChildren.erase(itmsh);
1370 //=======================================================================
1371 //function : ChangeElementNodes
1373 //=======================================================================
1375 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1376 const SMDS_MeshNode * nodes[],
1379 // keep current nodes of elem
1380 set<const SMDS_MeshElement*> oldNodes;
1381 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1383 oldNodes.insert( itn->next() );
1385 if ( !element->IsPoly() )
1386 myInfo.remove( element ); // element may change type
1390 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1391 switch ( elem->GetType() )
1393 case SMDSAbs_0DElement: {
1394 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1395 Ok = elem0d->ChangeNode( nodes[0] );
1398 case SMDSAbs_Edge: {
1399 if ( nbnodes == 2 ) {
1400 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1401 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1403 else if ( nbnodes == 3 ) {
1404 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1405 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1409 case SMDSAbs_Face: {
1410 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1411 Ok = face->ChangeNodes( nodes, nbnodes );
1413 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1414 Ok = QF->ChangeNodes( nodes, nbnodes );
1416 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1417 Ok = face->ChangeNodes(nodes, nbnodes);
1420 case SMDSAbs_Volume: {
1421 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1422 Ok = vol->ChangeNodes( nodes, nbnodes );
1424 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1425 Ok = QV->ChangeNodes( nodes, nbnodes );
1429 MESSAGE ( "WRONG ELEM TYPE");
1432 if ( Ok ) { // update InverseElements
1434 set<const SMDS_MeshElement*>::iterator it;
1436 // AddInverseElement to new nodes
1437 for ( int i = 0; i < nbnodes; i++ ) {
1438 it = oldNodes.find( nodes[i] );
1439 if ( it == oldNodes.end() )
1441 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1443 // remove from oldNodes a node that remains in elem
1444 oldNodes.erase( it );
1446 // RemoveInverseElement from the nodes removed from elem
1447 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1449 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1450 (const_cast<SMDS_MeshElement *>( *it ));
1451 n->RemoveInverseElement( elem );
1455 if ( !element->IsPoly() )
1456 myInfo.add( element ); // element may change type
1461 //=======================================================================
1462 //function : ChangePolyhedronNodes
1463 //purpose : to change nodes of polyhedral volume
1464 //=======================================================================
1465 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1466 const vector<const SMDS_MeshNode*>& nodes,
1467 const vector<int> & quantities)
1469 if (elem->GetType() != SMDSAbs_Volume) {
1470 MESSAGE("WRONG ELEM TYPE");
1474 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1479 // keep current nodes of elem
1480 set<const SMDS_MeshElement*> oldNodes;
1481 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1482 while (itn->more()) {
1483 oldNodes.insert(itn->next());
1487 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1492 // update InverseElements
1494 // AddInverseElement to new nodes
1495 int nbnodes = nodes.size();
1496 set<const SMDS_MeshElement*>::iterator it;
1497 for (int i = 0; i < nbnodes; i++) {
1498 it = oldNodes.find(nodes[i]);
1499 if (it == oldNodes.end()) {
1501 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1503 // remove from oldNodes a node that remains in elem
1508 // RemoveInverseElement from the nodes removed from elem
1509 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1510 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1511 (const_cast<SMDS_MeshElement *>( *it ));
1512 n->RemoveInverseElement(elem);
1519 //=======================================================================
1520 //function : Find0DElement
1522 //=======================================================================
1523 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1525 const SMDS_MeshNode * node = FindNode(idnode);
1526 if(node == NULL) return NULL;
1527 return Find0DElement(node);
1530 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1532 if (!node) return 0;
1533 const SMDS_Mesh0DElement* toReturn = NULL;
1534 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1535 while (it1->more() && (toReturn == NULL)) {
1536 const SMDS_MeshElement* e = it1->next();
1537 if (e->NbNodes() == 1) {
1538 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1544 //=======================================================================
1545 //function : Find0DElementOrCreate
1547 //=======================================================================
1548 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1550 // if (!node) return 0;
1551 // SMDS_Mesh0DElement * toReturn = NULL;
1552 // toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1553 // if (toReturn == NULL) {
1554 // //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1555 // toReturn = new SMDS_Mesh0DElement(node);
1556 // my0DElements.Add(toReturn);
1557 // myInfo.myNb0DElements++;
1563 //=======================================================================
1564 //function : FindEdge
1566 //=======================================================================
1568 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1570 const SMDS_MeshNode * node1=FindNode(idnode1);
1571 const SMDS_MeshNode * node2=FindNode(idnode2);
1572 if((node1==NULL)||(node2==NULL)) return NULL;
1573 return FindEdge(node1,node2);
1576 //#include "Profiler.h"
1577 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1578 const SMDS_MeshNode * node2)
1580 if ( !node1 ) return 0;
1581 const SMDS_MeshEdge * toReturn=NULL;
1584 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1587 while(it1->more()) {
1588 const SMDS_MeshElement * e = it1->next();
1589 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1590 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1599 //=======================================================================
1600 //function : FindEdgeOrCreate
1602 //=======================================================================
1604 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1605 const SMDS_MeshNode * node2)
1607 if ( !node1 || !node2) return 0;
1608 SMDS_MeshEdge * toReturn=NULL;
1609 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1610 if(toReturn==NULL) {
1611 //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1612 int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1613 adjustmyCellsCapacity(ID);
1614 toReturn=new SMDS_MeshEdge(node1,node2);
1615 myCells[ID] = toReturn;
1622 //=======================================================================
1623 //function : FindEdge
1625 //=======================================================================
1627 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1630 const SMDS_MeshNode * node1=FindNode(idnode1);
1631 const SMDS_MeshNode * node2=FindNode(idnode2);
1632 const SMDS_MeshNode * node3=FindNode(idnode3);
1633 return FindEdge(node1,node2,node3);
1636 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1637 const SMDS_MeshNode * node2,
1638 const SMDS_MeshNode * node3)
1640 if ( !node1 ) return 0;
1641 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1642 while(it1->more()) {
1643 const SMDS_MeshElement * e = it1->next();
1644 if ( e->NbNodes() == 3 ) {
1645 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1646 while(it2->more()) {
1647 const SMDS_MeshElement* n = it2->next();
1657 return static_cast<const SMDS_MeshEdge *> (e);
1664 //=======================================================================
1665 //function : FindFace
1667 //=======================================================================
1669 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1672 const SMDS_MeshNode * node1=FindNode(idnode1);
1673 const SMDS_MeshNode * node2=FindNode(idnode2);
1674 const SMDS_MeshNode * node3=FindNode(idnode3);
1675 return FindFace(node1, node2, node3);
1678 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1679 const SMDS_MeshNode *node2,
1680 const SMDS_MeshNode *node3)
1682 if ( !node1 ) return 0;
1683 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1684 while(it1->more()) {
1685 const SMDS_MeshElement * e = it1->next();
1686 if ( e->NbNodes() == 3 ) {
1687 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1688 while(it2->more()) {
1689 const SMDS_MeshElement* n = it2->next();
1699 return static_cast<const SMDS_MeshFace *> (e);
1705 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1706 const SMDS_MeshNode *node2,
1707 const SMDS_MeshNode *node3)
1709 SMDS_MeshFace * toReturn=NULL;
1710 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1711 if(toReturn==NULL) {
1712 toReturn = createTriangle(node1,node2,node3);
1718 //=======================================================================
1719 //function : FindFace
1721 //=======================================================================
1723 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1724 int idnode3, int idnode4) const
1726 const SMDS_MeshNode * node1=FindNode(idnode1);
1727 const SMDS_MeshNode * node2=FindNode(idnode2);
1728 const SMDS_MeshNode * node3=FindNode(idnode3);
1729 const SMDS_MeshNode * node4=FindNode(idnode4);
1730 return FindFace(node1, node2, node3, node4);
1733 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1734 const SMDS_MeshNode *node2,
1735 const SMDS_MeshNode *node3,
1736 const SMDS_MeshNode *node4)
1738 if ( !node1 ) return 0;
1739 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1740 while(it1->more()) {
1741 const SMDS_MeshElement * e = it1->next();
1742 if ( e->NbNodes() == 4 ) {
1743 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1744 while(it2->more()) {
1745 const SMDS_MeshElement* n = it2->next();
1756 return static_cast<const SMDS_MeshFace *> (e);
1762 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1763 const SMDS_MeshNode *node2,
1764 const SMDS_MeshNode *node3,
1765 const SMDS_MeshNode *node4)
1767 SMDS_MeshFace * toReturn=NULL;
1768 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1769 if(toReturn==NULL) {
1770 int ID = myElementIDFactory->GetFreeID();
1771 toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1777 //=======================================================================
1778 //function : FindFace
1779 //purpose :quadratic triangle
1780 //=======================================================================
1782 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1783 int idnode3, int idnode4,
1784 int idnode5, int idnode6) const
1786 const SMDS_MeshNode * node1 = FindNode(idnode1);
1787 const SMDS_MeshNode * node2 = FindNode(idnode2);
1788 const SMDS_MeshNode * node3 = FindNode(idnode3);
1789 const SMDS_MeshNode * node4 = FindNode(idnode4);
1790 const SMDS_MeshNode * node5 = FindNode(idnode5);
1791 const SMDS_MeshNode * node6 = FindNode(idnode6);
1792 return FindFace(node1, node2, node3, node4, node5, node6);
1795 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1796 const SMDS_MeshNode *node2,
1797 const SMDS_MeshNode *node3,
1798 const SMDS_MeshNode *node4,
1799 const SMDS_MeshNode *node5,
1800 const SMDS_MeshNode *node6)
1802 if ( !node1 ) return 0;
1803 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1804 while(it1->more()) {
1805 const SMDS_MeshElement * e = it1->next();
1806 if ( e->NbNodes() == 6 ) {
1807 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1808 while(it2->more()) {
1809 const SMDS_MeshElement* n = it2->next();
1822 return static_cast<const SMDS_MeshFace *> (e);
1829 //=======================================================================
1830 //function : FindFace
1831 //purpose : quadratic quadrangle
1832 //=======================================================================
1834 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1835 int idnode3, int idnode4,
1836 int idnode5, int idnode6,
1837 int idnode7, int idnode8) const
1839 const SMDS_MeshNode * node1 = FindNode(idnode1);
1840 const SMDS_MeshNode * node2 = FindNode(idnode2);
1841 const SMDS_MeshNode * node3 = FindNode(idnode3);
1842 const SMDS_MeshNode * node4 = FindNode(idnode4);
1843 const SMDS_MeshNode * node5 = FindNode(idnode5);
1844 const SMDS_MeshNode * node6 = FindNode(idnode6);
1845 const SMDS_MeshNode * node7 = FindNode(idnode7);
1846 const SMDS_MeshNode * node8 = FindNode(idnode8);
1847 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1850 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1851 const SMDS_MeshNode *node2,
1852 const SMDS_MeshNode *node3,
1853 const SMDS_MeshNode *node4,
1854 const SMDS_MeshNode *node5,
1855 const SMDS_MeshNode *node6,
1856 const SMDS_MeshNode *node7,
1857 const SMDS_MeshNode *node8)
1859 if ( !node1 ) return 0;
1860 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1861 while(it1->more()) {
1862 const SMDS_MeshElement * e = it1->next();
1863 if ( e->NbNodes() == 8 ) {
1864 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1865 while(it2->more()) {
1866 const SMDS_MeshElement* n = it2->next();
1881 return static_cast<const SMDS_MeshFace *> (e);
1888 //=======================================================================
1889 //function : FindElement
1891 //=======================================================================
1893 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1895 if ((IDelem < 0) || IDelem >= myCells.size())
1897 return myCells[IDelem];
1900 //=======================================================================
1901 //function : FindFace
1902 //purpose : find polygon
1903 //=======================================================================
1905 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1907 int nbnodes = nodes_ids.size();
1908 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1909 for (int inode = 0; inode < nbnodes; inode++) {
1910 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1911 if (node == NULL) return NULL;
1912 poly_nodes[inode] = node;
1914 return FindFace(poly_nodes);
1917 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1919 if ( nodes.size() > 2 && nodes[0] ) {
1920 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1921 while (itF->more()) {
1922 const SMDS_MeshElement* f = itF->next();
1923 if ( f->NbNodes() == nodes.size() ) {
1924 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1925 while(it2->more()) {
1926 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1932 return static_cast<const SMDS_MeshFace *> (f);
1939 //=======================================================================
1940 //function : DumpNodes
1942 //=======================================================================
1944 void SMDS_Mesh::DumpNodes() const
1946 MESSAGE("dump nodes of mesh : ");
1947 SMDS_NodeIteratorPtr itnode=nodesIterator();
1948 while(itnode->more()) ; //MESSAGE(itnode->next());
1951 //=======================================================================
1952 //function : Dump0DElements
1954 //=======================================================================
1955 void SMDS_Mesh::Dump0DElements() const
1957 MESSAGE("dump 0D elements of mesh : ");
1958 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
1959 while(it0d->more()) ; //MESSAGE(it0d->next());
1962 //=======================================================================
1963 //function : DumpEdges
1965 //=======================================================================
1967 void SMDS_Mesh::DumpEdges() const
1969 MESSAGE("dump edges of mesh : ");
1970 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1971 while(itedge->more()) ; //MESSAGE(itedge->next());
1974 //=======================================================================
1975 //function : DumpFaces
1977 //=======================================================================
1979 void SMDS_Mesh::DumpFaces() const
1981 MESSAGE("dump faces of mesh : ");
1982 SMDS_FaceIteratorPtr itface=facesIterator();
1983 while(itface->more()) ; //MESSAGE(itface->next());
1986 //=======================================================================
1987 //function : DumpVolumes
1989 //=======================================================================
1991 void SMDS_Mesh::DumpVolumes() const
1993 MESSAGE("dump volumes of mesh : ");
1994 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1995 while(itvol->more()) ; //MESSAGE(itvol->next());
1998 //=======================================================================
1999 //function : DebugStats
2001 //=======================================================================
2003 void SMDS_Mesh::DebugStats() const
2005 MESSAGE("Debug stats of mesh : ");
2007 MESSAGE("===== NODES ====="<<NbNodes());
2008 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2009 MESSAGE("===== EDGES ====="<<NbEdges());
2010 MESSAGE("===== FACES ====="<<NbFaces());
2011 MESSAGE("===== VOLUMES ====="<<NbVolumes());
2013 MESSAGE("End Debug stats of mesh ");
2017 SMDS_NodeIteratorPtr itnode=nodesIterator();
2018 int sizeofnodes = 0;
2019 int sizeoffaces = 0;
2021 while(itnode->more())
2023 const SMDS_MeshNode *node = itnode->next();
2025 sizeofnodes += sizeof(*node);
2027 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2030 const SMDS_MeshElement *me = it->next();
2031 sizeofnodes += sizeof(me);
2035 SMDS_FaceIteratorPtr itface=facesIterator();
2036 while(itface->more())
2038 const SMDS_MeshElement *face = itface->next();
2039 sizeoffaces += sizeof(*face);
2042 MESSAGE("total size of node elements = " << sizeofnodes);;
2043 MESSAGE("total size of face elements = " << sizeoffaces);;
2048 ///////////////////////////////////////////////////////////////////////////////
2049 /// Return the number of nodes
2050 ///////////////////////////////////////////////////////////////////////////////
2051 int SMDS_Mesh::NbNodes() const
2053 return myNodes.size();
2056 ///////////////////////////////////////////////////////////////////////////////
2057 /// Return the number of 0D elements
2058 ///////////////////////////////////////////////////////////////////////////////
2059 int SMDS_Mesh::Nb0DElements() const
2061 return myInfo.Nb0DElements(); // -PR- a verfier
2064 ///////////////////////////////////////////////////////////////////////////////
2065 /// Return the number of edges (including construction edges)
2066 ///////////////////////////////////////////////////////////////////////////////
2067 int SMDS_Mesh::NbEdges() const
2069 return myInfo.NbEdges(); // -PR- a verfier
2072 ///////////////////////////////////////////////////////////////////////////////
2073 /// Return the number of faces (including construction faces)
2074 ///////////////////////////////////////////////////////////////////////////////
2075 int SMDS_Mesh::NbFaces() const
2077 return myInfo.NbFaces(); // -PR- a verfier
2080 ///////////////////////////////////////////////////////////////////////////////
2081 /// Return the number of volumes
2082 ///////////////////////////////////////////////////////////////////////////////
2083 int SMDS_Mesh::NbVolumes() const
2085 return myInfo.NbVolumes(); // -PR- a verfier
2088 ///////////////////////////////////////////////////////////////////////////////
2089 /// Return the number of child mesh of this mesh.
2090 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2091 /// (2003-09-08) of SMESH
2092 ///////////////////////////////////////////////////////////////////////////////
2093 int SMDS_Mesh::NbSubMesh() const
2095 return myChildren.size();
2098 ///////////////////////////////////////////////////////////////////////////////
2099 /// Destroy the mesh and all its elements
2100 /// All pointer on elements owned by this mesh become illegals.
2101 ///////////////////////////////////////////////////////////////////////////////
2102 SMDS_Mesh::~SMDS_Mesh()
2104 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2105 while(itc!=myChildren.end())
2113 delete myNodeIDFactory;
2114 delete myElementIDFactory;
2118 SMDS_ElemIteratorPtr eIt = elementsIterator();
2119 while ( eIt->more() )
2120 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2121 SMDS_NodeIteratorPtr itn = nodesIterator();
2123 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2126 // SetOfNodes::Iterator itn(myNodes);
2127 // for (; itn.More(); itn.Next())
2128 // delete itn.Value();
2130 // SetOf0DElements::Iterator it0d (my0DElements);
2131 // for (; it0d.More(); it0d.Next())
2133 // SMDS_MeshElement* elem = it0d.Value();
2137 // SetOfEdges::Iterator ite(myEdges);
2138 // for (; ite.More(); ite.Next())
2140 // SMDS_MeshElement* elem = ite.Value();
2144 // SetOfFaces::Iterator itf(myFaces);
2145 // for (; itf.More(); itf.Next())
2147 // SMDS_MeshElement* elem = itf.Value();
2151 // SetOfVolumes::Iterator itv(myVolumes);
2152 // for (; itv.More(); itv.Next())
2154 // SMDS_MeshElement* elem = itv.Value();
2159 //================================================================================
2161 * \brief Clear all data
2163 //================================================================================
2165 void SMDS_Mesh::Clear()
2167 if (myParent!=NULL) {
2168 SMDS_ElemIteratorPtr eIt = elementsIterator();
2169 while ( eIt->more() )
2170 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2171 SMDS_NodeIteratorPtr itn = nodesIterator();
2173 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2176 myNodeIDFactory->Clear();
2177 myElementIDFactory->Clear();
2180 SMDS_ElemIteratorPtr itv = elementsIterator();
2185 // SMDS_VolumeIteratorPtr itv = volumesIterator();
2186 // while (itv->more())
2187 // delete itv->next();
2188 // myVolumes.Clear();
2190 // SMDS_FaceIteratorPtr itf = facesIterator();
2191 // while (itf->more())
2192 // delete itf->next();
2195 // SMDS_EdgeIteratorPtr ite = edgesIterator();
2196 // while (ite->more())
2197 // delete ite->next();
2200 // SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2201 // while (it0d->more())
2202 // delete it0d->next();
2203 // my0DElements.Clear();
2205 SMDS_NodeIteratorPtr itn = nodesIterator();
2210 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2211 while(itc!=myChildren.end())
2217 ///////////////////////////////////////////////////////////////////////////////
2218 /// Return true if this mesh create faces with edges.
2219 /// A false returned value mean that faces are created with nodes. A concequence
2220 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2221 ///////////////////////////////////////////////////////////////////////////////
2222 bool SMDS_Mesh::hasConstructionEdges()
2224 return myHasConstructionEdges;
2227 ///////////////////////////////////////////////////////////////////////////////
2228 /// Return true if this mesh create volumes with faces
2229 /// A false returned value mean that volumes are created with nodes or edges.
2230 /// (see hasConstructionEdges)
2231 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2233 ///////////////////////////////////////////////////////////////////////////////
2234 bool SMDS_Mesh::hasConstructionFaces()
2236 return myHasConstructionFaces;
2239 ///////////////////////////////////////////////////////////////////////////////
2240 /// Return true if nodes are linked to the finit elements, they are belonging to.
2241 /// Currently, It always return true.
2242 ///////////////////////////////////////////////////////////////////////////////
2243 bool SMDS_Mesh::hasInverseElements()
2245 return myHasInverseElements;
2248 ///////////////////////////////////////////////////////////////////////////////
2249 /// Make this mesh creating construction edges (see hasConstructionEdges)
2250 /// @param b true to have construction edges, else false.
2251 ///////////////////////////////////////////////////////////////////////////////
2252 void SMDS_Mesh::setConstructionEdges(bool b)
2254 myHasConstructionEdges=b;
2257 ///////////////////////////////////////////////////////////////////////////////
2258 /// Make this mesh creating construction faces (see hasConstructionFaces)
2259 /// @param b true to have construction faces, else false.
2260 ///////////////////////////////////////////////////////////////////////////////
2261 void SMDS_Mesh::setConstructionFaces(bool b)
2263 myHasConstructionFaces=b;
2266 ///////////////////////////////////////////////////////////////////////////////
2267 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2268 /// @param b true to link nodes to elements, else false.
2269 ///////////////////////////////////////////////////////////////////////////////
2270 void SMDS_Mesh::setInverseElements(bool b)
2272 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2273 myHasInverseElements=b;
2276 ///////////////////////////////////////////////////////////////////////////////
2277 ///Iterator on NCollection_Map
2278 ///////////////////////////////////////////////////////////////////////////////
2279 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2280 struct MYNode_Map_Iterator: public FATHER
2284 MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2291 while (_ctr < _map.size())
2302 ELEM current = _map[_ctr];
2308 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2309 struct MYElem_Map_Iterator: public FATHER
2314 MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2322 while (_ctr < _map.size())
2325 if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2334 ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2340 ///////////////////////////////////////////////////////////////////////////////
2341 /// Return an iterator on nodes of the current mesh factory
2342 ///////////////////////////////////////////////////////////////////////////////
2344 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2346 //return SMDS_NodeIteratorPtr
2347 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2348 typedef MYNode_Map_Iterator
2349 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2350 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2353 ///////////////////////////////////////////////////////////////////////////////
2354 ///Return an iterator on 0D elements of the current mesh.
2355 ///////////////////////////////////////////////////////////////////////////////
2357 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2359 typedef MYElem_Map_Iterator
2360 < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2361 return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2364 ///////////////////////////////////////////////////////////////////////////////
2365 ///Return an iterator on edges of the current mesh.
2366 ///////////////////////////////////////////////////////////////////////////////
2368 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2370 typedef MYElem_Map_Iterator
2371 < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2372 return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2375 ///////////////////////////////////////////////////////////////////////////////
2376 ///Return an iterator on faces of the current mesh.
2377 ///////////////////////////////////////////////////////////////////////////////
2379 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2381 typedef MYElem_Map_Iterator
2382 < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2383 return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2386 ///////////////////////////////////////////////////////////////////////////////
2387 ///Return an iterator on volumes of the current mesh.
2388 ///////////////////////////////////////////////////////////////////////////////
2390 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2392 typedef MYElem_Map_Iterator
2393 < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2394 return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2397 ///////////////////////////////////////////////////////////////////////////////
2398 /// Return an iterator on elements of the current mesh factory
2399 ///////////////////////////////////////////////////////////////////////////////
2400 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2404 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2406 case SMDSAbs_Volume:
2407 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2409 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2411 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2412 case SMDSAbs_0DElement:
2413 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2415 return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2416 //return myNodeIDFactory->elementsIterator();
2419 return myElementIDFactory->elementsIterator();
2422 ///////////////////////////////////////////////////////////////////////////////
2423 /// Do intersection of sets (more than 2)
2424 ///////////////////////////////////////////////////////////////////////////////
2425 static set<const SMDS_MeshElement*> * intersectionOfSets(
2426 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2428 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2429 set<const SMDS_MeshElement*>* rsetB;
2431 for(int i=0; i<numberOfSets-1; i++)
2433 rsetB=new set<const SMDS_MeshElement*>();
2435 rsetA->begin(), rsetA->end(),
2436 vs[i+1].begin(), vs[i+1].end(),
2437 inserter(*rsetB, rsetB->begin()));
2444 ///////////////////////////////////////////////////////////////////////////////
2445 /// Return the list of finit elements owning the given element
2446 ///////////////////////////////////////////////////////////////////////////////
2447 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2449 int numberOfSets=element->NbNodes();
2450 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2452 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2455 while(itNodes->more())
2457 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2458 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2460 //initSet[i]=set<const SMDS_MeshElement*>();
2462 initSet[i].insert(itFe->next());
2466 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2471 ///////////////////////////////////////////////////////////////////////////////
2472 /// Return the list of nodes used only by the given elements
2473 ///////////////////////////////////////////////////////////////////////////////
2474 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2475 set<const SMDS_MeshElement*>& elements)
2477 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2478 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2480 while(itElements!=elements.end())
2482 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2485 while(itNodes->more())
2487 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2488 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2489 set<const SMDS_MeshElement*> s;
2491 s.insert(itFe->next());
2492 if(s==elements) toReturn->insert(n);
2498 ///////////////////////////////////////////////////////////////////////////////
2499 ///Find the children of an element that are made of given nodes
2500 ///@param setOfChildren The set in which matching children will be inserted
2501 ///@param element The element were to search matching children
2502 ///@param nodes The nodes that the children must have to be selected
2503 ///////////////////////////////////////////////////////////////////////////////
2504 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2505 const SMDS_MeshElement * element,
2506 set<const SMDS_MeshElement*>& nodes)
2508 switch(element->GetType())
2511 MESSAGE("Internal Error: This should not happend");
2513 case SMDSAbs_0DElement:
2519 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2522 const SMDS_MeshElement * e=itn->next();
2523 if(nodes.find(e)!=nodes.end())
2525 setOfChildren.insert(element);
2532 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2535 const SMDS_MeshElement * e=itn->next();
2536 if(nodes.find(e)!=nodes.end())
2538 setOfChildren.insert(element);
2542 if(hasConstructionEdges())
2544 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2546 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2549 case SMDSAbs_Volume:
2551 if(hasConstructionFaces())
2553 SMDS_ElemIteratorPtr ite=element->facesIterator();
2555 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2557 else if(hasConstructionEdges())
2559 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2561 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2567 ///////////////////////////////////////////////////////////////////////////////
2568 ///@param elem The element to delete
2569 ///@param removenodes if true remaining nodes will be removed
2570 ///////////////////////////////////////////////////////////////////////////////
2571 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2572 const bool removenodes)
2574 list<const SMDS_MeshElement *> removedElems;
2575 list<const SMDS_MeshElement *> removedNodes;
2576 RemoveElement( elem, removedElems, removedNodes, removenodes );
2579 ///////////////////////////////////////////////////////////////////////////////
2580 ///@param elem The element to delete
2581 ///@param removedElems contains all removed elements
2582 ///@param removedNodes contains all removed nodes
2583 ///@param removenodes if true remaining nodes will be removed
2584 ///////////////////////////////////////////////////////////////////////////////
2585 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2586 list<const SMDS_MeshElement *>& removedElems,
2587 list<const SMDS_MeshElement *>& removedNodes,
2590 // get finite elements built on elem
2591 set<const SMDS_MeshElement*> * s1;
2592 if (elem->GetType() == SMDSAbs_0DElement ||
2593 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2594 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2595 elem->GetType() == SMDSAbs_Volume)
2597 s1 = new set<const SMDS_MeshElement*>();
2601 s1 = getFinitElements(elem);
2603 // get exclusive nodes (which would become free afterwards)
2604 set<const SMDS_MeshElement*> * s2;
2605 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2607 // do not remove nodes except elem
2608 s2 = new set<const SMDS_MeshElement*>();
2613 s2 = getExclusiveNodes(*s1);
2615 // form the set of finite and construction elements to remove
2616 set<const SMDS_MeshElement*> s3;
2617 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2618 while(it!=s1->end())
2620 addChildrenWithNodes(s3, *it ,*s2);
2624 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2626 // remove finite and construction elements
2630 // Remove element from <InverseElements> of its nodes
2631 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2634 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2635 (const_cast<SMDS_MeshElement *>(itn->next()));
2636 n->RemoveInverseElement( (*it) );
2639 switch((*it)->GetType())
2642 MESSAGE("Internal Error: This should not happen");
2644 case SMDSAbs_0DElement:
2645 myCells[(*it)->GetID()] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2649 myCells[(*it)->GetID()] = 0;
2650 myInfo.RemoveEdge(*it);
2653 myCells[(*it)->GetID()] = 0;
2654 myInfo.RemoveFace(*it);
2656 case SMDSAbs_Volume:
2657 myCells[(*it)->GetID()] = 0;
2658 myInfo.RemoveVolume(*it);
2661 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2662 removedElems.push_back( (*it) );
2663 myElementIDFactory->ReleaseID((*it)->GetID());
2668 // remove exclusive (free) nodes
2672 while(it!=s2->end())
2674 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2675 myNodes[(*it)->GetID()] = 0;
2677 myNodeIDFactory->ReleaseID((*it)->GetID());
2678 removedNodes.push_back( (*it) );
2689 ///////////////////////////////////////////////////////////////////////////////
2690 ///@param elem The element to delete
2691 ///////////////////////////////////////////////////////////////////////////////
2692 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2694 SMDSAbs_ElementType aType = elem->GetType();
2695 if (aType == SMDSAbs_Node) {
2696 // only free node can be removed by this method
2697 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2698 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2699 if (!itFe->more()) { // free node
2700 myNodes[elem->GetID()] = 0;
2702 myNodeIDFactory->ReleaseID(elem->GetID());
2706 if (hasConstructionEdges() || hasConstructionFaces())
2707 // this methods is only for meshes without descendants
2710 // Remove element from <InverseElements> of its nodes
2711 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2712 while (itn->more()) {
2713 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2714 (const_cast<SMDS_MeshElement *>(itn->next()));
2715 n->RemoveInverseElement(elem);
2718 // in meshes without descendants elements are always free
2720 case SMDSAbs_0DElement:
2721 myCells[elem->GetID()] = 0;
2722 myInfo.remove(elem);
2725 myCells[elem->GetID()] = 0;
2726 myInfo.RemoveEdge(elem);
2729 myCells[elem->GetID()] = 0;
2730 myInfo.RemoveFace(elem);
2732 case SMDSAbs_Volume:
2733 myCells[elem->GetID()] = 0;
2734 myInfo.RemoveVolume(elem);
2739 myElementIDFactory->ReleaseID(elem->GetID());
2745 * Checks if the element is present in mesh.
2746 * Useful to determine dead pointers.
2748 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2750 // we should not imply on validity of *elem, so iterate on containers
2751 // of all types in the hope of finding <elem> somewhere there
2752 SMDS_NodeIteratorPtr itn = nodesIterator();
2754 if (elem == itn->next())
2756 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2757 while (it0d->more())
2758 if (elem == it0d->next())
2760 SMDS_EdgeIteratorPtr ite = edgesIterator();
2762 if (elem == ite->next())
2764 SMDS_FaceIteratorPtr itf = facesIterator();
2766 if (elem == itf->next())
2768 SMDS_VolumeIteratorPtr itv = volumesIterator();
2770 if (elem == itv->next())
2775 //=======================================================================
2776 //function : MaxNodeID
2778 //=======================================================================
2780 int SMDS_Mesh::MaxNodeID() const
2785 //=======================================================================
2786 //function : MinNodeID
2788 //=======================================================================
2790 int SMDS_Mesh::MinNodeID() const
2795 //=======================================================================
2796 //function : MaxElementID
2798 //=======================================================================
2800 int SMDS_Mesh::MaxElementID() const
2802 return myElementIDFactory->GetMaxID();
2805 //=======================================================================
2806 //function : MinElementID
2808 //=======================================================================
2810 int SMDS_Mesh::MinElementID() const
2812 return myElementIDFactory->GetMinID();
2815 //=======================================================================
2816 //function : Renumber
2817 //purpose : Renumber all nodes or elements.
2818 //=======================================================================
2820 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2822 MESSAGE("Renumber");
2826 SMDS_MeshNodeIDFactory * idFactory =
2827 isNodes ? myNodeIDFactory : myElementIDFactory;
2829 // get existing elements in the order of ID increasing
2830 map<int,SMDS_MeshElement*> elemMap;
2831 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2832 while ( idElemIt->more() ) {
2833 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2834 int id = elem->GetID();
2835 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2837 // release their ids
2838 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2840 // for ( ; elemIt != elemMap.end(); elemIt++ )
2842 // int id = (*elemIt).first;
2843 // idFactory->ReleaseID( id );
2847 elemIt = elemMap.begin();
2848 for ( ; elemIt != elemMap.end(); elemIt++ )
2850 idFactory->BindID( ID, (*elemIt).second );
2855 //=======================================================================
2856 //function : GetElementType
2857 //purpose : Return type of element or node with id
2858 //=======================================================================
2860 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2862 SMDS_MeshElement* elem = 0;
2864 elem = myElementIDFactory->MeshElement( id );
2866 elem = myNodeIDFactory->MeshElement( id );
2870 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2874 return elem->GetType();
2879 //********************************************************************
2880 //********************************************************************
2881 //******** *********
2882 //***** Methods for addition of quadratic elements ******
2883 //******** *********
2884 //********************************************************************
2885 //********************************************************************
2887 //=======================================================================
2888 //function : AddEdgeWithID
2890 //=======================================================================
2891 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2893 return SMDS_Mesh::AddEdgeWithID
2894 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2895 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2896 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2900 //=======================================================================
2901 //function : AddEdge
2903 //=======================================================================
2904 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2905 const SMDS_MeshNode* n2,
2906 const SMDS_MeshNode* n12)
2908 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2911 //=======================================================================
2912 //function : AddEdgeWithID
2914 //=======================================================================
2915 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2916 const SMDS_MeshNode * n2,
2917 const SMDS_MeshNode * n12,
2920 if ( !n1 || !n2 || !n12 ) return 0;
2921 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2922 if(myElementIDFactory->BindID(ID, edge)) {
2923 SMDS_MeshNode *node1,*node2, *node12;
2924 //node1 = const_cast<SMDS_MeshNode*>(n1);
2925 //node2 = const_cast<SMDS_MeshNode*>(n2);
2926 //node12 = const_cast<SMDS_MeshNode*>(n12);
2927 //node1->AddInverseElement(edge); // --- fait avec BindID
2928 //node2->AddInverseElement(edge);
2929 //node12->AddInverseElement(edge);
2930 adjustmyCellsCapacity(ID);
2932 myInfo.myNbQuadEdges++;
2942 //=======================================================================
2943 //function : AddFace
2945 //=======================================================================
2946 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2947 const SMDS_MeshNode * n2,
2948 const SMDS_MeshNode * n3,
2949 const SMDS_MeshNode * n12,
2950 const SMDS_MeshNode * n23,
2951 const SMDS_MeshNode * n31)
2953 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2954 myElementIDFactory->GetFreeID());
2957 //=======================================================================
2958 //function : AddFaceWithID
2960 //=======================================================================
2961 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2962 int n12,int n23,int n31, int ID)
2964 return SMDS_Mesh::AddFaceWithID
2965 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2966 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2967 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2968 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2969 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2970 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2974 //=======================================================================
2975 //function : AddFaceWithID
2977 //=======================================================================
2978 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2979 const SMDS_MeshNode * n2,
2980 const SMDS_MeshNode * n3,
2981 const SMDS_MeshNode * n12,
2982 const SMDS_MeshNode * n23,
2983 const SMDS_MeshNode * n31,
2986 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2987 if(hasConstructionEdges()) {
2988 // creation quadratic edges - not implemented
2991 SMDS_QuadraticFaceOfNodes* face =
2992 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2993 adjustmyCellsCapacity(ID);
2995 myInfo.myNbQuadTriangles++;
2997 if (!registerElement(ID, face)) {
2998 RemoveElement(face, false);
3005 //=======================================================================
3006 //function : AddFace
3008 //=======================================================================
3009 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3010 const SMDS_MeshNode * n2,
3011 const SMDS_MeshNode * n3,
3012 const SMDS_MeshNode * n4,
3013 const SMDS_MeshNode * n12,
3014 const SMDS_MeshNode * n23,
3015 const SMDS_MeshNode * n34,
3016 const SMDS_MeshNode * n41)
3018 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3019 myElementIDFactory->GetFreeID());
3022 //=======================================================================
3023 //function : AddFaceWithID
3025 //=======================================================================
3026 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3027 int n12,int n23,int n34,int n41, int ID)
3029 return SMDS_Mesh::AddFaceWithID
3030 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3031 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3032 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3033 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3034 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3035 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3036 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3037 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3041 //=======================================================================
3042 //function : AddFaceWithID
3044 //=======================================================================
3045 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3046 const SMDS_MeshNode * n2,
3047 const SMDS_MeshNode * n3,
3048 const SMDS_MeshNode * n4,
3049 const SMDS_MeshNode * n12,
3050 const SMDS_MeshNode * n23,
3051 const SMDS_MeshNode * n34,
3052 const SMDS_MeshNode * n41,
3055 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3056 if(hasConstructionEdges()) {
3057 // creation quadratic edges - not implemented
3059 SMDS_QuadraticFaceOfNodes* face =
3060 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
3061 adjustmyCellsCapacity(ID);
3063 myInfo.myNbQuadQuadrangles++;
3065 if (!registerElement(ID, face)) {
3066 RemoveElement(face, false);
3073 //=======================================================================
3074 //function : AddVolume
3076 //=======================================================================
3077 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3078 const SMDS_MeshNode * n2,
3079 const SMDS_MeshNode * n3,
3080 const SMDS_MeshNode * n4,
3081 const SMDS_MeshNode * n12,
3082 const SMDS_MeshNode * n23,
3083 const SMDS_MeshNode * n31,
3084 const SMDS_MeshNode * n14,
3085 const SMDS_MeshNode * n24,
3086 const SMDS_MeshNode * n34)
3088 int ID = myElementIDFactory->GetFreeID();
3089 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3090 n31, n14, n24, n34, ID);
3091 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3095 //=======================================================================
3096 //function : AddVolumeWithID
3098 //=======================================================================
3099 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3100 int n12,int n23,int n31,
3101 int n14,int n24,int n34, int ID)
3103 return SMDS_Mesh::AddVolumeWithID
3104 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3105 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3106 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3107 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3108 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3109 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3110 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3111 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3112 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3113 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3117 //=======================================================================
3118 //function : AddVolumeWithID
3119 //purpose : 2d order tetrahedron of 10 nodes
3120 //=======================================================================
3121 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3122 const SMDS_MeshNode * n2,
3123 const SMDS_MeshNode * n3,
3124 const SMDS_MeshNode * n4,
3125 const SMDS_MeshNode * n12,
3126 const SMDS_MeshNode * n23,
3127 const SMDS_MeshNode * n31,
3128 const SMDS_MeshNode * n14,
3129 const SMDS_MeshNode * n24,
3130 const SMDS_MeshNode * n34,
3133 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3135 if(hasConstructionFaces()) {
3136 // creation quadratic faces - not implemented
3139 SMDS_QuadraticVolumeOfNodes * volume =
3140 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3141 adjustmyCellsCapacity(ID);
3142 myCells[ID] = volume;
3143 myInfo.myNbQuadTetras++;
3145 if (!registerElement(ID, volume)) {
3146 RemoveElement(volume, false);
3153 //=======================================================================
3154 //function : AddVolume
3156 //=======================================================================
3157 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3158 const SMDS_MeshNode * n2,
3159 const SMDS_MeshNode * n3,
3160 const SMDS_MeshNode * n4,
3161 const SMDS_MeshNode * n5,
3162 const SMDS_MeshNode * n12,
3163 const SMDS_MeshNode * n23,
3164 const SMDS_MeshNode * n34,
3165 const SMDS_MeshNode * n41,
3166 const SMDS_MeshNode * n15,
3167 const SMDS_MeshNode * n25,
3168 const SMDS_MeshNode * n35,
3169 const SMDS_MeshNode * n45)
3171 int ID = myElementIDFactory->GetFreeID();
3172 SMDS_MeshVolume * v =
3173 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3174 n15, n25, n35, n45, ID);
3175 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3179 //=======================================================================
3180 //function : AddVolumeWithID
3182 //=======================================================================
3183 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3184 int n12,int n23,int n34,int n41,
3185 int n15,int n25,int n35,int n45, int ID)
3187 return SMDS_Mesh::AddVolumeWithID
3188 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3189 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3190 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3191 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3192 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3193 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3194 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3195 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3196 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3197 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3198 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3199 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3200 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3204 //=======================================================================
3205 //function : AddVolumeWithID
3206 //purpose : 2d order pyramid of 13 nodes
3207 //=======================================================================
3208 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3209 const SMDS_MeshNode * n2,
3210 const SMDS_MeshNode * n3,
3211 const SMDS_MeshNode * n4,
3212 const SMDS_MeshNode * n5,
3213 const SMDS_MeshNode * n12,
3214 const SMDS_MeshNode * n23,
3215 const SMDS_MeshNode * n34,
3216 const SMDS_MeshNode * n41,
3217 const SMDS_MeshNode * n15,
3218 const SMDS_MeshNode * n25,
3219 const SMDS_MeshNode * n35,
3220 const SMDS_MeshNode * n45,
3223 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3224 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3226 if(hasConstructionFaces()) {
3227 // creation quadratic faces - not implemented
3230 SMDS_QuadraticVolumeOfNodes * volume =
3231 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3232 n34,n41,n15,n25,n35,n45);
3233 adjustmyCellsCapacity(ID);
3234 myCells[ID] = volume;
3235 myInfo.myNbQuadPyramids++;
3237 if (!registerElement(ID, volume)) {
3238 RemoveElement(volume, false);
3245 //=======================================================================
3246 //function : AddVolume
3248 //=======================================================================
3249 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3250 const SMDS_MeshNode * n2,
3251 const SMDS_MeshNode * n3,
3252 const SMDS_MeshNode * n4,
3253 const SMDS_MeshNode * n5,
3254 const SMDS_MeshNode * n6,
3255 const SMDS_MeshNode * n12,
3256 const SMDS_MeshNode * n23,
3257 const SMDS_MeshNode * n31,
3258 const SMDS_MeshNode * n45,
3259 const SMDS_MeshNode * n56,
3260 const SMDS_MeshNode * n64,
3261 const SMDS_MeshNode * n14,
3262 const SMDS_MeshNode * n25,
3263 const SMDS_MeshNode * n36)
3265 int ID = myElementIDFactory->GetFreeID();
3266 SMDS_MeshVolume * v =
3267 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3268 n45, n56, n64, n14, n25, n36, ID);
3269 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3273 //=======================================================================
3274 //function : AddVolumeWithID
3276 //=======================================================================
3277 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3278 int n4, int n5, int n6,
3279 int n12,int n23,int n31,
3280 int n45,int n56,int n64,
3281 int n14,int n25,int n36, int ID)
3283 return SMDS_Mesh::AddVolumeWithID
3284 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3285 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3286 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3287 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3288 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3289 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3290 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3291 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3292 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3293 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3294 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3295 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3296 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3297 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3298 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3302 //=======================================================================
3303 //function : AddVolumeWithID
3304 //purpose : 2d order Pentahedron with 15 nodes
3305 //=======================================================================
3306 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3307 const SMDS_MeshNode * n2,
3308 const SMDS_MeshNode * n3,
3309 const SMDS_MeshNode * n4,
3310 const SMDS_MeshNode * n5,
3311 const SMDS_MeshNode * n6,
3312 const SMDS_MeshNode * n12,
3313 const SMDS_MeshNode * n23,
3314 const SMDS_MeshNode * n31,
3315 const SMDS_MeshNode * n45,
3316 const SMDS_MeshNode * n56,
3317 const SMDS_MeshNode * n64,
3318 const SMDS_MeshNode * n14,
3319 const SMDS_MeshNode * n25,
3320 const SMDS_MeshNode * n36,
3323 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3324 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3326 if(hasConstructionFaces()) {
3327 // creation quadratic faces - not implemented
3330 SMDS_QuadraticVolumeOfNodes * volume =
3331 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3332 n45,n56,n64,n14,n25,n36);
3333 adjustmyCellsCapacity(ID);
3334 myCells[ID] = volume;
3335 myInfo.myNbQuadPrisms++;
3337 if (!registerElement(ID, volume)) {
3338 RemoveElement(volume, false);
3345 //=======================================================================
3346 //function : AddVolume
3348 //=======================================================================
3349 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3350 const SMDS_MeshNode * n2,
3351 const SMDS_MeshNode * n3,
3352 const SMDS_MeshNode * n4,
3353 const SMDS_MeshNode * n5,
3354 const SMDS_MeshNode * n6,
3355 const SMDS_MeshNode * n7,
3356 const SMDS_MeshNode * n8,
3357 const SMDS_MeshNode * n12,
3358 const SMDS_MeshNode * n23,
3359 const SMDS_MeshNode * n34,
3360 const SMDS_MeshNode * n41,
3361 const SMDS_MeshNode * n56,
3362 const SMDS_MeshNode * n67,
3363 const SMDS_MeshNode * n78,
3364 const SMDS_MeshNode * n85,
3365 const SMDS_MeshNode * n15,
3366 const SMDS_MeshNode * n26,
3367 const SMDS_MeshNode * n37,
3368 const SMDS_MeshNode * n48)
3370 int ID = myElementIDFactory->GetFreeID();
3371 SMDS_MeshVolume * v =
3372 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3373 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3374 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3378 //=======================================================================
3379 //function : AddVolumeWithID
3381 //=======================================================================
3382 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3383 int n5, int n6, int n7, int n8,
3384 int n12,int n23,int n34,int n41,
3385 int n56,int n67,int n78,int n85,
3386 int n15,int n26,int n37,int n48, int ID)
3388 return SMDS_Mesh::AddVolumeWithID
3389 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3390 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3391 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3392 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3393 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3394 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3395 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3396 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3397 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3398 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3399 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3400 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3401 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3402 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3403 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3404 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3405 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3406 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3407 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3408 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3412 //=======================================================================
3413 //function : AddVolumeWithID
3414 //purpose : 2d order Hexahedrons with 20 nodes
3415 //=======================================================================
3416 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3417 const SMDS_MeshNode * n2,
3418 const SMDS_MeshNode * n3,
3419 const SMDS_MeshNode * n4,
3420 const SMDS_MeshNode * n5,
3421 const SMDS_MeshNode * n6,
3422 const SMDS_MeshNode * n7,
3423 const SMDS_MeshNode * n8,
3424 const SMDS_MeshNode * n12,
3425 const SMDS_MeshNode * n23,
3426 const SMDS_MeshNode * n34,
3427 const SMDS_MeshNode * n41,
3428 const SMDS_MeshNode * n56,
3429 const SMDS_MeshNode * n67,
3430 const SMDS_MeshNode * n78,
3431 const SMDS_MeshNode * n85,
3432 const SMDS_MeshNode * n15,
3433 const SMDS_MeshNode * n26,
3434 const SMDS_MeshNode * n37,
3435 const SMDS_MeshNode * n48,
3438 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3439 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3441 if(hasConstructionFaces()) {
3443 // creation quadratic faces - not implemented
3445 SMDS_QuadraticVolumeOfNodes * volume =
3446 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3447 n56,n67,n78,n85,n15,n26,n37,n48);
3448 adjustmyCellsCapacity(ID);
3449 myCells[ID] = volume;
3450 myInfo.myNbQuadHexas++;
3452 if (!registerElement(ID, volume)) {
3453 RemoveElement(volume, false);
3459 void SMDS_Mesh::updateNodeMinMax()
3462 while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3464 myNodeMax=myNodes.size()-1;
3465 while (!myNodes[myNodeMax] && (myNodeMin>=0))
3469 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3471 int val = myIDElements.size();
3472 MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3473 myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3474 val = myNodes.size();
3475 MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3476 myNodes.resize(val +nbNodes, 0);
3479 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3481 int val = myVtkIndex.size();
3482 MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3483 myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3484 val = myCells.size();
3485 MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3486 myNodes.resize(val +nbCells, 0);