1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "SMDS_Mesh.hxx"
31 #include "SMDS_ElementFactory.hxx"
32 #include "SMDS_ElementHolder.hxx"
33 #include "SMDS_SetIterator.hxx"
34 #include "SMDS_SpacePosition.hxx"
35 #include "SMDS_UnstructuredGrid.hxx"
37 #include <utilities.h>
39 #include <vtkUnstructuredGrid.h>
40 //#include <vtkUnstructuredGridWriter.h>
42 #include <vtkUnsignedCharArray.h>
43 #include <vtkCellLinks.h>
44 #include <vtkIdList.h>
50 //#include <boost/make_shared.hpp>
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 : ChangePolyhedronNodes
1058 //=======================================================================
1060 bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element,
1061 const std::vector<const SMDS_MeshNode*>& nodes,
1062 const std::vector<int>& quantities)
1064 // keep current nodes of element
1065 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1069 // change vtkUnstructuredGrid::Faces
1070 if ( const SMDS_MeshVolume* vol = DownCast<SMDS_MeshVolume>( element ))
1071 Ok = vol->ChangeNodes( nodes, quantities );
1073 // change vtkUnstructuredGrid::Connectivity and inverse connectivity
1075 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1077 boost::container::flat_set< const SMDS_MeshNode* > uniqueNodes( nodes.begin(), nodes.end() );
1078 const SMDS_MeshNode** nodesPtr = &( *uniqueNodes.begin());
1079 const int nbNodes = (int) uniqueNodes.size();
1080 Ok = cell->ChangeNodes( nodesPtr, nbNodes );
1083 updateInverseElements( element, nodesPtr, nbNodes, oldNodes );
1091 //=======================================================================
1092 //function : ChangeElementNodes
1094 //=======================================================================
1096 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1097 const SMDS_MeshNode * nodes[],
1100 // keep current nodes of element
1101 std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1105 if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
1106 Ok = cell->ChangeNodes(nodes, nbnodes);
1111 updateInverseElements( element, nodes, nbnodes, oldNodes );
1116 //=======================================================================
1117 //function : updateInverseElements
1118 //purpose : update InverseElements when element changes node
1119 //=======================================================================
1121 void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement * element,
1122 const SMDS_MeshNode* const* nodes,
1124 std::set<const SMDS_MeshNode*>& oldNodes )
1126 if ( GetGrid()->HasLinks() ) // update InverseElements
1128 std::set<const SMDS_MeshNode*>::iterator it;
1130 // AddInverseElement to new nodes
1131 for ( int i = 0; i < nbnodes; i++ )
1133 it = oldNodes.find( nodes[i] );
1134 if ( it == oldNodes.end() )
1136 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( element );
1138 // remove from oldNodes a node that remains in elem
1139 oldNodes.erase( it );
1141 // RemoveInverseElement from the nodes removed from elem
1142 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1144 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1145 n->RemoveInverseElement( element );
1151 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1153 if (!node) return 0;
1154 const SMDS_Mesh0DElement* toReturn = NULL;
1155 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1156 while (it1->more() && (toReturn == NULL)) {
1157 const SMDS_MeshElement* e = it1->next();
1158 if (e->NbNodes() == 1) {
1159 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1165 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
1167 if (!node) return 0;
1168 const SMDS_BallElement* toReturn = NULL;
1169 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
1170 while (it1->more() && (toReturn == NULL)) {
1171 const SMDS_MeshElement* e = it1->next();
1172 if (e->GetGeomType() == SMDSGeom_BALL)
1173 toReturn = static_cast<const SMDS_BallElement*>(e);
1178 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1179 const SMDS_MeshNode * node2)
1181 if ( !node1 ) return 0;
1182 const SMDS_MeshEdge * toReturn=NULL;
1183 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1184 while(it1->more()) {
1185 const SMDS_MeshElement * e = it1->next();
1186 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1187 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1194 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1195 const SMDS_MeshNode * node2,
1196 const SMDS_MeshNode * node3)
1198 if ( !node1 ) return 0;
1199 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1200 while(it1->more()) {
1201 const SMDS_MeshElement * e = it1->next();
1202 if ( e->NbNodes() == 3 ) {
1203 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1204 while(it2->more()) {
1205 const SMDS_MeshElement* n = it2->next();
1215 return static_cast<const SMDS_MeshEdge *> (e);
1221 //=======================================================================
1222 //function : FindFace
1224 //=======================================================================
1226 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1227 const SMDS_MeshNode *node2,
1228 const SMDS_MeshNode *node3)
1230 if ( !node1 ) return 0;
1231 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1232 while(it1->more()) {
1233 const SMDS_MeshElement * e = it1->next();
1234 if ( e->NbNodes() == 3 ) {
1235 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1236 while(it2->more()) {
1237 const SMDS_MeshElement* n = it2->next();
1247 return static_cast<const SMDS_MeshFace *> (e);
1253 //=======================================================================
1254 //function : FindFace
1256 //=======================================================================
1258 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1259 const SMDS_MeshNode *node2,
1260 const SMDS_MeshNode *node3,
1261 const SMDS_MeshNode *node4)
1263 if ( !node1 ) return 0;
1264 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1265 while(it1->more()) {
1266 const SMDS_MeshElement * e = it1->next();
1267 if ( e->NbNodes() == 4 ) {
1268 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1269 while(it2->more()) {
1270 const SMDS_MeshElement* n = it2->next();
1281 return static_cast<const SMDS_MeshFace *> (e);
1287 //=======================================================================
1288 //function : FindFace
1289 //purpose :quadratic triangle
1290 //=======================================================================
1292 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1293 const SMDS_MeshNode *node2,
1294 const SMDS_MeshNode *node3,
1295 const SMDS_MeshNode *node4,
1296 const SMDS_MeshNode *node5,
1297 const SMDS_MeshNode *node6)
1299 if ( !node1 ) return 0;
1300 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1301 while(it1->more()) {
1302 const SMDS_MeshElement * e = it1->next();
1303 if ( e->NbNodes() == 6 ) {
1304 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1305 while(it2->more()) {
1306 const SMDS_MeshElement* n = it2->next();
1319 return static_cast<const SMDS_MeshFace *> (e);
1326 //=======================================================================
1327 //function : FindFace
1328 //purpose : quadratic quadrangle
1329 //=======================================================================
1331 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1332 const SMDS_MeshNode *node2,
1333 const SMDS_MeshNode *node3,
1334 const SMDS_MeshNode *node4,
1335 const SMDS_MeshNode *node5,
1336 const SMDS_MeshNode *node6,
1337 const SMDS_MeshNode *node7,
1338 const SMDS_MeshNode *node8)
1340 if ( !node1 ) return 0;
1341 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1342 while(it1->more()) {
1343 const SMDS_MeshElement * e = it1->next();
1344 if ( e->NbNodes() == 8 ) {
1345 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1346 while(it2->more()) {
1347 const SMDS_MeshElement* n = it2->next();
1362 return static_cast<const SMDS_MeshFace *> (e);
1369 //=======================================================================
1370 //function : FindElement
1372 //=======================================================================
1374 const SMDS_MeshElement* SMDS_Mesh::FindElement(smIdType IDelem) const
1376 return myCellFactory->FindElement( IDelem );
1379 //=======================================================================
1380 //function : FindFace
1381 //purpose : find polygon
1382 //=======================================================================
1385 const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector<const SMDS_MeshNode *>& nodes)
1387 return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
1391 //================================================================================
1393 * \brief Return element based on all given nodes
1394 * \param nodes - node of element
1395 * \param type - type of element
1396 * \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
1397 * \retval const SMDS_MeshElement* - found element or NULL
1399 //================================================================================
1401 const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector<const SMDS_MeshNode *>& nodes,
1402 const SMDSAbs_ElementType type,
1403 const bool noMedium)
1405 if ( nodes.size() > 0 && nodes[0] )
1407 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
1410 const SMDS_MeshElement* e = itF->next();
1411 int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
1412 if ( nbNodesToCheck == (int)nodes.size() )
1414 for ( size_t i = 1; e && i < nodes.size(); ++i )
1416 int nodeIndex = e->GetNodeIndex( nodes[ i ]);
1417 if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
1428 //================================================================================
1430 * \brief Return elements including all given nodes
1431 * \param [in] nodes - nodes to find elements around
1432 * \param [out] foundElems - the found elements
1433 * \param [in] type - type of elements to find
1434 * \return int - a number of found elements
1436 //================================================================================
1438 int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& nodes,
1439 std::vector<const SMDS_MeshElement *>& foundElems,
1440 const SMDSAbs_ElementType type)
1442 // chose a node with minimal number of inverse elements
1443 const SMDS_MeshNode* n0 = nodes[0];
1444 int minNbInverse = n0 ? n0->NbInverseElements( type ) : 1000;
1445 for ( size_t i = 1; i < nodes.size(); ++i )
1446 if ( nodes[i] && nodes[i]->NbInverseElements( type ) < minNbInverse )
1449 minNbInverse = n0->NbInverseElements( type );
1453 if ( n0 && minNbInverse > 0 )
1455 foundElems.reserve( minNbInverse );
1456 SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
1457 while ( eIt->more() )
1459 const SMDS_MeshElement* e = eIt->next();
1460 bool includeAll = true;
1461 for ( size_t i = 0; i < nodes.size() && includeAll; ++i )
1462 if ( nodes[i] != n0 && e->GetNodeIndex( nodes[i] ) < 0 )
1465 foundElems.push_back( e );
1468 return foundElems.size();
1471 ///////////////////////////////////////////////////////////////////////////////
1472 /// Return the number of nodes
1473 ///////////////////////////////////////////////////////////////////////////////
1474 smIdType SMDS_Mesh::NbNodes() const
1476 return myInfo.NbNodes();
1479 ///////////////////////////////////////////////////////////////////////////////
1480 /// Return the number of elements
1481 ///////////////////////////////////////////////////////////////////////////////
1482 smIdType SMDS_Mesh::NbElements() const
1484 return myInfo.NbElements();
1486 ///////////////////////////////////////////////////////////////////////////////
1487 /// Return the number of 0D elements
1488 ///////////////////////////////////////////////////////////////////////////////
1489 smIdType SMDS_Mesh::Nb0DElements() const
1491 return myInfo.Nb0DElements();
1494 ///////////////////////////////////////////////////////////////////////////////
1495 /// Return the number of 0D elements
1496 ///////////////////////////////////////////////////////////////////////////////
1497 smIdType SMDS_Mesh::NbBalls() const
1499 return myInfo.NbBalls();
1502 ///////////////////////////////////////////////////////////////////////////////
1503 /// Return the number of edges (including construction edges)
1504 ///////////////////////////////////////////////////////////////////////////////
1505 smIdType SMDS_Mesh::NbEdges() const
1507 return myInfo.NbEdges();
1510 ///////////////////////////////////////////////////////////////////////////////
1511 /// Return the number of faces (including construction faces)
1512 ///////////////////////////////////////////////////////////////////////////////
1513 smIdType SMDS_Mesh::NbFaces() const
1515 return myInfo.NbFaces();
1518 ///////////////////////////////////////////////////////////////////////////////
1519 /// Return the number of volumes
1520 ///////////////////////////////////////////////////////////////////////////////
1521 smIdType SMDS_Mesh::NbVolumes() const
1523 return myInfo.NbVolumes();
1526 ///////////////////////////////////////////////////////////////////////////////
1527 /// Return the number of child mesh of this mesh.
1528 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
1529 ///////////////////////////////////////////////////////////////////////////////
1530 smIdType SMDS_Mesh::NbSubMesh() const
1532 return myChildren.size();
1535 ///////////////////////////////////////////////////////////////////////////////
1536 /// Destroy the mesh and all its elements
1537 /// All pointer on elements owned by this mesh become illegals.
1538 ///////////////////////////////////////////////////////////////////////////////
1539 SMDS_Mesh::~SMDS_Mesh()
1541 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1542 while(itc!=myChildren.end())
1548 delete myNodeFactory;
1549 delete myCellFactory;
1554 //================================================================================
1556 * \brief Clear all data
1558 //================================================================================
1560 void SMDS_Mesh::Clear()
1562 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
1563 for ( ; holder != myElemHolders.end(); ++holder )
1566 myNodeFactory->Clear();
1567 myCellFactory->Clear();
1569 std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1570 while(itc!=myChildren.end())
1581 myGrid->Initialize();
1583 vtkPoints* points = vtkPoints::New();
1584 // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
1585 // using double type for storing coordinates of nodes instead float.
1586 points->SetDataType(VTK_DOUBLE);
1587 points->SetNumberOfPoints( 0 );
1588 myGrid->SetPoints( points );
1590 myGrid->DeleteLinks();
1593 ///////////////////////////////////////////////////////////////////////////////
1594 /// Return an iterator on nodes of the current mesh factory
1595 ///////////////////////////////////////////////////////////////////////////////
1597 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1599 return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter );
1602 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
1604 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1605 return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
1609 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
1611 if ( type == SMDSEntity_Node )
1613 return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
1615 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1616 return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
1620 ///////////////////////////////////////////////////////////////////////////////
1621 /// Return an iterator on elements of the current mesh factory
1622 ///////////////////////////////////////////////////////////////////////////////
1623 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
1625 typedef SMDS_ElemIterator TIterator;
1629 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1632 return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
1635 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
1636 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
1639 return SMDS_ElemIteratorPtr();
1642 ///////////////////////////////////////////////////////////////////////////////
1643 ///Return an iterator on edges of the current mesh.
1644 ///////////////////////////////////////////////////////////////////////////////
1646 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1648 typedef SMDS_EdgeIterator TIterator;
1649 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges();
1650 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
1654 ///////////////////////////////////////////////////////////////////////////////
1655 ///Return an iterator on faces of the current mesh.
1656 ///////////////////////////////////////////////////////////////////////////////
1658 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1660 typedef SMDS_FaceIterator TIterator;
1661 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces();
1662 return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
1666 ///////////////////////////////////////////////////////////////////////////////
1667 ///Return an iterator on volumes of the current mesh.
1668 ///////////////////////////////////////////////////////////////////////////////
1670 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1672 typedef SMDS_VolumeIterator TIterator;
1673 smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes();
1675 myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
1679 SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID,
1680 size_t nbElemsToReturn,
1681 const SMDS_MeshNode* sm1stNode) const
1683 return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
1686 SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID,
1687 size_t nbElemsToReturn,
1688 const SMDS_MeshElement* sm1stElem) const
1690 return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
1693 ///////////////////////////////////////////////////////////////////////////////
1694 /// Do intersection of sets (more than 2)
1695 ///////////////////////////////////////////////////////////////////////////////
1696 static std::set<const SMDS_MeshElement*> *
1697 intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
1699 std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
1700 std::set<const SMDS_MeshElement*>* rsetB;
1702 for(int i=0; i<numberOfSets-1; i++)
1704 rsetB = new std::set<const SMDS_MeshElement*>();
1705 set_intersection(rsetA->begin(), rsetA->end(),
1706 vs[i+1].begin(), vs[i+1].end(),
1707 inserter(*rsetB, rsetB->begin()));
1713 ///////////////////////////////////////////////////////////////////////////////
1714 /// Return the list of finite elements owning the given element: elements
1715 /// containing all the nodes of the given element, for instance faces and
1716 /// volumes containing a given edge.
1717 ///////////////////////////////////////////////////////////////////////////////
1718 static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1720 int numberOfSets=element->NbNodes();
1721 std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
1723 SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
1726 while ( itNodes->more() )
1728 const SMDS_MeshNode * n = itNodes->next();
1729 for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
1730 initSet[i].insert( itFe->next() );
1733 std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
1738 ///////////////////////////////////////////////////////////////////////////////
1739 /// Return the std::list of nodes used only by the given elements
1740 ///////////////////////////////////////////////////////////////////////////////
1742 std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
1744 std::set<const SMDS_MeshElement*> * toReturn = new std::set<const SMDS_MeshElement*>();
1745 std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
1747 while( itElements != elements.end() )
1749 SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
1752 while( itNodes->more() )
1754 const SMDS_MeshNode * n = itNodes->next();
1755 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1756 std::set<const SMDS_MeshElement*> s;
1757 while ( itFe->more() )
1758 s.insert( itFe->next() );
1759 if ( s == elements ) toReturn->insert(n);
1765 ///////////////////////////////////////////////////////////////////////////////
1766 ///Find the children of an element that are made of given nodes
1767 ///@param setOfChildren The set in which matching children will be inserted
1768 ///@param element The element were to search matching children
1769 ///@param nodes The nodes that the children must have to be selected
1770 ///////////////////////////////////////////////////////////////////////////////
1771 void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
1772 const SMDS_MeshElement * element,
1773 std::set<const SMDS_MeshElement*>& nodes)
1775 switch(element->GetType())
1778 throw SALOME_Exception("Internal Error: This should not happen");
1780 case SMDSAbs_0DElement:
1787 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1790 const SMDS_MeshElement * e=itn->next();
1791 if(nodes.find(e)!=nodes.end())
1793 setOfChildren.insert(element);
1800 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1803 const SMDS_MeshElement * e=itn->next();
1804 if(nodes.find(e)!=nodes.end())
1806 setOfChildren.insert(element);
1811 case SMDSAbs_Volume:
1812 case SMDSAbs_NbElementTypes:
1813 case SMDSAbs_All: break;
1817 ///////////////////////////////////////////////////////////////////////////////
1818 ///@param elem The element to delete
1819 ///@param removenodes if true remaining nodes will be removed
1820 ///////////////////////////////////////////////////////////////////////////////
1821 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1822 const bool removenodes)
1824 std::vector<const SMDS_MeshElement *> removedElems;
1825 std::vector<const SMDS_MeshElement *> removedNodes;
1826 RemoveElement( elem, removedElems, removedNodes, removenodes );
1829 ///////////////////////////////////////////////////////////////////////////////
1830 ///@param elem The element to delete
1831 ///@param removedElems to be filled with all removed elements
1832 ///@param removedNodes to be filled with all removed nodes
1833 ///@param removenodes if true remaining nodes will be removed
1834 ///////////////////////////////////////////////////////////////////////////////
1835 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1836 std::vector<const SMDS_MeshElement *>& removedElems,
1837 std::vector<const SMDS_MeshElement *>& removedNodes,
1840 // get finite elements built on elem
1841 std::set<const SMDS_MeshElement*> * s1;
1842 if ( (elem->GetType() == SMDSAbs_0DElement)
1843 || (elem->GetType() == SMDSAbs_Ball)
1844 || (elem->GetType() == SMDSAbs_Edge)
1845 || (elem->GetType() == SMDSAbs_Face)
1846 || (elem->GetType() == SMDSAbs_Volume) )
1848 s1 = new std::set<const SMDS_MeshElement*> ();
1852 s1 = getFinitElements(elem);
1854 // get exclusive nodes (which would become free afterwards)
1855 std::set<const SMDS_MeshElement*> * s2;
1856 if (elem->GetType() == SMDSAbs_Node) // a node is removed
1858 // do not remove nodes except elem
1859 s2 = new std::set<const SMDS_MeshElement*> ();
1864 s2 = getExclusiveNodes(*s1);
1866 // form the set of finite and construction elements to remove
1867 std::set<const SMDS_MeshElement*> s3;
1868 std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
1869 while (it != s1->end())
1871 addChildrenWithNodes(s3, *it, *s2);
1875 if (elem->GetType() != SMDSAbs_Node)
1878 // remove finite and construction elements
1879 for( it = s3.begin();it != s3.end(); ++it )
1881 // Remove element from <InverseElements> of its nodes
1882 SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
1885 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
1886 n->RemoveInverseElement((*it));
1889 vtkIdType vtkid = (*it)->GetVtkID();
1891 switch ((*it)->GetType()) {
1893 throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
1895 case SMDSAbs_Edge: myInfo.RemoveEdge(*it); break;
1896 case SMDSAbs_Face: myInfo.RemoveFace(*it); break;
1897 case SMDSAbs_Volume: myInfo.RemoveVolume(*it); break;
1898 case SMDSAbs_Ball: myInfo.myNbBalls--; break;
1899 case SMDSAbs_0DElement: myInfo.myNb0DElements--; break;
1900 case SMDSAbs_All: // avoid compilation warning
1901 case SMDSAbs_NbElementTypes: break;
1903 removedElems.push_back( *it);
1905 myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
1909 this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
1913 // remove exclusive (free) nodes
1916 for ( it = s2->begin(); it != s2->end(); ++it )
1919 myNodeFactory->Free( (*it) );
1920 removedNodes.push_back((*it));
1929 ///////////////////////////////////////////////////////////////////////////////
1930 ///@param elem The element to delete
1931 ///////////////////////////////////////////////////////////////////////////////
1932 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
1934 const vtkIdType vtkId = elem->GetVtkID();
1935 SMDSAbs_ElementType aType = elem->GetType();
1936 if ( aType == SMDSAbs_Node )
1938 // only free node can be removed by this method
1939 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( elem );
1940 if ( n->NbInverseElements() == 0 ) { // free node
1942 myNodeFactory->Free( n );
1946 throw SALOME_Exception( LOCALIZED( "RemoveFreeElement: not a free node" ));
1951 // Remove element from <InverseElements> of its nodes
1952 SMDS_NodeIteratorPtr itn = elem->nodeIterator();
1953 while (itn->more()) {
1954 SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>(itn->next());
1955 n->RemoveInverseElement(elem);
1958 // in meshes without descendants elements are always free
1960 case SMDSAbs_0DElement: myInfo.remove(elem); break;
1961 case SMDSAbs_Edge: myInfo.RemoveEdge(elem); break;
1962 case SMDSAbs_Face: myInfo.RemoveFace(elem); break;
1963 case SMDSAbs_Volume: myInfo.RemoveVolume(elem); break;
1964 case SMDSAbs_Ball: myInfo.remove(elem); break;
1967 myCellFactory->Free( elem );
1969 this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
1973 //=======================================================================
1975 * Checks if the element is present in mesh.
1977 //=======================================================================
1979 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1981 if ( !elem || elem->IsNull() )
1984 if ( elem->GetType() == SMDSAbs_Node )
1985 return ( elem == myNodeFactory->FindElement( elem->GetID() ));
1987 return ( elem == myCellFactory->FindElement( elem->GetID() ));
1990 //=======================================================================
1991 //function : MaxNodeID
1993 //=======================================================================
1995 smIdType SMDS_Mesh::MaxNodeID() const
1997 return myNodeFactory->GetMaxID();
2000 //=======================================================================
2001 //function : MinNodeID
2003 //=======================================================================
2005 smIdType SMDS_Mesh::MinNodeID() const
2007 return myNodeFactory->GetMinID();
2010 //=======================================================================
2011 //function : MaxElementID
2013 //=======================================================================
2015 smIdType SMDS_Mesh::MaxElementID() const
2017 return myCellFactory->GetMaxID();
2020 //=======================================================================
2021 //function : MinElementID
2023 //=======================================================================
2025 smIdType SMDS_Mesh::MinElementID() const
2027 return myCellFactory->GetMinID();
2030 //=======================================================================
2031 //function : Renumber
2032 //purpose : Renumber all nodes or elements.
2033 //=======================================================================
2035 // void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2037 // if ( deltaID == 0 )
2042 //=======================================================================
2043 //function : GetElementType
2044 //purpose : Return type of element or node with id
2045 //=======================================================================
2047 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const smIdType id, const bool iselem ) const
2049 const SMDS_MeshElement* elem = 0;
2051 elem = myCellFactory->FindElement( id );
2053 elem = myNodeFactory->FindElement( id );
2055 return elem ? elem->GetType() : SMDSAbs_All;
2060 //********************************************************************
2061 //********************************************************************
2062 //******** *********
2063 //***** Methods for addition of quadratic elements ******
2064 //******** *********
2065 //********************************************************************
2066 //********************************************************************
2068 //=======================================================================
2069 //function : AddEdgeWithID
2071 //=======================================================================
2072 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID)
2074 return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
2075 myNodeFactory->FindNode(n2),
2076 myNodeFactory->FindNode(n12),
2080 //=======================================================================
2081 //function : AddEdge
2083 //=======================================================================
2084 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2085 const SMDS_MeshNode* n2,
2086 const SMDS_MeshNode* n12)
2088 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myCellFactory->GetFreeID());
2091 //=======================================================================
2092 //function : AddEdgeWithID
2094 //=======================================================================
2095 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2096 const SMDS_MeshNode * n2,
2097 const SMDS_MeshNode * n12,
2100 if ( !n1 || !n2 || !n12 ) return 0;
2102 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2104 cell->init( SMDSEntity_Quad_Edge, /*nbNodes=*/3, n1, n2, n12 );
2105 myInfo.myNbQuadEdges++;
2106 return static_cast<SMDS_MeshEdge*>( cell );
2112 //=======================================================================
2113 //function : AddFace
2115 //=======================================================================
2116 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2117 const SMDS_MeshNode * n2,
2118 const SMDS_MeshNode * n3,
2119 const SMDS_MeshNode * n12,
2120 const SMDS_MeshNode * n23,
2121 const SMDS_MeshNode * n31)
2123 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2124 myCellFactory->GetFreeID());
2127 //=======================================================================
2128 //function : AddFaceWithID
2130 //=======================================================================
2131 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2132 smIdType n12,smIdType n23,smIdType n31, smIdType ID)
2134 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2135 myNodeFactory->FindNode(n2) ,
2136 myNodeFactory->FindNode(n3) ,
2137 myNodeFactory->FindNode(n12),
2138 myNodeFactory->FindNode(n23),
2139 myNodeFactory->FindNode(n31),
2143 //=======================================================================
2144 //function : AddFaceWithID
2146 //=======================================================================
2147 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2148 const SMDS_MeshNode * n2,
2149 const SMDS_MeshNode * n3,
2150 const SMDS_MeshNode * n12,
2151 const SMDS_MeshNode * n23,
2152 const SMDS_MeshNode * n31,
2155 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
2156 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2158 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2160 cell->init( SMDSEntity_Quad_Triangle, /*nbNodes=*/6, n1, n2, n3, n12, n23, n31 );
2161 myInfo.myNbQuadTriangles++;
2162 return static_cast<SMDS_MeshFace*>( cell );
2168 //=======================================================================
2169 //function : AddFace
2171 //=======================================================================
2172 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2173 const SMDS_MeshNode * n2,
2174 const SMDS_MeshNode * n3,
2175 const SMDS_MeshNode * n12,
2176 const SMDS_MeshNode * n23,
2177 const SMDS_MeshNode * n31,
2178 const SMDS_MeshNode * nCenter)
2180 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,nCenter,
2181 myCellFactory->GetFreeID());
2184 //=======================================================================
2185 //function : AddFaceWithID
2187 //=======================================================================
2188 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
2189 smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID)
2191 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2192 myNodeFactory->FindNode(n2) ,
2193 myNodeFactory->FindNode(n3) ,
2194 myNodeFactory->FindNode(n12),
2195 myNodeFactory->FindNode(n23),
2196 myNodeFactory->FindNode(n31),
2197 myNodeFactory->FindNode(nCenter),
2201 //=======================================================================
2202 //function : AddFaceWithID
2204 //=======================================================================
2205 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2206 const SMDS_MeshNode * n2,
2207 const SMDS_MeshNode * n3,
2208 const SMDS_MeshNode * n12,
2209 const SMDS_MeshNode * n23,
2210 const SMDS_MeshNode * n31,
2211 const SMDS_MeshNode * nCenter,
2214 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
2215 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2217 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2219 cell->init( SMDSEntity_BiQuad_Triangle, /*nbNodes=*/7, n1, n2, n3, n12, n23, n31, nCenter );
2220 myInfo.myNbBiQuadTriangles++;
2221 return static_cast<SMDS_MeshFace*>( cell );
2227 //=======================================================================
2228 //function : AddFace
2230 //=======================================================================
2231 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2232 const SMDS_MeshNode * n2,
2233 const SMDS_MeshNode * n3,
2234 const SMDS_MeshNode * n4,
2235 const SMDS_MeshNode * n12,
2236 const SMDS_MeshNode * n23,
2237 const SMDS_MeshNode * n34,
2238 const SMDS_MeshNode * n41)
2240 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2241 myCellFactory->GetFreeID());
2244 //=======================================================================
2245 //function : AddFaceWithID
2247 //=======================================================================
2248 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2249 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID)
2251 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2252 myNodeFactory->FindNode(n2) ,
2253 myNodeFactory->FindNode(n3) ,
2254 myNodeFactory->FindNode(n4) ,
2255 myNodeFactory->FindNode(n12),
2256 myNodeFactory->FindNode(n23),
2257 myNodeFactory->FindNode(n34),
2258 myNodeFactory->FindNode(n41),
2262 //=======================================================================
2263 //function : AddFaceWithID
2265 //=======================================================================
2266 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2267 const SMDS_MeshNode * n2,
2268 const SMDS_MeshNode * n3,
2269 const SMDS_MeshNode * n4,
2270 const SMDS_MeshNode * n12,
2271 const SMDS_MeshNode * n23,
2272 const SMDS_MeshNode * n34,
2273 const SMDS_MeshNode * n41,
2276 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2277 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2279 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2281 cell->init( SMDSEntity_Quad_Quadrangle, /*nbNodes=*/8, n1, n2, n3, n4, n12, n23, n34, n41 );
2282 myInfo.myNbQuadQuadrangles++;
2283 return static_cast<SMDS_MeshFace*>( cell );
2288 //=======================================================================
2289 //function : AddFace
2291 //=======================================================================
2292 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2293 const SMDS_MeshNode * n2,
2294 const SMDS_MeshNode * n3,
2295 const SMDS_MeshNode * n4,
2296 const SMDS_MeshNode * n12,
2297 const SMDS_MeshNode * n23,
2298 const SMDS_MeshNode * n34,
2299 const SMDS_MeshNode * n41,
2300 const SMDS_MeshNode * nCenter)
2302 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
2303 myCellFactory->GetFreeID());
2306 //=======================================================================
2307 //function : AddFaceWithID
2309 //=======================================================================
2310 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2311 smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType nCenter, smIdType ID)
2313 return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
2314 myNodeFactory->FindNode(n2) ,
2315 myNodeFactory->FindNode(n3) ,
2316 myNodeFactory->FindNode(n4) ,
2317 myNodeFactory->FindNode(n12),
2318 myNodeFactory->FindNode(n23),
2319 myNodeFactory->FindNode(n34),
2320 myNodeFactory->FindNode(n41),
2321 myNodeFactory->FindNode(nCenter),
2325 //=======================================================================
2326 //function : AddFaceWithID
2328 //=======================================================================
2329 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2330 const SMDS_MeshNode * n2,
2331 const SMDS_MeshNode * n3,
2332 const SMDS_MeshNode * n4,
2333 const SMDS_MeshNode * n12,
2334 const SMDS_MeshNode * n23,
2335 const SMDS_MeshNode * n34,
2336 const SMDS_MeshNode * n41,
2337 const SMDS_MeshNode * nCenter,
2340 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
2341 if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2343 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2345 cell->init( SMDSEntity_BiQuad_Quadrangle,
2346 /*nbNodes=*/9, n1, n2, n3, n4, n12, n23, n34, n41, nCenter );
2347 myInfo.myNbBiQuadQuadrangles++;
2348 return static_cast<SMDS_MeshFace*>( cell );
2354 //=======================================================================
2355 //function : AddVolume
2357 //=======================================================================
2358 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2359 const SMDS_MeshNode * n2,
2360 const SMDS_MeshNode * n3,
2361 const SMDS_MeshNode * n4,
2362 const SMDS_MeshNode * n12,
2363 const SMDS_MeshNode * n23,
2364 const SMDS_MeshNode * n31,
2365 const SMDS_MeshNode * n14,
2366 const SMDS_MeshNode * n24,
2367 const SMDS_MeshNode * n34)
2369 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2370 n31, n14, n24, n34, myCellFactory->GetFreeID());
2373 //=======================================================================
2374 //function : AddVolumeWithID
2376 //=======================================================================
2377 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2378 smIdType n12,smIdType n23,smIdType n31,
2379 smIdType n14,smIdType n24,smIdType n34, smIdType ID)
2381 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2382 myNodeFactory->FindNode(n2) ,
2383 myNodeFactory->FindNode(n3) ,
2384 myNodeFactory->FindNode(n4) ,
2385 myNodeFactory->FindNode(n12),
2386 myNodeFactory->FindNode(n23),
2387 myNodeFactory->FindNode(n31),
2388 myNodeFactory->FindNode(n14),
2389 myNodeFactory->FindNode(n24),
2390 myNodeFactory->FindNode(n34),
2394 //=======================================================================
2395 //function : AddVolumeWithID
2396 //purpose : 2d order tetrahedron of 10 nodes
2397 //=======================================================================
2398 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2399 const SMDS_MeshNode * n2,
2400 const SMDS_MeshNode * n3,
2401 const SMDS_MeshNode * n4,
2402 const SMDS_MeshNode * n12,
2403 const SMDS_MeshNode * n23,
2404 const SMDS_MeshNode * n31,
2405 const SMDS_MeshNode * n14,
2406 const SMDS_MeshNode * n24,
2407 const SMDS_MeshNode * n34,
2410 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2412 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2414 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2416 cell->init( SMDSEntity_Quad_Tetra,
2417 /*nbNodes=*/10, n1, n2, n3, n4, n12, n23, n31, n14, n24, n34 );
2418 myInfo.myNbQuadTetras++;
2419 return static_cast<SMDS_MeshVolume*>( cell );
2425 //=======================================================================
2426 //function : AddVolume
2428 //=======================================================================
2429 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2430 const SMDS_MeshNode * n2,
2431 const SMDS_MeshNode * n3,
2432 const SMDS_MeshNode * n4,
2433 const SMDS_MeshNode * n5,
2434 const SMDS_MeshNode * n12,
2435 const SMDS_MeshNode * n23,
2436 const SMDS_MeshNode * n34,
2437 const SMDS_MeshNode * n41,
2438 const SMDS_MeshNode * n15,
2439 const SMDS_MeshNode * n25,
2440 const SMDS_MeshNode * n35,
2441 const SMDS_MeshNode * n45)
2443 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2444 n15, n25, n35, n45, myCellFactory->GetFreeID());
2447 //=======================================================================
2448 //function : AddVolumeWithID
2450 //=======================================================================
2451 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5,
2452 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2453 smIdType n15,smIdType n25,smIdType n35,smIdType n45, smIdType ID)
2455 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2456 myNodeFactory->FindNode(n2) ,
2457 myNodeFactory->FindNode(n3) ,
2458 myNodeFactory->FindNode(n4) ,
2459 myNodeFactory->FindNode(n5) ,
2460 myNodeFactory->FindNode(n12),
2461 myNodeFactory->FindNode(n23),
2462 myNodeFactory->FindNode(n34),
2463 myNodeFactory->FindNode(n41),
2464 myNodeFactory->FindNode(n15),
2465 myNodeFactory->FindNode(n25),
2466 myNodeFactory->FindNode(n35),
2467 myNodeFactory->FindNode(n45),
2471 //=======================================================================
2472 //function : AddVolumeWithID
2473 //purpose : 2d order pyramid of 13 nodes
2474 //=======================================================================
2475 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2476 const SMDS_MeshNode * n2,
2477 const SMDS_MeshNode * n3,
2478 const SMDS_MeshNode * n4,
2479 const SMDS_MeshNode * n5,
2480 const SMDS_MeshNode * n12,
2481 const SMDS_MeshNode * n23,
2482 const SMDS_MeshNode * n34,
2483 const SMDS_MeshNode * n41,
2484 const SMDS_MeshNode * n15,
2485 const SMDS_MeshNode * n25,
2486 const SMDS_MeshNode * n35,
2487 const SMDS_MeshNode * n45,
2490 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2491 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2493 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2495 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2497 cell->init( SMDSEntity_Quad_Pyramid,
2498 /*nbNodes=*/13, n1, n2, n3, n4, n5, n12, n23, n34, n41, n15, n25, n35, n45);
2499 myInfo.myNbQuadPyramids++;
2500 return static_cast<SMDS_MeshVolume*>( cell );
2506 //=======================================================================
2507 //function : AddVolume
2508 //purpose : 2d order Pentahedron (prism) with 15 nodes
2509 //=======================================================================
2510 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2511 const SMDS_MeshNode * n2,
2512 const SMDS_MeshNode * n3,
2513 const SMDS_MeshNode * n4,
2514 const SMDS_MeshNode * n5,
2515 const SMDS_MeshNode * n6,
2516 const SMDS_MeshNode * n12,
2517 const SMDS_MeshNode * n23,
2518 const SMDS_MeshNode * n31,
2519 const SMDS_MeshNode * n45,
2520 const SMDS_MeshNode * n56,
2521 const SMDS_MeshNode * n64,
2522 const SMDS_MeshNode * n14,
2523 const SMDS_MeshNode * n25,
2524 const SMDS_MeshNode * n36)
2526 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2527 n45, n56, n64, n14, n25, n36, myCellFactory->GetFreeID());
2530 //=======================================================================
2531 //function : AddVolumeWithID
2532 //purpose : 2d order Pentahedron (prism) with 15 nodes
2533 //=======================================================================
2534 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2535 smIdType n4, smIdType n5, smIdType n6,
2536 smIdType n12,smIdType n23,smIdType n31,
2537 smIdType n45,smIdType n56,smIdType n64,
2538 smIdType n14,smIdType n25,smIdType n36, smIdType ID)
2540 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2541 myNodeFactory->FindNode(n2) ,
2542 myNodeFactory->FindNode(n3) ,
2543 myNodeFactory->FindNode(n4) ,
2544 myNodeFactory->FindNode(n5) ,
2545 myNodeFactory->FindNode(n6) ,
2546 myNodeFactory->FindNode(n12),
2547 myNodeFactory->FindNode(n23),
2548 myNodeFactory->FindNode(n31),
2549 myNodeFactory->FindNode(n45),
2550 myNodeFactory->FindNode(n56),
2551 myNodeFactory->FindNode(n64),
2552 myNodeFactory->FindNode(n14),
2553 myNodeFactory->FindNode(n25),
2554 myNodeFactory->FindNode(n36),
2558 //=======================================================================
2559 //function : AddVolumeWithID
2560 //purpose : 2d order Pentahedron (prism) with 15 nodes
2561 //=======================================================================
2562 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2563 const SMDS_MeshNode * n2,
2564 const SMDS_MeshNode * n3,
2565 const SMDS_MeshNode * n4,
2566 const SMDS_MeshNode * n5,
2567 const SMDS_MeshNode * n6,
2568 const SMDS_MeshNode * n12,
2569 const SMDS_MeshNode * n23,
2570 const SMDS_MeshNode * n31,
2571 const SMDS_MeshNode * n45,
2572 const SMDS_MeshNode * n56,
2573 const SMDS_MeshNode * n64,
2574 const SMDS_MeshNode * n14,
2575 const SMDS_MeshNode * n25,
2576 const SMDS_MeshNode * n36,
2579 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2580 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2582 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2584 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2586 cell->init( SMDSEntity_Quad_Penta, /*nbNodes=*/15,
2587 n1, n2, n3, n4, n5, n6, n12, n23, n31, n45, n56, n64, n14, n25, n36 );
2588 myInfo.myNbQuadPrisms++;
2589 return static_cast<SMDS_MeshVolume*>( cell );
2594 //=======================================================================
2595 //function : AddVolume
2596 //purpose : 2d order Pentahedron (prism) with 18 nodes
2597 //=======================================================================
2598 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2599 const SMDS_MeshNode * n2,
2600 const SMDS_MeshNode * n3,
2601 const SMDS_MeshNode * n4,
2602 const SMDS_MeshNode * n5,
2603 const SMDS_MeshNode * n6,
2604 const SMDS_MeshNode * n12,
2605 const SMDS_MeshNode * n23,
2606 const SMDS_MeshNode * n31,
2607 const SMDS_MeshNode * n45,
2608 const SMDS_MeshNode * n56,
2609 const SMDS_MeshNode * n64,
2610 const SMDS_MeshNode * n14,
2611 const SMDS_MeshNode * n25,
2612 const SMDS_MeshNode * n36,
2613 const SMDS_MeshNode * n1245,
2614 const SMDS_MeshNode * n2356,
2615 const SMDS_MeshNode * n1346)
2617 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2618 n45, n56, n64, n14, n25, n36, n1245, n2356, n1346,
2619 myCellFactory->GetFreeID());
2622 //=======================================================================
2623 //function : AddVolumeWithID
2624 //purpose : 2d order Pentahedron (prism) with 18 nodes
2625 //=======================================================================
2626 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
2627 smIdType n4, smIdType n5, smIdType n6,
2628 smIdType n12,smIdType n23,smIdType n31,
2629 smIdType n45,smIdType n56,smIdType n64,
2630 smIdType n14,smIdType n25,smIdType n36,
2631 smIdType n1245, smIdType n2356, smIdType n1346, smIdType ID)
2633 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
2634 myNodeFactory->FindNode(n2) ,
2635 myNodeFactory->FindNode(n3) ,
2636 myNodeFactory->FindNode(n4) ,
2637 myNodeFactory->FindNode(n5) ,
2638 myNodeFactory->FindNode(n6) ,
2639 myNodeFactory->FindNode(n12),
2640 myNodeFactory->FindNode(n23),
2641 myNodeFactory->FindNode(n31),
2642 myNodeFactory->FindNode(n45),
2643 myNodeFactory->FindNode(n56),
2644 myNodeFactory->FindNode(n64),
2645 myNodeFactory->FindNode(n14),
2646 myNodeFactory->FindNode(n25),
2647 myNodeFactory->FindNode(n36),
2648 myNodeFactory->FindNode(n1245),
2649 myNodeFactory->FindNode(n2356),
2650 myNodeFactory->FindNode(n1346),
2654 //=======================================================================
2655 //function : AddVolumeWithID
2656 //purpose : 2d order Pentahedron (prism) with 18 nodes
2657 //=======================================================================
2658 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2659 const SMDS_MeshNode * n2,
2660 const SMDS_MeshNode * n3,
2661 const SMDS_MeshNode * n4,
2662 const SMDS_MeshNode * n5,
2663 const SMDS_MeshNode * n6,
2664 const SMDS_MeshNode * n12,
2665 const SMDS_MeshNode * n23,
2666 const SMDS_MeshNode * n31,
2667 const SMDS_MeshNode * n45,
2668 const SMDS_MeshNode * n56,
2669 const SMDS_MeshNode * n64,
2670 const SMDS_MeshNode * n14,
2671 const SMDS_MeshNode * n25,
2672 const SMDS_MeshNode * n36,
2673 const SMDS_MeshNode * n1245,
2674 const SMDS_MeshNode * n2356,
2675 const SMDS_MeshNode * n1346,
2678 //MESSAGE("AddVolumeWithID penta18 "<< ID);
2679 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2680 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36 || !n1245 || !n2356 || !n1346)
2682 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2684 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2686 cell->init( SMDSEntity_BiQuad_Penta, /*nbNodes=*/18, n1, n2, n3, n4, n5, n6,
2687 n12, n23, n31, n45, n56, n64, n14, n25, n36, n1245, n2356, n1346 );
2688 myInfo.myNbBiQuadPrisms++;
2689 return static_cast<SMDS_MeshVolume*>( cell );
2695 //=======================================================================
2696 //function : AddVolume
2698 //=======================================================================
2699 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2700 const SMDS_MeshNode * n2,
2701 const SMDS_MeshNode * n3,
2702 const SMDS_MeshNode * n4,
2703 const SMDS_MeshNode * n5,
2704 const SMDS_MeshNode * n6,
2705 const SMDS_MeshNode * n7,
2706 const SMDS_MeshNode * n8,
2707 const SMDS_MeshNode * n12,
2708 const SMDS_MeshNode * n23,
2709 const SMDS_MeshNode * n34,
2710 const SMDS_MeshNode * n41,
2711 const SMDS_MeshNode * n56,
2712 const SMDS_MeshNode * n67,
2713 const SMDS_MeshNode * n78,
2714 const SMDS_MeshNode * n85,
2715 const SMDS_MeshNode * n15,
2716 const SMDS_MeshNode * n26,
2717 const SMDS_MeshNode * n37,
2718 const SMDS_MeshNode * n48)
2720 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2721 n56, n67, n78, n85, n15, n26, n37, n48,
2722 myCellFactory->GetFreeID());
2725 //=======================================================================
2726 //function : AddVolumeWithID
2728 //=======================================================================
2729 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2730 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2731 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2732 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2733 smIdType n15,smIdType n26,smIdType n37,smIdType n48, smIdType ID)
2735 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2736 myNodeFactory->FindNode(n2),
2737 myNodeFactory->FindNode(n3),
2738 myNodeFactory->FindNode(n4),
2739 myNodeFactory->FindNode(n5),
2740 myNodeFactory->FindNode(n6),
2741 myNodeFactory->FindNode(n7),
2742 myNodeFactory->FindNode(n8),
2743 myNodeFactory->FindNode(n12),
2744 myNodeFactory->FindNode(n23),
2745 myNodeFactory->FindNode(n34),
2746 myNodeFactory->FindNode(n41),
2747 myNodeFactory->FindNode(n56),
2748 myNodeFactory->FindNode(n67),
2749 myNodeFactory->FindNode(n78),
2750 myNodeFactory->FindNode(n85),
2751 myNodeFactory->FindNode(n15),
2752 myNodeFactory->FindNode(n26),
2753 myNodeFactory->FindNode(n37),
2754 myNodeFactory->FindNode(n48),
2758 //=======================================================================
2759 //function : AddVolumeWithID
2760 //purpose : 2d order Hexahedrons with 20 nodes
2761 //=======================================================================
2762 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2763 const SMDS_MeshNode * n2,
2764 const SMDS_MeshNode * n3,
2765 const SMDS_MeshNode * n4,
2766 const SMDS_MeshNode * n5,
2767 const SMDS_MeshNode * n6,
2768 const SMDS_MeshNode * n7,
2769 const SMDS_MeshNode * n8,
2770 const SMDS_MeshNode * n12,
2771 const SMDS_MeshNode * n23,
2772 const SMDS_MeshNode * n34,
2773 const SMDS_MeshNode * n41,
2774 const SMDS_MeshNode * n56,
2775 const SMDS_MeshNode * n67,
2776 const SMDS_MeshNode * n78,
2777 const SMDS_MeshNode * n85,
2778 const SMDS_MeshNode * n15,
2779 const SMDS_MeshNode * n26,
2780 const SMDS_MeshNode * n37,
2781 const SMDS_MeshNode * n48,
2784 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2785 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2787 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2789 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2791 cell->init( SMDSEntity_Quad_Hexa, /*nbNodes=*/20, n1, n2, n3, n4, n5, n6, n7, n8,
2792 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48 );
2793 myInfo.myNbQuadHexas++;
2794 return static_cast<SMDS_MeshVolume*>( cell );
2799 //=======================================================================
2800 //function : AddVolume
2802 //=======================================================================
2803 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2804 const SMDS_MeshNode * n2,
2805 const SMDS_MeshNode * n3,
2806 const SMDS_MeshNode * n4,
2807 const SMDS_MeshNode * n5,
2808 const SMDS_MeshNode * n6,
2809 const SMDS_MeshNode * n7,
2810 const SMDS_MeshNode * n8,
2811 const SMDS_MeshNode * n12,
2812 const SMDS_MeshNode * n23,
2813 const SMDS_MeshNode * n34,
2814 const SMDS_MeshNode * n41,
2815 const SMDS_MeshNode * n56,
2816 const SMDS_MeshNode * n67,
2817 const SMDS_MeshNode * n78,
2818 const SMDS_MeshNode * n85,
2819 const SMDS_MeshNode * n15,
2820 const SMDS_MeshNode * n26,
2821 const SMDS_MeshNode * n37,
2822 const SMDS_MeshNode * n48,
2823 const SMDS_MeshNode * n1234,
2824 const SMDS_MeshNode * n1256,
2825 const SMDS_MeshNode * n2367,
2826 const SMDS_MeshNode * n3478,
2827 const SMDS_MeshNode * n1458,
2828 const SMDS_MeshNode * n5678,
2829 const SMDS_MeshNode * nCenter)
2831 return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2832 n56, n67, n78, n85, n15, n26, n37, n48,
2833 n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
2834 myCellFactory->GetFreeID());
2837 //=======================================================================
2838 //function : AddVolumeWithID
2840 //=======================================================================
2841 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
2842 smIdType n5, smIdType n6, smIdType n7, smIdType n8,
2843 smIdType n12,smIdType n23,smIdType n34,smIdType n41,
2844 smIdType n56,smIdType n67,smIdType n78,smIdType n85,
2845 smIdType n15,smIdType n26,smIdType n37,smIdType n48,
2846 smIdType n1234,smIdType n1256,smIdType n2367,smIdType n3478,
2847 smIdType n1458,smIdType n5678,smIdType nCenter, smIdType ID)
2849 return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
2850 myNodeFactory->FindNode(n2),
2851 myNodeFactory->FindNode(n3),
2852 myNodeFactory->FindNode(n4),
2853 myNodeFactory->FindNode(n5),
2854 myNodeFactory->FindNode(n6),
2855 myNodeFactory->FindNode(n7),
2856 myNodeFactory->FindNode(n8),
2857 myNodeFactory->FindNode(n12),
2858 myNodeFactory->FindNode(n23),
2859 myNodeFactory->FindNode(n34),
2860 myNodeFactory->FindNode(n41),
2861 myNodeFactory->FindNode(n56),
2862 myNodeFactory->FindNode(n67),
2863 myNodeFactory->FindNode(n78),
2864 myNodeFactory->FindNode(n85),
2865 myNodeFactory->FindNode(n15),
2866 myNodeFactory->FindNode(n26),
2867 myNodeFactory->FindNode(n37),
2868 myNodeFactory->FindNode(n48),
2869 myNodeFactory->FindNode(n1234),
2870 myNodeFactory->FindNode(n1256),
2871 myNodeFactory->FindNode(n2367),
2872 myNodeFactory->FindNode(n3478),
2873 myNodeFactory->FindNode(n1458),
2874 myNodeFactory->FindNode(n5678),
2875 myNodeFactory->FindNode(nCenter),
2879 //=======================================================================
2880 //function : AddVolumeWithID
2881 //purpose : 2d order Hexahedrons with 27 nodes
2882 //=======================================================================
2883 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2884 const SMDS_MeshNode * n2,
2885 const SMDS_MeshNode * n3,
2886 const SMDS_MeshNode * n4,
2887 const SMDS_MeshNode * n5,
2888 const SMDS_MeshNode * n6,
2889 const SMDS_MeshNode * n7,
2890 const SMDS_MeshNode * n8,
2891 const SMDS_MeshNode * n12,
2892 const SMDS_MeshNode * n23,
2893 const SMDS_MeshNode * n34,
2894 const SMDS_MeshNode * n41,
2895 const SMDS_MeshNode * n56,
2896 const SMDS_MeshNode * n67,
2897 const SMDS_MeshNode * n78,
2898 const SMDS_MeshNode * n85,
2899 const SMDS_MeshNode * n15,
2900 const SMDS_MeshNode * n26,
2901 const SMDS_MeshNode * n37,
2902 const SMDS_MeshNode * n48,
2903 const SMDS_MeshNode * n1234,
2904 const SMDS_MeshNode * n1256,
2905 const SMDS_MeshNode * n2367,
2906 const SMDS_MeshNode * n3478,
2907 const SMDS_MeshNode * n1458,
2908 const SMDS_MeshNode * n5678,
2909 const SMDS_MeshNode * nCenter,
2912 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2913 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
2914 !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
2916 if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2918 if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
2920 cell->init( SMDSEntity_TriQuad_Hexa, /*nbNodes=*/27, n1, n2, n3, n4, n5, n6, n7, n8,
2921 n12, n23, n34, n41, n56, n67, n78, n85, n15, n26, n37, n48,
2922 n1234, n1256, n2367, n3478, n1458, n5678, nCenter);
2923 myInfo.myNbTriQuadHexas++;
2924 return static_cast<SMDS_MeshVolume*>( cell );
2929 void SMDS_Mesh::dumpGrid(std::string ficdump)
2931 // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
2932 // aWriter->SetFileName(ficdump.c_str());
2933 // aWriter->SetInput(myGrid);
2934 // if(myGrid->GetNumberOfCells())
2936 // aWriter->Write();
2938 // aWriter->Delete();
2939 ficdump = ficdump + "_connectivity";
2940 std::ofstream ficcon(ficdump.c_str(), ios::out);
2941 int nbPoints = myGrid->GetNumberOfPoints();
2942 ficcon << "-------------------------------- points " << nbPoints << endl;
2943 for (int i=0; i<nbPoints; i++)
2945 ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
2947 int nbCells = myGrid->GetNumberOfCells();
2948 ficcon << "-------------------------------- cells " << nbCells << endl;
2949 for (vtkIdType i=0; i<nbCells; i++)
2951 ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
2952 int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
2953 vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
2954 for (int j=0; j<nbptcell; j++)
2956 ficcon << " " << listid->GetId(j);
2960 ficcon << "-------------------------------- connectivity " << nbPoints << endl;
2961 vtkCellLinks *links = myGrid->GetLinks();
2962 for (int i=0; i<nbPoints; i++)
2964 int ncells = links->GetNcells(i);
2965 vtkIdType *cells = links->GetCells(i);
2966 ficcon << i << " - " << ncells << " -";
2967 for (int j=0; j<ncells; j++)
2969 ficcon << " " << cells[j];
2977 void SMDS_Mesh::CompactMesh()
2979 this->myCompactTime = this->myModifTime;
2981 bool idsChange = HasNumerationHoles();
2984 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
2985 for ( ; holder != myElemHolders.end(); ++holder )
2986 (*holder)->beforeCompacting();
2988 smIdType oldCellSize = myCellFactory->GetMaxID();
2990 // remove "holes" in SMDS numeration
2991 std::vector<smIdType> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
2992 myNodeFactory->Compact( idNodesOldToNew );
2993 myCellFactory->Compact( idCellsNewToOld );
2995 // make VTK IDs correspond to SMDS IDs
2996 smIdType newNodeSize = myNodeFactory->NbUsedElements();
2997 smIdType newCellSize = myCellFactory->NbUsedElements();
2998 myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
3000 if ( idsChange && !myElemHolders.empty() )
3002 // idCellsNewToOld -> idCellsOldToNew
3003 idCellsOldToNew.resize( oldCellSize, oldCellSize );
3004 for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
3006 if ( idCellsNewToOld[ iNew ] >= (smIdType) idCellsOldToNew.size() )
3007 idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
3008 idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
3012 std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
3013 for ( ; holder != myElemHolders.end(); ++holder )
3015 (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
3017 (*holder)->compact();
3022 smIdType SMDS_Mesh::FromVtkToSmds( vtkIdType vtkid ) const
3024 return myCellFactory->FromVtkToSmds( vtkid );
3027 double SMDS_Mesh::getMaxDim()
3029 double dmax = 1.e-3;
3030 if ((xmax - xmin) > dmax) dmax = xmax -xmin;
3031 if ((ymax - ymin) > dmax) dmax = ymax -ymin;
3032 if ((zmax - zmin) > dmax) dmax = zmax -zmin;
3036 //! modification that needs compact structure and redraw
3037 void SMDS_Mesh::Modified()
3039 if (this->myModified)
3042 this->myModifTime++;
3047 //! get last modification timeStamp
3048 vtkMTimeType SMDS_Mesh::GetMTime() const
3050 return this->myModifTime;
3053 bool SMDS_Mesh::IsCompacted()
3055 return ( this->myCompactTime == this->myModifTime );
3058 //! are there holes in elements or nodes numeration
3059 bool SMDS_Mesh::HasNumerationHoles()
3061 return ( myNodeFactory->CompactChangePointers() ||
3062 myCellFactory->CompactChangePointers() );
3065 void SMDS_Mesh::setNbShapes( size_t nbShapes )
3067 myNodeFactory->SetNbShapes( nbShapes );