1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "SMDS_Mesh.hxx"
31 #include "SMDS_ElementFactory.hxx"
32 #include "SMDS_ElementHolder.hxx"
33 #include "SMDS_SetIterator.hxx"
34 #include "SMDS_SpacePosition.hxx"
35 #include "SMDS_UnstructuredGrid.hxx"
37 #include <utilities.h>
39 #include <vtkUnstructuredGrid.h>
40 //#include <vtkUnstructuredGridWriter.h>
42 #include <vtkUnsignedCharArray.h>
43 #include <vtkCellLinks.h>
44 #include <vtkIdList.h>
50 #include <boost/make_shared.hpp>
52 #if !defined WIN32 && !defined __APPLE__
53 #include <sys/sysinfo.h>
56 // number of added entities to check memory after
57 #define CHECKMEMORY_INTERVAL 100000
59 #define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
61 int SMDS_Mesh::chunkSize = 1024;
63 //================================================================================
65 * \brief Raise an exception if free memory (ram+swap) too low
66 * \param doNotRaise - if true, suppres exception, just return free memory size
67 * \retval int - amount of available memory in MB or negative number in failure case
69 //================================================================================
71 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
74 #if !defined WIN32 && !defined __APPLE__
76 int err = sysinfo( &si );
80 const unsigned long Mbyte = 1024 * 1024;
82 static int limit = -1;
84 if ( si.totalswap == 0 )
86 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
88 limit = WEXITSTATUS(status);
91 double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
92 limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
98 limit = int ( limit * 1.5 );
99 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
102 // compute separately to avoid overflow
104 ( si.freeram * si.mem_unit ) / Mbyte +
105 ( si.freeswap * si.mem_unit ) / Mbyte;
107 if ( freeMb > limit )
108 return freeMb - limit;
113 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
114 throw std::bad_alloc();
120 ///////////////////////////////////////////////////////////////////////////////
121 /// Create a new mesh object
122 ///////////////////////////////////////////////////////////////////////////////
123 SMDS_Mesh::SMDS_Mesh():
124 myNodeFactory( new SMDS_NodeFactory( this )),
125 myCellFactory( new SMDS_ElementFactory( this )),
127 myModified(false), myModifTime(0), myCompactTime(0),
128 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
130 myGrid = SMDS_UnstructuredGrid::New();
131 myGrid->setSMDS_mesh(this);
132 myGrid->Initialize();
134 vtkPoints* points = vtkPoints::New();
135 // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
136 // Use double type for storing coordinates of nodes instead of float.
137 points->SetDataType(VTK_DOUBLE);
138 points->SetNumberOfPoints( 0 );
139 myGrid->SetPoints( points );
143 // initialize static maps in SMDS_MeshCell, to be thread-safe
144 SMDS_MeshCell::InitStaticMembers();
147 ///////////////////////////////////////////////////////////////////////////////
148 /// Create a new child mesh
149 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
150 /// (2003-09-08) of SMESH
151 ///////////////////////////////////////////////////////////////////////////////
152 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
153 myNodeFactory( new SMDS_NodeFactory( this )),
154 myCellFactory( new SMDS_ElementFactory( this )),
159 ///////////////////////////////////////////////////////////////////////////////
160 ///Create a submesh and add it to the current mesh
161 ///////////////////////////////////////////////////////////////////////////////
163 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
165 SMDS_Mesh *submesh = new SMDS_Mesh(this);
166 myChildren.insert(myChildren.end(), submesh);
170 ///////////////////////////////////////////////////////////////////////////////
171 ///create a MeshNode and add it to the current Mesh
172 ///An ID is automatically assigned to the node.
173 ///@return : The created node
174 ///////////////////////////////////////////////////////////////////////////////
176 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
178 return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() );
181 ///////////////////////////////////////////////////////////////////////////////
182 ///create a MeshNode and add it to the current Mesh
183 ///@param ID : The ID of the MeshNode to create
184 ///@return : The created node or NULL if a node with this ID already exists
185 ///////////////////////////////////////////////////////////////////////////////
186 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID )
188 // find the MeshNode corresponding to ID
189 SMDS_MeshNode *node = myNodeFactory->NewNode( ID );
192 node->init( x, y, z );
195 this->adjustBoundingBox(x, y, z);
200 ///////////////////////////////////////////////////////////////////////////////
201 /// create a Mesh0DElement and add it to the current Mesh
202 /// @return : The created Mesh0DElement
203 ///////////////////////////////////////////////////////////////////////////////
204 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
206 const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode);
207 if (!node) return NULL;
208 return SMDS_Mesh::Add0DElementWithID(node, ID);
211 ///////////////////////////////////////////////////////////////////////////////
212 /// create a Mesh0DElement and add it to the current Mesh
213 /// @return : The created Mesh0DElement
214 ///////////////////////////////////////////////////////////////////////////////
215 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
217 return SMDS_Mesh::Add0DElementWithID( node, myCellFactory->GetFreeID() );
220 ///////////////////////////////////////////////////////////////////////////////
221 /// Create a new Mesh0DElement and at it to the mesh
222 /// @param idnode ID of the node
223 /// @param ID ID of the 0D element to create
224 /// @return The created 0D element or NULL if an element with this
225 /// ID already exists or if input node is not found.
226 ///////////////////////////////////////////////////////////////////////////////
227 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
231 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
233 if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID ))
235 cell->init( SMDSEntity_0D, /*nbNodes=*/1, n );
236 myInfo.myNb0DElements++;
237 return static_cast< SMDS_Mesh0DElement*> ( cell );
243 ///////////////////////////////////////////////////////////////////////////////
244 /// create a Ball and add it to the current Mesh
245 /// @return : The created Ball
246 ///////////////////////////////////////////////////////////////////////////////
247 SMDS_BallElement* SMDS_Mesh::AddBallWithID( int idnode, double diameter, int ID )
249 const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode );
250 if (!node) return NULL;
251 return SMDS_Mesh::AddBallWithID( node, diameter, ID );
254 ///////////////////////////////////////////////////////////////////////////////
255 /// create a Ball and add it to the current Mesh
256 /// @return : The created Ball
257 ///////////////////////////////////////////////////////////////////////////////
258 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
260 return SMDS_Mesh::AddBallWithID(node, diameter, myCellFactory->GetFreeID());
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Create a new Ball and at it to the mesh
265 /// @param idnode ID of the node
266 // @param diameter ball diameter
267 /// @param ID ID of the 0D element to create
268 /// @return The created 0D element or NULL if an element with this
269 /// ID already exists or if input node is not found.
270 ///////////////////////////////////////////////////////////////////////////////
271 SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
275 if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
277 SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID ));
280 ball->init( n, diameter );
286 ///////////////////////////////////////////////////////////////////////////////
287 /// create a MeshEdge and add it to the current Mesh
288 /// @return : The created MeshEdge
289 ///////////////////////////////////////////////////////////////////////////////
291 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
293 const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
294 const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
295 if(!node1 || !node2) return NULL;
296 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
299 ///////////////////////////////////////////////////////////////////////////////
300 /// create a MeshEdge and add it to the current Mesh
301 /// @return : The created MeshEdge
302 ///////////////////////////////////////////////////////////////////////////////
304 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
305 const SMDS_MeshNode * node2)
307 return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID());
310 ///////////////////////////////////////////////////////////////////////////////
311 /// Create a new edge and at it to the mesh
312 /// @param idnode1 ID of the first node
313 /// @param idnode2 ID of the second node
314 /// @param ID ID of the edge to create
315 /// @return The created edge or NULL if an element with this ID already exists or
316 /// if input nodes are not found.
317 ///////////////////////////////////////////////////////////////////////////////
319 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
320 const SMDS_MeshNode * n2,
323 if ( !n1 || !n2 ) return 0;
325 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
327 cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 );
329 return static_cast<SMDS_MeshEdge*>( cell );
334 ///////////////////////////////////////////////////////////////////////////////
335 /// Add a triangle defined by its nodes. An ID is automatically affected to the
337 ///////////////////////////////////////////////////////////////////////////////
339 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
340 const SMDS_MeshNode * n2,
341 const SMDS_MeshNode * n3)
343 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID());
346 ///////////////////////////////////////////////////////////////////////////////
347 /// Add a triangle defined by its nodes IDs
348 ///////////////////////////////////////////////////////////////////////////////
350 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
352 const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
353 const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
354 const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3);
355 if(!node1 || !node2 || !node3) return NULL;
356 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
359 ///////////////////////////////////////////////////////////////////////////////
360 /// Add a triangle defined by its nodes
361 ///////////////////////////////////////////////////////////////////////////////
363 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
364 const SMDS_MeshNode * n2,
365 const SMDS_MeshNode * n3,
368 if ( !n1 || !n2 || !n3 ) return 0;
369 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
371 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
373 cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 );
374 myInfo.myNbTriangles++;
375 return static_cast<SMDS_MeshFace*>( cell );
380 ///////////////////////////////////////////////////////////////////////////////
381 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
383 ///////////////////////////////////////////////////////////////////////////////
385 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
386 const SMDS_MeshNode * n2,
387 const SMDS_MeshNode * n3,
388 const SMDS_MeshNode * n4)
390 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID());
393 ///////////////////////////////////////////////////////////////////////////////
394 /// Add a quadrangle defined by its nodes IDs
395 ///////////////////////////////////////////////////////////////////////////////
397 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
403 const SMDS_MeshNode *node1, *node2, *node3, *node4;
404 node1 = myNodeFactory->FindNode(idnode1);
405 node2 = myNodeFactory->FindNode(idnode2);
406 node3 = myNodeFactory->FindNode(idnode3);
407 node4 = myNodeFactory->FindNode(idnode4);
408 if ( !node1 || !node2 || !node3 || !node4 ) return NULL;
409 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
412 ///////////////////////////////////////////////////////////////////////////////
413 /// Add a quadrangle defined by its nodes
414 ///////////////////////////////////////////////////////////////////////////////
416 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
417 const SMDS_MeshNode * n2,
418 const SMDS_MeshNode * n3,
419 const SMDS_MeshNode * n4,
422 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
423 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
425 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
427 cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 );
428 myInfo.myNbQuadrangles++;
429 return static_cast<SMDS_MeshFace*>( cell );
434 ///////////////////////////////////////////////////////////////////////////////
435 ///Create a new tetrahedron and add it to the mesh.
436 ///@return The created tetrahedron
437 ///////////////////////////////////////////////////////////////////////////////
439 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
440 const SMDS_MeshNode * n2,
441 const SMDS_MeshNode * n3,
442 const SMDS_MeshNode * n4)
444 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() );
447 ///////////////////////////////////////////////////////////////////////////////
448 ///Create a new tetrahedron and add it to the mesh.
449 ///@param ID The ID of the new volume
450 ///@return The created tetrahedron or NULL if an element with this ID already exists
451 ///or if input nodes are not found.
452 ///////////////////////////////////////////////////////////////////////////////
454 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
460 const SMDS_MeshNode *node1, *node2, *node3, *node4;
461 node1 = myNodeFactory->FindNode(idnode1);
462 node2 = myNodeFactory->FindNode(idnode2);
463 node3 = myNodeFactory->FindNode(idnode3);
464 node4 = myNodeFactory->FindNode(idnode4);
465 if(!node1 || !node2 || !node3 || !node4) return NULL;
466 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
469 ///////////////////////////////////////////////////////////////////////////////
470 ///Create a new tetrahedron and add it to the mesh.
471 ///@param ID The ID of the new volume
472 ///@return The created tetrahedron
473 ///////////////////////////////////////////////////////////////////////////////
475 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
476 const SMDS_MeshNode * n2,
477 const SMDS_MeshNode * n3,
478 const SMDS_MeshNode * n4,
481 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
482 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
484 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
486 cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 );
488 return static_cast<SMDS_MeshVolume*>( cell );
493 ///////////////////////////////////////////////////////////////////////////////
494 ///Create a new pyramid and add it to the mesh.
495 ///Nodes 1,2,3 and 4 define the base of the pyramid
496 ///@return The created pyramid
497 ///////////////////////////////////////////////////////////////////////////////
499 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
500 const SMDS_MeshNode * n2,
501 const SMDS_MeshNode * n3,
502 const SMDS_MeshNode * n4,
503 const SMDS_MeshNode * n5)
505 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() );
508 ///////////////////////////////////////////////////////////////////////////////
509 ///Create a new pyramid and add it to the mesh.
510 ///Nodes 1,2,3 and 4 define the base of the pyramid
511 ///@param ID The ID of the new volume
512 ///@return The created pyramid or NULL if an element with this ID already exists
513 ///or if input nodes are not found.
514 ///////////////////////////////////////////////////////////////////////////////
516 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
523 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
524 node1 = myNodeFactory->FindNode(idnode1);
525 node2 = myNodeFactory->FindNode(idnode2);
526 node3 = myNodeFactory->FindNode(idnode3);
527 node4 = myNodeFactory->FindNode(idnode4);
528 node5 = myNodeFactory->FindNode(idnode5);
529 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
530 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
533 ///////////////////////////////////////////////////////////////////////////////
534 ///Create a new pyramid and add it to the mesh.
535 ///Nodes 1,2,3 and 4 define the base of the pyramid
536 ///@param ID The ID of the new volume
537 ///@return The created pyramid
538 ///////////////////////////////////////////////////////////////////////////////
540 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
541 const SMDS_MeshNode * n2,
542 const SMDS_MeshNode * n3,
543 const SMDS_MeshNode * n4,
544 const SMDS_MeshNode * n5,
547 if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0;
548 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
550 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
552 cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 );
553 myInfo.myNbPyramids++;
554 return static_cast<SMDS_MeshVolume*>( cell );
559 ///////////////////////////////////////////////////////////////////////////////
560 ///Create a new prism and add it to the mesh.
561 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
562 ///@return The created prism
563 ///////////////////////////////////////////////////////////////////////////////
565 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
566 const SMDS_MeshNode * n2,
567 const SMDS_MeshNode * n3,
568 const SMDS_MeshNode * n4,
569 const SMDS_MeshNode * n5,
570 const SMDS_MeshNode * n6)
572 int ID = myCellFactory->GetFreeID();
573 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
576 ///////////////////////////////////////////////////////////////////////////////
577 ///Create a new prism and add it to the mesh.
578 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
579 ///@param ID The ID of the new volume
580 ///@return The created prism or NULL if an element with this ID already exists
581 ///or if input nodes are not found.
582 ///////////////////////////////////////////////////////////////////////////////
584 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
592 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
593 node1 = myNodeFactory->FindNode(idnode1);
594 node2 = myNodeFactory->FindNode(idnode2);
595 node3 = myNodeFactory->FindNode(idnode3);
596 node4 = myNodeFactory->FindNode(idnode4);
597 node5 = myNodeFactory->FindNode(idnode5);
598 node6 = myNodeFactory->FindNode(idnode6);
599 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
602 ///////////////////////////////////////////////////////////////////////////////
603 ///Create a new prism and add it to the mesh.
604 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
605 ///@param ID The ID of the new volume
606 ///@return The created prism
607 ///////////////////////////////////////////////////////////////////////////////
609 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
610 const SMDS_MeshNode * n2,
611 const SMDS_MeshNode * n3,
612 const SMDS_MeshNode * n4,
613 const SMDS_MeshNode * n5,
614 const SMDS_MeshNode * n6,
617 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0;
618 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
620 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
622 cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 );
624 return static_cast<SMDS_MeshVolume*>( cell );
629 ///////////////////////////////////////////////////////////////////////////////
630 ///Create a new hexagonal prism and add it to the mesh.
631 ///@return The created prism
632 ///////////////////////////////////////////////////////////////////////////////
634 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
635 const SMDS_MeshNode * n2,
636 const SMDS_MeshNode * n3,
637 const SMDS_MeshNode * n4,
638 const SMDS_MeshNode * n5,
639 const SMDS_MeshNode * n6,
640 const SMDS_MeshNode * n7,
641 const SMDS_MeshNode * n8,
642 const SMDS_MeshNode * n9,
643 const SMDS_MeshNode * n10,
644 const SMDS_MeshNode * n11,
645 const SMDS_MeshNode * n12)
647 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
648 n7, n8, n9, n10, n11, n12,
649 myCellFactory->GetFreeID() );
652 ///////////////////////////////////////////////////////////////////////////////
653 ///Create a new hexagonal prism and add it to the mesh.
654 ///@param ID The ID of the new volume
655 ///@return The created prism or NULL if an element with this ID already exists
656 ///or if input nodes are not found.
657 ///////////////////////////////////////////////////////////////////////////////
659 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
673 const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1);
674 const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2);
675 const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3);
676 const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4);
677 const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5);
678 const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6);
679 const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7);
680 const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8);
681 const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9);
682 const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10);
683 const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11);
684 const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12);
685 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
686 node7, node8, node9, node10, node11, node12,
690 ///////////////////////////////////////////////////////////////////////////////
691 ///Create a new hexagonal prism and add it to the mesh.
692 ///@param ID The ID of the new volume
693 ///@return The created prism
694 ///////////////////////////////////////////////////////////////////////////////
696 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
697 const SMDS_MeshNode * n2,
698 const SMDS_MeshNode * n3,
699 const SMDS_MeshNode * n4,
700 const SMDS_MeshNode * n5,
701 const SMDS_MeshNode * n6,
702 const SMDS_MeshNode * n7,
703 const SMDS_MeshNode * n8,
704 const SMDS_MeshNode * n9,
705 const SMDS_MeshNode * n10,
706 const SMDS_MeshNode * n11,
707 const SMDS_MeshNode * n12,
710 SMDS_MeshVolume* volume = 0;
711 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
712 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
714 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
716 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
718 cell->init( SMDSEntity_Hexagonal_Prism,
719 /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 );
720 myInfo.myNbHexPrism++;
721 return static_cast<SMDS_MeshVolume*>( cell );
726 ///////////////////////////////////////////////////////////////////////////////
727 ///Create a new hexahedron and add it to the mesh.
728 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
729 ///@return The created hexahedron
730 ///////////////////////////////////////////////////////////////////////////////
732 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
733 const SMDS_MeshNode * n2,
734 const SMDS_MeshNode * n3,
735 const SMDS_MeshNode * n4,
736 const SMDS_MeshNode * n5,
737 const SMDS_MeshNode * n6,
738 const SMDS_MeshNode * n7,
739 const SMDS_MeshNode * n8)
741 int ID = myCellFactory->GetFreeID();
742 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
745 ///////////////////////////////////////////////////////////////////////////////
746 ///Create a new hexahedron and add it to the mesh.
747 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
748 ///@param ID The ID of the new volume
749 ///@return The created hexahedron or NULL if an element with this ID already
750 ///exists or if input nodes are not found.
751 ///////////////////////////////////////////////////////////////////////////////
753 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
763 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
764 node1 = myNodeFactory->FindNode(idnode1);
765 node2 = myNodeFactory->FindNode(idnode2);
766 node3 = myNodeFactory->FindNode(idnode3);
767 node4 = myNodeFactory->FindNode(idnode4);
768 node5 = myNodeFactory->FindNode(idnode5);
769 node6 = myNodeFactory->FindNode(idnode6);
770 node7 = myNodeFactory->FindNode(idnode7);
771 node8 = myNodeFactory->FindNode(idnode8);
772 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
776 ///////////////////////////////////////////////////////////////////////////////
777 ///Create a new hexahedron and add it to the mesh.
778 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
779 ///@param ID The ID of the new volume
780 ///@return The created prism or NULL if an element with this ID already exists
781 ///or if input nodes are not found.
782 ///////////////////////////////////////////////////////////////////////////////
784 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
785 const SMDS_MeshNode * n2,
786 const SMDS_MeshNode * n3,
787 const SMDS_MeshNode * n4,
788 const SMDS_MeshNode * n5,
789 const SMDS_MeshNode * n6,
790 const SMDS_MeshNode * n7,
791 const SMDS_MeshNode * n8,
794 SMDS_MeshVolume* volume = 0;
795 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
796 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
798 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
800 cell->init( SMDSEntity_Hexa,
801 /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 );
803 return static_cast<SMDS_MeshVolume*>( cell );
808 ///////////////////////////////////////////////////////////////////////////////
809 /// Add a polygon defined by its nodes IDs
810 ///////////////////////////////////////////////////////////////////////////////
812 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<int> & nodes_ids,
815 int nbNodes = nodes_ids.size();
816 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
817 for (int i = 0; i < nbNodes; i++) {
818 nodes[i] = myNodeFactory->FindNode( nodes_ids[i] );
819 if (!nodes[i]) return NULL;
821 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
824 ///////////////////////////////////////////////////////////////////////////////
825 /// Add a polygon defined by its nodes
826 ///////////////////////////////////////////////////////////////////////////////
829 SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
832 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
834 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
836 cell->init( SMDSEntity_Polygon, nodes );
837 myInfo.myNbPolygons++;
838 return static_cast<SMDS_MeshFace*>( cell );
843 ///////////////////////////////////////////////////////////////////////////////
844 /// Add a polygon defined by its nodes.
845 /// An ID is automatically affected to the created face.
846 ///////////////////////////////////////////////////////////////////////////////
848 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
850 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
853 ///////////////////////////////////////////////////////////////////////////////
854 /// Add a quadratic polygon defined by its nodes IDs
855 ///////////////////////////////////////////////////////////////////////////////
857 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int> & nodes_ids,
860 std::vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
861 for ( size_t i = 0; i < nodes.size(); i++) {
862 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
863 if (!nodes[i]) return NULL;
865 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
868 ///////////////////////////////////////////////////////////////////////////////
869 /// Add a quadratic polygon defined by its nodes
870 ///////////////////////////////////////////////////////////////////////////////
873 SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
876 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
877 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
879 cell->init( SMDSEntity_Quad_Polygon, nodes );
880 myInfo.myNbQuadPolygons++;
881 return static_cast<SMDS_MeshFace*>( cell );
886 ///////////////////////////////////////////////////////////////////////////////
887 /// Add a quadratic polygon defined by its nodes.
888 /// An ID is automatically affected to the created face.
889 ///////////////////////////////////////////////////////////////////////////////
891 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
893 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
896 ///////////////////////////////////////////////////////////////////////////////
897 /// Create a new polyhedral volume and add it to the mesh.
898 /// @param ID The ID of the new volume
899 /// @return The created volume or NULL if an element with this ID already exists
900 /// or if input nodes are not found.
901 ///////////////////////////////////////////////////////////////////////////////
903 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int> & nodes_ids,
904 const std::vector<int> & quantities,
907 int nbNodes = nodes_ids.size();
908 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
909 for (int i = 0; i < nbNodes; i++) {
910 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
911 if (!nodes[i]) return NULL;
913 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
916 ///////////////////////////////////////////////////////////////////////////////
917 /// Create a new polyhedral volume and add it to the mesh.
918 /// @param ID The ID of the new volume
919 /// @return The created volume
920 ///////////////////////////////////////////////////////////////////////////////
923 SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<const SMDS_MeshNode*>& nodes,
924 const std::vector<int> & quantities,
927 if ( nodes.empty() || quantities.empty() )
929 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
931 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
933 SMDS_MeshVolume* volume = static_cast<SMDS_MeshVolume*>( cell );
934 volume->init( nodes, quantities );
935 myInfo.myNbPolyhedrons++;
941 ///////////////////////////////////////////////////////////////////////////////
942 /// Create a new polyhedral volume and add it to the mesh.
943 /// @return The created volume
944 ///////////////////////////////////////////////////////////////////////////////
946 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
947 (const std::vector<const SMDS_MeshNode*> & nodes,
948 const std::vector<int> & quantities)
950 int ID = myCellFactory->GetFreeID();
951 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
954 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
956 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
957 SMDS_MeshVolume * vol = static_cast<SMDS_MeshVolume*>( cell );
958 vol->init( vtkNodeIds );
963 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
965 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
966 SMDS_MeshFace * f = static_cast<SMDS_MeshFace*>( cell );
967 f->init( vtkNodeIds );
972 //=======================================================================
973 //function : MoveNode
975 //=======================================================================
977 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
979 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
983 ///////////////////////////////////////////////////////////////////////////////
984 /// Return the node whose SMDS ID is 'ID'.
985 ///////////////////////////////////////////////////////////////////////////////
986 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
988 return myNodeFactory->FindNode( ID );
991 ///////////////////////////////////////////////////////////////////////////////
992 /// Return the node whose VTK ID is 'vtkId'.
993 ///////////////////////////////////////////////////////////////////////////////
994 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
996 return myNodeFactory->FindNode( vtkId + 1 );
999 const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const
1001 return myCellFactory->FindElement( FromVtkToSmds( IDelem ));
1004 ///////////////////////////////////////////////////////////////////////////////
1005 /// Remove a node and all the elements which own this node
1006 ///////////////////////////////////////////////////////////////////////////////
1008 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1010 RemoveElement(node, true);
1013 //=======================================================================
1014 //function : RemoveFromParent
1016 //=======================================================================
1018 bool SMDS_Mesh::RemoveFromParent()
1020 if (myParent==NULL) return false;
1021 else return (myParent->RemoveSubMesh(this));
1024 //=======================================================================
1025 //function : RemoveSubMesh
1027 //=======================================================================
1029 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1033 std::list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1034 for (; itmsh!=myChildren.end() && !found; itmsh++)
1036 SMDS_Mesh * submesh = *itmsh;
1037 if (submesh == aMesh)
1040 myChildren.erase(itmsh);
1047 //=======================================================================
1048 //function : ChangeElementNodes
1050 //=======================================================================
1052 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1053 const SMDS_MeshNode * nodes[],
1056 // keep current nodes of element
1057 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1061 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1062 Ok = cell->ChangeNodes(nodes, nbnodes);
1067 if ( Ok && GetGrid()->HasLinks() ) // update InverseElements
1069 std::set<const SMDS_MeshNode*>::iterator it;
1071 // AddInverseElement to new nodes
1072 for ( int i = 0; i < nbnodes; i++ ) {
1073 it = oldNodes.find( nodes[i] );
1074 if ( it == oldNodes.end() )
1076 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( element );
1078 // remove from oldNodes a node that remains in elem
1079 oldNodes.erase( it );
1081 // RemoveInverseElement from the nodes removed from elem
1082 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1084 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1085 n->RemoveInverseElement( element );
1092 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1094 if (!node) return 0;
1095 const SMDS_Mesh0DElement* toReturn = NULL;
1096 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1097 while (it1->more() && (toReturn == NULL)) {
1098 const SMDS_MeshElement* e = it1->next();
1099 if (e->NbNodes() == 1) {
1100 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1106 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
1108 if (!node) return 0;
1109 const SMDS_BallElement* toReturn = NULL;
1110 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
1111 while (it1->more() && (toReturn == NULL)) {
1112 const SMDS_MeshElement* e = it1->next();
1113 if (e->GetGeomType() == SMDSGeom_BALL)
1114 toReturn = static_cast<const SMDS_BallElement*>(e);
1119 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1120 const SMDS_MeshNode * node2)
1122 if ( !node1 ) return 0;
1123 const SMDS_MeshEdge * toReturn=NULL;
1124 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1125 while(it1->more()) {
1126 const SMDS_MeshElement * e = it1->next();
1127 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1128 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1135 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1136 const SMDS_MeshNode * node2,
1137 const SMDS_MeshNode * node3)
1139 if ( !node1 ) return 0;
1140 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1141 while(it1->more()) {
1142 const SMDS_MeshElement * e = it1->next();
1143 if ( e->NbNodes() == 3 ) {
1144 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1145 while(it2->more()) {
1146 const SMDS_MeshElement* n = it2->next();
1156 return static_cast<const SMDS_MeshEdge *> (e);
1162 //=======================================================================
1163 //function : FindFace
1165 //=======================================================================
1167 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1168 const SMDS_MeshNode *node2,
1169 const SMDS_MeshNode *node3)
1171 if ( !node1 ) return 0;
1172 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1173 while(it1->more()) {
1174 const SMDS_MeshElement * e = it1->next();
1175 if ( e->NbNodes() == 3 ) {
1176 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1177 while(it2->more()) {
1178 const SMDS_MeshElement* n = it2->next();
1188 return static_cast<const SMDS_MeshFace *> (e);
1194 //=======================================================================
1195 //function : FindFace
1197 //=======================================================================
1199 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1200 const SMDS_MeshNode *node2,
1201 const SMDS_MeshNode *node3,
1202 const SMDS_MeshNode *node4)
1204 if ( !node1 ) return 0;
1205 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1206 while(it1->more()) {
1207 const SMDS_MeshElement * e = it1->next();
1208 if ( e->NbNodes() == 4 ) {
1209 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1210 while(it2->more()) {
1211 const SMDS_MeshElement* n = it2->next();
1222 return static_cast<const SMDS_MeshFace *> (e);
1228 //=======================================================================
1229 //function : FindFace
1230 //purpose :quadratic triangle
1231 //=======================================================================
1233 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1234 const SMDS_MeshNode *node2,
1235 const SMDS_MeshNode *node3,
1236 const SMDS_MeshNode *node4,
1237 const SMDS_MeshNode *node5,
1238 const SMDS_MeshNode *node6)
1240 if ( !node1 ) return 0;
1241 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1242 while(it1->more()) {
1243 const SMDS_MeshElement * e = it1->next();
1244 if ( e->NbNodes() == 6 ) {
1245 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1246 while(it2->more()) {
1247 const SMDS_MeshElement* n = it2->next();
1260 return static_cast<const SMDS_MeshFace *> (e);
1267 //=======================================================================
1268 //function : FindFace
1269 //purpose : quadratic quadrangle
1270 //=======================================================================
1272 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1273 const SMDS_MeshNode *node2,
1274 const SMDS_MeshNode *node3,
1275 const SMDS_MeshNode *node4,
1276 const SMDS_MeshNode *node5,
1277 const SMDS_MeshNode *node6,
1278 const SMDS_MeshNode *node7,
1279 const SMDS_MeshNode *node8)
1281 if ( !node1 ) return 0;
1282 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1283 while(it1->more()) {
1284 const SMDS_MeshElement * e = it1->next();
1285 if ( e->NbNodes() == 8 ) {
1286 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1287 while(it2->more()) {
1288 const SMDS_MeshElement* n = it2->next();
1303 return static_cast<const SMDS_MeshFace *> (e);
1310 //=======================================================================
1311 //function : FindElement
1313 //=======================================================================
1315 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1317 return myCellFactory->FindElement( IDelem );
1320 //=======================================================================
1321 //function : FindFace
1322 //purpose : find polygon
1323 //=======================================================================
1326 const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector<const SMDS_MeshNode *>& nodes)
1328 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1332 //================================================================================
1334 * \brief Return element based on all given nodes
1335 * \param nodes - node of element
1336 * \param type - type of element
1337 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1338 * \retval const SMDS_MeshElement* - found element or NULL
1340 //================================================================================
1342 const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector<const SMDS_MeshNode *>& nodes,
1343 const SMDSAbs_ElementType type,
1344 const bool noMedium)
1346 if ( nodes.size() > 0 && nodes[0] )
1348 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1351 const SMDS_MeshElement* e = itF->next();
1352 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1353 if ( nbNodesToCheck == (int)nodes.size() )
1355 for ( size_t i = 1; e && i < nodes.size(); ++i )
1357 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1358 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1369 //================================================================================
1371 * \brief Return elements including all given nodes
1372 * \param [in] nodes - nodes to find elements around
1373 * \param [out] foundElems - the found elements
1374 * \param [in] type - type of elements to find
1375 * \return int - a number of found elements
1377 //================================================================================
1379 int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
1380 std::vector<const SMDS_MeshElement *>& foundElems,
1381 const SMDSAbs_ElementType type)
1383 // chose a node with minimal number of inverse elements
1384 const SMDS_MeshNode* n0 = nodes[0];
1385 int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
1386 for ( size_t i = 1; i < nodes.size(); ++i )
1387 if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
1390 minNbInverse = n0->NbInverseElements( type );
1396 foundElems.reserve( minNbInverse );
1397 SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
1398 while ( eIt->more() )
1400 const SMDS_MeshElement* e = eIt->next();
1401 bool includeAll = true;
1402 for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
1403 if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
1406 foundElems.push_back( e );
1409 return foundElems.size();
1412 ///////////////////////////////////////////////////////////////////////////////
1413 /// Return the number of nodes
1414 ///////////////////////////////////////////////////////////////////////////////
1415 int SMDS_Mesh::NbNodes() const
1417 return myInfo.NbNodes();
1420 ///////////////////////////////////////////////////////////////////////////////
1421 /// Return the number of elements
1422 ///////////////////////////////////////////////////////////////////////////////
1423 int SMDS_Mesh::NbElements() const
1425 return myInfo.NbElements();
1427 ///////////////////////////////////////////////////////////////////////////////
1428 /// Return the number of 0D elements
1429 ///////////////////////////////////////////////////////////////////////////////
1430 int SMDS_Mesh::Nb0DElements() const
1432 return myInfo.Nb0DElements();
1435 ///////////////////////////////////////////////////////////////////////////////
1436 /// Return the number of 0D elements
1437 ///////////////////////////////////////////////////////////////////////////////
1438 int SMDS_Mesh::NbBalls() const
1440 return myInfo.NbBalls();
1443 ///////////////////////////////////////////////////////////////////////////////
1444 /// Return the number of edges (including construction edges)
1445 ///////////////////////////////////////////////////////////////////////////////
1446 int SMDS_Mesh::NbEdges() const
1448 return myInfo.NbEdges();
1451 ///////////////////////////////////////////////////////////////////////////////
1452 /// Return the number of faces (including construction faces)
1453 ///////////////////////////////////////////////////////////////////////////////
1454 int SMDS_Mesh::NbFaces() const
1456 return myInfo.NbFaces();
1459 ///////////////////////////////////////////////////////////////////////////////
1460 /// Return the number of volumes
1461 ///////////////////////////////////////////////////////////////////////////////
1462 int SMDS_Mesh::NbVolumes() const
1464 return myInfo.NbVolumes();
1467 ///////////////////////////////////////////////////////////////////////////////
1468 /// Return the number of child mesh of this mesh.
1469 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
1470 ///////////////////////////////////////////////////////////////////////////////
1471 int SMDS_Mesh::NbSubMesh() const
1473 return myChildren.size();
1476 ///////////////////////////////////////////////////////////////////////////////
1477 /// Destroy the mesh and all its elements
1478 /// All pointer on elements owned by this mesh become illegals.
1479 ///////////////////////////////////////////////////////////////////////////////
1480 SMDS_Mesh::~SMDS_Mesh()
1482 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1483 while(itc!=myChildren.end())
1489 delete myNodeFactory;
1490 delete myCellFactory;
1495 //================================================================================
1497 * \brief Clear all data
1499 //================================================================================
1501 void SMDS_Mesh::Clear()
1503 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
1504 for ( ; holder != myElemHolders.end(); ++holder )
1507 myNodeFactory->Clear();
1508 myCellFactory->Clear();
1510 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1511 while(itc!=myChildren.end())
1522 myGrid->Initialize();
1524 vtkPoints* points = vtkPoints::New();
1525 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
1526 // using double type for storing coordinates of nodes instead float.
1527 points->SetDataType(VTK_DOUBLE);
1528 points->SetNumberOfPoints( 0 );
1529 myGrid->SetPoints( points );
1531 myGrid->DeleteLinks();
1534 ///////////////////////////////////////////////////////////////////////////////
1535 /// Return an iterator on nodes of the current mesh factory
1536 ///////////////////////////////////////////////////////////////////////////////
1538 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1540 return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter );
1543 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
1545 return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
1546 myInfo.NbElements( type ));
1549 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
1551 if ( type == SMDSEntity_Node )
1553 return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
1555 return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
1556 myInfo.NbElements( type ));
1559 ///////////////////////////////////////////////////////////////////////////////
1560 /// Return an iterator on elements of the current mesh factory
1561 ///////////////////////////////////////////////////////////////////////////////
1562 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
1564 typedef SMDS_ElemIterator TIterator;
1568 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1571 return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1574 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
1575 myInfo.NbElements( type ));
1577 return SMDS_ElemIteratorPtr();
1580 ///////////////////////////////////////////////////////////////////////////////
1581 ///Return an iterator on edges of the current mesh.
1582 ///////////////////////////////////////////////////////////////////////////////
1584 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1586 typedef SMDS_EdgeIterator TIterator;
1587 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
1591 ///////////////////////////////////////////////////////////////////////////////
1592 ///Return an iterator on faces of the current mesh.
1593 ///////////////////////////////////////////////////////////////////////////////
1595 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1597 typedef SMDS_FaceIterator TIterator;
1598 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
1602 ///////////////////////////////////////////////////////////////////////////////
1603 ///Return an iterator on volumes of the current mesh.
1604 ///////////////////////////////////////////////////////////////////////////////
1606 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1608 typedef SMDS_VolumeIterator TIterator;
1610 myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
1611 myInfo.NbVolumes());
1614 SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, size_t nbElemsToReturn) const
1616 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn );
1619 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, size_t nbElemsToReturn) const
1621 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn );
1624 ///////////////////////////////////////////////////////////////////////////////
1625 /// Do intersection of sets (more than 2)
1626 ///////////////////////////////////////////////////////////////////////////////
1627 static std::set<const SMDS_MeshElement*> *
1628 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1630 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1631 std::set<const SMDS_MeshElement*>* rsetB;
1633 for(int i=0; i<numberOfSets-1; i++)
1635 rsetB = new std::set<const SMDS_MeshElement*>();
1636 set_intersection(rsetA->begin(), rsetA->end(),
1637 vs[i+1].begin(), vs[i+1].end(),
1638 inserter(*rsetB, rsetB->begin()));
1644 ///////////////////////////////////////////////////////////////////////////////
1645 /// Return the list of finite elements owning the given element: elements
1646 /// containing all the nodes of the given element, for instance faces and
1647 /// volumes containing a given edge.
1648 ///////////////////////////////////////////////////////////////////////////////
1649 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1651 int numberOfSets=element->NbNodes();
1652 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1654 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1657 while ( itNodes->more() )
1659 const SMDS_MeshNode * n = itNodes->next();
1660 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1661 initSet[i].insert( itFe->next() );
1664 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1669 ///////////////////////////////////////////////////////////////////////////////
1670 /// Return the std::list of nodes used only by the given elements
1671 ///////////////////////////////////////////////////////////////////////////////
1673 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1675 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1676 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1678 while( itElements != elements.end() )
1680 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1683 while( itNodes->more() )
1685 const SMDS_MeshNode * n = itNodes->next();
1686 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1687 std::set<const SMDS_MeshElement*> s;
1688 while ( itFe->more() )
1689 s.insert( itFe->next() );
1690 if ( s == elements ) toReturn->insert(n);
1696 ///////////////////////////////////////////////////////////////////////////////
1697 ///Find the children of an element that are made of given nodes
1698 ///@param setOfChildren The set in which matching children will be inserted
1699 ///@param element The element were to search matching children
1700 ///@param nodes The nodes that the children must have to be selected
1701 ///////////////////////////////////////////////////////////////////////////////
1702 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1703 const SMDS_MeshElement * element,
1704 std::set<const SMDS_MeshElement*>& nodes)
1706 switch(element->GetType())
1709 throw SALOME_Exception("Internal Error: This should not happen");
1711 case SMDSAbs_0DElement:
1718 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1721 const SMDS_MeshElement * e=itn->next();
1722 if(nodes.find(e)!=nodes.end())
1724 setOfChildren.insert(element);
1731 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1734 const SMDS_MeshElement * e=itn->next();
1735 if(nodes.find(e)!=nodes.end())
1737 setOfChildren.insert(element);
1742 case SMDSAbs_Volume:
1743 case SMDSAbs_NbElementTypes:
1744 case SMDSAbs_All: break;
1748 ///////////////////////////////////////////////////////////////////////////////
1749 ///@param elem The element to delete
1750 ///@param removenodes if true remaining nodes will be removed
1751 ///////////////////////////////////////////////////////////////////////////////
1752 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1753 const bool removenodes)
1755 std::vector<const SMDS_MeshElement *> removedElems;
1756 std::vector<const SMDS_MeshElement *> removedNodes;
1757 RemoveElement( elem, removedElems, removedNodes, removenodes );
1760 ///////////////////////////////////////////////////////////////////////////////
1761 ///@param elem The element to delete
1762 ///@param removedElems to be filled with all removed elements
1763 ///@param removedNodes to be filled with all removed nodes
1764 ///@param removenodes if true remaining nodes will be removed
1765 ///////////////////////////////////////////////////////////////////////////////
1766 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1767 std::vector<const SMDS_MeshElement *>& removedElems,
1768 std::vector<const SMDS_MeshElement *>& removedNodes,
1771 // get finite elements built on elem
1772 std::set<const SMDS_MeshElement*> * s1;
1773 if ( (elem->GetType() == SMDSAbs_0DElement)
1774 || (elem->GetType() == SMDSAbs_Ball)
1775 || (elem->GetType() == SMDSAbs_Edge)
1776 || (elem->GetType() == SMDSAbs_Face)
1777 || (elem->GetType() == SMDSAbs_Volume) )
1779 s1 = new std::set<const SMDS_MeshElement*> ();
1783 s1 = getFinitElements(elem);
1785 // get exclusive nodes (which would become free afterwards)
1786 std::set<const SMDS_MeshElement*> * s2;
1787 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1789 // do not remove nodes except elem
1790 s2 = new std::set<const SMDS_MeshElement*> ();
1795 s2 = getExclusiveNodes(*s1);
1797 // form the set of finite and construction elements to remove
1798 std::set<const SMDS_MeshElement*> s3;
1799 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1800 while (it != s1->end())
1802 addChildrenWithNodes(s3, *it, *s2);
1806 if (elem->GetType() != SMDSAbs_Node)
1809 // remove finite and construction elements
1810 for( it = s3.begin();it != s3.end(); ++it )
1812 // Remove element from <InverseElements> of its nodes
1813 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1816 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1817 n->RemoveInverseElement((*it));
1820 int vtkid = (*it)->GetVtkID();
1822 switch ((*it)->GetType()) {
1824 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1826 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1827 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1828 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1829 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1830 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1831 case SMDSAbs_All: // avoid compilation warning
1832 case SMDSAbs_NbElementTypes: break;
1835 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1839 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1843 // remove exclusive (free) nodes
1846 for ( it = s2->begin(); it != s2->end(); ++it )
1849 myNodeFactory->Free( (*it) );
1850 removedNodes.push_back((*it));
1859 ///////////////////////////////////////////////////////////////////////////////
1860 ///@param elem The element to delete
1861 ///////////////////////////////////////////////////////////////////////////////
1862 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1864 const int vtkId = elem->GetVtkID();
1865 SMDSAbs_ElementType aType = elem->GetType();
1866 if ( aType == SMDSAbs_Node )
1868 // only free node can be removed by this method
1869 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1870 if ( n->NbInverseElements() == 0 ) { // free node
1872 myNodeFactory->Free( n );
1876 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1881 // Remove element from <InverseElements> of its nodes
1882 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1883 while (itn->more()) {
1884 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1885 n->RemoveInverseElement(elem);
1888 // in meshes without descendants elements are always free
1890 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1891 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1892 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1893 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1894 case SMDSAbs_Ball: myInfo.remove(elem); break;
1897 myCellFactory->Free( elem );
1899 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1903 //=======================================================================
1905 * Checks if the element is present in mesh.
1907 //=======================================================================
1909 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1911 if ( !elem || elem->IsNull() )
1914 if ( elem->GetType() == SMDSAbs_Node )
1915 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
1917 return ( elem == myCellFactory->FindElement( elem->GetID() ));
1920 //=======================================================================
1921 //function : MaxNodeID
1923 //=======================================================================
1925 int SMDS_Mesh::MaxNodeID() const
1927 return myNodeFactory->GetMaxID();
1930 //=======================================================================
1931 //function : MinNodeID
1933 //=======================================================================
1935 int SMDS_Mesh::MinNodeID() const
1937 return myNodeFactory->GetMinID();
1940 //=======================================================================
1941 //function : MaxElementID
1943 //=======================================================================
1945 int SMDS_Mesh::MaxElementID() const
1947 return myCellFactory->GetMaxID();
1950 //=======================================================================
1951 //function : MinElementID
1953 //=======================================================================
1955 int SMDS_Mesh::MinElementID() const
1957 return myCellFactory->GetMinID();
1960 //=======================================================================
1961 //function : Renumber
1962 //purpose : Renumber all nodes or elements.
1963 //=======================================================================
1965 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
1967 // if ( deltaID == 0 )
1972 //=======================================================================
1973 //function : GetElementType
1974 //purpose : Return type of element or node with id
1975 //=======================================================================
1977 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
1979 const SMDS_MeshElement* elem = 0;
1981 elem = myCellFactory->FindElement( id );
1983 elem = myNodeFactory->FindElement( id );
1985 return elem ? elem->GetType() : SMDSAbs_All;
1990 //********************************************************************
1991 //********************************************************************
1992 //******** *********
1993 //***** Methods for addition of quadratic elements ******
1994 //******** *********
1995 //********************************************************************
1996 //********************************************************************
1998 //=======================================================================
1999 //function : AddEdgeWithID
2001 //=======================================================================
2002 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2004 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2005 myNodeFactory->FindNode(n2),
2006 myNodeFactory->FindNode(n12),
2010 //=======================================================================
2011 //function : AddEdge
2013 //=======================================================================
2014 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2015 const SMDS_MeshNode* n2,
2016 const SMDS_MeshNode* n12)
2018 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2021 //=======================================================================
2022 //function : AddEdgeWithID
2024 //=======================================================================
2025 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2026 const SMDS_MeshNode * n2,
2027 const SMDS_MeshNode * n12,
2030 if ( !n1 || !n2 || !n12 ) return 0;
2032 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2034 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2035 myInfo.myNbQuadEdges++;
2036 return static_cast<SMDS_MeshEdge*>( cell );
2042 //=======================================================================
2043 //function : AddFace
2045 //=======================================================================
2046 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2047 const SMDS_MeshNode * n2,
2048 const SMDS_MeshNode * n3,
2049 const SMDS_MeshNode * n12,
2050 const SMDS_MeshNode * n23,
2051 const SMDS_MeshNode * n31)
2053 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2054 myCellFactory->GetFreeID());
2057 //=======================================================================
2058 //function : AddFaceWithID
2060 //=======================================================================
2061 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2062 int n12,int n23,int n31, int ID)
2064 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2065 myNodeFactory->FindNode(n2) ,
2066 myNodeFactory->FindNode(n3) ,
2067 myNodeFactory->FindNode(n12),
2068 myNodeFactory->FindNode(n23),
2069 myNodeFactory->FindNode(n31),
2073 //=======================================================================
2074 //function : AddFaceWithID
2076 //=======================================================================
2077 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2078 const SMDS_MeshNode * n2,
2079 const SMDS_MeshNode * n3,
2080 const SMDS_MeshNode * n12,
2081 const SMDS_MeshNode * n23,
2082 const SMDS_MeshNode * n31,
2085 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2086 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2088 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2090 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2091 myInfo.myNbQuadTriangles++;
2092 return static_cast<SMDS_MeshFace*>( cell );
2098 //=======================================================================
2099 //function : AddFace
2101 //=======================================================================
2102 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2103 const SMDS_MeshNode * n2,
2104 const SMDS_MeshNode * n3,
2105 const SMDS_MeshNode * n12,
2106 const SMDS_MeshNode * n23,
2107 const SMDS_MeshNode * n31,
2108 const SMDS_MeshNode * nCenter)
2110 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2111 myCellFactory->GetFreeID());
2114 //=======================================================================
2115 //function : AddFaceWithID
2117 //=======================================================================
2118 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2119 int n12,int n23,int n31, int nCenter, int ID)
2121 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2122 myNodeFactory->FindNode(n2) ,
2123 myNodeFactory->FindNode(n3) ,
2124 myNodeFactory->FindNode(n12),
2125 myNodeFactory->FindNode(n23),
2126 myNodeFactory->FindNode(n31),
2127 myNodeFactory->FindNode(nCenter),
2131 //=======================================================================
2132 //function : AddFaceWithID
2134 //=======================================================================
2135 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2136 const SMDS_MeshNode * n2,
2137 const SMDS_MeshNode * n3,
2138 const SMDS_MeshNode * n12,
2139 const SMDS_MeshNode * n23,
2140 const SMDS_MeshNode * n31,
2141 const SMDS_MeshNode * nCenter,
2144 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2145 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2147 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2149 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2150 myInfo.myNbBiQuadTriangles++;
2151 return static_cast<SMDS_MeshFace*>( cell );
2157 //=======================================================================
2158 //function : AddFace
2160 //=======================================================================
2161 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2162 const SMDS_MeshNode * n2,
2163 const SMDS_MeshNode * n3,
2164 const SMDS_MeshNode * n4,
2165 const SMDS_MeshNode * n12,
2166 const SMDS_MeshNode * n23,
2167 const SMDS_MeshNode * n34,
2168 const SMDS_MeshNode * n41)
2170 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2171 myCellFactory->GetFreeID());
2174 //=======================================================================
2175 //function : AddFaceWithID
2177 //=======================================================================
2178 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2179 int n12,int n23,int n34,int n41, int ID)
2181 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2182 myNodeFactory->FindNode(n2) ,
2183 myNodeFactory->FindNode(n3) ,
2184 myNodeFactory->FindNode(n4) ,
2185 myNodeFactory->FindNode(n12),
2186 myNodeFactory->FindNode(n23),
2187 myNodeFactory->FindNode(n34),
2188 myNodeFactory->FindNode(n41),
2192 //=======================================================================
2193 //function : AddFaceWithID
2195 //=======================================================================
2196 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2197 const SMDS_MeshNode * n2,
2198 const SMDS_MeshNode * n3,
2199 const SMDS_MeshNode * n4,
2200 const SMDS_MeshNode * n12,
2201 const SMDS_MeshNode * n23,
2202 const SMDS_MeshNode * n34,
2203 const SMDS_MeshNode * n41,
2206 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2207 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2209 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2211 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2212 myInfo.myNbQuadQuadrangles++;
2213 return static_cast<SMDS_MeshFace*>( cell );
2218 //=======================================================================
2219 //function : AddFace
2221 //=======================================================================
2222 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2223 const SMDS_MeshNode * n2,
2224 const SMDS_MeshNode * n3,
2225 const SMDS_MeshNode * n4,
2226 const SMDS_MeshNode * n12,
2227 const SMDS_MeshNode * n23,
2228 const SMDS_MeshNode * n34,
2229 const SMDS_MeshNode * n41,
2230 const SMDS_MeshNode * nCenter)
2232 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2233 myCellFactory->GetFreeID());
2236 //=======================================================================
2237 //function : AddFaceWithID
2239 //=======================================================================
2240 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2241 int n12,int n23,int n34,int n41, int nCenter, int ID)
2243 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2244 myNodeFactory->FindNode(n2) ,
2245 myNodeFactory->FindNode(n3) ,
2246 myNodeFactory->FindNode(n4) ,
2247 myNodeFactory->FindNode(n12),
2248 myNodeFactory->FindNode(n23),
2249 myNodeFactory->FindNode(n34),
2250 myNodeFactory->FindNode(n41),
2251 myNodeFactory->FindNode(nCenter),
2255 //=======================================================================
2256 //function : AddFaceWithID
2258 //=======================================================================
2259 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2260 const SMDS_MeshNode * n2,
2261 const SMDS_MeshNode * n3,
2262 const SMDS_MeshNode * n4,
2263 const SMDS_MeshNode * n12,
2264 const SMDS_MeshNode * n23,
2265 const SMDS_MeshNode * n34,
2266 const SMDS_MeshNode * n41,
2267 const SMDS_MeshNode * nCenter,
2270 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2271 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2273 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2275 cell->init( SMDSEntity_BiQuad_Quadrangle,
2276 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2277 myInfo.myNbBiQuadQuadrangles++;
2278 return static_cast<SMDS_MeshFace*>( cell );
2284 //=======================================================================
2285 //function : AddVolume
2287 //=======================================================================
2288 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2289 const SMDS_MeshNode * n2,
2290 const SMDS_MeshNode * n3,
2291 const SMDS_MeshNode * n4,
2292 const SMDS_MeshNode * n12,
2293 const SMDS_MeshNode * n23,
2294 const SMDS_MeshNode * n31,
2295 const SMDS_MeshNode * n14,
2296 const SMDS_MeshNode * n24,
2297 const SMDS_MeshNode * n34)
2299 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2300 n31, n14, n24, n34, myCellFactory->GetFreeID());
2303 //=======================================================================
2304 //function : AddVolumeWithID
2306 //=======================================================================
2307 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2308 int n12,int n23,int n31,
2309 int n14,int n24,int n34, int ID)
2311 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2312 myNodeFactory->FindNode(n2) ,
2313 myNodeFactory->FindNode(n3) ,
2314 myNodeFactory->FindNode(n4) ,
2315 myNodeFactory->FindNode(n12),
2316 myNodeFactory->FindNode(n23),
2317 myNodeFactory->FindNode(n31),
2318 myNodeFactory->FindNode(n14),
2319 myNodeFactory->FindNode(n24),
2320 myNodeFactory->FindNode(n34),
2324 //=======================================================================
2325 //function : AddVolumeWithID
2326 //purpose : 2d order tetrahedron of 10 nodes
2327 //=======================================================================
2328 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2329 const SMDS_MeshNode * n2,
2330 const SMDS_MeshNode * n3,
2331 const SMDS_MeshNode * n4,
2332 const SMDS_MeshNode * n12,
2333 const SMDS_MeshNode * n23,
2334 const SMDS_MeshNode * n31,
2335 const SMDS_MeshNode * n14,
2336 const SMDS_MeshNode * n24,
2337 const SMDS_MeshNode * n34,
2340 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2342 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2344 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2346 cell->init( SMDSEntity_Quad_Tetra,
2347 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2348 myInfo.myNbQuadTetras++;
2349 return static_cast<SMDS_MeshVolume*>( cell );
2355 //=======================================================================
2356 //function : AddVolume
2358 //=======================================================================
2359 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2360 const SMDS_MeshNode * n2,
2361 const SMDS_MeshNode * n3,
2362 const SMDS_MeshNode * n4,
2363 const SMDS_MeshNode * n5,
2364 const SMDS_MeshNode * n12,
2365 const SMDS_MeshNode * n23,
2366 const SMDS_MeshNode * n34,
2367 const SMDS_MeshNode * n41,
2368 const SMDS_MeshNode * n15,
2369 const SMDS_MeshNode * n25,
2370 const SMDS_MeshNode * n35,
2371 const SMDS_MeshNode * n45)
2373 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2374 n15, n25, n35, n45, myCellFactory->GetFreeID());
2377 //=======================================================================
2378 //function : AddVolumeWithID
2380 //=======================================================================
2381 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2382 int n12,int n23,int n34,int n41,
2383 int n15,int n25,int n35,int n45, int ID)
2385 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2386 myNodeFactory->FindNode(n2) ,
2387 myNodeFactory->FindNode(n3) ,
2388 myNodeFactory->FindNode(n4) ,
2389 myNodeFactory->FindNode(n5) ,
2390 myNodeFactory->FindNode(n12),
2391 myNodeFactory->FindNode(n23),
2392 myNodeFactory->FindNode(n34),
2393 myNodeFactory->FindNode(n41),
2394 myNodeFactory->FindNode(n15),
2395 myNodeFactory->FindNode(n25),
2396 myNodeFactory->FindNode(n35),
2397 myNodeFactory->FindNode(n45),
2401 //=======================================================================
2402 //function : AddVolumeWithID
2403 //purpose : 2d order pyramid of 13 nodes
2404 //=======================================================================
2405 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2406 const SMDS_MeshNode * n2,
2407 const SMDS_MeshNode * n3,
2408 const SMDS_MeshNode * n4,
2409 const SMDS_MeshNode * n5,
2410 const SMDS_MeshNode * n12,
2411 const SMDS_MeshNode * n23,
2412 const SMDS_MeshNode * n34,
2413 const SMDS_MeshNode * n41,
2414 const SMDS_MeshNode * n15,
2415 const SMDS_MeshNode * n25,
2416 const SMDS_MeshNode * n35,
2417 const SMDS_MeshNode * n45,
2420 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2421 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2423 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2425 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2427 cell->init( SMDSEntity_Quad_Pyramid,
2428 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2429 myInfo.myNbQuadPyramids++;
2430 return static_cast<SMDS_MeshVolume*>( cell );
2436 //=======================================================================
2437 //function : AddVolume
2438 //purpose : 2d order Pentahedron (prism) with 15 nodes
2439 //=======================================================================
2440 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2441 const SMDS_MeshNode * n2,
2442 const SMDS_MeshNode * n3,
2443 const SMDS_MeshNode * n4,
2444 const SMDS_MeshNode * n5,
2445 const SMDS_MeshNode * n6,
2446 const SMDS_MeshNode * n12,
2447 const SMDS_MeshNode * n23,
2448 const SMDS_MeshNode * n31,
2449 const SMDS_MeshNode * n45,
2450 const SMDS_MeshNode * n56,
2451 const SMDS_MeshNode * n64,
2452 const SMDS_MeshNode * n14,
2453 const SMDS_MeshNode * n25,
2454 const SMDS_MeshNode * n36)
2456 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2457 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2460 //=======================================================================
2461 //function : AddVolumeWithID
2462 //purpose : 2d order Pentahedron (prism) with 15 nodes
2463 //=======================================================================
2464 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2465 int n4, int n5, int n6,
2466 int n12,int n23,int n31,
2467 int n45,int n56,int n64,
2468 int n14,int n25,int n36, int ID)
2470 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2471 myNodeFactory->FindNode(n2) ,
2472 myNodeFactory->FindNode(n3) ,
2473 myNodeFactory->FindNode(n4) ,
2474 myNodeFactory->FindNode(n5) ,
2475 myNodeFactory->FindNode(n6) ,
2476 myNodeFactory->FindNode(n12),
2477 myNodeFactory->FindNode(n23),
2478 myNodeFactory->FindNode(n31),
2479 myNodeFactory->FindNode(n45),
2480 myNodeFactory->FindNode(n56),
2481 myNodeFactory->FindNode(n64),
2482 myNodeFactory->FindNode(n14),
2483 myNodeFactory->FindNode(n25),
2484 myNodeFactory->FindNode(n36),
2488 //=======================================================================
2489 //function : AddVolumeWithID
2490 //purpose : 2d order Pentahedron (prism) with 15 nodes
2491 //=======================================================================
2492 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2493 const SMDS_MeshNode * n2,
2494 const SMDS_MeshNode * n3,
2495 const SMDS_MeshNode * n4,
2496 const SMDS_MeshNode * n5,
2497 const SMDS_MeshNode * n6,
2498 const SMDS_MeshNode * n12,
2499 const SMDS_MeshNode * n23,
2500 const SMDS_MeshNode * n31,
2501 const SMDS_MeshNode * n45,
2502 const SMDS_MeshNode * n56,
2503 const SMDS_MeshNode * n64,
2504 const SMDS_MeshNode * n14,
2505 const SMDS_MeshNode * n25,
2506 const SMDS_MeshNode * n36,
2509 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2510 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2512 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2514 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2516 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2517 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2518 myInfo.myNbQuadPrisms++;
2519 return static_cast<SMDS_MeshVolume*>( cell );
2524 //=======================================================================
2525 //function : AddVolume
2526 //purpose : 2d order Pentahedron (prism) with 18 nodes
2527 //=======================================================================
2528 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2529 const SMDS_MeshNode * n2,
2530 const SMDS_MeshNode * n3,
2531 const SMDS_MeshNode * n4,
2532 const SMDS_MeshNode * n5,
2533 const SMDS_MeshNode * n6,
2534 const SMDS_MeshNode * n12,
2535 const SMDS_MeshNode * n23,
2536 const SMDS_MeshNode * n31,
2537 const SMDS_MeshNode * n45,
2538 const SMDS_MeshNode * n56,
2539 const SMDS_MeshNode * n64,
2540 const SMDS_MeshNode * n14,
2541 const SMDS_MeshNode * n25,
2542 const SMDS_MeshNode * n36,
2543 const SMDS_MeshNode * n1245,
2544 const SMDS_MeshNode * n2356,
2545 const SMDS_MeshNode * n1346)
2547 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2548 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2549 myCellFactory->GetFreeID());
2552 //=======================================================================
2553 //function : AddVolumeWithID
2554 //purpose : 2d order Pentahedron (prism) with 18 nodes
2555 //=======================================================================
2556 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2557 int n4, int n5, int n6,
2558 int n12,int n23,int n31,
2559 int n45,int n56,int n64,
2560 int n14,int n25,int n36,
2561 int n1245, int n2356, int n1346, int ID)
2563 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2564 myNodeFactory->FindNode(n2) ,
2565 myNodeFactory->FindNode(n3) ,
2566 myNodeFactory->FindNode(n4) ,
2567 myNodeFactory->FindNode(n5) ,
2568 myNodeFactory->FindNode(n6) ,
2569 myNodeFactory->FindNode(n12),
2570 myNodeFactory->FindNode(n23),
2571 myNodeFactory->FindNode(n31),
2572 myNodeFactory->FindNode(n45),
2573 myNodeFactory->FindNode(n56),
2574 myNodeFactory->FindNode(n64),
2575 myNodeFactory->FindNode(n14),
2576 myNodeFactory->FindNode(n25),
2577 myNodeFactory->FindNode(n36),
2578 myNodeFactory->FindNode(n1245),
2579 myNodeFactory->FindNode(n2356),
2580 myNodeFactory->FindNode(n1346),
2584 //=======================================================================
2585 //function : AddVolumeWithID
2586 //purpose : 2d order Pentahedron (prism) with 18 nodes
2587 //=======================================================================
2588 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2589 const SMDS_MeshNode * n2,
2590 const SMDS_MeshNode * n3,
2591 const SMDS_MeshNode * n4,
2592 const SMDS_MeshNode * n5,
2593 const SMDS_MeshNode * n6,
2594 const SMDS_MeshNode * n12,
2595 const SMDS_MeshNode * n23,
2596 const SMDS_MeshNode * n31,
2597 const SMDS_MeshNode * n45,
2598 const SMDS_MeshNode * n56,
2599 const SMDS_MeshNode * n64,
2600 const SMDS_MeshNode * n14,
2601 const SMDS_MeshNode * n25,
2602 const SMDS_MeshNode * n36,
2603 const SMDS_MeshNode * n1245,
2604 const SMDS_MeshNode * n2356,
2605 const SMDS_MeshNode * n1346,
2608 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2609 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2610 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2612 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2614 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2616 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2617 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2618 myInfo.myNbBiQuadPrisms++;
2619 return static_cast<SMDS_MeshVolume*>( cell );
2625 //=======================================================================
2626 //function : AddVolume
2628 //=======================================================================
2629 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2630 const SMDS_MeshNode * n2,
2631 const SMDS_MeshNode * n3,
2632 const SMDS_MeshNode * n4,
2633 const SMDS_MeshNode * n5,
2634 const SMDS_MeshNode * n6,
2635 const SMDS_MeshNode * n7,
2636 const SMDS_MeshNode * n8,
2637 const SMDS_MeshNode * n12,
2638 const SMDS_MeshNode * n23,
2639 const SMDS_MeshNode * n34,
2640 const SMDS_MeshNode * n41,
2641 const SMDS_MeshNode * n56,
2642 const SMDS_MeshNode * n67,
2643 const SMDS_MeshNode * n78,
2644 const SMDS_MeshNode * n85,
2645 const SMDS_MeshNode * n15,
2646 const SMDS_MeshNode * n26,
2647 const SMDS_MeshNode * n37,
2648 const SMDS_MeshNode * n48)
2650 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2651 n56, n67, n78, n85, n15, n26, n37, n48,
2652 myCellFactory->GetFreeID());
2655 //=======================================================================
2656 //function : AddVolumeWithID
2658 //=======================================================================
2659 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2660 int n5, int n6, int n7, int n8,
2661 int n12,int n23,int n34,int n41,
2662 int n56,int n67,int n78,int n85,
2663 int n15,int n26,int n37,int n48, int ID)
2665 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2666 myNodeFactory->FindNode(n2),
2667 myNodeFactory->FindNode(n3),
2668 myNodeFactory->FindNode(n4),
2669 myNodeFactory->FindNode(n5),
2670 myNodeFactory->FindNode(n6),
2671 myNodeFactory->FindNode(n7),
2672 myNodeFactory->FindNode(n8),
2673 myNodeFactory->FindNode(n12),
2674 myNodeFactory->FindNode(n23),
2675 myNodeFactory->FindNode(n34),
2676 myNodeFactory->FindNode(n41),
2677 myNodeFactory->FindNode(n56),
2678 myNodeFactory->FindNode(n67),
2679 myNodeFactory->FindNode(n78),
2680 myNodeFactory->FindNode(n85),
2681 myNodeFactory->FindNode(n15),
2682 myNodeFactory->FindNode(n26),
2683 myNodeFactory->FindNode(n37),
2684 myNodeFactory->FindNode(n48),
2688 //=======================================================================
2689 //function : AddVolumeWithID
2690 //purpose : 2d order Hexahedrons with 20 nodes
2691 //=======================================================================
2692 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2693 const SMDS_MeshNode * n2,
2694 const SMDS_MeshNode * n3,
2695 const SMDS_MeshNode * n4,
2696 const SMDS_MeshNode * n5,
2697 const SMDS_MeshNode * n6,
2698 const SMDS_MeshNode * n7,
2699 const SMDS_MeshNode * n8,
2700 const SMDS_MeshNode * n12,
2701 const SMDS_MeshNode * n23,
2702 const SMDS_MeshNode * n34,
2703 const SMDS_MeshNode * n41,
2704 const SMDS_MeshNode * n56,
2705 const SMDS_MeshNode * n67,
2706 const SMDS_MeshNode * n78,
2707 const SMDS_MeshNode * n85,
2708 const SMDS_MeshNode * n15,
2709 const SMDS_MeshNode * n26,
2710 const SMDS_MeshNode * n37,
2711 const SMDS_MeshNode * n48,
2714 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2715 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2717 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2719 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2721 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2722 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2723 myInfo.myNbQuadHexas++;
2724 return static_cast<SMDS_MeshVolume*>( cell );
2729 //=======================================================================
2730 //function : AddVolume
2732 //=======================================================================
2733 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2734 const SMDS_MeshNode * n2,
2735 const SMDS_MeshNode * n3,
2736 const SMDS_MeshNode * n4,
2737 const SMDS_MeshNode * n5,
2738 const SMDS_MeshNode * n6,
2739 const SMDS_MeshNode * n7,
2740 const SMDS_MeshNode * n8,
2741 const SMDS_MeshNode * n12,
2742 const SMDS_MeshNode * n23,
2743 const SMDS_MeshNode * n34,
2744 const SMDS_MeshNode * n41,
2745 const SMDS_MeshNode * n56,
2746 const SMDS_MeshNode * n67,
2747 const SMDS_MeshNode * n78,
2748 const SMDS_MeshNode * n85,
2749 const SMDS_MeshNode * n15,
2750 const SMDS_MeshNode * n26,
2751 const SMDS_MeshNode * n37,
2752 const SMDS_MeshNode * n48,
2753 const SMDS_MeshNode * n1234,
2754 const SMDS_MeshNode * n1256,
2755 const SMDS_MeshNode * n2367,
2756 const SMDS_MeshNode * n3478,
2757 const SMDS_MeshNode * n1458,
2758 const SMDS_MeshNode * n5678,
2759 const SMDS_MeshNode * nCenter)
2761 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2762 n56, n67, n78, n85, n15, n26, n37, n48,
2763 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2764 myCellFactory->GetFreeID());
2767 //=======================================================================
2768 //function : AddVolumeWithID
2770 //=======================================================================
2771 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2772 int n5, int n6, int n7, int n8,
2773 int n12,int n23,int n34,int n41,
2774 int n56,int n67,int n78,int n85,
2775 int n15,int n26,int n37,int n48,
2776 int n1234,int n1256,int n2367,int n3478,
2777 int n1458,int n5678,int nCenter, int ID)
2779 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2780 myNodeFactory->FindNode(n2),
2781 myNodeFactory->FindNode(n3),
2782 myNodeFactory->FindNode(n4),
2783 myNodeFactory->FindNode(n5),
2784 myNodeFactory->FindNode(n6),
2785 myNodeFactory->FindNode(n7),
2786 myNodeFactory->FindNode(n8),
2787 myNodeFactory->FindNode(n12),
2788 myNodeFactory->FindNode(n23),
2789 myNodeFactory->FindNode(n34),
2790 myNodeFactory->FindNode(n41),
2791 myNodeFactory->FindNode(n56),
2792 myNodeFactory->FindNode(n67),
2793 myNodeFactory->FindNode(n78),
2794 myNodeFactory->FindNode(n85),
2795 myNodeFactory->FindNode(n15),
2796 myNodeFactory->FindNode(n26),
2797 myNodeFactory->FindNode(n37),
2798 myNodeFactory->FindNode(n48),
2799 myNodeFactory->FindNode(n1234),
2800 myNodeFactory->FindNode(n1256),
2801 myNodeFactory->FindNode(n2367),
2802 myNodeFactory->FindNode(n3478),
2803 myNodeFactory->FindNode(n1458),
2804 myNodeFactory->FindNode(n5678),
2805 myNodeFactory->FindNode(nCenter),
2809 //=======================================================================
2810 //function : AddVolumeWithID
2811 //purpose : 2d order Hexahedrons with 27 nodes
2812 //=======================================================================
2813 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2814 const SMDS_MeshNode * n2,
2815 const SMDS_MeshNode * n3,
2816 const SMDS_MeshNode * n4,
2817 const SMDS_MeshNode * n5,
2818 const SMDS_MeshNode * n6,
2819 const SMDS_MeshNode * n7,
2820 const SMDS_MeshNode * n8,
2821 const SMDS_MeshNode * n12,
2822 const SMDS_MeshNode * n23,
2823 const SMDS_MeshNode * n34,
2824 const SMDS_MeshNode * n41,
2825 const SMDS_MeshNode * n56,
2826 const SMDS_MeshNode * n67,
2827 const SMDS_MeshNode * n78,
2828 const SMDS_MeshNode * n85,
2829 const SMDS_MeshNode * n15,
2830 const SMDS_MeshNode * n26,
2831 const SMDS_MeshNode * n37,
2832 const SMDS_MeshNode * n48,
2833 const SMDS_MeshNode * n1234,
2834 const SMDS_MeshNode * n1256,
2835 const SMDS_MeshNode * n2367,
2836 const SMDS_MeshNode * n3478,
2837 const SMDS_MeshNode * n1458,
2838 const SMDS_MeshNode * n5678,
2839 const SMDS_MeshNode * nCenter,
2842 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2843 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2844 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2846 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2848 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2850 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2851 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2852 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2853 myInfo.myNbTriQuadHexas++;
2854 return static_cast<SMDS_MeshVolume*>( cell );
2859 void SMDS_Mesh::dumpGrid(std::string ficdump)
2861 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2862 // aWriter->SetFileName(ficdump.c_str());
2863 // aWriter->SetInput(myGrid);
2864 // if(myGrid->GetNumberOfCells())
2866 // aWriter->Write();
2868 // aWriter->Delete();
2869 ficdump = ficdump + "_connectivity";
2870 std::ofstream ficcon(ficdump.c_str(), ios::out);
2871 int nbPoints = myGrid->GetNumberOfPoints();
2872 ficcon << "-------------------------------- points " << nbPoints << endl;
2873 for (int i=0; i<nbPoints; i++)
2875 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2877 int nbCells = myGrid->GetNumberOfCells();
2878 ficcon << "-------------------------------- cells " << nbCells << endl;
2879 for (int i=0; i<nbCells; i++)
2881 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2882 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2883 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2884 for (int j=0; j<nbptcell; j++)
2886 ficcon << " " << listid->GetId(j);
2890 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2891 vtkCellLinks *links = myGrid->GetLinks();
2892 for (int i=0; i<nbPoints; i++)
2894 int ncells = links->GetNcells(i);
2895 vtkIdType *cells = links->GetCells(i);
2896 ficcon << i << " - " << ncells << " -";
2897 for (int j=0; j<ncells; j++)
2899 ficcon << " " << cells[j];
2907 void SMDS_Mesh::CompactMesh()
2909 this->myCompactTime = this->myModifTime;
2911 bool idsChange = ( myNodeFactory->CompactChangePointers() ||
2912 myCellFactory->CompactChangePointers() );
2915 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2916 for ( ; holder != myElemHolders.end(); ++holder )
2917 (*holder)->beforeCompacting();
2920 // remove "holes" in SMDS numeration
2921 std::vector<int> idNodesOldToNew, idCellsNewToOld;
2922 myNodeFactory->Compact( idNodesOldToNew );
2923 myCellFactory->Compact( idCellsNewToOld );
2925 // make VTK IDs correspond to SMDS IDs
2926 int newNodeSize = myNodeFactory->NbUsedElements();
2927 int newCellSize = myCellFactory->NbUsedElements();
2928 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
2930 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2931 for ( ; holder != myElemHolders.end(); ++holder )
2933 (*holder)->restoreElements( idNodesOldToNew, idCellsNewToOld );
2935 (*holder)->compact();
2940 int SMDS_Mesh::FromVtkToSmds( int vtkid ) const
2942 return myCellFactory->FromVtkToSmds( vtkid );
2945 double SMDS_Mesh::getMaxDim()
2947 double dmax = 1.e-3;
2948 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
2949 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
2950 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
2954 //! modification that needs compact structure and redraw
2955 void SMDS_Mesh::Modified()
2957 if (this->myModified)
2959 this->myModifTime++;
2964 //! get last modification timeStamp
2965 vtkMTimeType SMDS_Mesh::GetMTime() const
2967 return this->myModifTime;
2970 bool SMDS_Mesh::IsCompacted()
2972 return ( this->myCompactTime == this->myModifTime );
2975 void SMDS_Mesh::setNbShapes( size_t nbShapes )
2977 myNodeFactory->SetNbShapes( nbShapes );