1 // Copyright (C) 2007-2020 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)
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, smIdType 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(smIdType idnode, smIdType 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, smIdType 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( smIdType idnode, double diameter, smIdType 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, smIdType 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(smIdType idnode1, smIdType idnode2, smIdType 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(smIdType idnode1,
355 const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
356 const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
357 const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3);
358 if(!node1 || !node2 || !node3) return NULL;
359 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
362 ///////////////////////////////////////////////////////////////////////////////
363 /// Add a triangle defined by its nodes
364 ///////////////////////////////////////////////////////////////////////////////
366 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
367 const SMDS_MeshNode * n2,
368 const SMDS_MeshNode * n3,
371 if ( !n1 || !n2 || !n3 ) return 0;
372 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
374 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
376 cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 );
377 myInfo.myNbTriangles++;
378 return static_cast<SMDS_MeshFace*>( cell );
383 ///////////////////////////////////////////////////////////////////////////////
384 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
386 ///////////////////////////////////////////////////////////////////////////////
388 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
389 const SMDS_MeshNode * n2,
390 const SMDS_MeshNode * n3,
391 const SMDS_MeshNode * n4)
393 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID());
396 ///////////////////////////////////////////////////////////////////////////////
397 /// Add a quadrangle defined by its nodes IDs
398 ///////////////////////////////////////////////////////////////////////////////
400 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType idnode1,
406 const SMDS_MeshNode *node1, *node2, *node3, *node4;
407 node1 = myNodeFactory->FindNode(idnode1);
408 node2 = myNodeFactory->FindNode(idnode2);
409 node3 = myNodeFactory->FindNode(idnode3);
410 node4 = myNodeFactory->FindNode(idnode4);
411 if ( !node1 || !node2 || !node3 || !node4 ) return NULL;
412 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
415 ///////////////////////////////////////////////////////////////////////////////
416 /// Add a quadrangle defined by its nodes
417 ///////////////////////////////////////////////////////////////////////////////
419 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
420 const SMDS_MeshNode * n2,
421 const SMDS_MeshNode * n3,
422 const SMDS_MeshNode * n4,
425 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
426 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
428 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
430 cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 );
431 myInfo.myNbQuadrangles++;
432 return static_cast<SMDS_MeshFace*>( cell );
437 ///////////////////////////////////////////////////////////////////////////////
438 ///Create a new tetrahedron and add it to the mesh.
439 ///@return The created tetrahedron
440 ///////////////////////////////////////////////////////////////////////////////
442 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
443 const SMDS_MeshNode * n2,
444 const SMDS_MeshNode * n3,
445 const SMDS_MeshNode * n4)
447 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() );
450 ///////////////////////////////////////////////////////////////////////////////
451 ///Create a new tetrahedron and add it to the mesh.
452 ///@param ID The ID of the new volume
453 ///@return The created tetrahedron or NULL if an element with this ID already exists
454 ///or if input nodes are not found.
455 ///////////////////////////////////////////////////////////////////////////////
457 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
463 const SMDS_MeshNode *node1, *node2, *node3, *node4;
464 node1 = myNodeFactory->FindNode(idnode1);
465 node2 = myNodeFactory->FindNode(idnode2);
466 node3 = myNodeFactory->FindNode(idnode3);
467 node4 = myNodeFactory->FindNode(idnode4);
468 if(!node1 || !node2 || !node3 || !node4) return NULL;
469 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
472 ///////////////////////////////////////////////////////////////////////////////
473 ///Create a new tetrahedron and add it to the mesh.
474 ///@param ID The ID of the new volume
475 ///@return The created tetrahedron
476 ///////////////////////////////////////////////////////////////////////////////
478 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
479 const SMDS_MeshNode * n2,
480 const SMDS_MeshNode * n3,
481 const SMDS_MeshNode * n4,
484 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
485 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
487 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
489 cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 );
491 return static_cast<SMDS_MeshVolume*>( cell );
496 ///////////////////////////////////////////////////////////////////////////////
497 ///Create a new pyramid and add it to the mesh.
498 ///Nodes 1,2,3 and 4 define the base of the pyramid
499 ///@return The created pyramid
500 ///////////////////////////////////////////////////////////////////////////////
502 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
503 const SMDS_MeshNode * n2,
504 const SMDS_MeshNode * n3,
505 const SMDS_MeshNode * n4,
506 const SMDS_MeshNode * n5)
508 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() );
511 ///////////////////////////////////////////////////////////////////////////////
512 ///Create a new pyramid and add it to the mesh.
513 ///Nodes 1,2,3 and 4 define the base of the pyramid
514 ///@param ID The ID of the new volume
515 ///@return The created pyramid or NULL if an element with this ID already exists
516 ///or if input nodes are not found.
517 ///////////////////////////////////////////////////////////////////////////////
519 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
526 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
527 node1 = myNodeFactory->FindNode(idnode1);
528 node2 = myNodeFactory->FindNode(idnode2);
529 node3 = myNodeFactory->FindNode(idnode3);
530 node4 = myNodeFactory->FindNode(idnode4);
531 node5 = myNodeFactory->FindNode(idnode5);
532 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
533 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
536 ///////////////////////////////////////////////////////////////////////////////
537 ///Create a new pyramid and add it to the mesh.
538 ///Nodes 1,2,3 and 4 define the base of the pyramid
539 ///@param ID The ID of the new volume
540 ///@return The created pyramid
541 ///////////////////////////////////////////////////////////////////////////////
543 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
544 const SMDS_MeshNode * n2,
545 const SMDS_MeshNode * n3,
546 const SMDS_MeshNode * n4,
547 const SMDS_MeshNode * n5,
550 if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0;
551 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
553 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
555 cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 );
556 myInfo.myNbPyramids++;
557 return static_cast<SMDS_MeshVolume*>( cell );
562 ///////////////////////////////////////////////////////////////////////////////
563 ///Create a new prism and add it to the mesh.
564 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
565 ///@return The created prism
566 ///////////////////////////////////////////////////////////////////////////////
568 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
569 const SMDS_MeshNode * n2,
570 const SMDS_MeshNode * n3,
571 const SMDS_MeshNode * n4,
572 const SMDS_MeshNode * n5,
573 const SMDS_MeshNode * n6)
575 smIdType ID = myCellFactory->GetFreeID();
576 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
579 ///////////////////////////////////////////////////////////////////////////////
580 ///Create a new prism and add it to the mesh.
581 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
582 ///@param ID The ID of the new volume
583 ///@return The created prism or NULL if an element with this ID already exists
584 ///or if input nodes are not found.
585 ///////////////////////////////////////////////////////////////////////////////
587 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
595 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
596 node1 = myNodeFactory->FindNode(idnode1);
597 node2 = myNodeFactory->FindNode(idnode2);
598 node3 = myNodeFactory->FindNode(idnode3);
599 node4 = myNodeFactory->FindNode(idnode4);
600 node5 = myNodeFactory->FindNode(idnode5);
601 node6 = myNodeFactory->FindNode(idnode6);
602 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
605 ///////////////////////////////////////////////////////////////////////////////
606 ///Create a new prism and add it to the mesh.
607 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
608 ///@param ID The ID of the new volume
609 ///@return The created prism
610 ///////////////////////////////////////////////////////////////////////////////
612 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
613 const SMDS_MeshNode * n2,
614 const SMDS_MeshNode * n3,
615 const SMDS_MeshNode * n4,
616 const SMDS_MeshNode * n5,
617 const SMDS_MeshNode * n6,
620 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0;
621 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
623 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
625 cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 );
627 return static_cast<SMDS_MeshVolume*>( cell );
632 ///////////////////////////////////////////////////////////////////////////////
633 ///Create a new hexagonal prism and add it to the mesh.
634 ///@return The created prism
635 ///////////////////////////////////////////////////////////////////////////////
637 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
638 const SMDS_MeshNode * n2,
639 const SMDS_MeshNode * n3,
640 const SMDS_MeshNode * n4,
641 const SMDS_MeshNode * n5,
642 const SMDS_MeshNode * n6,
643 const SMDS_MeshNode * n7,
644 const SMDS_MeshNode * n8,
645 const SMDS_MeshNode * n9,
646 const SMDS_MeshNode * n10,
647 const SMDS_MeshNode * n11,
648 const SMDS_MeshNode * n12)
650 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
651 n7, n8, n9, n10, n11, n12,
652 myCellFactory->GetFreeID() );
655 ///////////////////////////////////////////////////////////////////////////////
656 ///Create a new hexagonal prism and add it to the mesh.
657 ///@param ID The ID of the new volume
658 ///@return The created prism or NULL if an element with this ID already exists
659 ///or if input nodes are not found.
660 ///////////////////////////////////////////////////////////////////////////////
662 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
676 const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1);
677 const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2);
678 const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3);
679 const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4);
680 const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5);
681 const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6);
682 const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7);
683 const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8);
684 const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9);
685 const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10);
686 const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11);
687 const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12);
688 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
689 node7, node8, node9, node10, node11, node12,
693 ///////////////////////////////////////////////////////////////////////////////
694 ///Create a new hexagonal prism and add it to the mesh.
695 ///@param ID The ID of the new volume
696 ///@return The created prism
697 ///////////////////////////////////////////////////////////////////////////////
699 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
700 const SMDS_MeshNode * n2,
701 const SMDS_MeshNode * n3,
702 const SMDS_MeshNode * n4,
703 const SMDS_MeshNode * n5,
704 const SMDS_MeshNode * n6,
705 const SMDS_MeshNode * n7,
706 const SMDS_MeshNode * n8,
707 const SMDS_MeshNode * n9,
708 const SMDS_MeshNode * n10,
709 const SMDS_MeshNode * n11,
710 const SMDS_MeshNode * n12,
713 SMDS_MeshVolume* volume = 0;
714 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
715 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
717 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
719 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
721 cell->init( SMDSEntity_Hexagonal_Prism,
722 /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 );
723 myInfo.myNbHexPrism++;
724 return static_cast<SMDS_MeshVolume*>( cell );
729 ///////////////////////////////////////////////////////////////////////////////
730 ///Create a new hexahedron and add it to the mesh.
731 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
732 ///@return The created hexahedron
733 ///////////////////////////////////////////////////////////////////////////////
735 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
736 const SMDS_MeshNode * n2,
737 const SMDS_MeshNode * n3,
738 const SMDS_MeshNode * n4,
739 const SMDS_MeshNode * n5,
740 const SMDS_MeshNode * n6,
741 const SMDS_MeshNode * n7,
742 const SMDS_MeshNode * n8)
744 smIdType ID = myCellFactory->GetFreeID();
745 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
748 ///////////////////////////////////////////////////////////////////////////////
749 ///Create a new hexahedron and add it to the mesh.
750 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
751 ///@param ID The ID of the new volume
752 ///@return The created hexahedron or NULL if an element with this ID already
753 ///exists or if input nodes are not found.
754 ///////////////////////////////////////////////////////////////////////////////
756 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
766 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
767 node1 = myNodeFactory->FindNode(idnode1);
768 node2 = myNodeFactory->FindNode(idnode2);
769 node3 = myNodeFactory->FindNode(idnode3);
770 node4 = myNodeFactory->FindNode(idnode4);
771 node5 = myNodeFactory->FindNode(idnode5);
772 node6 = myNodeFactory->FindNode(idnode6);
773 node7 = myNodeFactory->FindNode(idnode7);
774 node8 = myNodeFactory->FindNode(idnode8);
775 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
779 ///////////////////////////////////////////////////////////////////////////////
780 ///Create a new hexahedron and add it to the mesh.
781 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
782 ///@param ID The ID of the new volume
783 ///@return The created prism or NULL if an element with this ID already exists
784 ///or if input nodes are not found.
785 ///////////////////////////////////////////////////////////////////////////////
787 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
788 const SMDS_MeshNode * n2,
789 const SMDS_MeshNode * n3,
790 const SMDS_MeshNode * n4,
791 const SMDS_MeshNode * n5,
792 const SMDS_MeshNode * n6,
793 const SMDS_MeshNode * n7,
794 const SMDS_MeshNode * n8,
797 SMDS_MeshVolume* volume = 0;
798 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
799 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
801 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
803 cell->init( SMDSEntity_Hexa,
804 /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 );
806 return static_cast<SMDS_MeshVolume*>( cell );
811 ///////////////////////////////////////////////////////////////////////////////
812 /// Add a polygon defined by its nodes IDs
813 ///////////////////////////////////////////////////////////////////////////////
815 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
818 size_t nbNodes = nodes_ids.size();
819 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
820 for ( size_t i = 0; i < nbNodes; i++) {
821 nodes[i] = myNodeFactory->FindNode( nodes_ids[i] );
822 if (!nodes[i]) return NULL;
824 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
827 ///////////////////////////////////////////////////////////////////////////////
828 /// Add a polygon defined by its nodes
829 ///////////////////////////////////////////////////////////////////////////////
832 SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
835 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
838 throw std::invalid_argument("Polygon without nodes is forbidden");
839 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
841 cell->init( SMDSEntity_Polygon, nodes );
842 myInfo.myNbPolygons++;
843 return static_cast<SMDS_MeshFace*>( cell );
848 ///////////////////////////////////////////////////////////////////////////////
849 /// Add a polygon defined by its nodes.
850 /// An ID is automatically affected to the created face.
851 ///////////////////////////////////////////////////////////////////////////////
853 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
855 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
858 ///////////////////////////////////////////////////////////////////////////////
859 /// Add a quadratic polygon defined by its nodes IDs
860 ///////////////////////////////////////////////////////////////////////////////
862 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
865 std::vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
866 for ( size_t i = 0; i < nodes.size(); i++) {
867 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
868 if (!nodes[i]) return NULL;
870 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
873 ///////////////////////////////////////////////////////////////////////////////
874 /// Add a quadratic polygon defined by its nodes
875 ///////////////////////////////////////////////////////////////////////////////
878 SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
881 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
883 throw std::invalid_argument("Polygon without nodes is forbidden");
884 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
886 cell->init( SMDSEntity_Quad_Polygon, nodes );
887 myInfo.myNbQuadPolygons++;
888 return static_cast<SMDS_MeshFace*>( cell );
893 ///////////////////////////////////////////////////////////////////////////////
894 /// Add a quadratic polygon defined by its nodes.
895 /// An ID is automatically affected to the created face.
896 ///////////////////////////////////////////////////////////////////////////////
898 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
900 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
903 ///////////////////////////////////////////////////////////////////////////////
904 /// Create a new polyhedral volume and add it to the mesh.
905 /// @param ID The ID of the new volume
906 /// @return The created volume or NULL if an element with this ID already exists
907 /// or if input nodes are not found.
908 ///////////////////////////////////////////////////////////////////////////////
910 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<smIdType> & nodes_ids,
911 const std::vector<int> & quantities,
914 size_t nbNodes = nodes_ids.size();
915 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
916 for ( size_t i = 0; i < nbNodes; i++) {
917 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
918 if (!nodes[i]) return NULL;
920 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
923 ///////////////////////////////////////////////////////////////////////////////
924 /// Create a new polyhedral volume and add it to the mesh.
925 /// @param ID The ID of the new volume
926 /// @return The created volume
927 ///////////////////////////////////////////////////////////////////////////////
930 SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<const SMDS_MeshNode*>& nodes,
931 const std::vector<int> & quantities,
934 if ( nodes.empty() || quantities.empty() )
936 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
938 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
940 SMDS_MeshVolume* volume = static_cast<SMDS_MeshVolume*>( cell );
941 volume->init( nodes, quantities );
942 myInfo.myNbPolyhedrons++;
948 ///////////////////////////////////////////////////////////////////////////////
949 /// Create a new polyhedral volume and add it to the mesh.
950 /// @return The created volume
951 ///////////////////////////////////////////////////////////////////////////////
953 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
954 (const std::vector<const SMDS_MeshNode*> & nodes,
955 const std::vector<int> & quantities)
957 smIdType ID = myCellFactory->GetFreeID();
958 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
961 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
963 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
964 SMDS_MeshVolume * vol = static_cast<SMDS_MeshVolume*>( cell );
965 vol->init( vtkNodeIds );
970 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
972 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
973 SMDS_MeshFace * f = static_cast<SMDS_MeshFace*>( cell );
974 f->init( vtkNodeIds );
979 //=======================================================================
980 //function : MoveNode
982 //=======================================================================
984 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
986 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
990 ///////////////////////////////////////////////////////////////////////////////
991 /// Return the node whose SMDS ID is 'ID'.
992 ///////////////////////////////////////////////////////////////////////////////
993 const SMDS_MeshNode * SMDS_Mesh::FindNode(smIdType ID) const
995 return myNodeFactory->FindNode( ID );
998 ///////////////////////////////////////////////////////////////////////////////
999 /// Return the node whose VTK ID is 'vtkId'.
1000 ///////////////////////////////////////////////////////////////////////////////
1001 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(vtkIdType vtkId) const
1003 return myNodeFactory->FindNode( vtkId + 1 );
1006 const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(vtkIdType IDelem) const
1008 return myCellFactory->FindElement( FromVtkToSmds( IDelem ));
1011 ///////////////////////////////////////////////////////////////////////////////
1012 /// Remove a node and all the elements which own this node
1013 ///////////////////////////////////////////////////////////////////////////////
1015 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1017 RemoveElement(node, true);
1020 //=======================================================================
1021 //function : RemoveFromParent
1023 //=======================================================================
1025 bool SMDS_Mesh::RemoveFromParent()
1027 if (myParent==NULL) return false;
1028 else return (myParent->RemoveSubMesh(this));
1031 //=======================================================================
1032 //function : RemoveSubMesh
1034 //=======================================================================
1036 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1040 std::list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1041 for (; itmsh!=myChildren.end() && !found; itmsh++)
1043 SMDS_Mesh * submesh = *itmsh;
1044 if (submesh == aMesh)
1047 myChildren.erase(itmsh);
1054 //=======================================================================
1055 //function : ChangePolyhedronNodes
1057 //=======================================================================
1059 bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element,
1060 const std::vector<const SMDS_MeshNode*>& nodes,
1061 const std::vector<int>& quantities)
1063 // keep current nodes of element
1064 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1068 if ( const SMDS_MeshVolume* vol = DownCast<SMDS_MeshVolume>( element ))
1069 Ok = vol->ChangeNodes( nodes, quantities );
1074 updateInverseElements( element, &nodes[0], nodes.size(), oldNodes );
1079 //=======================================================================
1080 //function : ChangeElementNodes
1082 //=======================================================================
1084 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1085 const SMDS_MeshNode * nodes[],
1088 // keep current nodes of element
1089 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1093 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1094 Ok = cell->ChangeNodes(nodes, nbnodes);
1099 updateInverseElements( element, nodes, nbnodes, oldNodes );
1104 //=======================================================================
1105 //function : updateInverseElements
1106 //purpose : update InverseElements when element changes node
1107 //=======================================================================
1109 void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement * element,
1110 const SMDS_MeshNode* const* nodes,
1112 std::set<const SMDS_MeshNode*>& oldNodes )
1114 if ( GetGrid()->HasLinks() ) // update InverseElements
1116 std::set<const SMDS_MeshNode*>::iterator it;
1118 // AddInverseElement to new nodes
1119 for ( int i = 0; i < nbnodes; i++ )
1121 it = oldNodes.find( nodes[i] );
1122 if ( it == oldNodes.end() )
1124 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( element );
1126 // remove from oldNodes a node that remains in elem
1127 oldNodes.erase( it );
1129 // RemoveInverseElement from the nodes removed from elem
1130 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1132 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1133 n->RemoveInverseElement( element );
1139 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1141 if (!node) return 0;
1142 const SMDS_Mesh0DElement* toReturn = NULL;
1143 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1144 while (it1->more() && (toReturn == NULL)) {
1145 const SMDS_MeshElement* e = it1->next();
1146 if (e->NbNodes() == 1) {
1147 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1153 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
1155 if (!node) return 0;
1156 const SMDS_BallElement* toReturn = NULL;
1157 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
1158 while (it1->more() && (toReturn == NULL)) {
1159 const SMDS_MeshElement* e = it1->next();
1160 if (e->GetGeomType() == SMDSGeom_BALL)
1161 toReturn = static_cast<const SMDS_BallElement*>(e);
1166 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1167 const SMDS_MeshNode * node2)
1169 if ( !node1 ) return 0;
1170 const SMDS_MeshEdge * toReturn=NULL;
1171 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1172 while(it1->more()) {
1173 const SMDS_MeshElement * e = it1->next();
1174 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1175 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1182 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1183 const SMDS_MeshNode * node2,
1184 const SMDS_MeshNode * node3)
1186 if ( !node1 ) return 0;
1187 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1188 while(it1->more()) {
1189 const SMDS_MeshElement * e = it1->next();
1190 if ( e->NbNodes() == 3 ) {
1191 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1192 while(it2->more()) {
1193 const SMDS_MeshElement* n = it2->next();
1203 return static_cast<const SMDS_MeshEdge *> (e);
1209 //=======================================================================
1210 //function : FindFace
1212 //=======================================================================
1214 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1215 const SMDS_MeshNode *node2,
1216 const SMDS_MeshNode *node3)
1218 if ( !node1 ) return 0;
1219 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1220 while(it1->more()) {
1221 const SMDS_MeshElement * e = it1->next();
1222 if ( e->NbNodes() == 3 ) {
1223 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1224 while(it2->more()) {
1225 const SMDS_MeshElement* n = it2->next();
1235 return static_cast<const SMDS_MeshFace *> (e);
1241 //=======================================================================
1242 //function : FindFace
1244 //=======================================================================
1246 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1247 const SMDS_MeshNode *node2,
1248 const SMDS_MeshNode *node3,
1249 const SMDS_MeshNode *node4)
1251 if ( !node1 ) return 0;
1252 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1253 while(it1->more()) {
1254 const SMDS_MeshElement * e = it1->next();
1255 if ( e->NbNodes() == 4 ) {
1256 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1257 while(it2->more()) {
1258 const SMDS_MeshElement* n = it2->next();
1269 return static_cast<const SMDS_MeshFace *> (e);
1275 //=======================================================================
1276 //function : FindFace
1277 //purpose :quadratic triangle
1278 //=======================================================================
1280 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1281 const SMDS_MeshNode *node2,
1282 const SMDS_MeshNode *node3,
1283 const SMDS_MeshNode *node4,
1284 const SMDS_MeshNode *node5,
1285 const SMDS_MeshNode *node6)
1287 if ( !node1 ) return 0;
1288 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1289 while(it1->more()) {
1290 const SMDS_MeshElement * e = it1->next();
1291 if ( e->NbNodes() == 6 ) {
1292 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1293 while(it2->more()) {
1294 const SMDS_MeshElement* n = it2->next();
1307 return static_cast<const SMDS_MeshFace *> (e);
1314 //=======================================================================
1315 //function : FindFace
1316 //purpose : quadratic quadrangle
1317 //=======================================================================
1319 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1320 const SMDS_MeshNode *node2,
1321 const SMDS_MeshNode *node3,
1322 const SMDS_MeshNode *node4,
1323 const SMDS_MeshNode *node5,
1324 const SMDS_MeshNode *node6,
1325 const SMDS_MeshNode *node7,
1326 const SMDS_MeshNode *node8)
1328 if ( !node1 ) return 0;
1329 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1330 while(it1->more()) {
1331 const SMDS_MeshElement * e = it1->next();
1332 if ( e->NbNodes() == 8 ) {
1333 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1334 while(it2->more()) {
1335 const SMDS_MeshElement* n = it2->next();
1350 return static_cast<const SMDS_MeshFace *> (e);
1357 //=======================================================================
1358 //function : FindElement
1360 //=======================================================================
1362 const SMDS_MeshElement* SMDS_Mesh::FindElement(smIdType IDelem) const
1364 return myCellFactory->FindElement( IDelem );
1367 //=======================================================================
1368 //function : FindFace
1369 //purpose : find polygon
1370 //=======================================================================
1373 const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector<const SMDS_MeshNode *>& nodes)
1375 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1379 //================================================================================
1381 * \brief Return element based on all given nodes
1382 * \param nodes - node of element
1383 * \param type - type of element
1384 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1385 * \retval const SMDS_MeshElement* - found element or NULL
1387 //================================================================================
1389 const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector<const SMDS_MeshNode *>& nodes,
1390 const SMDSAbs_ElementType type,
1391 const bool noMedium)
1393 if ( nodes.size() > 0 && nodes[0] )
1395 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1398 const SMDS_MeshElement* e = itF->next();
1399 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1400 if ( nbNodesToCheck == (int)nodes.size() )
1402 for ( size_t i = 1; e && i < nodes.size(); ++i )
1404 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1405 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1416 //================================================================================
1418 * \brief Return elements including all given nodes
1419 * \param [in] nodes - nodes to find elements around
1420 * \param [out] foundElems - the found elements
1421 * \param [in] type - type of elements to find
1422 * \return int - a number of found elements
1424 //================================================================================
1426 int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
1427 std::vector<const SMDS_MeshElement *>& foundElems,
1428 const SMDSAbs_ElementType type)
1430 // chose a node with minimal number of inverse elements
1431 const SMDS_MeshNode* n0 = nodes[0];
1432 int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
1433 for ( size_t i = 1; i < nodes.size(); ++i )
1434 if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
1437 minNbInverse = n0->NbInverseElements( type );
1443 foundElems.reserve( minNbInverse );
1444 SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
1445 while ( eIt->more() )
1447 const SMDS_MeshElement* e = eIt->next();
1448 bool includeAll = true;
1449 for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
1450 if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
1453 foundElems.push_back( e );
1456 return foundElems.size();
1459 ///////////////////////////////////////////////////////////////////////////////
1460 /// Return the number of nodes
1461 ///////////////////////////////////////////////////////////////////////////////
1462 smIdType SMDS_Mesh::NbNodes() const
1464 return myInfo.NbNodes();
1467 ///////////////////////////////////////////////////////////////////////////////
1468 /// Return the number of elements
1469 ///////////////////////////////////////////////////////////////////////////////
1470 smIdType SMDS_Mesh::NbElements() const
1472 return myInfo.NbElements();
1474 ///////////////////////////////////////////////////////////////////////////////
1475 /// Return the number of 0D elements
1476 ///////////////////////////////////////////////////////////////////////////////
1477 smIdType SMDS_Mesh::Nb0DElements() const
1479 return myInfo.Nb0DElements();
1482 ///////////////////////////////////////////////////////////////////////////////
1483 /// Return the number of 0D elements
1484 ///////////////////////////////////////////////////////////////////////////////
1485 smIdType SMDS_Mesh::NbBalls() const
1487 return myInfo.NbBalls();
1490 ///////////////////////////////////////////////////////////////////////////////
1491 /// Return the number of edges (including construction edges)
1492 ///////////////////////////////////////////////////////////////////////////////
1493 smIdType SMDS_Mesh::NbEdges() const
1495 return myInfo.NbEdges();
1498 ///////////////////////////////////////////////////////////////////////////////
1499 /// Return the number of faces (including construction faces)
1500 ///////////////////////////////////////////////////////////////////////////////
1501 smIdType SMDS_Mesh::NbFaces() const
1503 return myInfo.NbFaces();
1506 ///////////////////////////////////////////////////////////////////////////////
1507 /// Return the number of volumes
1508 ///////////////////////////////////////////////////////////////////////////////
1509 smIdType SMDS_Mesh::NbVolumes() const
1511 return myInfo.NbVolumes();
1514 ///////////////////////////////////////////////////////////////////////////////
1515 /// Return the number of child mesh of this mesh.
1516 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
1517 ///////////////////////////////////////////////////////////////////////////////
1518 smIdType SMDS_Mesh::NbSubMesh() const
1520 return myChildren.size();
1523 ///////////////////////////////////////////////////////////////////////////////
1524 /// Destroy the mesh and all its elements
1525 /// All pointer on elements owned by this mesh become illegals.
1526 ///////////////////////////////////////////////////////////////////////////////
1527 SMDS_Mesh::~SMDS_Mesh()
1529 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1530 while(itc!=myChildren.end())
1536 delete myNodeFactory;
1537 delete myCellFactory;
1542 //================================================================================
1544 * \brief Clear all data
1546 //================================================================================
1548 void SMDS_Mesh::Clear()
1550 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
1551 for ( ; holder != myElemHolders.end(); ++holder )
1554 myNodeFactory->Clear();
1555 myCellFactory->Clear();
1557 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1558 while(itc!=myChildren.end())
1569 myGrid->Initialize();
1571 vtkPoints* points = vtkPoints::New();
1572 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
1573 // using double type for storing coordinates of nodes instead float.
1574 points->SetDataType(VTK_DOUBLE);
1575 points->SetNumberOfPoints( 0 );
1576 myGrid->SetPoints( points );
1578 myGrid->DeleteLinks();
1581 ///////////////////////////////////////////////////////////////////////////////
1582 /// Return an iterator on nodes of the current mesh factory
1583 ///////////////////////////////////////////////////////////////////////////////
1585 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1587 return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter );
1590 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
1592 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1593 return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
1597 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
1599 if ( type == SMDSEntity_Node )
1601 return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
1603 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1604 return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
1608 ///////////////////////////////////////////////////////////////////////////////
1609 /// Return an iterator on elements of the current mesh factory
1610 ///////////////////////////////////////////////////////////////////////////////
1611 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
1613 typedef SMDS_ElemIterator TIterator;
1617 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1620 return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1623 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1624 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
1627 return SMDS_ElemIteratorPtr();
1630 ///////////////////////////////////////////////////////////////////////////////
1631 ///Return an iterator on edges of the current mesh.
1632 ///////////////////////////////////////////////////////////////////////////////
1634 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1636 typedef SMDS_EdgeIterator TIterator;
1637 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges();
1638 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
1642 ///////////////////////////////////////////////////////////////////////////////
1643 ///Return an iterator on faces of the current mesh.
1644 ///////////////////////////////////////////////////////////////////////////////
1646 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1648 typedef SMDS_FaceIterator TIterator;
1649 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces();
1650 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
1654 ///////////////////////////////////////////////////////////////////////////////
1655 ///Return an iterator on volumes of the current mesh.
1656 ///////////////////////////////////////////////////////////////////////////////
1658 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1660 typedef SMDS_VolumeIterator TIterator;
1661 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes();
1663 myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
1667 SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID,
1668 size_t nbElemsToReturn,
1669 const SMDS_MeshNode* sm1stNode) const
1671 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
1674 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID,
1675 size_t nbElemsToReturn,
1676 const SMDS_MeshElement* sm1stElem) const
1678 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
1681 ///////////////////////////////////////////////////////////////////////////////
1682 /// Do intersection of sets (more than 2)
1683 ///////////////////////////////////////////////////////////////////////////////
1684 static std::set<const SMDS_MeshElement*> *
1685 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1687 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1688 std::set<const SMDS_MeshElement*>* rsetB;
1690 for(int i=0; i<numberOfSets-1; i++)
1692 rsetB = new std::set<const SMDS_MeshElement*>();
1693 set_intersection(rsetA->begin(), rsetA->end(),
1694 vs[i+1].begin(), vs[i+1].end(),
1695 inserter(*rsetB, rsetB->begin()));
1701 ///////////////////////////////////////////////////////////////////////////////
1702 /// Return the list of finite elements owning the given element: elements
1703 /// containing all the nodes of the given element, for instance faces and
1704 /// volumes containing a given edge.
1705 ///////////////////////////////////////////////////////////////////////////////
1706 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1708 int numberOfSets=element->NbNodes();
1709 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1711 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1714 while ( itNodes->more() )
1716 const SMDS_MeshNode * n = itNodes->next();
1717 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1718 initSet[i].insert( itFe->next() );
1721 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1726 ///////////////////////////////////////////////////////////////////////////////
1727 /// Return the std::list of nodes used only by the given elements
1728 ///////////////////////////////////////////////////////////////////////////////
1730 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1732 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1733 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1735 while( itElements != elements.end() )
1737 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1740 while( itNodes->more() )
1742 const SMDS_MeshNode * n = itNodes->next();
1743 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1744 std::set<const SMDS_MeshElement*> s;
1745 while ( itFe->more() )
1746 s.insert( itFe->next() );
1747 if ( s == elements ) toReturn->insert(n);
1753 ///////////////////////////////////////////////////////////////////////////////
1754 ///Find the children of an element that are made of given nodes
1755 ///@param setOfChildren The set in which matching children will be inserted
1756 ///@param element The element were to search matching children
1757 ///@param nodes The nodes that the children must have to be selected
1758 ///////////////////////////////////////////////////////////////////////////////
1759 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1760 const SMDS_MeshElement * element,
1761 std::set<const SMDS_MeshElement*>& nodes)
1763 switch(element->GetType())
1766 throw SALOME_Exception("Internal Error: This should not happen");
1768 case SMDSAbs_0DElement:
1775 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1778 const SMDS_MeshElement * e=itn->next();
1779 if(nodes.find(e)!=nodes.end())
1781 setOfChildren.insert(element);
1788 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1791 const SMDS_MeshElement * e=itn->next();
1792 if(nodes.find(e)!=nodes.end())
1794 setOfChildren.insert(element);
1799 case SMDSAbs_Volume:
1800 case SMDSAbs_NbElementTypes:
1801 case SMDSAbs_All: break;
1805 ///////////////////////////////////////////////////////////////////////////////
1806 ///@param elem The element to delete
1807 ///@param removenodes if true remaining nodes will be removed
1808 ///////////////////////////////////////////////////////////////////////////////
1809 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1810 const bool removenodes)
1812 std::vector<const SMDS_MeshElement *> removedElems;
1813 std::vector<const SMDS_MeshElement *> removedNodes;
1814 RemoveElement( elem, removedElems, removedNodes, removenodes );
1817 ///////////////////////////////////////////////////////////////////////////////
1818 ///@param elem The element to delete
1819 ///@param removedElems to be filled with all removed elements
1820 ///@param removedNodes to be filled with all removed nodes
1821 ///@param removenodes if true remaining nodes will be removed
1822 ///////////////////////////////////////////////////////////////////////////////
1823 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1824 std::vector<const SMDS_MeshElement *>& removedElems,
1825 std::vector<const SMDS_MeshElement *>& removedNodes,
1828 // get finite elements built on elem
1829 std::set<const SMDS_MeshElement*> * s1;
1830 if ( (elem->GetType() == SMDSAbs_0DElement)
1831 || (elem->GetType() == SMDSAbs_Ball)
1832 || (elem->GetType() == SMDSAbs_Edge)
1833 || (elem->GetType() == SMDSAbs_Face)
1834 || (elem->GetType() == SMDSAbs_Volume) )
1836 s1 = new std::set<const SMDS_MeshElement*> ();
1840 s1 = getFinitElements(elem);
1842 // get exclusive nodes (which would become free afterwards)
1843 std::set<const SMDS_MeshElement*> * s2;
1844 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1846 // do not remove nodes except elem
1847 s2 = new std::set<const SMDS_MeshElement*> ();
1852 s2 = getExclusiveNodes(*s1);
1854 // form the set of finite and construction elements to remove
1855 std::set<const SMDS_MeshElement*> s3;
1856 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1857 while (it != s1->end())
1859 addChildrenWithNodes(s3, *it, *s2);
1863 if (elem->GetType() != SMDSAbs_Node)
1866 // remove finite and construction elements
1867 for( it = s3.begin();it != s3.end(); ++it )
1869 // Remove element from <InverseElements> of its nodes
1870 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1873 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1874 n->RemoveInverseElement((*it));
1877 vtkIdType vtkid = (*it)->GetVtkID();
1879 switch ((*it)->GetType()) {
1881 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1883 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1884 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1885 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1886 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1887 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1888 case SMDSAbs_All: // avoid compilation warning
1889 case SMDSAbs_NbElementTypes: break;
1891 removedElems.push_back( *it);
1893 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1897 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1901 // remove exclusive (free) nodes
1904 for ( it = s2->begin(); it != s2->end(); ++it )
1907 myNodeFactory->Free( (*it) );
1908 removedNodes.push_back((*it));
1917 ///////////////////////////////////////////////////////////////////////////////
1918 ///@param elem The element to delete
1919 ///////////////////////////////////////////////////////////////////////////////
1920 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1922 const vtkIdType vtkId = elem->GetVtkID();
1923 SMDSAbs_ElementType aType = elem->GetType();
1924 if ( aType == SMDSAbs_Node )
1926 // only free node can be removed by this method
1927 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1928 if ( n->NbInverseElements() == 0 ) { // free node
1930 myNodeFactory->Free( n );
1934 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1939 // Remove element from <InverseElements> of its nodes
1940 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1941 while (itn->more()) {
1942 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1943 n->RemoveInverseElement(elem);
1946 // in meshes without descendants elements are always free
1948 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1949 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1950 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1951 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1952 case SMDSAbs_Ball: myInfo.remove(elem); break;
1955 myCellFactory->Free( elem );
1957 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1961 //=======================================================================
1963 * Checks if the element is present in mesh.
1965 //=======================================================================
1967 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1969 if ( !elem || elem->IsNull() )
1972 if ( elem->GetType() == SMDSAbs_Node )
1973 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
1975 return ( elem == myCellFactory->FindElement( elem->GetID() ));
1978 //=======================================================================
1979 //function : MaxNodeID
1981 //=======================================================================
1983 smIdType SMDS_Mesh::MaxNodeID() const
1985 return myNodeFactory->GetMaxID();
1988 //=======================================================================
1989 //function : MinNodeID
1991 //=======================================================================
1993 smIdType SMDS_Mesh::MinNodeID() const
1995 return myNodeFactory->GetMinID();
1998 //=======================================================================
1999 //function : MaxElementID
2001 //=======================================================================
2003 smIdType SMDS_Mesh::MaxElementID() const
2005 return myCellFactory->GetMaxID();
2008 //=======================================================================
2009 //function : MinElementID
2011 //=======================================================================
2013 smIdType SMDS_Mesh::MinElementID() const
2015 return myCellFactory->GetMinID();
2018 //=======================================================================
2019 //function : Renumber
2020 //purpose : Renumber all nodes or elements.
2021 //=======================================================================
2023 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2025 // if ( deltaID == 0 )
2030 //=======================================================================
2031 //function : GetElementType
2032 //purpose : Return type of element or node with id
2033 //=======================================================================
2035 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const smIdType id, const bool iselem ) const
2037 const SMDS_MeshElement* elem = 0;
2039 elem = myCellFactory->FindElement( id );
2041 elem = myNodeFactory->FindElement( id );
2043 return elem ? elem->GetType() : SMDSAbs_All;
2048 //********************************************************************
2049 //********************************************************************
2050 //******** *********
2051 //***** Methods for addition of quadratic elements ******
2052 //******** *********
2053 //********************************************************************
2054 //********************************************************************
2056 //=======================================================================
2057 //function : AddEdgeWithID
2059 //=======================================================================
2060 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID)
2062 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2063 myNodeFactory->FindNode(n2),
2064 myNodeFactory->FindNode(n12),
2068 //=======================================================================
2069 //function : AddEdge
2071 //=======================================================================
2072 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2073 const SMDS_MeshNode* n2,
2074 const SMDS_MeshNode* n12)
2076 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2079 //=======================================================================
2080 //function : AddEdgeWithID
2082 //=======================================================================
2083 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2084 const SMDS_MeshNode * n2,
2085 const SMDS_MeshNode * n12,
2088 if ( !n1 || !n2 || !n12 ) return 0;
2090 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2092 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2093 myInfo.myNbQuadEdges++;
2094 return static_cast<SMDS_MeshEdge*>( cell );
2100 //=======================================================================
2101 //function : AddFace
2103 //=======================================================================
2104 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2105 const SMDS_MeshNode * n2,
2106 const SMDS_MeshNode * n3,
2107 const SMDS_MeshNode * n12,
2108 const SMDS_MeshNode * n23,
2109 const SMDS_MeshNode * n31)
2111 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2112 myCellFactory->GetFreeID());
2115 //=======================================================================
2116 //function : AddFaceWithID
2118 //=======================================================================
2119 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2120 smIdType n12,smIdType n23,smIdType n31, smIdType ID)
2122 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2123 myNodeFactory->FindNode(n2) ,
2124 myNodeFactory->FindNode(n3) ,
2125 myNodeFactory->FindNode(n12),
2126 myNodeFactory->FindNode(n23),
2127 myNodeFactory->FindNode(n31),
2131 //=======================================================================
2132 //function : AddFaceWithID
2134 //=======================================================================
2135 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2136 const SMDS_MeshNode * n2,
2137 const SMDS_MeshNode * n3,
2138 const SMDS_MeshNode * n12,
2139 const SMDS_MeshNode * n23,
2140 const SMDS_MeshNode * n31,
2143 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2144 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2146 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2148 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2149 myInfo.myNbQuadTriangles++;
2150 return static_cast<SMDS_MeshFace*>( cell );
2156 //=======================================================================
2157 //function : AddFace
2159 //=======================================================================
2160 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2161 const SMDS_MeshNode * n2,
2162 const SMDS_MeshNode * n3,
2163 const SMDS_MeshNode * n12,
2164 const SMDS_MeshNode * n23,
2165 const SMDS_MeshNode * n31,
2166 const SMDS_MeshNode * nCenter)
2168 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2169 myCellFactory->GetFreeID());
2172 //=======================================================================
2173 //function : AddFaceWithID
2175 //=======================================================================
2176 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2177 smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID)
2179 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2180 myNodeFactory->FindNode(n2) ,
2181 myNodeFactory->FindNode(n3) ,
2182 myNodeFactory->FindNode(n12),
2183 myNodeFactory->FindNode(n23),
2184 myNodeFactory->FindNode(n31),
2185 myNodeFactory->FindNode(nCenter),
2189 //=======================================================================
2190 //function : AddFaceWithID
2192 //=======================================================================
2193 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2194 const SMDS_MeshNode * n2,
2195 const SMDS_MeshNode * n3,
2196 const SMDS_MeshNode * n12,
2197 const SMDS_MeshNode * n23,
2198 const SMDS_MeshNode * n31,
2199 const SMDS_MeshNode * nCenter,
2202 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2203 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2205 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2207 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2208 myInfo.myNbBiQuadTriangles++;
2209 return static_cast<SMDS_MeshFace*>( cell );
2215 //=======================================================================
2216 //function : AddFace
2218 //=======================================================================
2219 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2220 const SMDS_MeshNode * n2,
2221 const SMDS_MeshNode * n3,
2222 const SMDS_MeshNode * n4,
2223 const SMDS_MeshNode * n12,
2224 const SMDS_MeshNode * n23,
2225 const SMDS_MeshNode * n34,
2226 const SMDS_MeshNode * n41)
2228 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2229 myCellFactory->GetFreeID());
2232 //=======================================================================
2233 //function : AddFaceWithID
2235 //=======================================================================
2236 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2237 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID)
2239 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2240 myNodeFactory->FindNode(n2) ,
2241 myNodeFactory->FindNode(n3) ,
2242 myNodeFactory->FindNode(n4) ,
2243 myNodeFactory->FindNode(n12),
2244 myNodeFactory->FindNode(n23),
2245 myNodeFactory->FindNode(n34),
2246 myNodeFactory->FindNode(n41),
2250 //=======================================================================
2251 //function : AddFaceWithID
2253 //=======================================================================
2254 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2255 const SMDS_MeshNode * n2,
2256 const SMDS_MeshNode * n3,
2257 const SMDS_MeshNode * n4,
2258 const SMDS_MeshNode * n12,
2259 const SMDS_MeshNode * n23,
2260 const SMDS_MeshNode * n34,
2261 const SMDS_MeshNode * n41,
2264 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2265 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2267 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2269 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2270 myInfo.myNbQuadQuadrangles++;
2271 return static_cast<SMDS_MeshFace*>( cell );
2276 //=======================================================================
2277 //function : AddFace
2279 //=======================================================================
2280 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2281 const SMDS_MeshNode * n2,
2282 const SMDS_MeshNode * n3,
2283 const SMDS_MeshNode * n4,
2284 const SMDS_MeshNode * n12,
2285 const SMDS_MeshNode * n23,
2286 const SMDS_MeshNode * n34,
2287 const SMDS_MeshNode * n41,
2288 const SMDS_MeshNode * nCenter)
2290 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2291 myCellFactory->GetFreeID());
2294 //=======================================================================
2295 //function : AddFaceWithID
2297 //=======================================================================
2298 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2299 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType nCenter, smIdType ID)
2301 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2302 myNodeFactory->FindNode(n2) ,
2303 myNodeFactory->FindNode(n3) ,
2304 myNodeFactory->FindNode(n4) ,
2305 myNodeFactory->FindNode(n12),
2306 myNodeFactory->FindNode(n23),
2307 myNodeFactory->FindNode(n34),
2308 myNodeFactory->FindNode(n41),
2309 myNodeFactory->FindNode(nCenter),
2313 //=======================================================================
2314 //function : AddFaceWithID
2316 //=======================================================================
2317 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2318 const SMDS_MeshNode * n2,
2319 const SMDS_MeshNode * n3,
2320 const SMDS_MeshNode * n4,
2321 const SMDS_MeshNode * n12,
2322 const SMDS_MeshNode * n23,
2323 const SMDS_MeshNode * n34,
2324 const SMDS_MeshNode * n41,
2325 const SMDS_MeshNode * nCenter,
2328 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2329 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2331 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2333 cell->init( SMDSEntity_BiQuad_Quadrangle,
2334 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2335 myInfo.myNbBiQuadQuadrangles++;
2336 return static_cast<SMDS_MeshFace*>( cell );
2342 //=======================================================================
2343 //function : AddVolume
2345 //=======================================================================
2346 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2347 const SMDS_MeshNode * n2,
2348 const SMDS_MeshNode * n3,
2349 const SMDS_MeshNode * n4,
2350 const SMDS_MeshNode * n12,
2351 const SMDS_MeshNode * n23,
2352 const SMDS_MeshNode * n31,
2353 const SMDS_MeshNode * n14,
2354 const SMDS_MeshNode * n24,
2355 const SMDS_MeshNode * n34)
2357 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2358 n31, n14, n24, n34, myCellFactory->GetFreeID());
2361 //=======================================================================
2362 //function : AddVolumeWithID
2364 //=======================================================================
2365 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2366 smIdType n12,smIdType n23,smIdType n31,
2367 smIdType n14,smIdType n24,smIdType n34, smIdType ID)
2369 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2370 myNodeFactory->FindNode(n2) ,
2371 myNodeFactory->FindNode(n3) ,
2372 myNodeFactory->FindNode(n4) ,
2373 myNodeFactory->FindNode(n12),
2374 myNodeFactory->FindNode(n23),
2375 myNodeFactory->FindNode(n31),
2376 myNodeFactory->FindNode(n14),
2377 myNodeFactory->FindNode(n24),
2378 myNodeFactory->FindNode(n34),
2382 //=======================================================================
2383 //function : AddVolumeWithID
2384 //purpose : 2d order tetrahedron of 10 nodes
2385 //=======================================================================
2386 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2387 const SMDS_MeshNode * n2,
2388 const SMDS_MeshNode * n3,
2389 const SMDS_MeshNode * n4,
2390 const SMDS_MeshNode * n12,
2391 const SMDS_MeshNode * n23,
2392 const SMDS_MeshNode * n31,
2393 const SMDS_MeshNode * n14,
2394 const SMDS_MeshNode * n24,
2395 const SMDS_MeshNode * n34,
2398 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2400 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2402 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2404 cell->init( SMDSEntity_Quad_Tetra,
2405 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2406 myInfo.myNbQuadTetras++;
2407 return static_cast<SMDS_MeshVolume*>( cell );
2413 //=======================================================================
2414 //function : AddVolume
2416 //=======================================================================
2417 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2418 const SMDS_MeshNode * n2,
2419 const SMDS_MeshNode * n3,
2420 const SMDS_MeshNode * n4,
2421 const SMDS_MeshNode * n5,
2422 const SMDS_MeshNode * n12,
2423 const SMDS_MeshNode * n23,
2424 const SMDS_MeshNode * n34,
2425 const SMDS_MeshNode * n41,
2426 const SMDS_MeshNode * n15,
2427 const SMDS_MeshNode * n25,
2428 const SMDS_MeshNode * n35,
2429 const SMDS_MeshNode * n45)
2431 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2432 n15, n25, n35, n45, myCellFactory->GetFreeID());
2435 //=======================================================================
2436 //function : AddVolumeWithID
2438 //=======================================================================
2439 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5,
2440 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2441 smIdType n15,smIdType n25,smIdType n35,smIdType n45, smIdType ID)
2443 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2444 myNodeFactory->FindNode(n2) ,
2445 myNodeFactory->FindNode(n3) ,
2446 myNodeFactory->FindNode(n4) ,
2447 myNodeFactory->FindNode(n5) ,
2448 myNodeFactory->FindNode(n12),
2449 myNodeFactory->FindNode(n23),
2450 myNodeFactory->FindNode(n34),
2451 myNodeFactory->FindNode(n41),
2452 myNodeFactory->FindNode(n15),
2453 myNodeFactory->FindNode(n25),
2454 myNodeFactory->FindNode(n35),
2455 myNodeFactory->FindNode(n45),
2459 //=======================================================================
2460 //function : AddVolumeWithID
2461 //purpose : 2d order pyramid of 13 nodes
2462 //=======================================================================
2463 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2464 const SMDS_MeshNode * n2,
2465 const SMDS_MeshNode * n3,
2466 const SMDS_MeshNode * n4,
2467 const SMDS_MeshNode * n5,
2468 const SMDS_MeshNode * n12,
2469 const SMDS_MeshNode * n23,
2470 const SMDS_MeshNode * n34,
2471 const SMDS_MeshNode * n41,
2472 const SMDS_MeshNode * n15,
2473 const SMDS_MeshNode * n25,
2474 const SMDS_MeshNode * n35,
2475 const SMDS_MeshNode * n45,
2478 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2479 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2481 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2483 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2485 cell->init( SMDSEntity_Quad_Pyramid,
2486 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2487 myInfo.myNbQuadPyramids++;
2488 return static_cast<SMDS_MeshVolume*>( cell );
2494 //=======================================================================
2495 //function : AddVolume
2496 //purpose : 2d order Pentahedron (prism) with 15 nodes
2497 //=======================================================================
2498 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2499 const SMDS_MeshNode * n2,
2500 const SMDS_MeshNode * n3,
2501 const SMDS_MeshNode * n4,
2502 const SMDS_MeshNode * n5,
2503 const SMDS_MeshNode * n6,
2504 const SMDS_MeshNode * n12,
2505 const SMDS_MeshNode * n23,
2506 const SMDS_MeshNode * n31,
2507 const SMDS_MeshNode * n45,
2508 const SMDS_MeshNode * n56,
2509 const SMDS_MeshNode * n64,
2510 const SMDS_MeshNode * n14,
2511 const SMDS_MeshNode * n25,
2512 const SMDS_MeshNode * n36)
2514 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2515 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2518 //=======================================================================
2519 //function : AddVolumeWithID
2520 //purpose : 2d order Pentahedron (prism) with 15 nodes
2521 //=======================================================================
2522 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2523 smIdType n4, smIdType n5, smIdType n6,
2524 smIdType n12,smIdType n23,smIdType n31,
2525 smIdType n45,smIdType n56,smIdType n64,
2526 smIdType n14,smIdType n25,smIdType n36, smIdType ID)
2528 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2529 myNodeFactory->FindNode(n2) ,
2530 myNodeFactory->FindNode(n3) ,
2531 myNodeFactory->FindNode(n4) ,
2532 myNodeFactory->FindNode(n5) ,
2533 myNodeFactory->FindNode(n6) ,
2534 myNodeFactory->FindNode(n12),
2535 myNodeFactory->FindNode(n23),
2536 myNodeFactory->FindNode(n31),
2537 myNodeFactory->FindNode(n45),
2538 myNodeFactory->FindNode(n56),
2539 myNodeFactory->FindNode(n64),
2540 myNodeFactory->FindNode(n14),
2541 myNodeFactory->FindNode(n25),
2542 myNodeFactory->FindNode(n36),
2546 //=======================================================================
2547 //function : AddVolumeWithID
2548 //purpose : 2d order Pentahedron (prism) with 15 nodes
2549 //=======================================================================
2550 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2551 const SMDS_MeshNode * n2,
2552 const SMDS_MeshNode * n3,
2553 const SMDS_MeshNode * n4,
2554 const SMDS_MeshNode * n5,
2555 const SMDS_MeshNode * n6,
2556 const SMDS_MeshNode * n12,
2557 const SMDS_MeshNode * n23,
2558 const SMDS_MeshNode * n31,
2559 const SMDS_MeshNode * n45,
2560 const SMDS_MeshNode * n56,
2561 const SMDS_MeshNode * n64,
2562 const SMDS_MeshNode * n14,
2563 const SMDS_MeshNode * n25,
2564 const SMDS_MeshNode * n36,
2567 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2568 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2570 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2572 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2574 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2575 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2576 myInfo.myNbQuadPrisms++;
2577 return static_cast<SMDS_MeshVolume*>( cell );
2582 //=======================================================================
2583 //function : AddVolume
2584 //purpose : 2d order Pentahedron (prism) with 18 nodes
2585 //=======================================================================
2586 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2587 const SMDS_MeshNode * n2,
2588 const SMDS_MeshNode * n3,
2589 const SMDS_MeshNode * n4,
2590 const SMDS_MeshNode * n5,
2591 const SMDS_MeshNode * n6,
2592 const SMDS_MeshNode * n12,
2593 const SMDS_MeshNode * n23,
2594 const SMDS_MeshNode * n31,
2595 const SMDS_MeshNode * n45,
2596 const SMDS_MeshNode * n56,
2597 const SMDS_MeshNode * n64,
2598 const SMDS_MeshNode * n14,
2599 const SMDS_MeshNode * n25,
2600 const SMDS_MeshNode * n36,
2601 const SMDS_MeshNode * n1245,
2602 const SMDS_MeshNode * n2356,
2603 const SMDS_MeshNode * n1346)
2605 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2606 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2607 myCellFactory->GetFreeID());
2610 //=======================================================================
2611 //function : AddVolumeWithID
2612 //purpose : 2d order Pentahedron (prism) with 18 nodes
2613 //=======================================================================
2614 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2615 smIdType n4, smIdType n5, smIdType n6,
2616 smIdType n12,smIdType n23,smIdType n31,
2617 smIdType n45,smIdType n56,smIdType n64,
2618 smIdType n14,smIdType n25,smIdType n36,
2619 smIdType n1245, smIdType n2356, smIdType n1346, smIdType ID)
2621 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2622 myNodeFactory->FindNode(n2) ,
2623 myNodeFactory->FindNode(n3) ,
2624 myNodeFactory->FindNode(n4) ,
2625 myNodeFactory->FindNode(n5) ,
2626 myNodeFactory->FindNode(n6) ,
2627 myNodeFactory->FindNode(n12),
2628 myNodeFactory->FindNode(n23),
2629 myNodeFactory->FindNode(n31),
2630 myNodeFactory->FindNode(n45),
2631 myNodeFactory->FindNode(n56),
2632 myNodeFactory->FindNode(n64),
2633 myNodeFactory->FindNode(n14),
2634 myNodeFactory->FindNode(n25),
2635 myNodeFactory->FindNode(n36),
2636 myNodeFactory->FindNode(n1245),
2637 myNodeFactory->FindNode(n2356),
2638 myNodeFactory->FindNode(n1346),
2642 //=======================================================================
2643 //function : AddVolumeWithID
2644 //purpose : 2d order Pentahedron (prism) with 18 nodes
2645 //=======================================================================
2646 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2647 const SMDS_MeshNode * n2,
2648 const SMDS_MeshNode * n3,
2649 const SMDS_MeshNode * n4,
2650 const SMDS_MeshNode * n5,
2651 const SMDS_MeshNode * n6,
2652 const SMDS_MeshNode * n12,
2653 const SMDS_MeshNode * n23,
2654 const SMDS_MeshNode * n31,
2655 const SMDS_MeshNode * n45,
2656 const SMDS_MeshNode * n56,
2657 const SMDS_MeshNode * n64,
2658 const SMDS_MeshNode * n14,
2659 const SMDS_MeshNode * n25,
2660 const SMDS_MeshNode * n36,
2661 const SMDS_MeshNode * n1245,
2662 const SMDS_MeshNode * n2356,
2663 const SMDS_MeshNode * n1346,
2666 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2667 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2668 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2670 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2672 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2674 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2675 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2676 myInfo.myNbBiQuadPrisms++;
2677 return static_cast<SMDS_MeshVolume*>( cell );
2683 //=======================================================================
2684 //function : AddVolume
2686 //=======================================================================
2687 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2688 const SMDS_MeshNode * n2,
2689 const SMDS_MeshNode * n3,
2690 const SMDS_MeshNode * n4,
2691 const SMDS_MeshNode * n5,
2692 const SMDS_MeshNode * n6,
2693 const SMDS_MeshNode * n7,
2694 const SMDS_MeshNode * n8,
2695 const SMDS_MeshNode * n12,
2696 const SMDS_MeshNode * n23,
2697 const SMDS_MeshNode * n34,
2698 const SMDS_MeshNode * n41,
2699 const SMDS_MeshNode * n56,
2700 const SMDS_MeshNode * n67,
2701 const SMDS_MeshNode * n78,
2702 const SMDS_MeshNode * n85,
2703 const SMDS_MeshNode * n15,
2704 const SMDS_MeshNode * n26,
2705 const SMDS_MeshNode * n37,
2706 const SMDS_MeshNode * n48)
2708 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2709 n56, n67, n78, n85, n15, n26, n37, n48,
2710 myCellFactory->GetFreeID());
2713 //=======================================================================
2714 //function : AddVolumeWithID
2716 //=======================================================================
2717 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2718 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2719 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2720 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2721 smIdType n15,smIdType n26,smIdType n37,smIdType n48, smIdType ID)
2723 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2724 myNodeFactory->FindNode(n2),
2725 myNodeFactory->FindNode(n3),
2726 myNodeFactory->FindNode(n4),
2727 myNodeFactory->FindNode(n5),
2728 myNodeFactory->FindNode(n6),
2729 myNodeFactory->FindNode(n7),
2730 myNodeFactory->FindNode(n8),
2731 myNodeFactory->FindNode(n12),
2732 myNodeFactory->FindNode(n23),
2733 myNodeFactory->FindNode(n34),
2734 myNodeFactory->FindNode(n41),
2735 myNodeFactory->FindNode(n56),
2736 myNodeFactory->FindNode(n67),
2737 myNodeFactory->FindNode(n78),
2738 myNodeFactory->FindNode(n85),
2739 myNodeFactory->FindNode(n15),
2740 myNodeFactory->FindNode(n26),
2741 myNodeFactory->FindNode(n37),
2742 myNodeFactory->FindNode(n48),
2746 //=======================================================================
2747 //function : AddVolumeWithID
2748 //purpose : 2d order Hexahedrons with 20 nodes
2749 //=======================================================================
2750 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2751 const SMDS_MeshNode * n2,
2752 const SMDS_MeshNode * n3,
2753 const SMDS_MeshNode * n4,
2754 const SMDS_MeshNode * n5,
2755 const SMDS_MeshNode * n6,
2756 const SMDS_MeshNode * n7,
2757 const SMDS_MeshNode * n8,
2758 const SMDS_MeshNode * n12,
2759 const SMDS_MeshNode * n23,
2760 const SMDS_MeshNode * n34,
2761 const SMDS_MeshNode * n41,
2762 const SMDS_MeshNode * n56,
2763 const SMDS_MeshNode * n67,
2764 const SMDS_MeshNode * n78,
2765 const SMDS_MeshNode * n85,
2766 const SMDS_MeshNode * n15,
2767 const SMDS_MeshNode * n26,
2768 const SMDS_MeshNode * n37,
2769 const SMDS_MeshNode * n48,
2772 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2773 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2775 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2777 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2779 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2780 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2781 myInfo.myNbQuadHexas++;
2782 return static_cast<SMDS_MeshVolume*>( cell );
2787 //=======================================================================
2788 //function : AddVolume
2790 //=======================================================================
2791 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2792 const SMDS_MeshNode * n2,
2793 const SMDS_MeshNode * n3,
2794 const SMDS_MeshNode * n4,
2795 const SMDS_MeshNode * n5,
2796 const SMDS_MeshNode * n6,
2797 const SMDS_MeshNode * n7,
2798 const SMDS_MeshNode * n8,
2799 const SMDS_MeshNode * n12,
2800 const SMDS_MeshNode * n23,
2801 const SMDS_MeshNode * n34,
2802 const SMDS_MeshNode * n41,
2803 const SMDS_MeshNode * n56,
2804 const SMDS_MeshNode * n67,
2805 const SMDS_MeshNode * n78,
2806 const SMDS_MeshNode * n85,
2807 const SMDS_MeshNode * n15,
2808 const SMDS_MeshNode * n26,
2809 const SMDS_MeshNode * n37,
2810 const SMDS_MeshNode * n48,
2811 const SMDS_MeshNode * n1234,
2812 const SMDS_MeshNode * n1256,
2813 const SMDS_MeshNode * n2367,
2814 const SMDS_MeshNode * n3478,
2815 const SMDS_MeshNode * n1458,
2816 const SMDS_MeshNode * n5678,
2817 const SMDS_MeshNode * nCenter)
2819 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2820 n56, n67, n78, n85, n15, n26, n37, n48,
2821 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2822 myCellFactory->GetFreeID());
2825 //=======================================================================
2826 //function : AddVolumeWithID
2828 //=======================================================================
2829 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2830 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2831 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2832 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2833 smIdType n15,smIdType n26,smIdType n37,smIdType n48,
2834 smIdType n1234,smIdType n1256,smIdType n2367,smIdType n3478,
2835 smIdType n1458,smIdType n5678,smIdType nCenter, smIdType ID)
2837 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2838 myNodeFactory->FindNode(n2),
2839 myNodeFactory->FindNode(n3),
2840 myNodeFactory->FindNode(n4),
2841 myNodeFactory->FindNode(n5),
2842 myNodeFactory->FindNode(n6),
2843 myNodeFactory->FindNode(n7),
2844 myNodeFactory->FindNode(n8),
2845 myNodeFactory->FindNode(n12),
2846 myNodeFactory->FindNode(n23),
2847 myNodeFactory->FindNode(n34),
2848 myNodeFactory->FindNode(n41),
2849 myNodeFactory->FindNode(n56),
2850 myNodeFactory->FindNode(n67),
2851 myNodeFactory->FindNode(n78),
2852 myNodeFactory->FindNode(n85),
2853 myNodeFactory->FindNode(n15),
2854 myNodeFactory->FindNode(n26),
2855 myNodeFactory->FindNode(n37),
2856 myNodeFactory->FindNode(n48),
2857 myNodeFactory->FindNode(n1234),
2858 myNodeFactory->FindNode(n1256),
2859 myNodeFactory->FindNode(n2367),
2860 myNodeFactory->FindNode(n3478),
2861 myNodeFactory->FindNode(n1458),
2862 myNodeFactory->FindNode(n5678),
2863 myNodeFactory->FindNode(nCenter),
2867 //=======================================================================
2868 //function : AddVolumeWithID
2869 //purpose : 2d order Hexahedrons with 27 nodes
2870 //=======================================================================
2871 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2872 const SMDS_MeshNode * n2,
2873 const SMDS_MeshNode * n3,
2874 const SMDS_MeshNode * n4,
2875 const SMDS_MeshNode * n5,
2876 const SMDS_MeshNode * n6,
2877 const SMDS_MeshNode * n7,
2878 const SMDS_MeshNode * n8,
2879 const SMDS_MeshNode * n12,
2880 const SMDS_MeshNode * n23,
2881 const SMDS_MeshNode * n34,
2882 const SMDS_MeshNode * n41,
2883 const SMDS_MeshNode * n56,
2884 const SMDS_MeshNode * n67,
2885 const SMDS_MeshNode * n78,
2886 const SMDS_MeshNode * n85,
2887 const SMDS_MeshNode * n15,
2888 const SMDS_MeshNode * n26,
2889 const SMDS_MeshNode * n37,
2890 const SMDS_MeshNode * n48,
2891 const SMDS_MeshNode * n1234,
2892 const SMDS_MeshNode * n1256,
2893 const SMDS_MeshNode * n2367,
2894 const SMDS_MeshNode * n3478,
2895 const SMDS_MeshNode * n1458,
2896 const SMDS_MeshNode * n5678,
2897 const SMDS_MeshNode * nCenter,
2900 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2901 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2902 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2904 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2906 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2908 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2909 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2910 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2911 myInfo.myNbTriQuadHexas++;
2912 return static_cast<SMDS_MeshVolume*>( cell );
2917 void SMDS_Mesh::dumpGrid(std::string ficdump)
2919 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2920 // aWriter->SetFileName(ficdump.c_str());
2921 // aWriter->SetInput(myGrid);
2922 // if(myGrid->GetNumberOfCells())
2924 // aWriter->Write();
2926 // aWriter->Delete();
2927 ficdump = ficdump + "_connectivity";
2928 std::ofstream ficcon(ficdump.c_str(), ios::out);
2929 int nbPoints = myGrid->GetNumberOfPoints();
2930 ficcon << "-------------------------------- points " << nbPoints << endl;
2931 for (int i=0; i<nbPoints; i++)
2933 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2935 int nbCells = myGrid->GetNumberOfCells();
2936 ficcon << "-------------------------------- cells " << nbCells << endl;
2937 for (vtkIdType i=0; i<nbCells; i++)
2939 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2940 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2941 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2942 for (int j=0; j<nbptcell; j++)
2944 ficcon << " " << listid->GetId(j);
2948 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2949 vtkCellLinks *links = myGrid->GetLinks();
2950 for (int i=0; i<nbPoints; i++)
2952 int ncells = links->GetNcells(i);
2953 vtkIdType *cells = links->GetCells(i);
2954 ficcon << i << " - " << ncells << " -";
2955 for (int j=0; j<ncells; j++)
2957 ficcon << " " << cells[j];
2965 void SMDS_Mesh::CompactMesh()
2968 this->myCompactTime = this->myModifTime;
2970 bool idsChange = HasNumerationHoles();
2973 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2974 for ( ; holder != myElemHolders.end(); ++holder )
2975 (*holder)->beforeCompacting();
2977 smIdType oldCellSize = myCellFactory->GetMaxID();
2979 // remove "holes" in SMDS numeration
2980 std::vector<smIdType> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
2981 myNodeFactory->Compact( idNodesOldToNew );
2982 myCellFactory->Compact( idCellsNewToOld );
2984 // make VTK IDs correspond to SMDS IDs
2985 smIdType newNodeSize = myNodeFactory->NbUsedElements();
2986 smIdType newCellSize = myCellFactory->NbUsedElements();
2987 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
2989 if ( idsChange && !myElemHolders.empty() )
2991 // idCellsNewToOld -> idCellsOldToNew
2992 idCellsOldToNew.resize( oldCellSize, oldCellSize );
2993 for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
2995 if ( idCellsNewToOld[ iNew ] >= (smIdType) idCellsOldToNew.size() )
2996 idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
2997 idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
3001 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
3002 for ( ; holder != myElemHolders.end(); ++holder )
3004 (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
3006 (*holder)->compact();
3011 smIdType SMDS_Mesh::FromVtkToSmds( vtkIdType vtkid ) const
3013 return myCellFactory->FromVtkToSmds( vtkid );
3016 double SMDS_Mesh::getMaxDim()
3018 double dmax = 1.e-3;
3019 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
3020 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
3021 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
3025 //! modification that needs compact structure and redraw
3026 void SMDS_Mesh::Modified()
3028 if (this->myModified)
3031 this->myModifTime++;
3036 //! get last modification timeStamp
3037 vtkMTimeType SMDS_Mesh::GetMTime() const
3039 return this->myModifTime;
3042 bool SMDS_Mesh::IsCompacted()
3044 return ( this->myCompactTime == this->myModifTime );
3047 //! are there holes in elements or nodes numeration
3048 bool SMDS_Mesh::HasNumerationHoles()
3050 return ( myNodeFactory->CompactChangePointers() ||
3051 myCellFactory->CompactChangePointers() );
3054 void SMDS_Mesh::setNbShapes( size_t nbShapes )
3056 myNodeFactory->SetNbShapes( nbShapes );