1 // Copyright (C) 2007-2023 CEA, EDF, 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>
51 #include <boost/container/flat_set.hpp>
53 #if !defined WIN32 && !defined __APPLE__
54 #include <sys/sysinfo.h>
57 // number of added entities to check memory after
58 #define CHECKMEMORY_INTERVAL 100000
60 #define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
62 int SMDS_Mesh::chunkSize = 1024;
64 //================================================================================
66 * \brief Raise an exception if free memory (ram+swap) too low
67 * \param doNotRaise - if true, suppress exception, just return free memory size
68 * \retval int - amount of available memory in MB or negative number in failure case
70 //================================================================================
72 int SMDS_Mesh::CheckMemory(const bool doNotRaise)
75 #if !defined WIN32 && !defined __APPLE__
77 int err = sysinfo( &si );
81 const unsigned long Mbyte = 1024 * 1024;
83 static int limit = -1;
85 if ( si.totalswap == 0 )
87 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
89 limit = WEXITSTATUS(status);
92 double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
93 limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
99 limit = int ( limit * 1.5 );
100 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
103 // compute separately to avoid overflow
105 ( si.freeram * si.mem_unit ) / Mbyte +
106 ( si.freeswap * si.mem_unit ) / Mbyte;
108 if ( freeMb > limit )
109 return freeMb - limit;
114 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
115 throw std::bad_alloc();
121 ///////////////////////////////////////////////////////////////////////////////
122 /// Create a new mesh object
123 ///////////////////////////////////////////////////////////////////////////////
124 SMDS_Mesh::SMDS_Mesh():
125 myNodeFactory( new SMDS_NodeFactory( this )),
126 myCellFactory( new SMDS_ElementFactory( this )),
128 myModified(false), myModifTime(0), myCompactTime(0),
129 xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
131 myGrid = SMDS_UnstructuredGrid::New();
132 myGrid->setSMDS_mesh(this);
133 myGrid->Initialize();
135 vtkPoints* points = vtkPoints::New();
136 // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
137 // Use double type for storing coordinates of nodes instead of float.
138 points->SetDataType(VTK_DOUBLE);
139 points->SetNumberOfPoints( 0 );
140 myGrid->SetPoints( points );
144 // initialize static maps in SMDS_MeshCell, to be thread-safe
145 SMDS_MeshCell::InitStaticMembers();
148 ///////////////////////////////////////////////////////////////////////////////
149 /// Create a new child mesh
150 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
151 /// (2003-09-08) of SMESH
152 ///////////////////////////////////////////////////////////////////////////////
153 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
154 myNodeFactory( new SMDS_NodeFactory( this )),
155 myCellFactory( new SMDS_ElementFactory( this )),
160 ///////////////////////////////////////////////////////////////////////////////
161 ///Create a submesh and add it to the current mesh
162 ///////////////////////////////////////////////////////////////////////////////
164 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
166 SMDS_Mesh *submesh = new SMDS_Mesh(this);
167 myChildren.insert(myChildren.end(), submesh);
171 ///////////////////////////////////////////////////////////////////////////////
172 ///create a MeshNode and add it to the current Mesh
173 ///An ID is automatically assigned to the node.
174 ///@return : The created node
175 ///////////////////////////////////////////////////////////////////////////////
177 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
179 return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() );
182 ///////////////////////////////////////////////////////////////////////////////
183 ///create a MeshNode and add it to the current Mesh
184 ///@param ID : The ID of the MeshNode to create
185 ///@return : The created node or NULL if a node with this ID already exists
186 ///////////////////////////////////////////////////////////////////////////////
187 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, smIdType ID )
189 // find the MeshNode corresponding to ID
190 SMDS_MeshNode *node = myNodeFactory->NewNode( ID );
193 node->init( x, y, z );
196 this->adjustBoundingBox(x, y, z);
201 ///////////////////////////////////////////////////////////////////////////////
202 /// create a Mesh0DElement and add it to the current Mesh
203 /// @return : The created Mesh0DElement
204 ///////////////////////////////////////////////////////////////////////////////
205 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(smIdType idnode, smIdType ID)
207 const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode);
208 if (!node) return NULL;
209 return SMDS_Mesh::Add0DElementWithID(node, ID);
212 ///////////////////////////////////////////////////////////////////////////////
213 /// create a Mesh0DElement and add it to the current Mesh
214 /// @return : The created Mesh0DElement
215 ///////////////////////////////////////////////////////////////////////////////
216 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
218 return SMDS_Mesh::Add0DElementWithID( node, myCellFactory->GetFreeID() );
221 ///////////////////////////////////////////////////////////////////////////////
222 /// Create a new Mesh0DElement and at it to the mesh
223 /// @param idnode ID of the node
224 /// @param ID ID of the 0D element to create
225 /// @return The created 0D element or NULL if an element with this
226 /// ID already exists or if input node is not found.
227 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, smIdType ID)
232 if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
234 if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID ))
236 cell->init( SMDSEntity_0D, /*nbNodes=*/1, n );
237 myInfo.myNb0DElements++;
238 return static_cast< SMDS_Mesh0DElement*> ( cell );
244 ///////////////////////////////////////////////////////////////////////////////
245 /// create a Ball and add it to the current Mesh
246 /// @return : The created Ball
247 ///////////////////////////////////////////////////////////////////////////////
248 SMDS_BallElement* SMDS_Mesh::AddBallWithID( smIdType idnode, double diameter, smIdType ID )
250 const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode );
251 if (!node) return NULL;
252 return SMDS_Mesh::AddBallWithID( node, diameter, ID );
255 ///////////////////////////////////////////////////////////////////////////////
256 /// create a Ball and add it to the current Mesh
257 /// @return : The created Ball
258 ///////////////////////////////////////////////////////////////////////////////
259 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
261 return SMDS_Mesh::AddBallWithID(node, diameter, myCellFactory->GetFreeID());
264 ///////////////////////////////////////////////////////////////////////////////
265 /// Create a new Ball and at it to the mesh
266 /// @param idnode ID of the node
267 // @param diameter ball diameter
268 /// @param ID ID of the 0D element to create
269 /// @return The created 0D element or NULL if an element with this
270 /// ID already exists or if input node is not found.
271 ///////////////////////////////////////////////////////////////////////////////
272 SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, smIdType ID)
276 if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
278 SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID ));
281 ball->init( n, diameter );
287 ///////////////////////////////////////////////////////////////////////////////
288 /// create a MeshEdge and add it to the current Mesh
289 /// @return : The created MeshEdge
290 ///////////////////////////////////////////////////////////////////////////////
292 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType idnode1, smIdType idnode2, smIdType ID)
294 const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
295 const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
296 if(!node1 || !node2) return NULL;
297 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
300 ///////////////////////////////////////////////////////////////////////////////
301 /// create a MeshEdge and add it to the current Mesh
302 /// @return : The created MeshEdge
303 ///////////////////////////////////////////////////////////////////////////////
305 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
306 const SMDS_MeshNode * node2)
308 return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID());
311 ///////////////////////////////////////////////////////////////////////////////
312 /// Create a new edge and at it to the mesh
313 /// @param idnode1 ID of the first node
314 /// @param idnode2 ID of the second node
315 /// @param ID ID of the edge to create
316 /// @return The created edge or NULL if an element with this ID already exists or
317 /// if input nodes are not found.
318 ///////////////////////////////////////////////////////////////////////////////
320 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
321 const SMDS_MeshNode * n2,
324 if ( !n1 || !n2 ) return 0;
326 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
328 cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 );
330 return static_cast<SMDS_MeshEdge*>( cell );
335 ///////////////////////////////////////////////////////////////////////////////
336 /// Add a triangle defined by its nodes. An ID is automatically affected to the
338 ///////////////////////////////////////////////////////////////////////////////
340 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
341 const SMDS_MeshNode * n2,
342 const SMDS_MeshNode * n3)
344 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID());
347 ///////////////////////////////////////////////////////////////////////////////
348 /// Add a triangle defined by its nodes IDs
349 ///////////////////////////////////////////////////////////////////////////////
351 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType idnode1,
356 const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
357 const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
358 const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3);
359 if(!node1 || !node2 || !node3) return NULL;
360 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
363 ///////////////////////////////////////////////////////////////////////////////
364 /// Add a triangle defined by its nodes
365 ///////////////////////////////////////////////////////////////////////////////
367 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
368 const SMDS_MeshNode * n2,
369 const SMDS_MeshNode * n3,
372 if ( !n1 || !n2 || !n3 ) return 0;
373 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
375 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
377 cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 );
378 myInfo.myNbTriangles++;
379 return static_cast<SMDS_MeshFace*>( cell );
384 ///////////////////////////////////////////////////////////////////////////////
385 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
387 ///////////////////////////////////////////////////////////////////////////////
389 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
390 const SMDS_MeshNode * n2,
391 const SMDS_MeshNode * n3,
392 const SMDS_MeshNode * n4)
394 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID());
397 ///////////////////////////////////////////////////////////////////////////////
398 /// Add a quadrangle defined by its nodes IDs
399 ///////////////////////////////////////////////////////////////////////////////
401 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType idnode1,
407 const SMDS_MeshNode *node1, *node2, *node3, *node4;
408 node1 = myNodeFactory->FindNode(idnode1);
409 node2 = myNodeFactory->FindNode(idnode2);
410 node3 = myNodeFactory->FindNode(idnode3);
411 node4 = myNodeFactory->FindNode(idnode4);
412 if ( !node1 || !node2 || !node3 || !node4 ) return NULL;
413 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
416 ///////////////////////////////////////////////////////////////////////////////
417 /// Add a quadrangle defined by its nodes
418 ///////////////////////////////////////////////////////////////////////////////
420 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
421 const SMDS_MeshNode * n2,
422 const SMDS_MeshNode * n3,
423 const SMDS_MeshNode * n4,
426 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
427 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
429 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
431 cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 );
432 myInfo.myNbQuadrangles++;
433 return static_cast<SMDS_MeshFace*>( cell );
438 ///////////////////////////////////////////////////////////////////////////////
439 ///Create a new tetrahedron and add it to the mesh.
440 ///@return The created tetrahedron
441 ///////////////////////////////////////////////////////////////////////////////
443 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
444 const SMDS_MeshNode * n2,
445 const SMDS_MeshNode * n3,
446 const SMDS_MeshNode * n4)
448 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() );
451 ///////////////////////////////////////////////////////////////////////////////
452 ///Create a new tetrahedron and add it to the mesh.
453 ///@param ID The ID of the new volume
454 ///@return The created tetrahedron or NULL if an element with this ID already exists
455 ///or if input nodes are not found.
456 ///////////////////////////////////////////////////////////////////////////////
458 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
464 const SMDS_MeshNode *node1, *node2, *node3, *node4;
465 node1 = myNodeFactory->FindNode(idnode1);
466 node2 = myNodeFactory->FindNode(idnode2);
467 node3 = myNodeFactory->FindNode(idnode3);
468 node4 = myNodeFactory->FindNode(idnode4);
469 if(!node1 || !node2 || !node3 || !node4) return NULL;
470 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
473 ///////////////////////////////////////////////////////////////////////////////
474 ///Create a new tetrahedron and add it to the mesh.
475 ///@param ID The ID of the new volume
476 ///@return The created tetrahedron
477 ///////////////////////////////////////////////////////////////////////////////
479 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
480 const SMDS_MeshNode * n2,
481 const SMDS_MeshNode * n3,
482 const SMDS_MeshNode * n4,
485 if ( !n1 || !n2 || !n3 || !n4 ) return 0;
486 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
488 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
490 cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 );
492 return static_cast<SMDS_MeshVolume*>( cell );
497 ///////////////////////////////////////////////////////////////////////////////
498 ///Create a new pyramid and add it to the mesh.
499 ///Nodes 1,2,3 and 4 define the base of the pyramid
500 ///@return The created pyramid
501 ///////////////////////////////////////////////////////////////////////////////
503 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
504 const SMDS_MeshNode * n2,
505 const SMDS_MeshNode * n3,
506 const SMDS_MeshNode * n4,
507 const SMDS_MeshNode * n5)
509 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() );
512 ///////////////////////////////////////////////////////////////////////////////
513 ///Create a new pyramid and add it to the mesh.
514 ///Nodes 1,2,3 and 4 define the base of the pyramid
515 ///@param ID The ID of the new volume
516 ///@return The created pyramid or NULL if an element with this ID already exists
517 ///or if input nodes are not found.
518 ///////////////////////////////////////////////////////////////////////////////
520 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
527 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
528 node1 = myNodeFactory->FindNode(idnode1);
529 node2 = myNodeFactory->FindNode(idnode2);
530 node3 = myNodeFactory->FindNode(idnode3);
531 node4 = myNodeFactory->FindNode(idnode4);
532 node5 = myNodeFactory->FindNode(idnode5);
533 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
534 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
537 ///////////////////////////////////////////////////////////////////////////////
538 ///Create a new pyramid and add it to the mesh.
539 ///Nodes 1,2,3 and 4 define the base of the pyramid
540 ///@param ID The ID of the new volume
541 ///@return The created pyramid
542 ///////////////////////////////////////////////////////////////////////////////
544 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
545 const SMDS_MeshNode * n2,
546 const SMDS_MeshNode * n3,
547 const SMDS_MeshNode * n4,
548 const SMDS_MeshNode * n5,
551 if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0;
552 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
554 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
556 cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 );
557 myInfo.myNbPyramids++;
558 return static_cast<SMDS_MeshVolume*>( cell );
563 ///////////////////////////////////////////////////////////////////////////////
564 ///Create a new prism and add it to the mesh.
565 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
566 ///@return The created prism
567 ///////////////////////////////////////////////////////////////////////////////
569 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
570 const SMDS_MeshNode * n2,
571 const SMDS_MeshNode * n3,
572 const SMDS_MeshNode * n4,
573 const SMDS_MeshNode * n5,
574 const SMDS_MeshNode * n6)
576 smIdType ID = myCellFactory->GetFreeID();
577 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
580 ///////////////////////////////////////////////////////////////////////////////
581 ///Create a new prism and add it to the mesh.
582 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
583 ///@param ID The ID of the new volume
584 ///@return The created prism or NULL if an element with this ID already exists
585 ///or if input nodes are not found.
586 ///////////////////////////////////////////////////////////////////////////////
588 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
596 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
597 node1 = myNodeFactory->FindNode(idnode1);
598 node2 = myNodeFactory->FindNode(idnode2);
599 node3 = myNodeFactory->FindNode(idnode3);
600 node4 = myNodeFactory->FindNode(idnode4);
601 node5 = myNodeFactory->FindNode(idnode5);
602 node6 = myNodeFactory->FindNode(idnode6);
603 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
606 ///////////////////////////////////////////////////////////////////////////////
607 ///Create a new prism and add it to the mesh.
608 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
609 ///@param ID The ID of the new volume
610 ///@return The created prism
611 ///////////////////////////////////////////////////////////////////////////////
613 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
614 const SMDS_MeshNode * n2,
615 const SMDS_MeshNode * n3,
616 const SMDS_MeshNode * n4,
617 const SMDS_MeshNode * n5,
618 const SMDS_MeshNode * n6,
621 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0;
622 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
624 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
626 cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 );
628 return static_cast<SMDS_MeshVolume*>( cell );
633 ///////////////////////////////////////////////////////////////////////////////
634 ///Create a new hexagonal prism and add it to the mesh.
635 ///@return The created prism
636 ///////////////////////////////////////////////////////////////////////////////
638 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
639 const SMDS_MeshNode * n2,
640 const SMDS_MeshNode * n3,
641 const SMDS_MeshNode * n4,
642 const SMDS_MeshNode * n5,
643 const SMDS_MeshNode * n6,
644 const SMDS_MeshNode * n7,
645 const SMDS_MeshNode * n8,
646 const SMDS_MeshNode * n9,
647 const SMDS_MeshNode * n10,
648 const SMDS_MeshNode * n11,
649 const SMDS_MeshNode * n12)
651 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
652 n7, n8, n9, n10, n11, n12,
653 myCellFactory->GetFreeID() );
656 ///////////////////////////////////////////////////////////////////////////////
657 ///Create a new hexagonal prism and add it to the mesh.
658 ///@param ID The ID of the new volume
659 ///@return The created prism or NULL if an element with this ID already exists
660 ///or if input nodes are not found.
661 ///////////////////////////////////////////////////////////////////////////////
663 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
677 const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1);
678 const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2);
679 const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3);
680 const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4);
681 const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5);
682 const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6);
683 const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7);
684 const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8);
685 const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9);
686 const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10);
687 const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11);
688 const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12);
689 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
690 node7, node8, node9, node10, node11, node12,
694 ///////////////////////////////////////////////////////////////////////////////
695 ///Create a new hexagonal prism and add it to the mesh.
696 ///@param ID The ID of the new volume
697 ///@return The created prism
698 ///////////////////////////////////////////////////////////////////////////////
700 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
701 const SMDS_MeshNode * n2,
702 const SMDS_MeshNode * n3,
703 const SMDS_MeshNode * n4,
704 const SMDS_MeshNode * n5,
705 const SMDS_MeshNode * n6,
706 const SMDS_MeshNode * n7,
707 const SMDS_MeshNode * n8,
708 const SMDS_MeshNode * n9,
709 const SMDS_MeshNode * n10,
710 const SMDS_MeshNode * n11,
711 const SMDS_MeshNode * n12,
714 SMDS_MeshVolume* volume = 0;
715 if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
716 !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
718 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
720 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
722 cell->init( SMDSEntity_Hexagonal_Prism,
723 /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 );
724 myInfo.myNbHexPrism++;
725 return static_cast<SMDS_MeshVolume*>( cell );
730 ///////////////////////////////////////////////////////////////////////////////
731 ///Create a new hexahedron and add it to the mesh.
732 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
733 ///@return The created hexahedron
734 ///////////////////////////////////////////////////////////////////////////////
736 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
737 const SMDS_MeshNode * n2,
738 const SMDS_MeshNode * n3,
739 const SMDS_MeshNode * n4,
740 const SMDS_MeshNode * n5,
741 const SMDS_MeshNode * n6,
742 const SMDS_MeshNode * n7,
743 const SMDS_MeshNode * n8)
745 smIdType ID = myCellFactory->GetFreeID();
746 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
749 ///////////////////////////////////////////////////////////////////////////////
750 ///Create a new hexahedron and add it to the mesh.
751 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
752 ///@param ID The ID of the new volume
753 ///@return The created hexahedron or NULL if an element with this ID already
754 ///exists or if input nodes are not found.
755 ///////////////////////////////////////////////////////////////////////////////
757 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
767 const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
768 node1 = myNodeFactory->FindNode(idnode1);
769 node2 = myNodeFactory->FindNode(idnode2);
770 node3 = myNodeFactory->FindNode(idnode3);
771 node4 = myNodeFactory->FindNode(idnode4);
772 node5 = myNodeFactory->FindNode(idnode5);
773 node6 = myNodeFactory->FindNode(idnode6);
774 node7 = myNodeFactory->FindNode(idnode7);
775 node8 = myNodeFactory->FindNode(idnode8);
776 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
780 ///////////////////////////////////////////////////////////////////////////////
781 ///Create a new hexahedron and add it to the mesh.
782 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
783 ///@param ID The ID of the new volume
784 ///@return The created prism or NULL if an element with this ID already exists
785 ///or if input nodes are not found.
786 ///////////////////////////////////////////////////////////////////////////////
788 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
789 const SMDS_MeshNode * n2,
790 const SMDS_MeshNode * n3,
791 const SMDS_MeshNode * n4,
792 const SMDS_MeshNode * n5,
793 const SMDS_MeshNode * n6,
794 const SMDS_MeshNode * n7,
795 const SMDS_MeshNode * n8,
798 SMDS_MeshVolume* volume = 0;
799 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
800 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
802 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
804 cell->init( SMDSEntity_Hexa,
805 /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 );
807 return static_cast<SMDS_MeshVolume*>( cell );
812 ///////////////////////////////////////////////////////////////////////////////
813 /// Add a polygon defined by its nodes IDs
814 ///////////////////////////////////////////////////////////////////////////////
816 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
819 size_t nbNodes = nodes_ids.size();
820 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
821 for ( size_t i = 0; i < nbNodes; i++) {
822 nodes[i] = myNodeFactory->FindNode( nodes_ids[i] );
823 if (!nodes[i]) return NULL;
825 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
828 ///////////////////////////////////////////////////////////////////////////////
829 /// Add a polygon defined by its nodes
830 ///////////////////////////////////////////////////////////////////////////////
833 SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
836 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
839 throw std::invalid_argument("Polygon without nodes is forbidden");
840 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
842 cell->init( SMDSEntity_Polygon, nodes );
843 myInfo.myNbPolygons++;
844 return static_cast<SMDS_MeshFace*>( cell );
849 ///////////////////////////////////////////////////////////////////////////////
850 /// Add a polygon defined by its nodes.
851 /// An ID is automatically affected to the created face.
852 ///////////////////////////////////////////////////////////////////////////////
854 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
856 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
859 ///////////////////////////////////////////////////////////////////////////////
860 /// Add a quadratic polygon defined by its nodes IDs
861 ///////////////////////////////////////////////////////////////////////////////
863 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
866 std::vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
867 for ( size_t i = 0; i < nodes.size(); i++) {
868 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
869 if (!nodes[i]) return NULL;
871 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
874 ///////////////////////////////////////////////////////////////////////////////
875 /// Add a quadratic polygon defined by its nodes
876 ///////////////////////////////////////////////////////////////////////////////
879 SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
882 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
884 throw std::invalid_argument("Polygon without nodes is forbidden");
885 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
887 cell->init( SMDSEntity_Quad_Polygon, nodes );
888 myInfo.myNbQuadPolygons++;
889 return static_cast<SMDS_MeshFace*>( cell );
894 ///////////////////////////////////////////////////////////////////////////////
895 /// Add a quadratic polygon defined by its nodes.
896 /// An ID is automatically affected to the created face.
897 ///////////////////////////////////////////////////////////////////////////////
899 SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
901 return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
904 ///////////////////////////////////////////////////////////////////////////////
905 /// Create a new polyhedral volume and add it to the mesh.
906 /// @param ID The ID of the new volume
907 /// @return The created volume or NULL if an element with this ID already exists
908 /// or if input nodes are not found.
909 ///////////////////////////////////////////////////////////////////////////////
911 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<smIdType> & nodes_ids,
912 const std::vector<int> & quantities,
915 size_t nbNodes = nodes_ids.size();
916 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
917 for ( size_t i = 0; i < nbNodes; i++) {
918 nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
919 if (!nodes[i]) return NULL;
921 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
924 ///////////////////////////////////////////////////////////////////////////////
925 /// Create a new polyhedral volume and add it to the mesh.
926 /// @param ID The ID of the new volume
927 /// @return The created volume
928 ///////////////////////////////////////////////////////////////////////////////
931 SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<const SMDS_MeshNode*>& nodes,
932 const std::vector<int> & quantities,
935 if ( nodes.empty() || quantities.empty() )
937 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
939 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
941 SMDS_MeshVolume* volume = static_cast<SMDS_MeshVolume*>( cell );
942 volume->init( nodes, quantities );
943 myInfo.myNbPolyhedrons++;
949 ///////////////////////////////////////////////////////////////////////////////
950 /// Create a new polyhedral volume and add it to the mesh.
951 /// @return The created volume
952 ///////////////////////////////////////////////////////////////////////////////
954 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
955 (const std::vector<const SMDS_MeshNode*> & nodes,
956 const std::vector<int> & quantities)
958 smIdType ID = myCellFactory->GetFreeID();
959 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
962 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
964 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
965 SMDS_MeshVolume * vol = static_cast<SMDS_MeshVolume*>( cell );
966 vol->init( vtkNodeIds );
971 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
973 SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
974 SMDS_MeshFace * f = static_cast<SMDS_MeshFace*>( cell );
975 f->init( vtkNodeIds );
980 //=======================================================================
981 //function : MoveNode
983 //=======================================================================
985 void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
987 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
991 ///////////////////////////////////////////////////////////////////////////////
992 /// Return the node whose SMDS ID is 'ID'.
993 ///////////////////////////////////////////////////////////////////////////////
994 const SMDS_MeshNode * SMDS_Mesh::FindNode(smIdType ID) const
996 return myNodeFactory->FindNode( ID );
999 ///////////////////////////////////////////////////////////////////////////////
1000 /// Return the node whose VTK ID is 'vtkId'.
1001 ///////////////////////////////////////////////////////////////////////////////
1002 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(vtkIdType vtkId) const
1004 return myNodeFactory->FindNode( vtkId + 1 );
1007 const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(vtkIdType IDelem) const
1009 return myCellFactory->FindElement( FromVtkToSmds( IDelem ));
1012 ///////////////////////////////////////////////////////////////////////////////
1013 /// Remove a node and all the elements which own this node
1014 ///////////////////////////////////////////////////////////////////////////////
1016 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1018 RemoveElement(node, true);
1021 //=======================================================================
1022 //function : RemoveFromParent
1024 //=======================================================================
1026 bool SMDS_Mesh::RemoveFromParent()
1028 if (myParent==NULL) return false;
1029 else return (myParent->RemoveSubMesh(this));
1032 //=======================================================================
1033 //function : RemoveSubMesh
1035 //=======================================================================
1037 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1041 std::list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1042 for (; itmsh!=myChildren.end() && !found; itmsh++)
1044 SMDS_Mesh * submesh = *itmsh;
1045 if (submesh == aMesh)
1048 myChildren.erase(itmsh);
1055 //=======================================================================
1056 //function : SetAllNodesNotMarked
1057 //purpose : Clear marked flag of all nodes
1058 //=======================================================================
1060 void SMDS_Mesh::SetAllNodesNotMarked()
1062 myNodeFactory->SetAllNotMarked();
1065 //=======================================================================
1066 //function : SetAllCellsNotMarked
1067 //purpose : Clear marked flag of all cells
1068 //=======================================================================
1070 void SMDS_Mesh::SetAllCellsNotMarked()
1072 myCellFactory->SetAllNotMarked();
1075 //=======================================================================
1076 //function : ChangePolyhedronNodes
1078 //=======================================================================
1080 bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element,
1081 const std::vector<const SMDS_MeshNode*>& nodes,
1082 const std::vector<int>& quantities)
1084 // keep current nodes of element
1085 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1089 // change vtkUnstructuredGrid::Faces
1090 if ( const SMDS_MeshVolume* vol = DownCast<SMDS_MeshVolume>( element ))
1091 Ok = vol->ChangeNodes( nodes, quantities );
1093 // change vtkUnstructuredGrid::Connectivity and inverse connectivity
1095 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1097 boost::container::flat_set< const SMDS_MeshNode* > uniqueNodes( nodes.begin(), nodes.end() );
1098 const SMDS_MeshNode** nodesPtr = &( *uniqueNodes.begin());
1099 const int nbNodes = (int) uniqueNodes.size();
1100 Ok = cell->ChangeNodes( nodesPtr, nbNodes );
1103 updateInverseElements( element, nodesPtr, nbNodes, oldNodes );
1111 //=======================================================================
1112 //function : ChangeElementNodes
1114 //=======================================================================
1116 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1117 const SMDS_MeshNode * nodes[],
1120 // keep current nodes of element
1121 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1125 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1126 Ok = cell->ChangeNodes(nodes, nbnodes);
1131 updateInverseElements( element, nodes, nbnodes, oldNodes );
1136 //=======================================================================
1137 //function : updateInverseElements
1138 //purpose : update InverseElements when element changes node
1139 //=======================================================================
1141 void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement * element,
1142 const SMDS_MeshNode* const* nodes,
1144 std::set<const SMDS_MeshNode*>& oldNodes )
1146 if ( GetGrid()->HasLinks() ) // update InverseElements
1148 std::set<const SMDS_MeshNode*>::iterator it;
1150 // AddInverseElement to new nodes
1151 for ( int i = 0; i < nbnodes; i++ )
1153 it = oldNodes.find( nodes[i] );
1154 if ( it == oldNodes.end() )
1156 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( element );
1158 // remove from oldNodes a node that remains in elem
1159 oldNodes.erase( it );
1161 // RemoveInverseElement from the nodes removed from elem
1162 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1164 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1165 n->RemoveInverseElement( element );
1171 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1173 if (!node) return 0;
1174 const SMDS_Mesh0DElement* toReturn = NULL;
1175 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1176 while (it1->more() && (toReturn == NULL)) {
1177 const SMDS_MeshElement* e = it1->next();
1178 if (e->NbNodes() == 1) {
1179 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1185 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
1187 if (!node) return 0;
1188 const SMDS_BallElement* toReturn = NULL;
1189 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
1190 while (it1->more() && (toReturn == NULL)) {
1191 const SMDS_MeshElement* e = it1->next();
1192 if (e->GetGeomType() == SMDSGeom_BALL)
1193 toReturn = static_cast<const SMDS_BallElement*>(e);
1198 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1199 const SMDS_MeshNode * node2)
1201 if ( !node1 ) return 0;
1202 const SMDS_MeshEdge * toReturn=NULL;
1203 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1204 while(it1->more()) {
1205 const SMDS_MeshElement * e = it1->next();
1206 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1207 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1214 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(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_Edge);
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_MeshEdge *> (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)
1250 if ( !node1 ) return 0;
1251 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1252 while(it1->more()) {
1253 const SMDS_MeshElement * e = it1->next();
1254 if ( e->NbNodes() == 3 ) {
1255 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1256 while(it2->more()) {
1257 const SMDS_MeshElement* n = it2->next();
1267 return static_cast<const SMDS_MeshFace *> (e);
1273 //=======================================================================
1274 //function : FindFace
1276 //=======================================================================
1278 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1279 const SMDS_MeshNode *node2,
1280 const SMDS_MeshNode *node3,
1281 const SMDS_MeshNode *node4)
1283 if ( !node1 ) return 0;
1284 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1285 while(it1->more()) {
1286 const SMDS_MeshElement * e = it1->next();
1287 if ( e->NbNodes() == 4 ) {
1288 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1289 while(it2->more()) {
1290 const SMDS_MeshElement* n = it2->next();
1301 return static_cast<const SMDS_MeshFace *> (e);
1307 //=======================================================================
1308 //function : FindFace
1309 //purpose :quadratic triangle
1310 //=======================================================================
1312 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1313 const SMDS_MeshNode *node2,
1314 const SMDS_MeshNode *node3,
1315 const SMDS_MeshNode *node4,
1316 const SMDS_MeshNode *node5,
1317 const SMDS_MeshNode *node6)
1319 if ( !node1 ) return 0;
1320 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1321 while(it1->more()) {
1322 const SMDS_MeshElement * e = it1->next();
1323 if ( e->NbNodes() == 6 ) {
1324 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1325 while(it2->more()) {
1326 const SMDS_MeshElement* n = it2->next();
1339 return static_cast<const SMDS_MeshFace *> (e);
1346 //=======================================================================
1347 //function : FindFace
1348 //purpose : quadratic quadrangle
1349 //=======================================================================
1351 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1352 const SMDS_MeshNode *node2,
1353 const SMDS_MeshNode *node3,
1354 const SMDS_MeshNode *node4,
1355 const SMDS_MeshNode *node5,
1356 const SMDS_MeshNode *node6,
1357 const SMDS_MeshNode *node7,
1358 const SMDS_MeshNode *node8)
1360 if ( !node1 ) return 0;
1361 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1362 while(it1->more()) {
1363 const SMDS_MeshElement * e = it1->next();
1364 if ( e->NbNodes() == 8 ) {
1365 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1366 while(it2->more()) {
1367 const SMDS_MeshElement* n = it2->next();
1382 return static_cast<const SMDS_MeshFace *> (e);
1389 //=======================================================================
1390 //function : FindElement
1392 //=======================================================================
1394 const SMDS_MeshElement* SMDS_Mesh::FindElement(smIdType IDelem) const
1396 return myCellFactory->FindElement( IDelem );
1399 //=======================================================================
1400 //function : FindFace
1401 //purpose : find polygon
1402 //=======================================================================
1405 const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector<const SMDS_MeshNode *>& nodes)
1407 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1411 //================================================================================
1413 * \brief Return element based on all given nodes
1414 * \param nodes - node of element
1415 * \param type - type of element
1416 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1417 * \retval const SMDS_MeshElement* - found element or NULL
1419 //================================================================================
1421 const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector<const SMDS_MeshNode *>& nodes,
1422 const SMDSAbs_ElementType type,
1423 const bool noMedium)
1425 if ( nodes.size() > 0 && nodes[0] )
1427 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1430 const SMDS_MeshElement* e = itF->next();
1431 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1432 if ( nbNodesToCheck == (int)nodes.size() )
1434 for ( size_t i = 1; e && i < nodes.size(); ++i )
1436 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1437 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1448 //================================================================================
1450 * \brief Return elements including all given nodes
1451 * \param [in] nodes - nodes to find elements around
1452 * \param [out] foundElems - the found elements
1453 * \param [in] type - type of elements to find
1454 * \return int - a number of found elements
1456 //================================================================================
1458 int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
1459 std::vector<const SMDS_MeshElement *>& foundElems,
1460 const SMDSAbs_ElementType type)
1462 // chose a node with minimal number of inverse elements
1463 const SMDS_MeshNode* n0 = nodes[0];
1464 int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
1465 for ( size_t i = 1; i < nodes.size(); ++i )
1466 if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
1469 minNbInverse = n0->NbInverseElements( type );
1473 if ( n0 && minNbInverse > 0 )
1475 foundElems.reserve( minNbInverse );
1476 SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
1477 while ( eIt->more() )
1479 const SMDS_MeshElement* e = eIt->next();
1480 bool includeAll = true;
1481 for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
1482 if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
1485 foundElems.push_back( e );
1488 return foundElems.size();
1491 ///////////////////////////////////////////////////////////////////////////////
1492 /// Return the number of nodes
1493 ///////////////////////////////////////////////////////////////////////////////
1494 smIdType SMDS_Mesh::NbNodes() const
1496 return myInfo.NbNodes();
1499 ///////////////////////////////////////////////////////////////////////////////
1500 /// Return the number of elements
1501 ///////////////////////////////////////////////////////////////////////////////
1502 smIdType SMDS_Mesh::NbElements() const
1504 return myInfo.NbElements();
1506 ///////////////////////////////////////////////////////////////////////////////
1507 /// Return the number of 0D elements
1508 ///////////////////////////////////////////////////////////////////////////////
1509 smIdType SMDS_Mesh::Nb0DElements() const
1511 return myInfo.Nb0DElements();
1514 ///////////////////////////////////////////////////////////////////////////////
1515 /// Return the number of 0D elements
1516 ///////////////////////////////////////////////////////////////////////////////
1517 smIdType SMDS_Mesh::NbBalls() const
1519 return myInfo.NbBalls();
1522 ///////////////////////////////////////////////////////////////////////////////
1523 /// Return the number of edges (including construction edges)
1524 ///////////////////////////////////////////////////////////////////////////////
1525 smIdType SMDS_Mesh::NbEdges() const
1527 return myInfo.NbEdges();
1530 ///////////////////////////////////////////////////////////////////////////////
1531 /// Return the number of faces (including construction faces)
1532 ///////////////////////////////////////////////////////////////////////////////
1533 smIdType SMDS_Mesh::NbFaces() const
1535 return myInfo.NbFaces();
1538 ///////////////////////////////////////////////////////////////////////////////
1539 /// Return the number of volumes
1540 ///////////////////////////////////////////////////////////////////////////////
1541 smIdType SMDS_Mesh::NbVolumes() const
1543 return myInfo.NbVolumes();
1546 ///////////////////////////////////////////////////////////////////////////////
1547 /// Return the number of child mesh of this mesh.
1548 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
1549 ///////////////////////////////////////////////////////////////////////////////
1550 smIdType SMDS_Mesh::NbSubMesh() const
1552 return myChildren.size();
1555 ///////////////////////////////////////////////////////////////////////////////
1556 /// Destroy the mesh and all its elements
1557 /// All pointer on elements owned by this mesh become illegals.
1558 ///////////////////////////////////////////////////////////////////////////////
1559 SMDS_Mesh::~SMDS_Mesh()
1561 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1562 while(itc!=myChildren.end())
1568 delete myNodeFactory;
1569 delete myCellFactory;
1574 //================================================================================
1576 * \brief Clear all data
1578 //================================================================================
1580 void SMDS_Mesh::Clear()
1582 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
1583 for ( ; holder != myElemHolders.end(); ++holder )
1586 myNodeFactory->Clear();
1587 myCellFactory->Clear();
1589 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1590 while(itc!=myChildren.end())
1601 myGrid->Initialize();
1603 vtkPoints* points = vtkPoints::New();
1604 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
1605 // using double type for storing coordinates of nodes instead float.
1606 points->SetDataType(VTK_DOUBLE);
1607 points->SetNumberOfPoints( 0 );
1608 myGrid->SetPoints( points );
1610 myGrid->DeleteLinks();
1613 ///////////////////////////////////////////////////////////////////////////////
1614 /// Return an iterator on nodes of the current mesh factory
1615 ///////////////////////////////////////////////////////////////////////////////
1617 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1619 return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter );
1622 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
1624 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1625 return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
1629 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
1631 if ( type == SMDSEntity_Node )
1633 return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
1635 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1636 return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
1640 ///////////////////////////////////////////////////////////////////////////////
1641 /// Return an iterator on elements of the current mesh factory
1642 ///////////////////////////////////////////////////////////////////////////////
1643 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
1645 typedef SMDS_ElemIterator TIterator;
1649 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1652 return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1655 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1656 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
1659 return SMDS_ElemIteratorPtr();
1662 ///////////////////////////////////////////////////////////////////////////////
1663 ///Return an iterator on edges of the current mesh.
1664 ///////////////////////////////////////////////////////////////////////////////
1666 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1668 typedef SMDS_EdgeIterator TIterator;
1669 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges();
1670 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
1674 ///////////////////////////////////////////////////////////////////////////////
1675 ///Return an iterator on faces of the current mesh.
1676 ///////////////////////////////////////////////////////////////////////////////
1678 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1680 typedef SMDS_FaceIterator TIterator;
1681 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces();
1682 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
1686 ///////////////////////////////////////////////////////////////////////////////
1687 ///Return an iterator on volumes of the current mesh.
1688 ///////////////////////////////////////////////////////////////////////////////
1690 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1692 typedef SMDS_VolumeIterator TIterator;
1693 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes();
1695 myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
1699 SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID,
1700 size_t nbElemsToReturn,
1701 const SMDS_MeshNode* sm1stNode) const
1703 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
1706 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID,
1707 size_t nbElemsToReturn,
1708 const SMDS_MeshElement* sm1stElem) const
1710 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
1713 ///////////////////////////////////////////////////////////////////////////////
1714 /// Do intersection of sets (more than 2)
1715 ///////////////////////////////////////////////////////////////////////////////
1716 static std::set<const SMDS_MeshElement*> *
1717 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1719 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1720 std::set<const SMDS_MeshElement*>* rsetB;
1722 for(int i=0; i<numberOfSets-1; i++)
1724 rsetB = new std::set<const SMDS_MeshElement*>();
1725 set_intersection(rsetA->begin(), rsetA->end(),
1726 vs[i+1].begin(), vs[i+1].end(),
1727 inserter(*rsetB, rsetB->begin()));
1733 ///////////////////////////////////////////////////////////////////////////////
1734 /// Return the list of finite elements owning the given element: elements
1735 /// containing all the nodes of the given element, for instance faces and
1736 /// volumes containing a given edge.
1737 ///////////////////////////////////////////////////////////////////////////////
1738 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1740 int numberOfSets=element->NbNodes();
1741 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1743 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1746 while ( itNodes->more() )
1748 const SMDS_MeshNode * n = itNodes->next();
1749 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1750 initSet[i].insert( itFe->next() );
1753 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1758 ///////////////////////////////////////////////////////////////////////////////
1759 /// Return the std::list of nodes used only by the given elements
1760 ///////////////////////////////////////////////////////////////////////////////
1762 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1764 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1765 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1767 while( itElements != elements.end() )
1769 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1772 while( itNodes->more() )
1774 const SMDS_MeshNode * n = itNodes->next();
1775 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1776 std::set<const SMDS_MeshElement*> s;
1777 while ( itFe->more() )
1778 s.insert( itFe->next() );
1779 if ( s == elements ) toReturn->insert(n);
1785 ///////////////////////////////////////////////////////////////////////////////
1786 ///Find the children of an element that are made of given nodes
1787 ///@param setOfChildren The set in which matching children will be inserted
1788 ///@param element The element were to search matching children
1789 ///@param nodes The nodes that the children must have to be selected
1790 ///////////////////////////////////////////////////////////////////////////////
1791 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1792 const SMDS_MeshElement * element,
1793 std::set<const SMDS_MeshElement*>& nodes)
1795 switch(element->GetType())
1798 throw SALOME_Exception("Internal Error: This should not happen");
1800 case SMDSAbs_0DElement:
1807 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1810 const SMDS_MeshElement * e=itn->next();
1811 if(nodes.find(e)!=nodes.end())
1813 setOfChildren.insert(element);
1820 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1823 const SMDS_MeshElement * e=itn->next();
1824 if(nodes.find(e)!=nodes.end())
1826 setOfChildren.insert(element);
1831 case SMDSAbs_Volume:
1832 case SMDSAbs_NbElementTypes:
1833 case SMDSAbs_All: break;
1837 ///////////////////////////////////////////////////////////////////////////////
1838 ///@param elem The element to delete
1839 ///@param removenodes if true remaining nodes will be removed
1840 ///////////////////////////////////////////////////////////////////////////////
1841 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1842 const bool removenodes)
1844 std::vector<const SMDS_MeshElement *> removedElems;
1845 std::vector<const SMDS_MeshElement *> removedNodes;
1846 RemoveElement( elem, removedElems, removedNodes, removenodes );
1849 ///////////////////////////////////////////////////////////////////////////////
1850 ///@param elem The element to delete
1851 ///@param removedElems to be filled with all removed elements
1852 ///@param removedNodes to be filled with all removed nodes
1853 ///@param removenodes if true remaining nodes will be removed
1854 ///////////////////////////////////////////////////////////////////////////////
1855 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1856 std::vector<const SMDS_MeshElement *>& removedElems,
1857 std::vector<const SMDS_MeshElement *>& removedNodes,
1860 // get finite elements built on elem
1861 std::set<const SMDS_MeshElement*> * s1;
1862 if ( (elem->GetType() == SMDSAbs_0DElement)
1863 || (elem->GetType() == SMDSAbs_Ball)
1864 || (elem->GetType() == SMDSAbs_Edge)
1865 || (elem->GetType() == SMDSAbs_Face)
1866 || (elem->GetType() == SMDSAbs_Volume) )
1868 s1 = new std::set<const SMDS_MeshElement*> ();
1872 s1 = getFinitElements(elem);
1874 // get exclusive nodes (which would become free afterwards)
1875 std::set<const SMDS_MeshElement*> * s2;
1876 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1878 // do not remove nodes except elem
1879 s2 = new std::set<const SMDS_MeshElement*> ();
1884 s2 = getExclusiveNodes(*s1);
1886 // form the set of finite and construction elements to remove
1887 std::set<const SMDS_MeshElement*> s3;
1888 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1889 while (it != s1->end())
1891 addChildrenWithNodes(s3, *it, *s2);
1895 if (elem->GetType() != SMDSAbs_Node)
1898 // remove finite and construction elements
1899 for( it = s3.begin();it != s3.end(); ++it )
1901 // Remove element from <InverseElements> of its nodes
1902 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1905 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1906 n->RemoveInverseElement((*it));
1909 vtkIdType vtkid = (*it)->GetVtkID();
1911 switch ((*it)->GetType()) {
1913 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1915 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1916 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1917 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1918 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1919 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1920 case SMDSAbs_All: // avoid compilation warning
1921 case SMDSAbs_NbElementTypes: break;
1923 removedElems.push_back( *it);
1925 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1929 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1933 // remove exclusive (free) nodes
1936 for ( it = s2->begin(); it != s2->end(); ++it )
1939 myNodeFactory->Free( (*it) );
1940 removedNodes.push_back((*it));
1949 ///////////////////////////////////////////////////////////////////////////////
1950 ///@param elem The element to delete
1951 ///////////////////////////////////////////////////////////////////////////////
1952 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1954 const vtkIdType vtkId = elem->GetVtkID();
1955 SMDSAbs_ElementType aType = elem->GetType();
1956 if ( aType == SMDSAbs_Node )
1958 // only free node can be removed by this method
1959 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1960 if ( n->NbInverseElements() == 0 ) { // free node
1962 myNodeFactory->Free( n );
1966 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1971 // Remove element from <InverseElements> of its nodes
1972 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1973 while (itn->more()) {
1974 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1975 n->RemoveInverseElement(elem);
1978 // in meshes without descendants elements are always free
1980 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1981 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1982 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1983 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1984 case SMDSAbs_Ball: myInfo.remove(elem); break;
1987 myCellFactory->Free( elem );
1989 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1993 //=======================================================================
1995 * Checks if the element is present in mesh.
1997 //=======================================================================
1999 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2001 if ( !elem || elem->IsNull() )
2004 if ( elem->GetType() == SMDSAbs_Node )
2005 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
2007 return ( elem == myCellFactory->FindElement( elem->GetID() ));
2010 //=======================================================================
2011 //function : MaxNodeID
2013 //=======================================================================
2015 smIdType SMDS_Mesh::MaxNodeID() const
2017 return myNodeFactory->GetMaxID();
2020 //=======================================================================
2021 //function : MinNodeID
2023 //=======================================================================
2025 smIdType SMDS_Mesh::MinNodeID() const
2027 return myNodeFactory->GetMinID();
2030 //=======================================================================
2031 //function : MaxElementID
2033 //=======================================================================
2035 smIdType SMDS_Mesh::MaxElementID() const
2037 return myCellFactory->GetMaxID();
2040 //=======================================================================
2041 //function : MinElementID
2043 //=======================================================================
2045 smIdType SMDS_Mesh::MinElementID() const
2047 return myCellFactory->GetMinID();
2050 //=======================================================================
2051 //function : Renumber
2052 //purpose : Renumber all nodes or elements.
2053 //=======================================================================
2055 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2057 // if ( deltaID == 0 )
2062 //=======================================================================
2063 //function : GetElementType
2064 //purpose : Return type of element or node with id
2065 //=======================================================================
2067 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const smIdType id, const bool iselem ) const
2069 const SMDS_MeshElement* elem = 0;
2071 elem = myCellFactory->FindElement( id );
2073 elem = myNodeFactory->FindElement( id );
2075 return elem ? elem->GetType() : SMDSAbs_All;
2080 //********************************************************************
2081 //********************************************************************
2082 //******** *********
2083 //***** Methods for addition of quadratic elements ******
2084 //******** *********
2085 //********************************************************************
2086 //********************************************************************
2088 //=======================================================================
2089 //function : AddEdgeWithID
2091 //=======================================================================
2092 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID)
2094 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2095 myNodeFactory->FindNode(n2),
2096 myNodeFactory->FindNode(n12),
2100 //=======================================================================
2101 //function : AddEdge
2103 //=======================================================================
2104 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2105 const SMDS_MeshNode* n2,
2106 const SMDS_MeshNode* n12)
2108 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2111 //=======================================================================
2112 //function : AddEdgeWithID
2114 //=======================================================================
2115 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2116 const SMDS_MeshNode * n2,
2117 const SMDS_MeshNode * n12,
2120 if ( !n1 || !n2 || !n12 ) return 0;
2122 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2124 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2125 myInfo.myNbQuadEdges++;
2126 return static_cast<SMDS_MeshEdge*>( cell );
2132 //=======================================================================
2133 //function : AddFace
2135 //=======================================================================
2136 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2137 const SMDS_MeshNode * n2,
2138 const SMDS_MeshNode * n3,
2139 const SMDS_MeshNode * n12,
2140 const SMDS_MeshNode * n23,
2141 const SMDS_MeshNode * n31)
2143 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2144 myCellFactory->GetFreeID());
2147 //=======================================================================
2148 //function : AddFaceWithID
2150 //=======================================================================
2151 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2152 smIdType n12,smIdType n23,smIdType n31, smIdType ID)
2154 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2155 myNodeFactory->FindNode(n2) ,
2156 myNodeFactory->FindNode(n3) ,
2157 myNodeFactory->FindNode(n12),
2158 myNodeFactory->FindNode(n23),
2159 myNodeFactory->FindNode(n31),
2163 //=======================================================================
2164 //function : AddFaceWithID
2166 //=======================================================================
2167 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2168 const SMDS_MeshNode * n2,
2169 const SMDS_MeshNode * n3,
2170 const SMDS_MeshNode * n12,
2171 const SMDS_MeshNode * n23,
2172 const SMDS_MeshNode * n31,
2175 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2176 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2178 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2180 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2181 myInfo.myNbQuadTriangles++;
2182 return static_cast<SMDS_MeshFace*>( cell );
2188 //=======================================================================
2189 //function : AddFace
2191 //=======================================================================
2192 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2193 const SMDS_MeshNode * n2,
2194 const SMDS_MeshNode * n3,
2195 const SMDS_MeshNode * n12,
2196 const SMDS_MeshNode * n23,
2197 const SMDS_MeshNode * n31,
2198 const SMDS_MeshNode * nCenter)
2200 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2201 myCellFactory->GetFreeID());
2204 //=======================================================================
2205 //function : AddFaceWithID
2207 //=======================================================================
2208 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2209 smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID)
2211 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2212 myNodeFactory->FindNode(n2) ,
2213 myNodeFactory->FindNode(n3) ,
2214 myNodeFactory->FindNode(n12),
2215 myNodeFactory->FindNode(n23),
2216 myNodeFactory->FindNode(n31),
2217 myNodeFactory->FindNode(nCenter),
2221 //=======================================================================
2222 //function : AddFaceWithID
2224 //=======================================================================
2225 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2226 const SMDS_MeshNode * n2,
2227 const SMDS_MeshNode * n3,
2228 const SMDS_MeshNode * n12,
2229 const SMDS_MeshNode * n23,
2230 const SMDS_MeshNode * n31,
2231 const SMDS_MeshNode * nCenter,
2234 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2235 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2237 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2239 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2240 myInfo.myNbBiQuadTriangles++;
2241 return static_cast<SMDS_MeshFace*>( cell );
2247 //=======================================================================
2248 //function : AddFace
2250 //=======================================================================
2251 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2252 const SMDS_MeshNode * n2,
2253 const SMDS_MeshNode * n3,
2254 const SMDS_MeshNode * n4,
2255 const SMDS_MeshNode * n12,
2256 const SMDS_MeshNode * n23,
2257 const SMDS_MeshNode * n34,
2258 const SMDS_MeshNode * n41)
2260 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2261 myCellFactory->GetFreeID());
2264 //=======================================================================
2265 //function : AddFaceWithID
2267 //=======================================================================
2268 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2269 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID)
2271 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2272 myNodeFactory->FindNode(n2) ,
2273 myNodeFactory->FindNode(n3) ,
2274 myNodeFactory->FindNode(n4) ,
2275 myNodeFactory->FindNode(n12),
2276 myNodeFactory->FindNode(n23),
2277 myNodeFactory->FindNode(n34),
2278 myNodeFactory->FindNode(n41),
2282 //=======================================================================
2283 //function : AddFaceWithID
2285 //=======================================================================
2286 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2287 const SMDS_MeshNode * n2,
2288 const SMDS_MeshNode * n3,
2289 const SMDS_MeshNode * n4,
2290 const SMDS_MeshNode * n12,
2291 const SMDS_MeshNode * n23,
2292 const SMDS_MeshNode * n34,
2293 const SMDS_MeshNode * n41,
2296 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2297 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2299 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2301 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2302 myInfo.myNbQuadQuadrangles++;
2303 return static_cast<SMDS_MeshFace*>( cell );
2308 //=======================================================================
2309 //function : AddFace
2311 //=======================================================================
2312 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2313 const SMDS_MeshNode * n2,
2314 const SMDS_MeshNode * n3,
2315 const SMDS_MeshNode * n4,
2316 const SMDS_MeshNode * n12,
2317 const SMDS_MeshNode * n23,
2318 const SMDS_MeshNode * n34,
2319 const SMDS_MeshNode * n41,
2320 const SMDS_MeshNode * nCenter)
2322 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2323 myCellFactory->GetFreeID());
2326 //=======================================================================
2327 //function : AddFaceWithID
2329 //=======================================================================
2330 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2331 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType nCenter, smIdType ID)
2333 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2334 myNodeFactory->FindNode(n2) ,
2335 myNodeFactory->FindNode(n3) ,
2336 myNodeFactory->FindNode(n4) ,
2337 myNodeFactory->FindNode(n12),
2338 myNodeFactory->FindNode(n23),
2339 myNodeFactory->FindNode(n34),
2340 myNodeFactory->FindNode(n41),
2341 myNodeFactory->FindNode(nCenter),
2345 //=======================================================================
2346 //function : AddFaceWithID
2348 //=======================================================================
2349 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2350 const SMDS_MeshNode * n2,
2351 const SMDS_MeshNode * n3,
2352 const SMDS_MeshNode * n4,
2353 const SMDS_MeshNode * n12,
2354 const SMDS_MeshNode * n23,
2355 const SMDS_MeshNode * n34,
2356 const SMDS_MeshNode * n41,
2357 const SMDS_MeshNode * nCenter,
2360 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2361 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2363 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2365 cell->init( SMDSEntity_BiQuad_Quadrangle,
2366 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2367 myInfo.myNbBiQuadQuadrangles++;
2368 return static_cast<SMDS_MeshFace*>( cell );
2374 //=======================================================================
2375 //function : AddVolume
2377 //=======================================================================
2378 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2379 const SMDS_MeshNode * n2,
2380 const SMDS_MeshNode * n3,
2381 const SMDS_MeshNode * n4,
2382 const SMDS_MeshNode * n12,
2383 const SMDS_MeshNode * n23,
2384 const SMDS_MeshNode * n31,
2385 const SMDS_MeshNode * n14,
2386 const SMDS_MeshNode * n24,
2387 const SMDS_MeshNode * n34)
2389 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2390 n31, n14, n24, n34, myCellFactory->GetFreeID());
2393 //=======================================================================
2394 //function : AddVolumeWithID
2396 //=======================================================================
2397 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2398 smIdType n12,smIdType n23,smIdType n31,
2399 smIdType n14,smIdType n24,smIdType n34, smIdType ID)
2401 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2402 myNodeFactory->FindNode(n2) ,
2403 myNodeFactory->FindNode(n3) ,
2404 myNodeFactory->FindNode(n4) ,
2405 myNodeFactory->FindNode(n12),
2406 myNodeFactory->FindNode(n23),
2407 myNodeFactory->FindNode(n31),
2408 myNodeFactory->FindNode(n14),
2409 myNodeFactory->FindNode(n24),
2410 myNodeFactory->FindNode(n34),
2414 //=======================================================================
2415 //function : AddVolumeWithID
2416 //purpose : 2d order tetrahedron of 10 nodes
2417 //=======================================================================
2418 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2419 const SMDS_MeshNode * n2,
2420 const SMDS_MeshNode * n3,
2421 const SMDS_MeshNode * n4,
2422 const SMDS_MeshNode * n12,
2423 const SMDS_MeshNode * n23,
2424 const SMDS_MeshNode * n31,
2425 const SMDS_MeshNode * n14,
2426 const SMDS_MeshNode * n24,
2427 const SMDS_MeshNode * n34,
2430 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2432 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2434 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2436 cell->init( SMDSEntity_Quad_Tetra,
2437 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2438 myInfo.myNbQuadTetras++;
2439 return static_cast<SMDS_MeshVolume*>( cell );
2445 //=======================================================================
2446 //function : AddVolume
2448 //=======================================================================
2449 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2450 const SMDS_MeshNode * n2,
2451 const SMDS_MeshNode * n3,
2452 const SMDS_MeshNode * n4,
2453 const SMDS_MeshNode * n5,
2454 const SMDS_MeshNode * n12,
2455 const SMDS_MeshNode * n23,
2456 const SMDS_MeshNode * n34,
2457 const SMDS_MeshNode * n41,
2458 const SMDS_MeshNode * n15,
2459 const SMDS_MeshNode * n25,
2460 const SMDS_MeshNode * n35,
2461 const SMDS_MeshNode * n45)
2463 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2464 n15, n25, n35, n45, myCellFactory->GetFreeID());
2467 //=======================================================================
2468 //function : AddVolumeWithID
2470 //=======================================================================
2471 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5,
2472 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2473 smIdType n15,smIdType n25,smIdType n35,smIdType n45, smIdType ID)
2475 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2476 myNodeFactory->FindNode(n2) ,
2477 myNodeFactory->FindNode(n3) ,
2478 myNodeFactory->FindNode(n4) ,
2479 myNodeFactory->FindNode(n5) ,
2480 myNodeFactory->FindNode(n12),
2481 myNodeFactory->FindNode(n23),
2482 myNodeFactory->FindNode(n34),
2483 myNodeFactory->FindNode(n41),
2484 myNodeFactory->FindNode(n15),
2485 myNodeFactory->FindNode(n25),
2486 myNodeFactory->FindNode(n35),
2487 myNodeFactory->FindNode(n45),
2491 //=======================================================================
2492 //function : AddVolumeWithID
2493 //purpose : 2d order pyramid of 13 nodes
2494 //=======================================================================
2495 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2496 const SMDS_MeshNode * n2,
2497 const SMDS_MeshNode * n3,
2498 const SMDS_MeshNode * n4,
2499 const SMDS_MeshNode * n5,
2500 const SMDS_MeshNode * n12,
2501 const SMDS_MeshNode * n23,
2502 const SMDS_MeshNode * n34,
2503 const SMDS_MeshNode * n41,
2504 const SMDS_MeshNode * n15,
2505 const SMDS_MeshNode * n25,
2506 const SMDS_MeshNode * n35,
2507 const SMDS_MeshNode * n45,
2510 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2511 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2513 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2515 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2517 cell->init( SMDSEntity_Quad_Pyramid,
2518 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2519 myInfo.myNbQuadPyramids++;
2520 return static_cast<SMDS_MeshVolume*>( cell );
2526 //=======================================================================
2527 //function : AddVolume
2528 //purpose : 2d order Pentahedron (prism) with 15 nodes
2529 //=======================================================================
2530 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2531 const SMDS_MeshNode * n2,
2532 const SMDS_MeshNode * n3,
2533 const SMDS_MeshNode * n4,
2534 const SMDS_MeshNode * n5,
2535 const SMDS_MeshNode * n6,
2536 const SMDS_MeshNode * n12,
2537 const SMDS_MeshNode * n23,
2538 const SMDS_MeshNode * n31,
2539 const SMDS_MeshNode * n45,
2540 const SMDS_MeshNode * n56,
2541 const SMDS_MeshNode * n64,
2542 const SMDS_MeshNode * n14,
2543 const SMDS_MeshNode * n25,
2544 const SMDS_MeshNode * n36)
2546 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2547 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2550 //=======================================================================
2551 //function : AddVolumeWithID
2552 //purpose : 2d order Pentahedron (prism) with 15 nodes
2553 //=======================================================================
2554 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2555 smIdType n4, smIdType n5, smIdType n6,
2556 smIdType n12,smIdType n23,smIdType n31,
2557 smIdType n45,smIdType n56,smIdType n64,
2558 smIdType n14,smIdType n25,smIdType n36, smIdType ID)
2560 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2561 myNodeFactory->FindNode(n2) ,
2562 myNodeFactory->FindNode(n3) ,
2563 myNodeFactory->FindNode(n4) ,
2564 myNodeFactory->FindNode(n5) ,
2565 myNodeFactory->FindNode(n6) ,
2566 myNodeFactory->FindNode(n12),
2567 myNodeFactory->FindNode(n23),
2568 myNodeFactory->FindNode(n31),
2569 myNodeFactory->FindNode(n45),
2570 myNodeFactory->FindNode(n56),
2571 myNodeFactory->FindNode(n64),
2572 myNodeFactory->FindNode(n14),
2573 myNodeFactory->FindNode(n25),
2574 myNodeFactory->FindNode(n36),
2578 //=======================================================================
2579 //function : AddVolumeWithID
2580 //purpose : 2d order Pentahedron (prism) with 15 nodes
2581 //=======================================================================
2582 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2583 const SMDS_MeshNode * n2,
2584 const SMDS_MeshNode * n3,
2585 const SMDS_MeshNode * n4,
2586 const SMDS_MeshNode * n5,
2587 const SMDS_MeshNode * n6,
2588 const SMDS_MeshNode * n12,
2589 const SMDS_MeshNode * n23,
2590 const SMDS_MeshNode * n31,
2591 const SMDS_MeshNode * n45,
2592 const SMDS_MeshNode * n56,
2593 const SMDS_MeshNode * n64,
2594 const SMDS_MeshNode * n14,
2595 const SMDS_MeshNode * n25,
2596 const SMDS_MeshNode * n36,
2599 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2600 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2602 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2604 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2606 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2607 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2608 myInfo.myNbQuadPrisms++;
2609 return static_cast<SMDS_MeshVolume*>( cell );
2614 //=======================================================================
2615 //function : AddVolume
2616 //purpose : 2d order Pentahedron (prism) with 18 nodes
2617 //=======================================================================
2618 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2619 const SMDS_MeshNode * n2,
2620 const SMDS_MeshNode * n3,
2621 const SMDS_MeshNode * n4,
2622 const SMDS_MeshNode * n5,
2623 const SMDS_MeshNode * n6,
2624 const SMDS_MeshNode * n12,
2625 const SMDS_MeshNode * n23,
2626 const SMDS_MeshNode * n31,
2627 const SMDS_MeshNode * n45,
2628 const SMDS_MeshNode * n56,
2629 const SMDS_MeshNode * n64,
2630 const SMDS_MeshNode * n14,
2631 const SMDS_MeshNode * n25,
2632 const SMDS_MeshNode * n36,
2633 const SMDS_MeshNode * n1245,
2634 const SMDS_MeshNode * n2356,
2635 const SMDS_MeshNode * n1346)
2637 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2638 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2639 myCellFactory->GetFreeID());
2642 //=======================================================================
2643 //function : AddVolumeWithID
2644 //purpose : 2d order Pentahedron (prism) with 18 nodes
2645 //=======================================================================
2646 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2647 smIdType n4, smIdType n5, smIdType n6,
2648 smIdType n12,smIdType n23,smIdType n31,
2649 smIdType n45,smIdType n56,smIdType n64,
2650 smIdType n14,smIdType n25,smIdType n36,
2651 smIdType n1245, smIdType n2356, smIdType n1346, smIdType ID)
2653 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2654 myNodeFactory->FindNode(n2) ,
2655 myNodeFactory->FindNode(n3) ,
2656 myNodeFactory->FindNode(n4) ,
2657 myNodeFactory->FindNode(n5) ,
2658 myNodeFactory->FindNode(n6) ,
2659 myNodeFactory->FindNode(n12),
2660 myNodeFactory->FindNode(n23),
2661 myNodeFactory->FindNode(n31),
2662 myNodeFactory->FindNode(n45),
2663 myNodeFactory->FindNode(n56),
2664 myNodeFactory->FindNode(n64),
2665 myNodeFactory->FindNode(n14),
2666 myNodeFactory->FindNode(n25),
2667 myNodeFactory->FindNode(n36),
2668 myNodeFactory->FindNode(n1245),
2669 myNodeFactory->FindNode(n2356),
2670 myNodeFactory->FindNode(n1346),
2674 //=======================================================================
2675 //function : AddVolumeWithID
2676 //purpose : 2d order Pentahedron (prism) with 18 nodes
2677 //=======================================================================
2678 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2679 const SMDS_MeshNode * n2,
2680 const SMDS_MeshNode * n3,
2681 const SMDS_MeshNode * n4,
2682 const SMDS_MeshNode * n5,
2683 const SMDS_MeshNode * n6,
2684 const SMDS_MeshNode * n12,
2685 const SMDS_MeshNode * n23,
2686 const SMDS_MeshNode * n31,
2687 const SMDS_MeshNode * n45,
2688 const SMDS_MeshNode * n56,
2689 const SMDS_MeshNode * n64,
2690 const SMDS_MeshNode * n14,
2691 const SMDS_MeshNode * n25,
2692 const SMDS_MeshNode * n36,
2693 const SMDS_MeshNode * n1245,
2694 const SMDS_MeshNode * n2356,
2695 const SMDS_MeshNode * n1346,
2698 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2699 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2700 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2702 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2704 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2706 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2707 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2708 myInfo.myNbBiQuadPrisms++;
2709 return static_cast<SMDS_MeshVolume*>( cell );
2715 //=======================================================================
2716 //function : AddVolume
2718 //=======================================================================
2719 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2720 const SMDS_MeshNode * n2,
2721 const SMDS_MeshNode * n3,
2722 const SMDS_MeshNode * n4,
2723 const SMDS_MeshNode * n5,
2724 const SMDS_MeshNode * n6,
2725 const SMDS_MeshNode * n7,
2726 const SMDS_MeshNode * n8,
2727 const SMDS_MeshNode * n12,
2728 const SMDS_MeshNode * n23,
2729 const SMDS_MeshNode * n34,
2730 const SMDS_MeshNode * n41,
2731 const SMDS_MeshNode * n56,
2732 const SMDS_MeshNode * n67,
2733 const SMDS_MeshNode * n78,
2734 const SMDS_MeshNode * n85,
2735 const SMDS_MeshNode * n15,
2736 const SMDS_MeshNode * n26,
2737 const SMDS_MeshNode * n37,
2738 const SMDS_MeshNode * n48)
2740 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2741 n56, n67, n78, n85, n15, n26, n37, n48,
2742 myCellFactory->GetFreeID());
2745 //=======================================================================
2746 //function : AddVolumeWithID
2748 //=======================================================================
2749 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2750 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2751 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2752 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2753 smIdType n15,smIdType n26,smIdType n37,smIdType n48, smIdType ID)
2755 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2756 myNodeFactory->FindNode(n2),
2757 myNodeFactory->FindNode(n3),
2758 myNodeFactory->FindNode(n4),
2759 myNodeFactory->FindNode(n5),
2760 myNodeFactory->FindNode(n6),
2761 myNodeFactory->FindNode(n7),
2762 myNodeFactory->FindNode(n8),
2763 myNodeFactory->FindNode(n12),
2764 myNodeFactory->FindNode(n23),
2765 myNodeFactory->FindNode(n34),
2766 myNodeFactory->FindNode(n41),
2767 myNodeFactory->FindNode(n56),
2768 myNodeFactory->FindNode(n67),
2769 myNodeFactory->FindNode(n78),
2770 myNodeFactory->FindNode(n85),
2771 myNodeFactory->FindNode(n15),
2772 myNodeFactory->FindNode(n26),
2773 myNodeFactory->FindNode(n37),
2774 myNodeFactory->FindNode(n48),
2778 //=======================================================================
2779 //function : AddVolumeWithID
2780 //purpose : 2d order Hexahedrons with 20 nodes
2781 //=======================================================================
2782 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2783 const SMDS_MeshNode * n2,
2784 const SMDS_MeshNode * n3,
2785 const SMDS_MeshNode * n4,
2786 const SMDS_MeshNode * n5,
2787 const SMDS_MeshNode * n6,
2788 const SMDS_MeshNode * n7,
2789 const SMDS_MeshNode * n8,
2790 const SMDS_MeshNode * n12,
2791 const SMDS_MeshNode * n23,
2792 const SMDS_MeshNode * n34,
2793 const SMDS_MeshNode * n41,
2794 const SMDS_MeshNode * n56,
2795 const SMDS_MeshNode * n67,
2796 const SMDS_MeshNode * n78,
2797 const SMDS_MeshNode * n85,
2798 const SMDS_MeshNode * n15,
2799 const SMDS_MeshNode * n26,
2800 const SMDS_MeshNode * n37,
2801 const SMDS_MeshNode * n48,
2804 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2805 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2807 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2809 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2811 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2812 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2813 myInfo.myNbQuadHexas++;
2814 return static_cast<SMDS_MeshVolume*>( cell );
2819 //=======================================================================
2820 //function : AddVolume
2822 //=======================================================================
2823 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2824 const SMDS_MeshNode * n2,
2825 const SMDS_MeshNode * n3,
2826 const SMDS_MeshNode * n4,
2827 const SMDS_MeshNode * n5,
2828 const SMDS_MeshNode * n6,
2829 const SMDS_MeshNode * n7,
2830 const SMDS_MeshNode * n8,
2831 const SMDS_MeshNode * n12,
2832 const SMDS_MeshNode * n23,
2833 const SMDS_MeshNode * n34,
2834 const SMDS_MeshNode * n41,
2835 const SMDS_MeshNode * n56,
2836 const SMDS_MeshNode * n67,
2837 const SMDS_MeshNode * n78,
2838 const SMDS_MeshNode * n85,
2839 const SMDS_MeshNode * n15,
2840 const SMDS_MeshNode * n26,
2841 const SMDS_MeshNode * n37,
2842 const SMDS_MeshNode * n48,
2843 const SMDS_MeshNode * n1234,
2844 const SMDS_MeshNode * n1256,
2845 const SMDS_MeshNode * n2367,
2846 const SMDS_MeshNode * n3478,
2847 const SMDS_MeshNode * n1458,
2848 const SMDS_MeshNode * n5678,
2849 const SMDS_MeshNode * nCenter)
2851 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2852 n56, n67, n78, n85, n15, n26, n37, n48,
2853 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2854 myCellFactory->GetFreeID());
2857 //=======================================================================
2858 //function : AddVolumeWithID
2860 //=======================================================================
2861 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2862 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2863 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2864 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2865 smIdType n15,smIdType n26,smIdType n37,smIdType n48,
2866 smIdType n1234,smIdType n1256,smIdType n2367,smIdType n3478,
2867 smIdType n1458,smIdType n5678,smIdType nCenter, smIdType ID)
2869 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2870 myNodeFactory->FindNode(n2),
2871 myNodeFactory->FindNode(n3),
2872 myNodeFactory->FindNode(n4),
2873 myNodeFactory->FindNode(n5),
2874 myNodeFactory->FindNode(n6),
2875 myNodeFactory->FindNode(n7),
2876 myNodeFactory->FindNode(n8),
2877 myNodeFactory->FindNode(n12),
2878 myNodeFactory->FindNode(n23),
2879 myNodeFactory->FindNode(n34),
2880 myNodeFactory->FindNode(n41),
2881 myNodeFactory->FindNode(n56),
2882 myNodeFactory->FindNode(n67),
2883 myNodeFactory->FindNode(n78),
2884 myNodeFactory->FindNode(n85),
2885 myNodeFactory->FindNode(n15),
2886 myNodeFactory->FindNode(n26),
2887 myNodeFactory->FindNode(n37),
2888 myNodeFactory->FindNode(n48),
2889 myNodeFactory->FindNode(n1234),
2890 myNodeFactory->FindNode(n1256),
2891 myNodeFactory->FindNode(n2367),
2892 myNodeFactory->FindNode(n3478),
2893 myNodeFactory->FindNode(n1458),
2894 myNodeFactory->FindNode(n5678),
2895 myNodeFactory->FindNode(nCenter),
2899 //=======================================================================
2900 //function : AddVolumeWithID
2901 //purpose : 2d order Hexahedrons with 27 nodes
2902 //=======================================================================
2903 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2904 const SMDS_MeshNode * n2,
2905 const SMDS_MeshNode * n3,
2906 const SMDS_MeshNode * n4,
2907 const SMDS_MeshNode * n5,
2908 const SMDS_MeshNode * n6,
2909 const SMDS_MeshNode * n7,
2910 const SMDS_MeshNode * n8,
2911 const SMDS_MeshNode * n12,
2912 const SMDS_MeshNode * n23,
2913 const SMDS_MeshNode * n34,
2914 const SMDS_MeshNode * n41,
2915 const SMDS_MeshNode * n56,
2916 const SMDS_MeshNode * n67,
2917 const SMDS_MeshNode * n78,
2918 const SMDS_MeshNode * n85,
2919 const SMDS_MeshNode * n15,
2920 const SMDS_MeshNode * n26,
2921 const SMDS_MeshNode * n37,
2922 const SMDS_MeshNode * n48,
2923 const SMDS_MeshNode * n1234,
2924 const SMDS_MeshNode * n1256,
2925 const SMDS_MeshNode * n2367,
2926 const SMDS_MeshNode * n3478,
2927 const SMDS_MeshNode * n1458,
2928 const SMDS_MeshNode * n5678,
2929 const SMDS_MeshNode * nCenter,
2932 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2933 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2934 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2936 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2938 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2940 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2941 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2942 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2943 myInfo.myNbTriQuadHexas++;
2944 return static_cast<SMDS_MeshVolume*>( cell );
2949 void SMDS_Mesh::dumpGrid(std::string ficdump)
2951 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2952 // aWriter->SetFileName(ficdump.c_str());
2953 // aWriter->SetInput(myGrid);
2954 // if(myGrid->GetNumberOfCells())
2956 // aWriter->Write();
2958 // aWriter->Delete();
2959 ficdump = ficdump + "_connectivity";
2960 std::ofstream ficcon(ficdump.c_str(), ios::out);
2961 int nbPoints = myGrid->GetNumberOfPoints();
2962 ficcon << "-------------------------------- points " << nbPoints << endl;
2963 for (int i=0; i<nbPoints; i++)
2965 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2967 int nbCells = myGrid->GetNumberOfCells();
2968 ficcon << "-------------------------------- cells " << nbCells << endl;
2969 for (vtkIdType i=0; i<nbCells; i++)
2971 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2972 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2973 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2974 for (int j=0; j<nbptcell; j++)
2976 ficcon << " " << listid->GetId(j);
2980 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2981 vtkCellLinks *links = myGrid->GetLinks();
2982 for (int i=0; i<nbPoints; i++)
2984 int ncells = links->GetNcells(i);
2985 vtkIdType *cells = links->GetCells(i);
2986 ficcon << i << " - " << ncells << " -";
2987 for (int j=0; j<ncells; j++)
2989 ficcon << " " << cells[j];
2997 void SMDS_Mesh::CompactMesh()
2999 this->myCompactTime = this->myModifTime;
3001 bool idsChange = HasNumerationHoles();
3004 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
3005 for ( ; holder != myElemHolders.end(); ++holder )
3006 (*holder)->beforeCompacting();
3008 smIdType oldCellSize = myCellFactory->GetMaxID();
3010 // remove "holes" in SMDS numeration
3011 std::vector<smIdType> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
3012 myNodeFactory->Compact( idNodesOldToNew );
3013 myCellFactory->Compact( idCellsNewToOld );
3015 // make VTK IDs correspond to SMDS IDs
3016 smIdType newNodeSize = myNodeFactory->NbUsedElements();
3017 smIdType newCellSize = myCellFactory->NbUsedElements();
3018 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
3020 if ( idsChange && !myElemHolders.empty() )
3022 // idCellsNewToOld -> idCellsOldToNew
3023 idCellsOldToNew.resize( oldCellSize, oldCellSize );
3024 for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
3026 if ( idCellsNewToOld[ iNew ] >= (smIdType) idCellsOldToNew.size() )
3027 idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
3028 idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
3032 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
3033 for ( ; holder != myElemHolders.end(); ++holder )
3035 (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
3037 (*holder)->compact();
3042 smIdType SMDS_Mesh::FromVtkToSmds( vtkIdType vtkid ) const
3044 return myCellFactory->FromVtkToSmds( vtkid );
3047 double SMDS_Mesh::getMaxDim()
3049 double dmax = 1.e-3;
3050 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
3051 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
3052 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
3056 //! modification that needs compact structure and redraw
3057 void SMDS_Mesh::Modified()
3059 if (this->myModified)
3062 this->myModifTime++;
3067 //! get last modification timeStamp
3068 vtkMTimeType SMDS_Mesh::GetMTime() const
3070 return this->myModifTime;
3073 bool SMDS_Mesh::IsCompacted()
3075 return ( this->myCompactTime == this->myModifTime );
3078 //! are there holes in elements or nodes numeration
3079 bool SMDS_Mesh::HasNumerationHoles()
3081 return ( myNodeFactory->CompactChangePointers() ||
3082 myCellFactory->CompactChangePointers() );
3085 void SMDS_Mesh::setNbShapes( size_t nbShapes )
3087 myNodeFactory->SetNbShapes( nbShapes );