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, suppress 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,
1615 size_t nbElemsToReturn,
1616 const SMDS_MeshNode* sm1stNode) const
1618 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
1621 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID,
1622 size_t nbElemsToReturn,
1623 const SMDS_MeshElement* sm1stElem) const
1625 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
1628 ///////////////////////////////////////////////////////////////////////////////
1629 /// Do intersection of sets (more than 2)
1630 ///////////////////////////////////////////////////////////////////////////////
1631 static std::set<const SMDS_MeshElement*> *
1632 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1634 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1635 std::set<const SMDS_MeshElement*>* rsetB;
1637 for(int i=0; i<numberOfSets-1; i++)
1639 rsetB = new std::set<const SMDS_MeshElement*>();
1640 set_intersection(rsetA->begin(), rsetA->end(),
1641 vs[i+1].begin(), vs[i+1].end(),
1642 inserter(*rsetB, rsetB->begin()));
1648 ///////////////////////////////////////////////////////////////////////////////
1649 /// Return the list of finite elements owning the given element: elements
1650 /// containing all the nodes of the given element, for instance faces and
1651 /// volumes containing a given edge.
1652 ///////////////////////////////////////////////////////////////////////////////
1653 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1655 int numberOfSets=element->NbNodes();
1656 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1658 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1661 while ( itNodes->more() )
1663 const SMDS_MeshNode * n = itNodes->next();
1664 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1665 initSet[i].insert( itFe->next() );
1668 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1673 ///////////////////////////////////////////////////////////////////////////////
1674 /// Return the std::list of nodes used only by the given elements
1675 ///////////////////////////////////////////////////////////////////////////////
1677 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1679 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1680 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1682 while( itElements != elements.end() )
1684 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1687 while( itNodes->more() )
1689 const SMDS_MeshNode * n = itNodes->next();
1690 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1691 std::set<const SMDS_MeshElement*> s;
1692 while ( itFe->more() )
1693 s.insert( itFe->next() );
1694 if ( s == elements ) toReturn->insert(n);
1700 ///////////////////////////////////////////////////////////////////////////////
1701 ///Find the children of an element that are made of given nodes
1702 ///@param setOfChildren The set in which matching children will be inserted
1703 ///@param element The element were to search matching children
1704 ///@param nodes The nodes that the children must have to be selected
1705 ///////////////////////////////////////////////////////////////////////////////
1706 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1707 const SMDS_MeshElement * element,
1708 std::set<const SMDS_MeshElement*>& nodes)
1710 switch(element->GetType())
1713 throw SALOME_Exception("Internal Error: This should not happen");
1715 case SMDSAbs_0DElement:
1722 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1725 const SMDS_MeshElement * e=itn->next();
1726 if(nodes.find(e)!=nodes.end())
1728 setOfChildren.insert(element);
1735 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1738 const SMDS_MeshElement * e=itn->next();
1739 if(nodes.find(e)!=nodes.end())
1741 setOfChildren.insert(element);
1746 case SMDSAbs_Volume:
1747 case SMDSAbs_NbElementTypes:
1748 case SMDSAbs_All: break;
1752 ///////////////////////////////////////////////////////////////////////////////
1753 ///@param elem The element to delete
1754 ///@param removenodes if true remaining nodes will be removed
1755 ///////////////////////////////////////////////////////////////////////////////
1756 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1757 const bool removenodes)
1759 std::vector<const SMDS_MeshElement *> removedElems;
1760 std::vector<const SMDS_MeshElement *> removedNodes;
1761 RemoveElement( elem, removedElems, removedNodes, removenodes );
1764 ///////////////////////////////////////////////////////////////////////////////
1765 ///@param elem The element to delete
1766 ///@param removedElems to be filled with all removed elements
1767 ///@param removedNodes to be filled with all removed nodes
1768 ///@param removenodes if true remaining nodes will be removed
1769 ///////////////////////////////////////////////////////////////////////////////
1770 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1771 std::vector<const SMDS_MeshElement *>& removedElems,
1772 std::vector<const SMDS_MeshElement *>& removedNodes,
1775 // get finite elements built on elem
1776 std::set<const SMDS_MeshElement*> * s1;
1777 if ( (elem->GetType() == SMDSAbs_0DElement)
1778 || (elem->GetType() == SMDSAbs_Ball)
1779 || (elem->GetType() == SMDSAbs_Edge)
1780 || (elem->GetType() == SMDSAbs_Face)
1781 || (elem->GetType() == SMDSAbs_Volume) )
1783 s1 = new std::set<const SMDS_MeshElement*> ();
1787 s1 = getFinitElements(elem);
1789 // get exclusive nodes (which would become free afterwards)
1790 std::set<const SMDS_MeshElement*> * s2;
1791 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1793 // do not remove nodes except elem
1794 s2 = new std::set<const SMDS_MeshElement*> ();
1799 s2 = getExclusiveNodes(*s1);
1801 // form the set of finite and construction elements to remove
1802 std::set<const SMDS_MeshElement*> s3;
1803 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1804 while (it != s1->end())
1806 addChildrenWithNodes(s3, *it, *s2);
1810 if (elem->GetType() != SMDSAbs_Node)
1813 // remove finite and construction elements
1814 for( it = s3.begin();it != s3.end(); ++it )
1816 // Remove element from <InverseElements> of its nodes
1817 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1820 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1821 n->RemoveInverseElement((*it));
1824 int vtkid = (*it)->GetVtkID();
1826 switch ((*it)->GetType()) {
1828 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1830 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1831 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1832 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1833 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1834 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1835 case SMDSAbs_All: // avoid compilation warning
1836 case SMDSAbs_NbElementTypes: break;
1838 removedElems.push_back( *it);
1840 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1844 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1848 // remove exclusive (free) nodes
1851 for ( it = s2->begin(); it != s2->end(); ++it )
1854 myNodeFactory->Free( (*it) );
1855 removedNodes.push_back((*it));
1864 ///////////////////////////////////////////////////////////////////////////////
1865 ///@param elem The element to delete
1866 ///////////////////////////////////////////////////////////////////////////////
1867 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1869 const int vtkId = elem->GetVtkID();
1870 SMDSAbs_ElementType aType = elem->GetType();
1871 if ( aType == SMDSAbs_Node )
1873 // only free node can be removed by this method
1874 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1875 if ( n->NbInverseElements() == 0 ) { // free node
1877 myNodeFactory->Free( n );
1881 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1886 // Remove element from <InverseElements> of its nodes
1887 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1888 while (itn->more()) {
1889 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1890 n->RemoveInverseElement(elem);
1893 // in meshes without descendants elements are always free
1895 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1896 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1897 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1898 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1899 case SMDSAbs_Ball: myInfo.remove(elem); break;
1902 myCellFactory->Free( elem );
1904 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1908 //=======================================================================
1910 * Checks if the element is present in mesh.
1912 //=======================================================================
1914 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1916 if ( !elem || elem->IsNull() )
1919 if ( elem->GetType() == SMDSAbs_Node )
1920 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
1922 return ( elem == myCellFactory->FindElement( elem->GetID() ));
1925 //=======================================================================
1926 //function : MaxNodeID
1928 //=======================================================================
1930 int SMDS_Mesh::MaxNodeID() const
1932 return myNodeFactory->GetMaxID();
1935 //=======================================================================
1936 //function : MinNodeID
1938 //=======================================================================
1940 int SMDS_Mesh::MinNodeID() const
1942 return myNodeFactory->GetMinID();
1945 //=======================================================================
1946 //function : MaxElementID
1948 //=======================================================================
1950 int SMDS_Mesh::MaxElementID() const
1952 return myCellFactory->GetMaxID();
1955 //=======================================================================
1956 //function : MinElementID
1958 //=======================================================================
1960 int SMDS_Mesh::MinElementID() const
1962 return myCellFactory->GetMinID();
1965 //=======================================================================
1966 //function : Renumber
1967 //purpose : Renumber all nodes or elements.
1968 //=======================================================================
1970 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
1972 // if ( deltaID == 0 )
1977 //=======================================================================
1978 //function : GetElementType
1979 //purpose : Return type of element or node with id
1980 //=======================================================================
1982 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
1984 const SMDS_MeshElement* elem = 0;
1986 elem = myCellFactory->FindElement( id );
1988 elem = myNodeFactory->FindElement( id );
1990 return elem ? elem->GetType() : SMDSAbs_All;
1995 //********************************************************************
1996 //********************************************************************
1997 //******** *********
1998 //***** Methods for addition of quadratic elements ******
1999 //******** *********
2000 //********************************************************************
2001 //********************************************************************
2003 //=======================================================================
2004 //function : AddEdgeWithID
2006 //=======================================================================
2007 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2009 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2010 myNodeFactory->FindNode(n2),
2011 myNodeFactory->FindNode(n12),
2015 //=======================================================================
2016 //function : AddEdge
2018 //=======================================================================
2019 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2020 const SMDS_MeshNode* n2,
2021 const SMDS_MeshNode* n12)
2023 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2026 //=======================================================================
2027 //function : AddEdgeWithID
2029 //=======================================================================
2030 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2031 const SMDS_MeshNode * n2,
2032 const SMDS_MeshNode * n12,
2035 if ( !n1 || !n2 || !n12 ) return 0;
2037 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2039 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2040 myInfo.myNbQuadEdges++;
2041 return static_cast<SMDS_MeshEdge*>( cell );
2047 //=======================================================================
2048 //function : AddFace
2050 //=======================================================================
2051 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2052 const SMDS_MeshNode * n2,
2053 const SMDS_MeshNode * n3,
2054 const SMDS_MeshNode * n12,
2055 const SMDS_MeshNode * n23,
2056 const SMDS_MeshNode * n31)
2058 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2059 myCellFactory->GetFreeID());
2062 //=======================================================================
2063 //function : AddFaceWithID
2065 //=======================================================================
2066 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2067 int n12,int n23,int n31, int ID)
2069 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2070 myNodeFactory->FindNode(n2) ,
2071 myNodeFactory->FindNode(n3) ,
2072 myNodeFactory->FindNode(n12),
2073 myNodeFactory->FindNode(n23),
2074 myNodeFactory->FindNode(n31),
2078 //=======================================================================
2079 //function : AddFaceWithID
2081 //=======================================================================
2082 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2083 const SMDS_MeshNode * n2,
2084 const SMDS_MeshNode * n3,
2085 const SMDS_MeshNode * n12,
2086 const SMDS_MeshNode * n23,
2087 const SMDS_MeshNode * n31,
2090 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2091 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2093 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2095 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2096 myInfo.myNbQuadTriangles++;
2097 return static_cast<SMDS_MeshFace*>( cell );
2103 //=======================================================================
2104 //function : AddFace
2106 //=======================================================================
2107 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2108 const SMDS_MeshNode * n2,
2109 const SMDS_MeshNode * n3,
2110 const SMDS_MeshNode * n12,
2111 const SMDS_MeshNode * n23,
2112 const SMDS_MeshNode * n31,
2113 const SMDS_MeshNode * nCenter)
2115 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2116 myCellFactory->GetFreeID());
2119 //=======================================================================
2120 //function : AddFaceWithID
2122 //=======================================================================
2123 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2124 int n12,int n23,int n31, int nCenter, int ID)
2126 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2127 myNodeFactory->FindNode(n2) ,
2128 myNodeFactory->FindNode(n3) ,
2129 myNodeFactory->FindNode(n12),
2130 myNodeFactory->FindNode(n23),
2131 myNodeFactory->FindNode(n31),
2132 myNodeFactory->FindNode(nCenter),
2136 //=======================================================================
2137 //function : AddFaceWithID
2139 //=======================================================================
2140 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2141 const SMDS_MeshNode * n2,
2142 const SMDS_MeshNode * n3,
2143 const SMDS_MeshNode * n12,
2144 const SMDS_MeshNode * n23,
2145 const SMDS_MeshNode * n31,
2146 const SMDS_MeshNode * nCenter,
2149 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2150 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2152 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2154 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2155 myInfo.myNbBiQuadTriangles++;
2156 return static_cast<SMDS_MeshFace*>( cell );
2162 //=======================================================================
2163 //function : AddFace
2165 //=======================================================================
2166 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2167 const SMDS_MeshNode * n2,
2168 const SMDS_MeshNode * n3,
2169 const SMDS_MeshNode * n4,
2170 const SMDS_MeshNode * n12,
2171 const SMDS_MeshNode * n23,
2172 const SMDS_MeshNode * n34,
2173 const SMDS_MeshNode * n41)
2175 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2176 myCellFactory->GetFreeID());
2179 //=======================================================================
2180 //function : AddFaceWithID
2182 //=======================================================================
2183 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2184 int n12,int n23,int n34,int n41, int ID)
2186 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2187 myNodeFactory->FindNode(n2) ,
2188 myNodeFactory->FindNode(n3) ,
2189 myNodeFactory->FindNode(n4) ,
2190 myNodeFactory->FindNode(n12),
2191 myNodeFactory->FindNode(n23),
2192 myNodeFactory->FindNode(n34),
2193 myNodeFactory->FindNode(n41),
2197 //=======================================================================
2198 //function : AddFaceWithID
2200 //=======================================================================
2201 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2202 const SMDS_MeshNode * n2,
2203 const SMDS_MeshNode * n3,
2204 const SMDS_MeshNode * n4,
2205 const SMDS_MeshNode * n12,
2206 const SMDS_MeshNode * n23,
2207 const SMDS_MeshNode * n34,
2208 const SMDS_MeshNode * n41,
2211 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2212 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2214 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2216 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2217 myInfo.myNbQuadQuadrangles++;
2218 return static_cast<SMDS_MeshFace*>( cell );
2223 //=======================================================================
2224 //function : AddFace
2226 //=======================================================================
2227 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2228 const SMDS_MeshNode * n2,
2229 const SMDS_MeshNode * n3,
2230 const SMDS_MeshNode * n4,
2231 const SMDS_MeshNode * n12,
2232 const SMDS_MeshNode * n23,
2233 const SMDS_MeshNode * n34,
2234 const SMDS_MeshNode * n41,
2235 const SMDS_MeshNode * nCenter)
2237 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2238 myCellFactory->GetFreeID());
2241 //=======================================================================
2242 //function : AddFaceWithID
2244 //=======================================================================
2245 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2246 int n12,int n23,int n34,int n41, int nCenter, int ID)
2248 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2249 myNodeFactory->FindNode(n2) ,
2250 myNodeFactory->FindNode(n3) ,
2251 myNodeFactory->FindNode(n4) ,
2252 myNodeFactory->FindNode(n12),
2253 myNodeFactory->FindNode(n23),
2254 myNodeFactory->FindNode(n34),
2255 myNodeFactory->FindNode(n41),
2256 myNodeFactory->FindNode(nCenter),
2260 //=======================================================================
2261 //function : AddFaceWithID
2263 //=======================================================================
2264 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2265 const SMDS_MeshNode * n2,
2266 const SMDS_MeshNode * n3,
2267 const SMDS_MeshNode * n4,
2268 const SMDS_MeshNode * n12,
2269 const SMDS_MeshNode * n23,
2270 const SMDS_MeshNode * n34,
2271 const SMDS_MeshNode * n41,
2272 const SMDS_MeshNode * nCenter,
2275 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2276 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2278 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2280 cell->init( SMDSEntity_BiQuad_Quadrangle,
2281 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2282 myInfo.myNbBiQuadQuadrangles++;
2283 return static_cast<SMDS_MeshFace*>( cell );
2289 //=======================================================================
2290 //function : AddVolume
2292 //=======================================================================
2293 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2294 const SMDS_MeshNode * n2,
2295 const SMDS_MeshNode * n3,
2296 const SMDS_MeshNode * n4,
2297 const SMDS_MeshNode * n12,
2298 const SMDS_MeshNode * n23,
2299 const SMDS_MeshNode * n31,
2300 const SMDS_MeshNode * n14,
2301 const SMDS_MeshNode * n24,
2302 const SMDS_MeshNode * n34)
2304 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2305 n31, n14, n24, n34, myCellFactory->GetFreeID());
2308 //=======================================================================
2309 //function : AddVolumeWithID
2311 //=======================================================================
2312 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2313 int n12,int n23,int n31,
2314 int n14,int n24,int n34, int ID)
2316 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2317 myNodeFactory->FindNode(n2) ,
2318 myNodeFactory->FindNode(n3) ,
2319 myNodeFactory->FindNode(n4) ,
2320 myNodeFactory->FindNode(n12),
2321 myNodeFactory->FindNode(n23),
2322 myNodeFactory->FindNode(n31),
2323 myNodeFactory->FindNode(n14),
2324 myNodeFactory->FindNode(n24),
2325 myNodeFactory->FindNode(n34),
2329 //=======================================================================
2330 //function : AddVolumeWithID
2331 //purpose : 2d order tetrahedron of 10 nodes
2332 //=======================================================================
2333 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2334 const SMDS_MeshNode * n2,
2335 const SMDS_MeshNode * n3,
2336 const SMDS_MeshNode * n4,
2337 const SMDS_MeshNode * n12,
2338 const SMDS_MeshNode * n23,
2339 const SMDS_MeshNode * n31,
2340 const SMDS_MeshNode * n14,
2341 const SMDS_MeshNode * n24,
2342 const SMDS_MeshNode * n34,
2345 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2347 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2349 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2351 cell->init( SMDSEntity_Quad_Tetra,
2352 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2353 myInfo.myNbQuadTetras++;
2354 return static_cast<SMDS_MeshVolume*>( cell );
2360 //=======================================================================
2361 //function : AddVolume
2363 //=======================================================================
2364 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2365 const SMDS_MeshNode * n2,
2366 const SMDS_MeshNode * n3,
2367 const SMDS_MeshNode * n4,
2368 const SMDS_MeshNode * n5,
2369 const SMDS_MeshNode * n12,
2370 const SMDS_MeshNode * n23,
2371 const SMDS_MeshNode * n34,
2372 const SMDS_MeshNode * n41,
2373 const SMDS_MeshNode * n15,
2374 const SMDS_MeshNode * n25,
2375 const SMDS_MeshNode * n35,
2376 const SMDS_MeshNode * n45)
2378 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2379 n15, n25, n35, n45, myCellFactory->GetFreeID());
2382 //=======================================================================
2383 //function : AddVolumeWithID
2385 //=======================================================================
2386 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2387 int n12,int n23,int n34,int n41,
2388 int n15,int n25,int n35,int n45, int ID)
2390 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2391 myNodeFactory->FindNode(n2) ,
2392 myNodeFactory->FindNode(n3) ,
2393 myNodeFactory->FindNode(n4) ,
2394 myNodeFactory->FindNode(n5) ,
2395 myNodeFactory->FindNode(n12),
2396 myNodeFactory->FindNode(n23),
2397 myNodeFactory->FindNode(n34),
2398 myNodeFactory->FindNode(n41),
2399 myNodeFactory->FindNode(n15),
2400 myNodeFactory->FindNode(n25),
2401 myNodeFactory->FindNode(n35),
2402 myNodeFactory->FindNode(n45),
2406 //=======================================================================
2407 //function : AddVolumeWithID
2408 //purpose : 2d order pyramid of 13 nodes
2409 //=======================================================================
2410 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2411 const SMDS_MeshNode * n2,
2412 const SMDS_MeshNode * n3,
2413 const SMDS_MeshNode * n4,
2414 const SMDS_MeshNode * n5,
2415 const SMDS_MeshNode * n12,
2416 const SMDS_MeshNode * n23,
2417 const SMDS_MeshNode * n34,
2418 const SMDS_MeshNode * n41,
2419 const SMDS_MeshNode * n15,
2420 const SMDS_MeshNode * n25,
2421 const SMDS_MeshNode * n35,
2422 const SMDS_MeshNode * n45,
2425 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2426 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2428 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2430 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2432 cell->init( SMDSEntity_Quad_Pyramid,
2433 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2434 myInfo.myNbQuadPyramids++;
2435 return static_cast<SMDS_MeshVolume*>( cell );
2441 //=======================================================================
2442 //function : AddVolume
2443 //purpose : 2d order Pentahedron (prism) with 15 nodes
2444 //=======================================================================
2445 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2446 const SMDS_MeshNode * n2,
2447 const SMDS_MeshNode * n3,
2448 const SMDS_MeshNode * n4,
2449 const SMDS_MeshNode * n5,
2450 const SMDS_MeshNode * n6,
2451 const SMDS_MeshNode * n12,
2452 const SMDS_MeshNode * n23,
2453 const SMDS_MeshNode * n31,
2454 const SMDS_MeshNode * n45,
2455 const SMDS_MeshNode * n56,
2456 const SMDS_MeshNode * n64,
2457 const SMDS_MeshNode * n14,
2458 const SMDS_MeshNode * n25,
2459 const SMDS_MeshNode * n36)
2461 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2462 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2465 //=======================================================================
2466 //function : AddVolumeWithID
2467 //purpose : 2d order Pentahedron (prism) with 15 nodes
2468 //=======================================================================
2469 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2470 int n4, int n5, int n6,
2471 int n12,int n23,int n31,
2472 int n45,int n56,int n64,
2473 int n14,int n25,int n36, int ID)
2475 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2476 myNodeFactory->FindNode(n2) ,
2477 myNodeFactory->FindNode(n3) ,
2478 myNodeFactory->FindNode(n4) ,
2479 myNodeFactory->FindNode(n5) ,
2480 myNodeFactory->FindNode(n6) ,
2481 myNodeFactory->FindNode(n12),
2482 myNodeFactory->FindNode(n23),
2483 myNodeFactory->FindNode(n31),
2484 myNodeFactory->FindNode(n45),
2485 myNodeFactory->FindNode(n56),
2486 myNodeFactory->FindNode(n64),
2487 myNodeFactory->FindNode(n14),
2488 myNodeFactory->FindNode(n25),
2489 myNodeFactory->FindNode(n36),
2493 //=======================================================================
2494 //function : AddVolumeWithID
2495 //purpose : 2d order Pentahedron (prism) with 15 nodes
2496 //=======================================================================
2497 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2498 const SMDS_MeshNode * n2,
2499 const SMDS_MeshNode * n3,
2500 const SMDS_MeshNode * n4,
2501 const SMDS_MeshNode * n5,
2502 const SMDS_MeshNode * n6,
2503 const SMDS_MeshNode * n12,
2504 const SMDS_MeshNode * n23,
2505 const SMDS_MeshNode * n31,
2506 const SMDS_MeshNode * n45,
2507 const SMDS_MeshNode * n56,
2508 const SMDS_MeshNode * n64,
2509 const SMDS_MeshNode * n14,
2510 const SMDS_MeshNode * n25,
2511 const SMDS_MeshNode * n36,
2514 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2515 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2517 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2519 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2521 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2522 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2523 myInfo.myNbQuadPrisms++;
2524 return static_cast<SMDS_MeshVolume*>( cell );
2529 //=======================================================================
2530 //function : AddVolume
2531 //purpose : 2d order Pentahedron (prism) with 18 nodes
2532 //=======================================================================
2533 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2534 const SMDS_MeshNode * n2,
2535 const SMDS_MeshNode * n3,
2536 const SMDS_MeshNode * n4,
2537 const SMDS_MeshNode * n5,
2538 const SMDS_MeshNode * n6,
2539 const SMDS_MeshNode * n12,
2540 const SMDS_MeshNode * n23,
2541 const SMDS_MeshNode * n31,
2542 const SMDS_MeshNode * n45,
2543 const SMDS_MeshNode * n56,
2544 const SMDS_MeshNode * n64,
2545 const SMDS_MeshNode * n14,
2546 const SMDS_MeshNode * n25,
2547 const SMDS_MeshNode * n36,
2548 const SMDS_MeshNode * n1245,
2549 const SMDS_MeshNode * n2356,
2550 const SMDS_MeshNode * n1346)
2552 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2553 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2554 myCellFactory->GetFreeID());
2557 //=======================================================================
2558 //function : AddVolumeWithID
2559 //purpose : 2d order Pentahedron (prism) with 18 nodes
2560 //=======================================================================
2561 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2562 int n4, int n5, int n6,
2563 int n12,int n23,int n31,
2564 int n45,int n56,int n64,
2565 int n14,int n25,int n36,
2566 int n1245, int n2356, int n1346, int ID)
2568 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2569 myNodeFactory->FindNode(n2) ,
2570 myNodeFactory->FindNode(n3) ,
2571 myNodeFactory->FindNode(n4) ,
2572 myNodeFactory->FindNode(n5) ,
2573 myNodeFactory->FindNode(n6) ,
2574 myNodeFactory->FindNode(n12),
2575 myNodeFactory->FindNode(n23),
2576 myNodeFactory->FindNode(n31),
2577 myNodeFactory->FindNode(n45),
2578 myNodeFactory->FindNode(n56),
2579 myNodeFactory->FindNode(n64),
2580 myNodeFactory->FindNode(n14),
2581 myNodeFactory->FindNode(n25),
2582 myNodeFactory->FindNode(n36),
2583 myNodeFactory->FindNode(n1245),
2584 myNodeFactory->FindNode(n2356),
2585 myNodeFactory->FindNode(n1346),
2589 //=======================================================================
2590 //function : AddVolumeWithID
2591 //purpose : 2d order Pentahedron (prism) with 18 nodes
2592 //=======================================================================
2593 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2594 const SMDS_MeshNode * n2,
2595 const SMDS_MeshNode * n3,
2596 const SMDS_MeshNode * n4,
2597 const SMDS_MeshNode * n5,
2598 const SMDS_MeshNode * n6,
2599 const SMDS_MeshNode * n12,
2600 const SMDS_MeshNode * n23,
2601 const SMDS_MeshNode * n31,
2602 const SMDS_MeshNode * n45,
2603 const SMDS_MeshNode * n56,
2604 const SMDS_MeshNode * n64,
2605 const SMDS_MeshNode * n14,
2606 const SMDS_MeshNode * n25,
2607 const SMDS_MeshNode * n36,
2608 const SMDS_MeshNode * n1245,
2609 const SMDS_MeshNode * n2356,
2610 const SMDS_MeshNode * n1346,
2613 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2614 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2615 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2617 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2619 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2621 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2622 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2623 myInfo.myNbBiQuadPrisms++;
2624 return static_cast<SMDS_MeshVolume*>( cell );
2630 //=======================================================================
2631 //function : AddVolume
2633 //=======================================================================
2634 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2635 const SMDS_MeshNode * n2,
2636 const SMDS_MeshNode * n3,
2637 const SMDS_MeshNode * n4,
2638 const SMDS_MeshNode * n5,
2639 const SMDS_MeshNode * n6,
2640 const SMDS_MeshNode * n7,
2641 const SMDS_MeshNode * n8,
2642 const SMDS_MeshNode * n12,
2643 const SMDS_MeshNode * n23,
2644 const SMDS_MeshNode * n34,
2645 const SMDS_MeshNode * n41,
2646 const SMDS_MeshNode * n56,
2647 const SMDS_MeshNode * n67,
2648 const SMDS_MeshNode * n78,
2649 const SMDS_MeshNode * n85,
2650 const SMDS_MeshNode * n15,
2651 const SMDS_MeshNode * n26,
2652 const SMDS_MeshNode * n37,
2653 const SMDS_MeshNode * n48)
2655 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2656 n56, n67, n78, n85, n15, n26, n37, n48,
2657 myCellFactory->GetFreeID());
2660 //=======================================================================
2661 //function : AddVolumeWithID
2663 //=======================================================================
2664 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2665 int n5, int n6, int n7, int n8,
2666 int n12,int n23,int n34,int n41,
2667 int n56,int n67,int n78,int n85,
2668 int n15,int n26,int n37,int n48, int ID)
2670 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2671 myNodeFactory->FindNode(n2),
2672 myNodeFactory->FindNode(n3),
2673 myNodeFactory->FindNode(n4),
2674 myNodeFactory->FindNode(n5),
2675 myNodeFactory->FindNode(n6),
2676 myNodeFactory->FindNode(n7),
2677 myNodeFactory->FindNode(n8),
2678 myNodeFactory->FindNode(n12),
2679 myNodeFactory->FindNode(n23),
2680 myNodeFactory->FindNode(n34),
2681 myNodeFactory->FindNode(n41),
2682 myNodeFactory->FindNode(n56),
2683 myNodeFactory->FindNode(n67),
2684 myNodeFactory->FindNode(n78),
2685 myNodeFactory->FindNode(n85),
2686 myNodeFactory->FindNode(n15),
2687 myNodeFactory->FindNode(n26),
2688 myNodeFactory->FindNode(n37),
2689 myNodeFactory->FindNode(n48),
2693 //=======================================================================
2694 //function : AddVolumeWithID
2695 //purpose : 2d order Hexahedrons with 20 nodes
2696 //=======================================================================
2697 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2698 const SMDS_MeshNode * n2,
2699 const SMDS_MeshNode * n3,
2700 const SMDS_MeshNode * n4,
2701 const SMDS_MeshNode * n5,
2702 const SMDS_MeshNode * n6,
2703 const SMDS_MeshNode * n7,
2704 const SMDS_MeshNode * n8,
2705 const SMDS_MeshNode * n12,
2706 const SMDS_MeshNode * n23,
2707 const SMDS_MeshNode * n34,
2708 const SMDS_MeshNode * n41,
2709 const SMDS_MeshNode * n56,
2710 const SMDS_MeshNode * n67,
2711 const SMDS_MeshNode * n78,
2712 const SMDS_MeshNode * n85,
2713 const SMDS_MeshNode * n15,
2714 const SMDS_MeshNode * n26,
2715 const SMDS_MeshNode * n37,
2716 const SMDS_MeshNode * n48,
2719 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2720 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2722 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2724 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2726 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2727 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2728 myInfo.myNbQuadHexas++;
2729 return static_cast<SMDS_MeshVolume*>( cell );
2734 //=======================================================================
2735 //function : AddVolume
2737 //=======================================================================
2738 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2739 const SMDS_MeshNode * n2,
2740 const SMDS_MeshNode * n3,
2741 const SMDS_MeshNode * n4,
2742 const SMDS_MeshNode * n5,
2743 const SMDS_MeshNode * n6,
2744 const SMDS_MeshNode * n7,
2745 const SMDS_MeshNode * n8,
2746 const SMDS_MeshNode * n12,
2747 const SMDS_MeshNode * n23,
2748 const SMDS_MeshNode * n34,
2749 const SMDS_MeshNode * n41,
2750 const SMDS_MeshNode * n56,
2751 const SMDS_MeshNode * n67,
2752 const SMDS_MeshNode * n78,
2753 const SMDS_MeshNode * n85,
2754 const SMDS_MeshNode * n15,
2755 const SMDS_MeshNode * n26,
2756 const SMDS_MeshNode * n37,
2757 const SMDS_MeshNode * n48,
2758 const SMDS_MeshNode * n1234,
2759 const SMDS_MeshNode * n1256,
2760 const SMDS_MeshNode * n2367,
2761 const SMDS_MeshNode * n3478,
2762 const SMDS_MeshNode * n1458,
2763 const SMDS_MeshNode * n5678,
2764 const SMDS_MeshNode * nCenter)
2766 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2767 n56, n67, n78, n85, n15, n26, n37, n48,
2768 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2769 myCellFactory->GetFreeID());
2772 //=======================================================================
2773 //function : AddVolumeWithID
2775 //=======================================================================
2776 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2777 int n5, int n6, int n7, int n8,
2778 int n12,int n23,int n34,int n41,
2779 int n56,int n67,int n78,int n85,
2780 int n15,int n26,int n37,int n48,
2781 int n1234,int n1256,int n2367,int n3478,
2782 int n1458,int n5678,int nCenter, int ID)
2784 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2785 myNodeFactory->FindNode(n2),
2786 myNodeFactory->FindNode(n3),
2787 myNodeFactory->FindNode(n4),
2788 myNodeFactory->FindNode(n5),
2789 myNodeFactory->FindNode(n6),
2790 myNodeFactory->FindNode(n7),
2791 myNodeFactory->FindNode(n8),
2792 myNodeFactory->FindNode(n12),
2793 myNodeFactory->FindNode(n23),
2794 myNodeFactory->FindNode(n34),
2795 myNodeFactory->FindNode(n41),
2796 myNodeFactory->FindNode(n56),
2797 myNodeFactory->FindNode(n67),
2798 myNodeFactory->FindNode(n78),
2799 myNodeFactory->FindNode(n85),
2800 myNodeFactory->FindNode(n15),
2801 myNodeFactory->FindNode(n26),
2802 myNodeFactory->FindNode(n37),
2803 myNodeFactory->FindNode(n48),
2804 myNodeFactory->FindNode(n1234),
2805 myNodeFactory->FindNode(n1256),
2806 myNodeFactory->FindNode(n2367),
2807 myNodeFactory->FindNode(n3478),
2808 myNodeFactory->FindNode(n1458),
2809 myNodeFactory->FindNode(n5678),
2810 myNodeFactory->FindNode(nCenter),
2814 //=======================================================================
2815 //function : AddVolumeWithID
2816 //purpose : 2d order Hexahedrons with 27 nodes
2817 //=======================================================================
2818 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2819 const SMDS_MeshNode * n2,
2820 const SMDS_MeshNode * n3,
2821 const SMDS_MeshNode * n4,
2822 const SMDS_MeshNode * n5,
2823 const SMDS_MeshNode * n6,
2824 const SMDS_MeshNode * n7,
2825 const SMDS_MeshNode * n8,
2826 const SMDS_MeshNode * n12,
2827 const SMDS_MeshNode * n23,
2828 const SMDS_MeshNode * n34,
2829 const SMDS_MeshNode * n41,
2830 const SMDS_MeshNode * n56,
2831 const SMDS_MeshNode * n67,
2832 const SMDS_MeshNode * n78,
2833 const SMDS_MeshNode * n85,
2834 const SMDS_MeshNode * n15,
2835 const SMDS_MeshNode * n26,
2836 const SMDS_MeshNode * n37,
2837 const SMDS_MeshNode * n48,
2838 const SMDS_MeshNode * n1234,
2839 const SMDS_MeshNode * n1256,
2840 const SMDS_MeshNode * n2367,
2841 const SMDS_MeshNode * n3478,
2842 const SMDS_MeshNode * n1458,
2843 const SMDS_MeshNode * n5678,
2844 const SMDS_MeshNode * nCenter,
2847 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2848 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2849 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2851 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2853 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2855 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2856 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2857 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2858 myInfo.myNbTriQuadHexas++;
2859 return static_cast<SMDS_MeshVolume*>( cell );
2864 void SMDS_Mesh::dumpGrid(std::string ficdump)
2866 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2867 // aWriter->SetFileName(ficdump.c_str());
2868 // aWriter->SetInput(myGrid);
2869 // if(myGrid->GetNumberOfCells())
2871 // aWriter->Write();
2873 // aWriter->Delete();
2874 ficdump = ficdump + "_connectivity";
2875 std::ofstream ficcon(ficdump.c_str(), ios::out);
2876 int nbPoints = myGrid->GetNumberOfPoints();
2877 ficcon << "-------------------------------- points " << nbPoints << endl;
2878 for (int i=0; i<nbPoints; i++)
2880 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2882 int nbCells = myGrid->GetNumberOfCells();
2883 ficcon << "-------------------------------- cells " << nbCells << endl;
2884 for (int i=0; i<nbCells; i++)
2886 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2887 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2888 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2889 for (int j=0; j<nbptcell; j++)
2891 ficcon << " " << listid->GetId(j);
2895 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2896 vtkCellLinks *links = myGrid->GetLinks();
2897 for (int i=0; i<nbPoints; i++)
2899 int ncells = links->GetNcells(i);
2900 vtkIdType *cells = links->GetCells(i);
2901 ficcon << i << " - " << ncells << " -";
2902 for (int j=0; j<ncells; j++)
2904 ficcon << " " << cells[j];
2912 void SMDS_Mesh::CompactMesh()
2914 this->myCompactTime = this->myModifTime;
2916 bool idsChange = ( myNodeFactory->CompactChangePointers() ||
2917 myCellFactory->CompactChangePointers() );
2920 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2921 for ( ; holder != myElemHolders.end(); ++holder )
2922 (*holder)->beforeCompacting();
2924 int oldCellSize = myCellFactory->GetMaxID();
2926 // remove "holes" in SMDS numeration
2927 std::vector<int> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
2928 myNodeFactory->Compact( idNodesOldToNew );
2929 myCellFactory->Compact( idCellsNewToOld );
2931 // make VTK IDs correspond to SMDS IDs
2932 int newNodeSize = myNodeFactory->NbUsedElements();
2933 int newCellSize = myCellFactory->NbUsedElements();
2934 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
2936 if ( idsChange && !myElemHolders.empty() )
2938 // idCellsNewToOld -> idCellsOldToNew
2939 idCellsOldToNew.resize( oldCellSize, oldCellSize );
2940 for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
2942 if ( idCellsNewToOld[ iNew ] >= (int) idCellsOldToNew.size() )
2943 idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
2944 idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
2948 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2949 for ( ; holder != myElemHolders.end(); ++holder )
2951 (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
2953 (*holder)->compact();
2958 int SMDS_Mesh::FromVtkToSmds( int vtkid ) const
2960 return myCellFactory->FromVtkToSmds( vtkid );
2963 double SMDS_Mesh::getMaxDim()
2965 double dmax = 1.e-3;
2966 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
2967 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
2968 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
2972 //! modification that needs compact structure and redraw
2973 void SMDS_Mesh::Modified()
2975 if (this->myModified)
2977 this->myModifTime++;
2982 //! get last modification timeStamp
2983 vtkMTimeType SMDS_Mesh::GetMTime() const
2985 return this->myModifTime;
2988 bool SMDS_Mesh::IsCompacted()
2990 return ( this->myCompactTime == this->myModifTime );
2993 void SMDS_Mesh::setNbShapes( size_t nbShapes )
2995 myNodeFactory->SetNbShapes( nbShapes );