1 // Copyright (C) 2007-2019 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 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1546 return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
1550 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
1552 if ( type == SMDSEntity_Node )
1554 return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
1556 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1557 return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
1561 ///////////////////////////////////////////////////////////////////////////////
1562 /// Return an iterator on elements of the current mesh factory
1563 ///////////////////////////////////////////////////////////////////////////////
1564 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
1566 typedef SMDS_ElemIterator TIterator;
1570 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1573 return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1576 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1577 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
1580 return SMDS_ElemIteratorPtr();
1583 ///////////////////////////////////////////////////////////////////////////////
1584 ///Return an iterator on edges of the current mesh.
1585 ///////////////////////////////////////////////////////////////////////////////
1587 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1589 typedef SMDS_EdgeIterator TIterator;
1590 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges();
1591 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
1595 ///////////////////////////////////////////////////////////////////////////////
1596 ///Return an iterator on faces of the current mesh.
1597 ///////////////////////////////////////////////////////////////////////////////
1599 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1601 typedef SMDS_FaceIterator TIterator;
1602 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces();
1603 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
1607 ///////////////////////////////////////////////////////////////////////////////
1608 ///Return an iterator on volumes of the current mesh.
1609 ///////////////////////////////////////////////////////////////////////////////
1611 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1613 typedef SMDS_VolumeIterator TIterator;
1614 int nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes();
1616 myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
1620 SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID,
1621 size_t nbElemsToReturn,
1622 const SMDS_MeshNode* sm1stNode) const
1624 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
1627 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID,
1628 size_t nbElemsToReturn,
1629 const SMDS_MeshElement* sm1stElem) const
1631 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
1634 ///////////////////////////////////////////////////////////////////////////////
1635 /// Do intersection of sets (more than 2)
1636 ///////////////////////////////////////////////////////////////////////////////
1637 static std::set<const SMDS_MeshElement*> *
1638 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1640 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1641 std::set<const SMDS_MeshElement*>* rsetB;
1643 for(int i=0; i<numberOfSets-1; i++)
1645 rsetB = new std::set<const SMDS_MeshElement*>();
1646 set_intersection(rsetA->begin(), rsetA->end(),
1647 vs[i+1].begin(), vs[i+1].end(),
1648 inserter(*rsetB, rsetB->begin()));
1654 ///////////////////////////////////////////////////////////////////////////////
1655 /// Return the list of finite elements owning the given element: elements
1656 /// containing all the nodes of the given element, for instance faces and
1657 /// volumes containing a given edge.
1658 ///////////////////////////////////////////////////////////////////////////////
1659 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1661 int numberOfSets=element->NbNodes();
1662 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1664 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1667 while ( itNodes->more() )
1669 const SMDS_MeshNode * n = itNodes->next();
1670 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1671 initSet[i].insert( itFe->next() );
1674 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1679 ///////////////////////////////////////////////////////////////////////////////
1680 /// Return the std::list of nodes used only by the given elements
1681 ///////////////////////////////////////////////////////////////////////////////
1683 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1685 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1686 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1688 while( itElements != elements.end() )
1690 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1693 while( itNodes->more() )
1695 const SMDS_MeshNode * n = itNodes->next();
1696 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1697 std::set<const SMDS_MeshElement*> s;
1698 while ( itFe->more() )
1699 s.insert( itFe->next() );
1700 if ( s == elements ) toReturn->insert(n);
1706 ///////////////////////////////////////////////////////////////////////////////
1707 ///Find the children of an element that are made of given nodes
1708 ///@param setOfChildren The set in which matching children will be inserted
1709 ///@param element The element were to search matching children
1710 ///@param nodes The nodes that the children must have to be selected
1711 ///////////////////////////////////////////////////////////////////////////////
1712 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1713 const SMDS_MeshElement * element,
1714 std::set<const SMDS_MeshElement*>& nodes)
1716 switch(element->GetType())
1719 throw SALOME_Exception("Internal Error: This should not happen");
1721 case SMDSAbs_0DElement:
1728 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1731 const SMDS_MeshElement * e=itn->next();
1732 if(nodes.find(e)!=nodes.end())
1734 setOfChildren.insert(element);
1741 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1744 const SMDS_MeshElement * e=itn->next();
1745 if(nodes.find(e)!=nodes.end())
1747 setOfChildren.insert(element);
1752 case SMDSAbs_Volume:
1753 case SMDSAbs_NbElementTypes:
1754 case SMDSAbs_All: break;
1758 ///////////////////////////////////////////////////////////////////////////////
1759 ///@param elem The element to delete
1760 ///@param removenodes if true remaining nodes will be removed
1761 ///////////////////////////////////////////////////////////////////////////////
1762 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1763 const bool removenodes)
1765 std::vector<const SMDS_MeshElement *> removedElems;
1766 std::vector<const SMDS_MeshElement *> removedNodes;
1767 RemoveElement( elem, removedElems, removedNodes, removenodes );
1770 ///////////////////////////////////////////////////////////////////////////////
1771 ///@param elem The element to delete
1772 ///@param removedElems to be filled with all removed elements
1773 ///@param removedNodes to be filled with all removed nodes
1774 ///@param removenodes if true remaining nodes will be removed
1775 ///////////////////////////////////////////////////////////////////////////////
1776 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1777 std::vector<const SMDS_MeshElement *>& removedElems,
1778 std::vector<const SMDS_MeshElement *>& removedNodes,
1781 // get finite elements built on elem
1782 std::set<const SMDS_MeshElement*> * s1;
1783 if ( (elem->GetType() == SMDSAbs_0DElement)
1784 || (elem->GetType() == SMDSAbs_Ball)
1785 || (elem->GetType() == SMDSAbs_Edge)
1786 || (elem->GetType() == SMDSAbs_Face)
1787 || (elem->GetType() == SMDSAbs_Volume) )
1789 s1 = new std::set<const SMDS_MeshElement*> ();
1793 s1 = getFinitElements(elem);
1795 // get exclusive nodes (which would become free afterwards)
1796 std::set<const SMDS_MeshElement*> * s2;
1797 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1799 // do not remove nodes except elem
1800 s2 = new std::set<const SMDS_MeshElement*> ();
1805 s2 = getExclusiveNodes(*s1);
1807 // form the set of finite and construction elements to remove
1808 std::set<const SMDS_MeshElement*> s3;
1809 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1810 while (it != s1->end())
1812 addChildrenWithNodes(s3, *it, *s2);
1816 if (elem->GetType() != SMDSAbs_Node)
1819 // remove finite and construction elements
1820 for( it = s3.begin();it != s3.end(); ++it )
1822 // Remove element from <InverseElements> of its nodes
1823 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1826 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1827 n->RemoveInverseElement((*it));
1830 int vtkid = (*it)->GetVtkID();
1832 switch ((*it)->GetType()) {
1834 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1836 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1837 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1838 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1839 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1840 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1841 case SMDSAbs_All: // avoid compilation warning
1842 case SMDSAbs_NbElementTypes: break;
1844 removedElems.push_back( *it);
1846 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1850 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1854 // remove exclusive (free) nodes
1857 for ( it = s2->begin(); it != s2->end(); ++it )
1860 myNodeFactory->Free( (*it) );
1861 removedNodes.push_back((*it));
1870 ///////////////////////////////////////////////////////////////////////////////
1871 ///@param elem The element to delete
1872 ///////////////////////////////////////////////////////////////////////////////
1873 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1875 const int vtkId = elem->GetVtkID();
1876 SMDSAbs_ElementType aType = elem->GetType();
1877 if ( aType == SMDSAbs_Node )
1879 // only free node can be removed by this method
1880 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1881 if ( n->NbInverseElements() == 0 ) { // free node
1883 myNodeFactory->Free( n );
1887 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1892 // Remove element from <InverseElements> of its nodes
1893 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1894 while (itn->more()) {
1895 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1896 n->RemoveInverseElement(elem);
1899 // in meshes without descendants elements are always free
1901 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1902 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1903 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1904 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1905 case SMDSAbs_Ball: myInfo.remove(elem); break;
1908 myCellFactory->Free( elem );
1910 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1914 //=======================================================================
1916 * Checks if the element is present in mesh.
1918 //=======================================================================
1920 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1922 if ( !elem || elem->IsNull() )
1925 if ( elem->GetType() == SMDSAbs_Node )
1926 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
1928 return ( elem == myCellFactory->FindElement( elem->GetID() ));
1931 //=======================================================================
1932 //function : MaxNodeID
1934 //=======================================================================
1936 int SMDS_Mesh::MaxNodeID() const
1938 return myNodeFactory->GetMaxID();
1941 //=======================================================================
1942 //function : MinNodeID
1944 //=======================================================================
1946 int SMDS_Mesh::MinNodeID() const
1948 return myNodeFactory->GetMinID();
1951 //=======================================================================
1952 //function : MaxElementID
1954 //=======================================================================
1956 int SMDS_Mesh::MaxElementID() const
1958 return myCellFactory->GetMaxID();
1961 //=======================================================================
1962 //function : MinElementID
1964 //=======================================================================
1966 int SMDS_Mesh::MinElementID() const
1968 return myCellFactory->GetMinID();
1971 //=======================================================================
1972 //function : Renumber
1973 //purpose : Renumber all nodes or elements.
1974 //=======================================================================
1976 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
1978 // if ( deltaID == 0 )
1983 //=======================================================================
1984 //function : GetElementType
1985 //purpose : Return type of element or node with id
1986 //=======================================================================
1988 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
1990 const SMDS_MeshElement* elem = 0;
1992 elem = myCellFactory->FindElement( id );
1994 elem = myNodeFactory->FindElement( id );
1996 return elem ? elem->GetType() : SMDSAbs_All;
2001 //********************************************************************
2002 //********************************************************************
2003 //******** *********
2004 //***** Methods for addition of quadratic elements ******
2005 //******** *********
2006 //********************************************************************
2007 //********************************************************************
2009 //=======================================================================
2010 //function : AddEdgeWithID
2012 //=======================================================================
2013 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2015 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2016 myNodeFactory->FindNode(n2),
2017 myNodeFactory->FindNode(n12),
2021 //=======================================================================
2022 //function : AddEdge
2024 //=======================================================================
2025 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2026 const SMDS_MeshNode* n2,
2027 const SMDS_MeshNode* n12)
2029 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2032 //=======================================================================
2033 //function : AddEdgeWithID
2035 //=======================================================================
2036 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2037 const SMDS_MeshNode * n2,
2038 const SMDS_MeshNode * n12,
2041 if ( !n1 || !n2 || !n12 ) return 0;
2043 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2045 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2046 myInfo.myNbQuadEdges++;
2047 return static_cast<SMDS_MeshEdge*>( cell );
2053 //=======================================================================
2054 //function : AddFace
2056 //=======================================================================
2057 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2058 const SMDS_MeshNode * n2,
2059 const SMDS_MeshNode * n3,
2060 const SMDS_MeshNode * n12,
2061 const SMDS_MeshNode * n23,
2062 const SMDS_MeshNode * n31)
2064 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2065 myCellFactory->GetFreeID());
2068 //=======================================================================
2069 //function : AddFaceWithID
2071 //=======================================================================
2072 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2073 int n12,int n23,int n31, int ID)
2075 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2076 myNodeFactory->FindNode(n2) ,
2077 myNodeFactory->FindNode(n3) ,
2078 myNodeFactory->FindNode(n12),
2079 myNodeFactory->FindNode(n23),
2080 myNodeFactory->FindNode(n31),
2084 //=======================================================================
2085 //function : AddFaceWithID
2087 //=======================================================================
2088 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2089 const SMDS_MeshNode * n2,
2090 const SMDS_MeshNode * n3,
2091 const SMDS_MeshNode * n12,
2092 const SMDS_MeshNode * n23,
2093 const SMDS_MeshNode * n31,
2096 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2097 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2099 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2101 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2102 myInfo.myNbQuadTriangles++;
2103 return static_cast<SMDS_MeshFace*>( cell );
2109 //=======================================================================
2110 //function : AddFace
2112 //=======================================================================
2113 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2114 const SMDS_MeshNode * n2,
2115 const SMDS_MeshNode * n3,
2116 const SMDS_MeshNode * n12,
2117 const SMDS_MeshNode * n23,
2118 const SMDS_MeshNode * n31,
2119 const SMDS_MeshNode * nCenter)
2121 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2122 myCellFactory->GetFreeID());
2125 //=======================================================================
2126 //function : AddFaceWithID
2128 //=======================================================================
2129 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2130 int n12,int n23,int n31, int nCenter, int ID)
2132 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2133 myNodeFactory->FindNode(n2) ,
2134 myNodeFactory->FindNode(n3) ,
2135 myNodeFactory->FindNode(n12),
2136 myNodeFactory->FindNode(n23),
2137 myNodeFactory->FindNode(n31),
2138 myNodeFactory->FindNode(nCenter),
2142 //=======================================================================
2143 //function : AddFaceWithID
2145 //=======================================================================
2146 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2147 const SMDS_MeshNode * n2,
2148 const SMDS_MeshNode * n3,
2149 const SMDS_MeshNode * n12,
2150 const SMDS_MeshNode * n23,
2151 const SMDS_MeshNode * n31,
2152 const SMDS_MeshNode * nCenter,
2155 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2156 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2158 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2160 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2161 myInfo.myNbBiQuadTriangles++;
2162 return static_cast<SMDS_MeshFace*>( cell );
2168 //=======================================================================
2169 //function : AddFace
2171 //=======================================================================
2172 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2173 const SMDS_MeshNode * n2,
2174 const SMDS_MeshNode * n3,
2175 const SMDS_MeshNode * n4,
2176 const SMDS_MeshNode * n12,
2177 const SMDS_MeshNode * n23,
2178 const SMDS_MeshNode * n34,
2179 const SMDS_MeshNode * n41)
2181 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2182 myCellFactory->GetFreeID());
2185 //=======================================================================
2186 //function : AddFaceWithID
2188 //=======================================================================
2189 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2190 int n12,int n23,int n34,int n41, int ID)
2192 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2193 myNodeFactory->FindNode(n2) ,
2194 myNodeFactory->FindNode(n3) ,
2195 myNodeFactory->FindNode(n4) ,
2196 myNodeFactory->FindNode(n12),
2197 myNodeFactory->FindNode(n23),
2198 myNodeFactory->FindNode(n34),
2199 myNodeFactory->FindNode(n41),
2203 //=======================================================================
2204 //function : AddFaceWithID
2206 //=======================================================================
2207 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2208 const SMDS_MeshNode * n2,
2209 const SMDS_MeshNode * n3,
2210 const SMDS_MeshNode * n4,
2211 const SMDS_MeshNode * n12,
2212 const SMDS_MeshNode * n23,
2213 const SMDS_MeshNode * n34,
2214 const SMDS_MeshNode * n41,
2217 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2218 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2220 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2222 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2223 myInfo.myNbQuadQuadrangles++;
2224 return static_cast<SMDS_MeshFace*>( cell );
2229 //=======================================================================
2230 //function : AddFace
2232 //=======================================================================
2233 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2234 const SMDS_MeshNode * n2,
2235 const SMDS_MeshNode * n3,
2236 const SMDS_MeshNode * n4,
2237 const SMDS_MeshNode * n12,
2238 const SMDS_MeshNode * n23,
2239 const SMDS_MeshNode * n34,
2240 const SMDS_MeshNode * n41,
2241 const SMDS_MeshNode * nCenter)
2243 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2244 myCellFactory->GetFreeID());
2247 //=======================================================================
2248 //function : AddFaceWithID
2250 //=======================================================================
2251 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2252 int n12,int n23,int n34,int n41, int nCenter, int ID)
2254 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2255 myNodeFactory->FindNode(n2) ,
2256 myNodeFactory->FindNode(n3) ,
2257 myNodeFactory->FindNode(n4) ,
2258 myNodeFactory->FindNode(n12),
2259 myNodeFactory->FindNode(n23),
2260 myNodeFactory->FindNode(n34),
2261 myNodeFactory->FindNode(n41),
2262 myNodeFactory->FindNode(nCenter),
2266 //=======================================================================
2267 //function : AddFaceWithID
2269 //=======================================================================
2270 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2271 const SMDS_MeshNode * n2,
2272 const SMDS_MeshNode * n3,
2273 const SMDS_MeshNode * n4,
2274 const SMDS_MeshNode * n12,
2275 const SMDS_MeshNode * n23,
2276 const SMDS_MeshNode * n34,
2277 const SMDS_MeshNode * n41,
2278 const SMDS_MeshNode * nCenter,
2281 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2282 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2284 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2286 cell->init( SMDSEntity_BiQuad_Quadrangle,
2287 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2288 myInfo.myNbBiQuadQuadrangles++;
2289 return static_cast<SMDS_MeshFace*>( cell );
2295 //=======================================================================
2296 //function : AddVolume
2298 //=======================================================================
2299 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2300 const SMDS_MeshNode * n2,
2301 const SMDS_MeshNode * n3,
2302 const SMDS_MeshNode * n4,
2303 const SMDS_MeshNode * n12,
2304 const SMDS_MeshNode * n23,
2305 const SMDS_MeshNode * n31,
2306 const SMDS_MeshNode * n14,
2307 const SMDS_MeshNode * n24,
2308 const SMDS_MeshNode * n34)
2310 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2311 n31, n14, n24, n34, myCellFactory->GetFreeID());
2314 //=======================================================================
2315 //function : AddVolumeWithID
2317 //=======================================================================
2318 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2319 int n12,int n23,int n31,
2320 int n14,int n24,int n34, int ID)
2322 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2323 myNodeFactory->FindNode(n2) ,
2324 myNodeFactory->FindNode(n3) ,
2325 myNodeFactory->FindNode(n4) ,
2326 myNodeFactory->FindNode(n12),
2327 myNodeFactory->FindNode(n23),
2328 myNodeFactory->FindNode(n31),
2329 myNodeFactory->FindNode(n14),
2330 myNodeFactory->FindNode(n24),
2331 myNodeFactory->FindNode(n34),
2335 //=======================================================================
2336 //function : AddVolumeWithID
2337 //purpose : 2d order tetrahedron of 10 nodes
2338 //=======================================================================
2339 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2340 const SMDS_MeshNode * n2,
2341 const SMDS_MeshNode * n3,
2342 const SMDS_MeshNode * n4,
2343 const SMDS_MeshNode * n12,
2344 const SMDS_MeshNode * n23,
2345 const SMDS_MeshNode * n31,
2346 const SMDS_MeshNode * n14,
2347 const SMDS_MeshNode * n24,
2348 const SMDS_MeshNode * n34,
2351 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2353 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2355 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2357 cell->init( SMDSEntity_Quad_Tetra,
2358 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2359 myInfo.myNbQuadTetras++;
2360 return static_cast<SMDS_MeshVolume*>( cell );
2366 //=======================================================================
2367 //function : AddVolume
2369 //=======================================================================
2370 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2371 const SMDS_MeshNode * n2,
2372 const SMDS_MeshNode * n3,
2373 const SMDS_MeshNode * n4,
2374 const SMDS_MeshNode * n5,
2375 const SMDS_MeshNode * n12,
2376 const SMDS_MeshNode * n23,
2377 const SMDS_MeshNode * n34,
2378 const SMDS_MeshNode * n41,
2379 const SMDS_MeshNode * n15,
2380 const SMDS_MeshNode * n25,
2381 const SMDS_MeshNode * n35,
2382 const SMDS_MeshNode * n45)
2384 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2385 n15, n25, n35, n45, myCellFactory->GetFreeID());
2388 //=======================================================================
2389 //function : AddVolumeWithID
2391 //=======================================================================
2392 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2393 int n12,int n23,int n34,int n41,
2394 int n15,int n25,int n35,int n45, int ID)
2396 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2397 myNodeFactory->FindNode(n2) ,
2398 myNodeFactory->FindNode(n3) ,
2399 myNodeFactory->FindNode(n4) ,
2400 myNodeFactory->FindNode(n5) ,
2401 myNodeFactory->FindNode(n12),
2402 myNodeFactory->FindNode(n23),
2403 myNodeFactory->FindNode(n34),
2404 myNodeFactory->FindNode(n41),
2405 myNodeFactory->FindNode(n15),
2406 myNodeFactory->FindNode(n25),
2407 myNodeFactory->FindNode(n35),
2408 myNodeFactory->FindNode(n45),
2412 //=======================================================================
2413 //function : AddVolumeWithID
2414 //purpose : 2d order pyramid of 13 nodes
2415 //=======================================================================
2416 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2417 const SMDS_MeshNode * n2,
2418 const SMDS_MeshNode * n3,
2419 const SMDS_MeshNode * n4,
2420 const SMDS_MeshNode * n5,
2421 const SMDS_MeshNode * n12,
2422 const SMDS_MeshNode * n23,
2423 const SMDS_MeshNode * n34,
2424 const SMDS_MeshNode * n41,
2425 const SMDS_MeshNode * n15,
2426 const SMDS_MeshNode * n25,
2427 const SMDS_MeshNode * n35,
2428 const SMDS_MeshNode * n45,
2431 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2432 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2434 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2436 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2438 cell->init( SMDSEntity_Quad_Pyramid,
2439 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2440 myInfo.myNbQuadPyramids++;
2441 return static_cast<SMDS_MeshVolume*>( cell );
2447 //=======================================================================
2448 //function : AddVolume
2449 //purpose : 2d order Pentahedron (prism) with 15 nodes
2450 //=======================================================================
2451 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2452 const SMDS_MeshNode * n2,
2453 const SMDS_MeshNode * n3,
2454 const SMDS_MeshNode * n4,
2455 const SMDS_MeshNode * n5,
2456 const SMDS_MeshNode * n6,
2457 const SMDS_MeshNode * n12,
2458 const SMDS_MeshNode * n23,
2459 const SMDS_MeshNode * n31,
2460 const SMDS_MeshNode * n45,
2461 const SMDS_MeshNode * n56,
2462 const SMDS_MeshNode * n64,
2463 const SMDS_MeshNode * n14,
2464 const SMDS_MeshNode * n25,
2465 const SMDS_MeshNode * n36)
2467 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2468 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2471 //=======================================================================
2472 //function : AddVolumeWithID
2473 //purpose : 2d order Pentahedron (prism) with 15 nodes
2474 //=======================================================================
2475 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2476 int n4, int n5, int n6,
2477 int n12,int n23,int n31,
2478 int n45,int n56,int n64,
2479 int n14,int n25,int n36, int ID)
2481 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2482 myNodeFactory->FindNode(n2) ,
2483 myNodeFactory->FindNode(n3) ,
2484 myNodeFactory->FindNode(n4) ,
2485 myNodeFactory->FindNode(n5) ,
2486 myNodeFactory->FindNode(n6) ,
2487 myNodeFactory->FindNode(n12),
2488 myNodeFactory->FindNode(n23),
2489 myNodeFactory->FindNode(n31),
2490 myNodeFactory->FindNode(n45),
2491 myNodeFactory->FindNode(n56),
2492 myNodeFactory->FindNode(n64),
2493 myNodeFactory->FindNode(n14),
2494 myNodeFactory->FindNode(n25),
2495 myNodeFactory->FindNode(n36),
2499 //=======================================================================
2500 //function : AddVolumeWithID
2501 //purpose : 2d order Pentahedron (prism) with 15 nodes
2502 //=======================================================================
2503 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2504 const SMDS_MeshNode * n2,
2505 const SMDS_MeshNode * n3,
2506 const SMDS_MeshNode * n4,
2507 const SMDS_MeshNode * n5,
2508 const SMDS_MeshNode * n6,
2509 const SMDS_MeshNode * n12,
2510 const SMDS_MeshNode * n23,
2511 const SMDS_MeshNode * n31,
2512 const SMDS_MeshNode * n45,
2513 const SMDS_MeshNode * n56,
2514 const SMDS_MeshNode * n64,
2515 const SMDS_MeshNode * n14,
2516 const SMDS_MeshNode * n25,
2517 const SMDS_MeshNode * n36,
2520 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2521 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2523 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2525 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2527 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2528 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2529 myInfo.myNbQuadPrisms++;
2530 return static_cast<SMDS_MeshVolume*>( cell );
2535 //=======================================================================
2536 //function : AddVolume
2537 //purpose : 2d order Pentahedron (prism) with 18 nodes
2538 //=======================================================================
2539 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2540 const SMDS_MeshNode * n2,
2541 const SMDS_MeshNode * n3,
2542 const SMDS_MeshNode * n4,
2543 const SMDS_MeshNode * n5,
2544 const SMDS_MeshNode * n6,
2545 const SMDS_MeshNode * n12,
2546 const SMDS_MeshNode * n23,
2547 const SMDS_MeshNode * n31,
2548 const SMDS_MeshNode * n45,
2549 const SMDS_MeshNode * n56,
2550 const SMDS_MeshNode * n64,
2551 const SMDS_MeshNode * n14,
2552 const SMDS_MeshNode * n25,
2553 const SMDS_MeshNode * n36,
2554 const SMDS_MeshNode * n1245,
2555 const SMDS_MeshNode * n2356,
2556 const SMDS_MeshNode * n1346)
2558 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2559 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2560 myCellFactory->GetFreeID());
2563 //=======================================================================
2564 //function : AddVolumeWithID
2565 //purpose : 2d order Pentahedron (prism) with 18 nodes
2566 //=======================================================================
2567 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2568 int n4, int n5, int n6,
2569 int n12,int n23,int n31,
2570 int n45,int n56,int n64,
2571 int n14,int n25,int n36,
2572 int n1245, int n2356, int n1346, int ID)
2574 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2575 myNodeFactory->FindNode(n2) ,
2576 myNodeFactory->FindNode(n3) ,
2577 myNodeFactory->FindNode(n4) ,
2578 myNodeFactory->FindNode(n5) ,
2579 myNodeFactory->FindNode(n6) ,
2580 myNodeFactory->FindNode(n12),
2581 myNodeFactory->FindNode(n23),
2582 myNodeFactory->FindNode(n31),
2583 myNodeFactory->FindNode(n45),
2584 myNodeFactory->FindNode(n56),
2585 myNodeFactory->FindNode(n64),
2586 myNodeFactory->FindNode(n14),
2587 myNodeFactory->FindNode(n25),
2588 myNodeFactory->FindNode(n36),
2589 myNodeFactory->FindNode(n1245),
2590 myNodeFactory->FindNode(n2356),
2591 myNodeFactory->FindNode(n1346),
2595 //=======================================================================
2596 //function : AddVolumeWithID
2597 //purpose : 2d order Pentahedron (prism) with 18 nodes
2598 //=======================================================================
2599 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2600 const SMDS_MeshNode * n2,
2601 const SMDS_MeshNode * n3,
2602 const SMDS_MeshNode * n4,
2603 const SMDS_MeshNode * n5,
2604 const SMDS_MeshNode * n6,
2605 const SMDS_MeshNode * n12,
2606 const SMDS_MeshNode * n23,
2607 const SMDS_MeshNode * n31,
2608 const SMDS_MeshNode * n45,
2609 const SMDS_MeshNode * n56,
2610 const SMDS_MeshNode * n64,
2611 const SMDS_MeshNode * n14,
2612 const SMDS_MeshNode * n25,
2613 const SMDS_MeshNode * n36,
2614 const SMDS_MeshNode * n1245,
2615 const SMDS_MeshNode * n2356,
2616 const SMDS_MeshNode * n1346,
2619 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2620 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2621 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2623 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2625 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2627 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2628 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2629 myInfo.myNbBiQuadPrisms++;
2630 return static_cast<SMDS_MeshVolume*>( cell );
2636 //=======================================================================
2637 //function : AddVolume
2639 //=======================================================================
2640 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2641 const SMDS_MeshNode * n2,
2642 const SMDS_MeshNode * n3,
2643 const SMDS_MeshNode * n4,
2644 const SMDS_MeshNode * n5,
2645 const SMDS_MeshNode * n6,
2646 const SMDS_MeshNode * n7,
2647 const SMDS_MeshNode * n8,
2648 const SMDS_MeshNode * n12,
2649 const SMDS_MeshNode * n23,
2650 const SMDS_MeshNode * n34,
2651 const SMDS_MeshNode * n41,
2652 const SMDS_MeshNode * n56,
2653 const SMDS_MeshNode * n67,
2654 const SMDS_MeshNode * n78,
2655 const SMDS_MeshNode * n85,
2656 const SMDS_MeshNode * n15,
2657 const SMDS_MeshNode * n26,
2658 const SMDS_MeshNode * n37,
2659 const SMDS_MeshNode * n48)
2661 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2662 n56, n67, n78, n85, n15, n26, n37, n48,
2663 myCellFactory->GetFreeID());
2666 //=======================================================================
2667 //function : AddVolumeWithID
2669 //=======================================================================
2670 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2671 int n5, int n6, int n7, int n8,
2672 int n12,int n23,int n34,int n41,
2673 int n56,int n67,int n78,int n85,
2674 int n15,int n26,int n37,int n48, int ID)
2676 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2677 myNodeFactory->FindNode(n2),
2678 myNodeFactory->FindNode(n3),
2679 myNodeFactory->FindNode(n4),
2680 myNodeFactory->FindNode(n5),
2681 myNodeFactory->FindNode(n6),
2682 myNodeFactory->FindNode(n7),
2683 myNodeFactory->FindNode(n8),
2684 myNodeFactory->FindNode(n12),
2685 myNodeFactory->FindNode(n23),
2686 myNodeFactory->FindNode(n34),
2687 myNodeFactory->FindNode(n41),
2688 myNodeFactory->FindNode(n56),
2689 myNodeFactory->FindNode(n67),
2690 myNodeFactory->FindNode(n78),
2691 myNodeFactory->FindNode(n85),
2692 myNodeFactory->FindNode(n15),
2693 myNodeFactory->FindNode(n26),
2694 myNodeFactory->FindNode(n37),
2695 myNodeFactory->FindNode(n48),
2699 //=======================================================================
2700 //function : AddVolumeWithID
2701 //purpose : 2d order Hexahedrons with 20 nodes
2702 //=======================================================================
2703 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2704 const SMDS_MeshNode * n2,
2705 const SMDS_MeshNode * n3,
2706 const SMDS_MeshNode * n4,
2707 const SMDS_MeshNode * n5,
2708 const SMDS_MeshNode * n6,
2709 const SMDS_MeshNode * n7,
2710 const SMDS_MeshNode * n8,
2711 const SMDS_MeshNode * n12,
2712 const SMDS_MeshNode * n23,
2713 const SMDS_MeshNode * n34,
2714 const SMDS_MeshNode * n41,
2715 const SMDS_MeshNode * n56,
2716 const SMDS_MeshNode * n67,
2717 const SMDS_MeshNode * n78,
2718 const SMDS_MeshNode * n85,
2719 const SMDS_MeshNode * n15,
2720 const SMDS_MeshNode * n26,
2721 const SMDS_MeshNode * n37,
2722 const SMDS_MeshNode * n48,
2725 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2726 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2728 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2730 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2732 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2733 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2734 myInfo.myNbQuadHexas++;
2735 return static_cast<SMDS_MeshVolume*>( cell );
2740 //=======================================================================
2741 //function : AddVolume
2743 //=======================================================================
2744 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2745 const SMDS_MeshNode * n2,
2746 const SMDS_MeshNode * n3,
2747 const SMDS_MeshNode * n4,
2748 const SMDS_MeshNode * n5,
2749 const SMDS_MeshNode * n6,
2750 const SMDS_MeshNode * n7,
2751 const SMDS_MeshNode * n8,
2752 const SMDS_MeshNode * n12,
2753 const SMDS_MeshNode * n23,
2754 const SMDS_MeshNode * n34,
2755 const SMDS_MeshNode * n41,
2756 const SMDS_MeshNode * n56,
2757 const SMDS_MeshNode * n67,
2758 const SMDS_MeshNode * n78,
2759 const SMDS_MeshNode * n85,
2760 const SMDS_MeshNode * n15,
2761 const SMDS_MeshNode * n26,
2762 const SMDS_MeshNode * n37,
2763 const SMDS_MeshNode * n48,
2764 const SMDS_MeshNode * n1234,
2765 const SMDS_MeshNode * n1256,
2766 const SMDS_MeshNode * n2367,
2767 const SMDS_MeshNode * n3478,
2768 const SMDS_MeshNode * n1458,
2769 const SMDS_MeshNode * n5678,
2770 const SMDS_MeshNode * nCenter)
2772 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2773 n56, n67, n78, n85, n15, n26, n37, n48,
2774 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2775 myCellFactory->GetFreeID());
2778 //=======================================================================
2779 //function : AddVolumeWithID
2781 //=======================================================================
2782 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2783 int n5, int n6, int n7, int n8,
2784 int n12,int n23,int n34,int n41,
2785 int n56,int n67,int n78,int n85,
2786 int n15,int n26,int n37,int n48,
2787 int n1234,int n1256,int n2367,int n3478,
2788 int n1458,int n5678,int nCenter, int ID)
2790 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2791 myNodeFactory->FindNode(n2),
2792 myNodeFactory->FindNode(n3),
2793 myNodeFactory->FindNode(n4),
2794 myNodeFactory->FindNode(n5),
2795 myNodeFactory->FindNode(n6),
2796 myNodeFactory->FindNode(n7),
2797 myNodeFactory->FindNode(n8),
2798 myNodeFactory->FindNode(n12),
2799 myNodeFactory->FindNode(n23),
2800 myNodeFactory->FindNode(n34),
2801 myNodeFactory->FindNode(n41),
2802 myNodeFactory->FindNode(n56),
2803 myNodeFactory->FindNode(n67),
2804 myNodeFactory->FindNode(n78),
2805 myNodeFactory->FindNode(n85),
2806 myNodeFactory->FindNode(n15),
2807 myNodeFactory->FindNode(n26),
2808 myNodeFactory->FindNode(n37),
2809 myNodeFactory->FindNode(n48),
2810 myNodeFactory->FindNode(n1234),
2811 myNodeFactory->FindNode(n1256),
2812 myNodeFactory->FindNode(n2367),
2813 myNodeFactory->FindNode(n3478),
2814 myNodeFactory->FindNode(n1458),
2815 myNodeFactory->FindNode(n5678),
2816 myNodeFactory->FindNode(nCenter),
2820 //=======================================================================
2821 //function : AddVolumeWithID
2822 //purpose : 2d order Hexahedrons with 27 nodes
2823 //=======================================================================
2824 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2825 const SMDS_MeshNode * n2,
2826 const SMDS_MeshNode * n3,
2827 const SMDS_MeshNode * n4,
2828 const SMDS_MeshNode * n5,
2829 const SMDS_MeshNode * n6,
2830 const SMDS_MeshNode * n7,
2831 const SMDS_MeshNode * n8,
2832 const SMDS_MeshNode * n12,
2833 const SMDS_MeshNode * n23,
2834 const SMDS_MeshNode * n34,
2835 const SMDS_MeshNode * n41,
2836 const SMDS_MeshNode * n56,
2837 const SMDS_MeshNode * n67,
2838 const SMDS_MeshNode * n78,
2839 const SMDS_MeshNode * n85,
2840 const SMDS_MeshNode * n15,
2841 const SMDS_MeshNode * n26,
2842 const SMDS_MeshNode * n37,
2843 const SMDS_MeshNode * n48,
2844 const SMDS_MeshNode * n1234,
2845 const SMDS_MeshNode * n1256,
2846 const SMDS_MeshNode * n2367,
2847 const SMDS_MeshNode * n3478,
2848 const SMDS_MeshNode * n1458,
2849 const SMDS_MeshNode * n5678,
2850 const SMDS_MeshNode * nCenter,
2853 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2854 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2855 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2857 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2859 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2861 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2862 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2863 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2864 myInfo.myNbTriQuadHexas++;
2865 return static_cast<SMDS_MeshVolume*>( cell );
2870 void SMDS_Mesh::dumpGrid(std::string ficdump)
2872 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2873 // aWriter->SetFileName(ficdump.c_str());
2874 // aWriter->SetInput(myGrid);
2875 // if(myGrid->GetNumberOfCells())
2877 // aWriter->Write();
2879 // aWriter->Delete();
2880 ficdump = ficdump + "_connectivity";
2881 std::ofstream ficcon(ficdump.c_str(), ios::out);
2882 int nbPoints = myGrid->GetNumberOfPoints();
2883 ficcon << "-------------------------------- points " << nbPoints << endl;
2884 for (int i=0; i<nbPoints; i++)
2886 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2888 int nbCells = myGrid->GetNumberOfCells();
2889 ficcon << "-------------------------------- cells " << nbCells << endl;
2890 for (int i=0; i<nbCells; i++)
2892 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2893 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2894 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2895 for (int j=0; j<nbptcell; j++)
2897 ficcon << " " << listid->GetId(j);
2901 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2902 vtkCellLinks *links = myGrid->GetLinks();
2903 for (int i=0; i<nbPoints; i++)
2905 int ncells = links->GetNcells(i);
2906 vtkIdType *cells = links->GetCells(i);
2907 ficcon << i << " - " << ncells << " -";
2908 for (int j=0; j<ncells; j++)
2910 ficcon << " " << cells[j];
2918 void SMDS_Mesh::CompactMesh()
2920 this->myCompactTime = this->myModifTime;
2922 bool idsChange = ( myNodeFactory->CompactChangePointers() ||
2923 myCellFactory->CompactChangePointers() );
2926 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2927 for ( ; holder != myElemHolders.end(); ++holder )
2928 (*holder)->beforeCompacting();
2930 int oldCellSize = myCellFactory->GetMaxID();
2932 // remove "holes" in SMDS numeration
2933 std::vector<int> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
2934 myNodeFactory->Compact( idNodesOldToNew );
2935 myCellFactory->Compact( idCellsNewToOld );
2937 // make VTK IDs correspond to SMDS IDs
2938 int newNodeSize = myNodeFactory->NbUsedElements();
2939 int newCellSize = myCellFactory->NbUsedElements();
2940 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
2942 if ( idsChange && !myElemHolders.empty() )
2944 // idCellsNewToOld -> idCellsOldToNew
2945 idCellsOldToNew.resize( oldCellSize, oldCellSize );
2946 for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
2948 if ( idCellsNewToOld[ iNew ] >= (int) idCellsOldToNew.size() )
2949 idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
2950 idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
2954 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2955 for ( ; holder != myElemHolders.end(); ++holder )
2957 (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
2959 (*holder)->compact();
2964 int SMDS_Mesh::FromVtkToSmds( int vtkid ) const
2966 return myCellFactory->FromVtkToSmds( vtkid );
2969 double SMDS_Mesh::getMaxDim()
2971 double dmax = 1.e-3;
2972 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
2973 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
2974 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
2978 //! modification that needs compact structure and redraw
2979 void SMDS_Mesh::Modified()
2981 if (this->myModified)
2984 this->myModifTime++;
2989 //! get last modification timeStamp
2990 vtkMTimeType SMDS_Mesh::GetMTime() const
2992 return this->myModifTime;
2995 bool SMDS_Mesh::IsCompacted()
2997 return ( this->myCompactTime == this->myModifTime );
3000 void SMDS_Mesh::setNbShapes( size_t nbShapes )
3002 myNodeFactory->SetNbShapes( nbShapes );