1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // SMESH SMDS : implementaion of Salome mesh data structure
24 #ifdef _MSC_VER
25 #pragma warning(disable:4786)
26 #endif
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
40 #include <algorithm>
41 #include <map>
42 #include <iterator>
43 using namespace std;
45 #ifndef WIN32
46 #if !(defined(__MACH__) && defined(__APPLE__))
47 #include <sys/sysinfo.h>
48 #endif
49 #endif
51 // number of added entitis to check memory after
52 #define CHECKMEMORY_INTERVAL 1000
54 //================================================================================
55 /*!
56 * \brief Raise an exception if free memory (ram+swap) too low
57 * \param doNotRaise - if true, suppres exception, just return free memory size
58 * \retval int - amount of available memory in MB or negative number in failure case
59 */
60 //================================================================================
62 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
63 {
64 #if (defined(__MACH__) && defined(__APPLE__))
65 return 1000;
66 #else
67 #ifndef WIN32
68 struct sysinfo si;
69 int err = sysinfo( &si );
70 if ( err )
71 return -1;
73 static int limit = -1;
74 if ( limit < 0 ) {
75 int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
76 if (status >= 0 ) {
77 limit = WEXITSTATUS(status);
78 }
79 if ( limit < 20 )
80 limit = 20;
81 else
82 limit = int( limit * 1.5 );
83 #ifdef _DEBUG_
84 MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
85 #endif
86 }
88 const unsigned long Mbyte = 1024 * 1024;
89 // compute separately to avoid overflow
90 int freeMb =
91 ( si.freeram * si.mem_unit ) / Mbyte +
92 ( si.freeswap * si.mem_unit ) / Mbyte;
94 if ( freeMb > limit )
95 return freeMb - limit;
97 if ( doNotRaise )
98 return 0;
99 #ifdef _DEBUG_
100 MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
101 #endif
102 throw std::bad_alloc();
103 #else
104 return -1;
105 #endif
106 #endif
107 }
109 ///////////////////////////////////////////////////////////////////////////////
110 /// Create a new mesh object
111 ///////////////////////////////////////////////////////////////////////////////
112 SMDS_Mesh::SMDS_Mesh()
113 :myParent(NULL),
114 myNodeIDFactory(new SMDS_MeshElementIDFactory()),
115 myElementIDFactory(new SMDS_MeshElementIDFactory()),
116 myHasConstructionEdges(false), myHasConstructionFaces(false),
117 myHasInverseElements(true)
118 {
119 }
121 ///////////////////////////////////////////////////////////////////////////////
122 /// Create a new child mesh
123 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
124 /// (2003-09-08) of SMESH
125 ///////////////////////////////////////////////////////////////////////////////
126 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
127 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
128 myElementIDFactory(parent->myElementIDFactory),
129 myHasConstructionEdges(false), myHasConstructionFaces(false),
130 myHasInverseElements(true)
131 {
132 }
134 ///////////////////////////////////////////////////////////////////////////////
135 ///Create a submesh and add it to the current mesh
136 ///////////////////////////////////////////////////////////////////////////////
138 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
139 {
140 SMDS_Mesh *submesh = new SMDS_Mesh(this);
141 myChildren.insert(myChildren.end(), submesh);
142 return submesh;
143 }
145 ///////////////////////////////////////////////////////////////////////////////
146 ///create a MeshNode and add it to the current Mesh
147 ///An ID is automatically assigned to the node.
148 ///@return : The created node
149 ///////////////////////////////////////////////////////////////////////////////
151 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
152 {
153 return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
154 }
156 ///////////////////////////////////////////////////////////////////////////////
157 ///create a MeshNode and add it to the current Mesh
158 ///@param ID : The ID of the MeshNode to create
159 ///@return : The created node or NULL if a node with this ID already exists
160 ///////////////////////////////////////////////////////////////////////////////
161 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
162 {
163 // find the MeshNode corresponding to ID
164 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
165 if(!node){
166 if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
167 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
168 myNodes.Add(node);
169 myNodeIDFactory->BindID(ID,node);
170 myInfo.myNbNodes++;
171 return node;
172 }else
173 return NULL;
174 }
176 ///////////////////////////////////////////////////////////////////////////////
177 /// create a Mesh0DElement and add it to the current Mesh
178 /// @return : The created Mesh0DElement
179 ///////////////////////////////////////////////////////////////////////////////
180 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
181 {
182 SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
183 if (!node) return NULL;
184 return SMDS_Mesh::Add0DElementWithID(node, ID);
185 }
187 ///////////////////////////////////////////////////////////////////////////////
188 /// create a Mesh0DElement and add it to the current Mesh
189 /// @return : The created Mesh0DElement
190 ///////////////////////////////////////////////////////////////////////////////
191 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
192 {
193 return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
194 }
196 ///////////////////////////////////////////////////////////////////////////////
197 /// Create a new Mesh0DElement and at it to the mesh
198 /// @param idnode ID of the node
199 /// @param ID ID of the 0D element to create
200 /// @return The created 0D element or NULL if an element with this
201 /// ID already exists or if input node is not found.
202 ///////////////////////////////////////////////////////////////////////////////
203 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
204 {
205 if (!n) return 0;
207 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
209 SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
210 if (myElementIDFactory->BindID(ID, el0d)) {
211 SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
212 node->AddInverseElement(el0d);
213 my0DElements.Add(el0d);
214 myInfo.myNb0DElements++;
215 return el0d;
216 }
218 delete el0d;
219 return NULL;
220 }
222 ///////////////////////////////////////////////////////////////////////////////
223 /// create a MeshEdge and add it to the current Mesh
224 /// @return : The created MeshEdge
225 ///////////////////////////////////////////////////////////////////////////////
227 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
228 {
229 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
230 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
231 if(!node1 || !node2) return NULL;
232 return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
233 }
235 ///////////////////////////////////////////////////////////////////////////////
236 /// create a MeshEdge and add it to the current Mesh
237 /// @return : The created MeshEdge
238 ///////////////////////////////////////////////////////////////////////////////
240 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
241 const SMDS_MeshNode * node2)
242 {
243 return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
244 }
246 ///////////////////////////////////////////////////////////////////////////////
247 /// Create a new edge and at it to the mesh
248 /// @param idnode1 ID of the first node
249 /// @param idnode2 ID of the second node
250 /// @param ID ID of the edge to create
251 /// @return The created edge or NULL if an element with this ID already exists or
252 /// if input nodes are not found.
253 ///////////////////////////////////////////////////////////////////////////////
255 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
256 const SMDS_MeshNode * n2,
257 int ID)
258 {
259 if ( !n1 || !n2 ) return 0;
261 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
263 SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
264 if(myElementIDFactory->BindID(ID, edge)) {
265 SMDS_MeshNode *node1,*node2;
266 node1=const_cast<SMDS_MeshNode*>(n1);
267 node2=const_cast<SMDS_MeshNode*>(n2);
268 node1->AddInverseElement(edge);
269 node2->AddInverseElement(edge);
270 myEdges.Add(edge);
271 myInfo.myNbEdges++;
272 return edge;
273 }
274 else {
275 delete edge;
276 return NULL;
277 }
278 }
280 ///////////////////////////////////////////////////////////////////////////////
281 /// Add a triangle defined by its nodes. An ID is automatically affected to the
282 /// Created face
283 ///////////////////////////////////////////////////////////////////////////////
285 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
286 const SMDS_MeshNode * n2,
287 const SMDS_MeshNode * n3)
288 {
289 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
290 }
292 ///////////////////////////////////////////////////////////////////////////////
293 /// Add a triangle defined by its nodes IDs
294 ///////////////////////////////////////////////////////////////////////////////
296 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
297 {
298 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
299 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
300 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
301 if(!node1 || !node2 || !node3) return NULL;
302 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
303 }
305 ///////////////////////////////////////////////////////////////////////////////
306 /// Add a triangle defined by its nodes
307 ///////////////////////////////////////////////////////////////////////////////
309 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
310 const SMDS_MeshNode * n2,
311 const SMDS_MeshNode * n3,
312 int ID)
313 {
314 SMDS_MeshFace * face=createTriangle(n1, n2, n3);
316 if (face && !registerElement(ID, face)) {
317 RemoveElement(face, false);
318 face = NULL;
319 }
320 return face;
321 }
323 ///////////////////////////////////////////////////////////////////////////////
324 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
325 /// created face
326 ///////////////////////////////////////////////////////////////////////////////
328 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
329 const SMDS_MeshNode * n2,
330 const SMDS_MeshNode * n3,
331 const SMDS_MeshNode * n4)
332 {
333 return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
334 }
336 ///////////////////////////////////////////////////////////////////////////////
337 /// Add a quadrangle defined by its nodes IDs
338 ///////////////////////////////////////////////////////////////////////////////
340 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
341 int idnode2,
342 int idnode3,
343 int idnode4,
344 int ID)
345 {
346 SMDS_MeshNode *node1, *node2, *node3, *node4;
347 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
348 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
349 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
350 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
351 if(!node1 || !node2 || !node3 || !node4) return NULL;
352 return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
353 }
355 ///////////////////////////////////////////////////////////////////////////////
356 /// Add a quadrangle defined by its nodes
357 ///////////////////////////////////////////////////////////////////////////////
359 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
360 const SMDS_MeshNode * n2,
361 const SMDS_MeshNode * n3,
362 const SMDS_MeshNode * n4,
363 int ID)
364 {
365 SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
367 if (face && !registerElement(ID, face)) {
368 RemoveElement(face, false);
369 face = NULL;
370 }
371 return face;
372 }
374 ///////////////////////////////////////////////////////////////////////////////
375 /// Add a triangle defined by its edges. An ID is automatically assigned to the
376 /// Created face
377 ///////////////////////////////////////////////////////////////////////////////
379 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
380 const SMDS_MeshEdge * e2,
381 const SMDS_MeshEdge * e3)
382 {
383 if (!hasConstructionEdges())
384 return NULL;
385 return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
386 }
388 ///////////////////////////////////////////////////////////////////////////////
389 /// Add a triangle defined by its edges
390 ///////////////////////////////////////////////////////////////////////////////
392 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
393 const SMDS_MeshEdge * e2,
394 const SMDS_MeshEdge * e3,
395 int ID)
396 {
397 if (!hasConstructionEdges())
398 return NULL;
399 if ( !e1 || !e2 || !e3 ) return 0;
401 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
403 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
404 myFaces.Add(face);
405 myInfo.myNbTriangles++;
407 if (!registerElement(ID, face)) {
408 RemoveElement(face, false);
409 face = NULL;
410 }
411 return face;
412 }
414 ///////////////////////////////////////////////////////////////////////////////
415 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
416 /// Created face
417 ///////////////////////////////////////////////////////////////////////////////
419 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
420 const SMDS_MeshEdge * e2,
421 const SMDS_MeshEdge * e3,
422 const SMDS_MeshEdge * e4)
423 {
424 if (!hasConstructionEdges())
425 return NULL;
426 return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
427 }
429 ///////////////////////////////////////////////////////////////////////////////
430 /// Add a quadrangle defined by its edges
431 ///////////////////////////////////////////////////////////////////////////////
433 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
434 const SMDS_MeshEdge * e2,
435 const SMDS_MeshEdge * e3,
436 const SMDS_MeshEdge * e4,
437 int ID)
438 {
439 if (!hasConstructionEdges())
440 return NULL;
441 if ( !e1 || !e2 || !e3 || !e4 ) return 0;
442 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
443 SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
444 myFaces.Add(face);
445 myInfo.myNbQuadrangles++;
447 if (!registerElement(ID, face))
448 {
449 RemoveElement(face, false);
450 face = NULL;
451 }
452 return face;
453 }
455 ///////////////////////////////////////////////////////////////////////////////
456 ///Create a new tetrahedron and add it to the mesh.
457 ///@return The created tetrahedron
458 ///////////////////////////////////////////////////////////////////////////////
460 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
461 const SMDS_MeshNode * n2,
462 const SMDS_MeshNode * n3,
463 const SMDS_MeshNode * n4)
464 {
465 int ID = myElementIDFactory->GetFreeID();
466 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
467 if(v==NULL) myElementIDFactory->ReleaseID(ID);
468 return v;
469 }
471 ///////////////////////////////////////////////////////////////////////////////
472 ///Create a new tetrahedron and add it to the mesh.
473 ///@param ID The ID of the new volume
474 ///@return The created tetrahedron or NULL if an element with this ID already exists
475 ///or if input nodes are not found.
476 ///////////////////////////////////////////////////////////////////////////////
478 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
479 int idnode2,
480 int idnode3,
481 int idnode4,
482 int ID)
483 {
484 SMDS_MeshNode *node1, *node2, *node3, *node4;
485 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
486 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
487 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
488 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
489 if(!node1 || !node2 || !node3 || !node4) return NULL;
490 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
491 }
493 ///////////////////////////////////////////////////////////////////////////////
494 ///Create a new tetrahedron and add it to the mesh.
495 ///@param ID The ID of the new volume
496 ///@return The created tetrahedron
497 ///////////////////////////////////////////////////////////////////////////////
499 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
500 const SMDS_MeshNode * n2,
501 const SMDS_MeshNode * n3,
502 const SMDS_MeshNode * n4,
503 int ID)
504 {
505 SMDS_MeshVolume* volume = 0;
506 if ( !n1 || !n2 || !n3 || !n4) return volume;
507 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
508 if(hasConstructionFaces()) {
509 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
510 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
511 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
512 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
513 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
514 myVolumes.Add(volume);
515 myInfo.myNbTetras++;
516 }
517 else if(hasConstructionEdges()) {
518 MESSAGE("Error : Not implemented");
519 return NULL;
520 }
521 else {
522 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
523 myVolumes.Add(volume);
524 myInfo.myNbTetras++;
525 }
527 if (!registerElement(ID, volume)) {
528 RemoveElement(volume, false);
529 volume = NULL;
530 }
531 return volume;
532 }
534 ///////////////////////////////////////////////////////////////////////////////
535 ///Create a new pyramid and add it to the mesh.
536 ///Nodes 1,2,3 and 4 define the base of the pyramid
537 ///@return The created pyramid
538 ///////////////////////////////////////////////////////////////////////////////
540 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
541 const SMDS_MeshNode * n2,
542 const SMDS_MeshNode * n3,
543 const SMDS_MeshNode * n4,
544 const SMDS_MeshNode * n5)
545 {
546 int ID = myElementIDFactory->GetFreeID();
547 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
548 if(v==NULL) myElementIDFactory->ReleaseID(ID);
549 return v;
550 }
552 ///////////////////////////////////////////////////////////////////////////////
553 ///Create a new pyramid and add it to the mesh.
554 ///Nodes 1,2,3 and 4 define the base of the pyramid
555 ///@param ID The ID of the new volume
556 ///@return The created pyramid or NULL if an element with this ID already exists
557 ///or if input nodes are not found.
558 ///////////////////////////////////////////////////////////////////////////////
560 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
561 int idnode2,
562 int idnode3,
563 int idnode4,
564 int idnode5,
565 int ID)
566 {
567 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
568 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
569 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
570 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
571 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
572 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
573 if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
574 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
575 }
577 ///////////////////////////////////////////////////////////////////////////////
578 ///Create a new pyramid and add it to the mesh.
579 ///Nodes 1,2,3 and 4 define the base of the pyramid
580 ///@param ID The ID of the new volume
581 ///@return The created pyramid
582 ///////////////////////////////////////////////////////////////////////////////
584 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
585 const SMDS_MeshNode * n2,
586 const SMDS_MeshNode * n3,
587 const SMDS_MeshNode * n4,
588 const SMDS_MeshNode * n5,
589 int ID)
590 {
591 SMDS_MeshVolume* volume = 0;
592 if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
593 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
594 if(hasConstructionFaces()) {
595 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
596 SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
597 SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
598 SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
599 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
600 myVolumes.Add(volume);
601 myInfo.myNbPyramids++;
602 }
603 else if(hasConstructionEdges()) {
604 MESSAGE("Error : Not implemented");
605 return NULL;
606 }
607 else {
608 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
609 myVolumes.Add(volume);
610 myInfo.myNbPyramids++;
611 }
613 if (!registerElement(ID, volume)) {
614 RemoveElement(volume, false);
615 volume = NULL;
616 }
617 return volume;
618 }
620 ///////////////////////////////////////////////////////////////////////////////
621 ///Create a new prism and add it to the mesh.
622 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
623 ///@return The created prism
624 ///////////////////////////////////////////////////////////////////////////////
626 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
627 const SMDS_MeshNode * n2,
628 const SMDS_MeshNode * n3,
629 const SMDS_MeshNode * n4,
630 const SMDS_MeshNode * n5,
631 const SMDS_MeshNode * n6)
632 {
633 int ID = myElementIDFactory->GetFreeID();
634 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
635 if(v==NULL) myElementIDFactory->ReleaseID(ID);
636 return v;
637 }
639 ///////////////////////////////////////////////////////////////////////////////
640 ///Create a new prism and add it to the mesh.
641 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
642 ///@param ID The ID of the new volume
643 ///@return The created prism or NULL if an element with this ID already exists
644 ///or if input nodes are not found.
645 ///////////////////////////////////////////////////////////////////////////////
647 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
648 int idnode2,
649 int idnode3,
650 int idnode4,
651 int idnode5,
652 int idnode6,
653 int ID)
654 {
655 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
656 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
657 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
658 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
659 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
660 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
661 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
662 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
663 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
664 }
666 ///////////////////////////////////////////////////////////////////////////////
667 ///Create a new prism and add it to the mesh.
668 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
669 ///@param ID The ID of the new volume
670 ///@return The created prism
671 ///////////////////////////////////////////////////////////////////////////////
673 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
674 const SMDS_MeshNode * n2,
675 const SMDS_MeshNode * n3,
676 const SMDS_MeshNode * n4,
677 const SMDS_MeshNode * n5,
678 const SMDS_MeshNode * n6,
679 int ID)
680 {
681 SMDS_MeshVolume* volume = 0;
682 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
683 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
684 if(hasConstructionFaces()) {
685 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
686 SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
687 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
688 SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
689 SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
690 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
691 myVolumes.Add(volume);
692 myInfo.myNbPrisms++;
693 }
694 else if(hasConstructionEdges()) {
695 MESSAGE("Error : Not implemented");
696 return NULL;
697 }
698 else {
699 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
700 myVolumes.Add(volume);
701 myInfo.myNbPrisms++;
702 }
704 if (!registerElement(ID, volume)) {
705 RemoveElement(volume, false);
706 volume = NULL;
707 }
708 return volume;
709 }
711 ///////////////////////////////////////////////////////////////////////////////
712 ///Create a new hexahedron and add it to the mesh.
713 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
714 ///@return The created hexahedron
715 ///////////////////////////////////////////////////////////////////////////////
717 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
718 const SMDS_MeshNode * n2,
719 const SMDS_MeshNode * n3,
720 const SMDS_MeshNode * n4,
721 const SMDS_MeshNode * n5,
722 const SMDS_MeshNode * n6,
723 const SMDS_MeshNode * n7,
724 const SMDS_MeshNode * n8)
725 {
726 int ID = myElementIDFactory->GetFreeID();
727 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
728 if(v==NULL) myElementIDFactory->ReleaseID(ID);
729 return v;
730 }
732 ///////////////////////////////////////////////////////////////////////////////
733 ///Create a new hexahedron and add it to the mesh.
734 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
735 ///@param ID The ID of the new volume
736 ///@return The created hexahedron or NULL if an element with this ID already
737 ///exists or if input nodes are not found.
738 ///////////////////////////////////////////////////////////////////////////////
740 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
741 int idnode2,
742 int idnode3,
743 int idnode4,
744 int idnode5,
745 int idnode6,
746 int idnode7,
747 int idnode8,
748 int ID)
749 {
750 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
751 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
752 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
753 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
754 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
755 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
756 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
757 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
758 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
759 if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
760 return NULL;
761 return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
762 node7, node8, ID);
763 }
765 ///////////////////////////////////////////////////////////////////////////////
766 ///Create a new hexahedron and add it to the mesh.
767 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
768 ///@param ID The ID of the new volume
769 ///@return The created prism or NULL if an element with this ID already exists
770 ///or if input nodes are not found.
771 ///////////////////////////////////////////////////////////////////////////////
773 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
774 const SMDS_MeshNode * n2,
775 const SMDS_MeshNode * n3,
776 const SMDS_MeshNode * n4,
777 const SMDS_MeshNode * n5,
778 const SMDS_MeshNode * n6,
779 const SMDS_MeshNode * n7,
780 const SMDS_MeshNode * n8,
781 int ID)
782 {
783 SMDS_MeshVolume* volume = 0;
784 if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
785 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
786 if(hasConstructionFaces()) {
787 SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
788 SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
789 SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
790 SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
791 SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
792 SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
793 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
794 myVolumes.Add(volume);
795 myInfo.myNbHexas++;
796 }
797 else if(hasConstructionEdges()) {
798 MESSAGE("Error : Not implemented");
799 return NULL;
800 }
801 else {
802 // volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
803 volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
804 myVolumes.Add(volume);
805 myInfo.myNbHexas++;
806 }
808 if (!registerElement(ID, volume)) {
809 RemoveElement(volume, false);
810 volume = NULL;
811 }
812 return volume;
813 }
815 ///////////////////////////////////////////////////////////////////////////////
816 ///Create a new tetrahedron defined by its faces and add it to the mesh.
817 ///@return The created tetrahedron
818 ///////////////////////////////////////////////////////////////////////////////
820 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
821 const SMDS_MeshFace * f2,
822 const SMDS_MeshFace * f3,
823 const SMDS_MeshFace * f4)
824 {
825 if (!hasConstructionFaces())
826 return NULL;
827 return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
828 }
830 ///////////////////////////////////////////////////////////////////////////////
831 ///Create a new tetrahedron defined by its faces and add it to the mesh.
832 ///@param ID The ID of the new volume
833 ///@return The created tetrahedron
834 ///////////////////////////////////////////////////////////////////////////////
836 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
837 const SMDS_MeshFace * f2,
838 const SMDS_MeshFace * f3,
839 const SMDS_MeshFace * f4,
840 int ID)
841 {
842 if (!hasConstructionFaces())
843 return NULL;
844 if ( !f1 || !f2 || !f3 || !f4) return 0;
845 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
846 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
847 myVolumes.Add(volume);
848 myInfo.myNbTetras++;
850 if (!registerElement(ID, volume)) {
851 RemoveElement(volume, false);
852 volume = NULL;
853 }
854 return volume;
855 }
857 ///////////////////////////////////////////////////////////////////////////////
858 ///Create a new pyramid defined by its faces and add it to the mesh.
859 ///@return The created pyramid
860 ///////////////////////////////////////////////////////////////////////////////
862 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
863 const SMDS_MeshFace * f2,
864 const SMDS_MeshFace * f3,
865 const SMDS_MeshFace * f4,
866 const SMDS_MeshFace * f5)
867 {
868 if (!hasConstructionFaces())
869 return NULL;
870 return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
871 }
873 ///////////////////////////////////////////////////////////////////////////////
874 ///Create a new pyramid defined by its faces and add it to the mesh.
875 ///@param ID The ID of the new volume
876 ///@return The created pyramid
877 ///////////////////////////////////////////////////////////////////////////////
879 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
880 const SMDS_MeshFace * f2,
881 const SMDS_MeshFace * f3,
882 const SMDS_MeshFace * f4,
883 const SMDS_MeshFace * f5,
884 int ID)
885 {
886 if (!hasConstructionFaces())
887 return NULL;
888 if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
889 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
890 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
891 myVolumes.Add(volume);
892 myInfo.myNbPyramids++;
894 if (!registerElement(ID, volume)) {
895 RemoveElement(volume, false);
896 volume = NULL;
897 }
898 return volume;
899 }
901 ///////////////////////////////////////////////////////////////////////////////
902 ///Create a new prism defined by its faces and add it to the mesh.
903 ///@return The created prism
904 ///////////////////////////////////////////////////////////////////////////////
906 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
907 const SMDS_MeshFace * f2,
908 const SMDS_MeshFace * f3,
909 const SMDS_MeshFace * f4,
910 const SMDS_MeshFace * f5,
911 const SMDS_MeshFace * f6)
912 {
913 if (!hasConstructionFaces())
914 return NULL;
915 return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
916 }
918 ///////////////////////////////////////////////////////////////////////////////
919 ///Create a new prism defined by its faces and add it to the mesh.
920 ///@param ID The ID of the new volume
921 ///@return The created prism
922 ///////////////////////////////////////////////////////////////////////////////
924 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
925 const SMDS_MeshFace * f2,
926 const SMDS_MeshFace * f3,
927 const SMDS_MeshFace * f4,
928 const SMDS_MeshFace * f5,
929 const SMDS_MeshFace * f6,
930 int ID)
931 {
932 if (!hasConstructionFaces())
933 return NULL;
934 if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
935 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
936 SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
937 myVolumes.Add(volume);
938 myInfo.myNbPrisms++;
940 if (!registerElement(ID, volume)) {
941 RemoveElement(volume, false);
942 volume = NULL;
943 }
944 return volume;
945 }
947 ///////////////////////////////////////////////////////////////////////////////
948 /// Add a polygon defined by its nodes IDs
949 ///////////////////////////////////////////////////////////////////////////////
951 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
952 const int ID)
953 {
954 int nbNodes = nodes_ids.size();
955 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
956 for (int i = 0; i < nbNodes; i++) {
957 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
958 if (!nodes[i]) return NULL;
959 }
960 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
961 }
963 ///////////////////////////////////////////////////////////////////////////////
964 /// Add a polygon defined by its nodes
965 ///////////////////////////////////////////////////////////////////////////////
967 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
968 (std::vector<const SMDS_MeshNode*> nodes,
969 const int ID)
970 {
971 SMDS_MeshFace * face;
973 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
974 if (hasConstructionEdges())
975 {
976 MESSAGE("Error : Not implemented");
977 return NULL;
978 }
979 else
980 {
981 for ( int i = 0; i < nodes.size(); ++i )
982 if ( !nodes[ i ] ) return 0;
983 face = new SMDS_PolygonalFaceOfNodes(nodes);
984 myFaces.Add(face);
985 myInfo.myNbPolygons++;
986 }
988 if (!registerElement(ID, face)) {
989 RemoveElement(face, false);
990 face = NULL;
991 }
992 return face;
993 }
995 ///////////////////////////////////////////////////////////////////////////////
996 /// Add a polygon defined by its nodes.
997 /// An ID is automatically affected to the created face.
998 ///////////////////////////////////////////////////////////////////////////////
1000 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1001 {
1002 return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1003 }
1005 ///////////////////////////////////////////////////////////////////////////////
1006 /// Create a new polyhedral volume and add it to the mesh.
1007 /// @param ID The ID of the new volume
1008 /// @return The created volume or NULL if an element with this ID already exists
1009 /// or if input nodes are not found.
1010 ///////////////////////////////////////////////////////////////////////////////
1012 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1013 (std::vector<int> nodes_ids,
1014 std::vector<int> quantities,
1015 const int ID)
1016 {
1017 int nbNodes = nodes_ids.size();
1018 std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1019 for (int i = 0; i < nbNodes; i++) {
1020 nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1021 if (!nodes[i]) return NULL;
1022 }
1023 return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1024 }
1026 ///////////////////////////////////////////////////////////////////////////////
1027 /// Create a new polyhedral volume and add it to the mesh.
1028 /// @param ID The ID of the new volume
1029 /// @return The created volume
1030 ///////////////////////////////////////////////////////////////////////////////
1032 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1033 (std::vector<const SMDS_MeshNode*> nodes,
1034 std::vector<int> quantities,
1035 const int ID)
1036 {
1037 SMDS_MeshVolume* volume;
1038 if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1039 if (hasConstructionFaces()) {
1040 MESSAGE("Error : Not implemented");
1041 return NULL;
1042 } else if (hasConstructionEdges()) {
1043 MESSAGE("Error : Not implemented");
1044 return NULL;
1045 } else {
1046 for ( int i = 0; i < nodes.size(); ++i )
1047 if ( !nodes[ i ] ) return 0;
1048 volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1049 myVolumes.Add(volume);
1050 myInfo.myNbPolyhedrons++;
1051 }
1053 if (!registerElement(ID, volume)) {
1054 RemoveElement(volume, false);
1055 volume = NULL;
1056 }
1057 return volume;
1058 }
1060 ///////////////////////////////////////////////////////////////////////////////
1061 /// Create a new polyhedral volume and add it to the mesh.
1062 /// @return The created volume
1063 ///////////////////////////////////////////////////////////////////////////////
1065 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1066 (std::vector<const SMDS_MeshNode*> nodes,
1067 std::vector<int> quantities)
1068 {
1069 int ID = myElementIDFactory->GetFreeID();
1070 SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1071 if (v == NULL) myElementIDFactory->ReleaseID(ID);
1072 return v;
1073 }
1075 ///////////////////////////////////////////////////////////////////////////////
1076 /// Registers element with the given ID, maintains inverse connections
1077 ///////////////////////////////////////////////////////////////////////////////
1078 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
1079 {
1080 if (myElementIDFactory->BindID(ID, element)) {
1081 SMDS_ElemIteratorPtr it = element->nodesIterator();
1082 while (it->more()) {
1083 SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
1084 (const_cast<SMDS_MeshElement*>(it->next()));
1085 node->AddInverseElement(element);
1086 }
1087 return true;
1088 }
1089 return false;
1090 }
1092 ///////////////////////////////////////////////////////////////////////////////
1093 /// Return the node whose ID is 'ID'.
1094 ///////////////////////////////////////////////////////////////////////////////
1095 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1096 {
1097 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1098 }
1100 ///////////////////////////////////////////////////////////////////////////////
1101 ///Create a triangle and add it to the current mesh. This methode do not bind a
1102 ///ID to the create triangle.
1103 ///////////////////////////////////////////////////////////////////////////////
1104 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1105 const SMDS_MeshNode * node2,
1106 const SMDS_MeshNode * node3)
1107 {
1108 if ( !node1 || !node2 || !node3) return 0;
1109 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1110 if(hasConstructionEdges())
1111 {
1112 SMDS_MeshEdge *edge1, *edge2, *edge3;
1113 edge1=FindEdgeOrCreate(node1,node2);
1114 edge2=FindEdgeOrCreate(node2,node3);
1115 edge3=FindEdgeOrCreate(node3,node1);
1117 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1118 myFaces.Add(face);
1119 myInfo.myNbTriangles++;
1120 return face;
1121 }
1122 else
1123 {
1124 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1125 myFaces.Add(face);
1126 myInfo.myNbTriangles++;
1127 return face;
1128 }
1129 }
1131 ///////////////////////////////////////////////////////////////////////////////
1132 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1133 ///a ID to the create triangle.
1134 ///////////////////////////////////////////////////////////////////////////////
1135 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1136 const SMDS_MeshNode * node2,
1137 const SMDS_MeshNode * node3,
1138 const SMDS_MeshNode * node4)
1139 {
1140 if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1141 if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1142 if(hasConstructionEdges())
1143 {
1144 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1145 edge1=FindEdgeOrCreate(node1,node2);
1146 edge2=FindEdgeOrCreate(node2,node3);
1147 edge3=FindEdgeOrCreate(node3,node4);
1148 edge4=FindEdgeOrCreate(node4,node1);
1150 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1151 myFaces.Add(face);
1152 myInfo.myNbQuadrangles++;
1153 return face;
1154 }
1155 else
1156 {
1157 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1158 myFaces.Add(face);
1159 myInfo.myNbQuadrangles++;
1160 return face;
1161 }
1162 }
1164 ///////////////////////////////////////////////////////////////////////////////
1165 /// Remove a node and all the elements which own this node
1166 ///////////////////////////////////////////////////////////////////////////////
1168 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1169 {
1170 RemoveElement(node, true);
1171 }
1173 ///////////////////////////////////////////////////////////////////////////////
1174 /// Remove an edge and all the elements which own this edge
1175 ///////////////////////////////////////////////////////////////////////////////
1177 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1178 {
1179 RemoveElement(elem0d,true);
1180 }
1182 ///////////////////////////////////////////////////////////////////////////////
1183 /// Remove an edge and all the elements which own this edge
1184 ///////////////////////////////////////////////////////////////////////////////
1186 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1187 {
1188 RemoveElement(edge,true);
1189 }
1191 ///////////////////////////////////////////////////////////////////////////////
1192 /// Remove an face and all the elements which own this face
1193 ///////////////////////////////////////////////////////////////////////////////
1195 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1196 {
1197 RemoveElement(face, true);
1198 }
1200 ///////////////////////////////////////////////////////////////////////////////
1201 /// Remove a volume
1202 ///////////////////////////////////////////////////////////////////////////////
1204 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1205 {
1206 RemoveElement(volume, true);
1207 }
1209 //=======================================================================
1210 //function : RemoveFromParent
1211 //purpose :
1212 //=======================================================================
1214 bool SMDS_Mesh::RemoveFromParent()
1215 {
1216 if (myParent==NULL) return false;
1217 else return (myParent->RemoveSubMesh(this));
1218 }
1220 //=======================================================================
1221 //function : RemoveSubMesh
1222 //purpose :
1223 //=======================================================================
1225 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1226 {
1227 bool found = false;
1229 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1230 for (; itmsh!=myChildren.end() && !found; itmsh++)
1231 {
1232 SMDS_Mesh * submesh = *itmsh;
1233 if (submesh == aMesh)
1234 {
1235 found = true;
1236 myChildren.erase(itmsh);
1237 }
1238 }
1240 return found;
1241 }
1243 //=======================================================================
1244 //function : ChangeElementNodes
1245 //purpose :
1246 //=======================================================================
1248 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1249 const SMDS_MeshNode * nodes[],
1250 const int nbnodes)
1251 {
1252 // keep current nodes of elem
1253 set<const SMDS_MeshElement*> oldNodes;
1254 SMDS_ElemIteratorPtr itn = element->nodesIterator();
1255 while(itn->more())
1256 oldNodes.insert( itn->next() );
1258 if ( !element->IsPoly() )
1259 myInfo.remove( element ); // element may change type
1261 // change nodes
1262 bool Ok = false;
1263 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1264 switch ( elem->GetType() )
1265 {
1266 case SMDSAbs_0DElement: {
1267 if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1268 Ok = elem0d->ChangeNode( nodes[0] );
1269 break;
1270 }
1271 case SMDSAbs_Edge: {
1272 if ( nbnodes == 2 ) {
1273 if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
1274 Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1275 }
1276 else if ( nbnodes == 3 ) {
1277 if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1278 Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1279 }
1280 break;
1281 }
1282 case SMDSAbs_Face: {
1283 if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1284 Ok = face->ChangeNodes( nodes, nbnodes );
1285 else
1286 if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1287 Ok = QF->ChangeNodes( nodes, nbnodes );
1288 else
1289 if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1290 Ok = face->ChangeNodes(nodes, nbnodes);
1291 break;
1292 }
1293 case SMDSAbs_Volume: {
1294 if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1295 Ok = vol->ChangeNodes( nodes, nbnodes );
1296 else
1297 if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1298 Ok = QV->ChangeNodes( nodes, nbnodes );
1299 break;
1300 }
1301 default:
1302 MESSAGE ( "WRONG ELEM TYPE");
1303 }
1305 if ( Ok ) { // update InverseElements
1307 set<const SMDS_MeshElement*>::iterator it;
1309 // AddInverseElement to new nodes
1310 for ( int i = 0; i < nbnodes; i++ ) {
1311 it = oldNodes.find( nodes[i] );
1312 if ( it == oldNodes.end() )
1313 // new node
1314 const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1315 else
1316 // remove from oldNodes a node that remains in elem
1317 oldNodes.erase( it );
1318 }
1319 // RemoveInverseElement from the nodes removed from elem
1320 for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1321 {
1322 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1323 (const_cast<SMDS_MeshElement *>( *it ));
1324 n->RemoveInverseElement( elem );
1325 }
1326 }
1328 if ( !element->IsPoly() )
1329 myInfo.add( element ); // element may change type
1331 return Ok;
1332 }
1334 //=======================================================================
1335 //function : ChangePolyhedronNodes
1336 //purpose : to change nodes of polyhedral volume
1337 //=======================================================================
1338 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1339 const vector<const SMDS_MeshNode*>& nodes,
1340 const vector<int> & quantities)
1341 {
1342 if (elem->GetType() != SMDSAbs_Volume) {
1343 MESSAGE("WRONG ELEM TYPE");
1344 return false;
1345 }
1347 const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1348 if (!vol) {
1349 return false;
1350 }
1352 // keep current nodes of elem
1353 set<const SMDS_MeshElement*> oldNodes;
1354 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1355 while (itn->more()) {
1356 oldNodes.insert(itn->next());
1357 }
1359 // change nodes
1360 bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1361 if (!Ok) {
1362 return false;
1363 }
1365 // update InverseElements
1367 // AddInverseElement to new nodes
1368 int nbnodes = nodes.size();
1369 set<const SMDS_MeshElement*>::iterator it;
1370 for (int i = 0; i < nbnodes; i++) {
1371 it = oldNodes.find(nodes[i]);
1372 if (it == oldNodes.end()) {
1373 // new node
1374 const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1375 } else {
1376 // remove from oldNodes a node that remains in elem
1377 oldNodes.erase(it);
1378 }
1379 }
1381 // RemoveInverseElement from the nodes removed from elem
1382 for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1383 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1384 (const_cast<SMDS_MeshElement *>( *it ));
1385 n->RemoveInverseElement(elem);
1386 }
1388 return Ok;
1389 }
1392 //=======================================================================
1393 //function : Find0DElement
1394 //purpose :
1395 //=======================================================================
1396 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1397 {
1398 const SMDS_MeshNode * node = FindNode(idnode);
1399 if(node == NULL) return NULL;
1400 return Find0DElement(node);
1401 }
1403 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1404 {
1405 if (!node) return 0;
1406 const SMDS_Mesh0DElement* toReturn = NULL;
1407 SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1408 while (it1->more() && (toReturn == NULL)) {
1409 const SMDS_MeshElement* e = it1->next();
1410 if (e->NbNodes() == 1) {
1411 toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1412 }
1413 }
1414 return toReturn;
1415 }
1417 //=======================================================================
1418 //function : Find0DElementOrCreate
1419 //purpose :
1420 //=======================================================================
1421 SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1422 {
1423 if (!node) return 0;
1424 SMDS_Mesh0DElement * toReturn = NULL;
1425 toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1426 if (toReturn == NULL) {
1427 if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1428 toReturn = new SMDS_Mesh0DElement(node);
1429 my0DElements.Add(toReturn);
1430 myInfo.myNb0DElements++;
1431 }
1432 return toReturn;
1433 }
1436 //=======================================================================
1437 //function : FindEdge
1438 //purpose :
1439 //=======================================================================
1441 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1442 {
1443 const SMDS_MeshNode * node1=FindNode(idnode1);
1444 const SMDS_MeshNode * node2=FindNode(idnode2);
1445 if((node1==NULL)||(node2==NULL)) return NULL;
1446 return FindEdge(node1,node2);
1447 }
1449 //#include "Profiler.h"
1450 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1451 const SMDS_MeshNode * node2)
1452 {
1453 if ( !node1 ) return 0;
1454 const SMDS_MeshEdge * toReturn=NULL;
1455 //PROFILER_Init();
1456 //PROFILER_Set();
1457 SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1458 //PROFILER_Get(0);
1459 //PROFILER_Set();
1460 while(it1->more()) {
1461 const SMDS_MeshElement * e = it1->next();
1462 if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1463 toReturn = static_cast<const SMDS_MeshEdge*>( e );
1464 break;
1465 }
1466 }
1467 //PROFILER_Get(1);
1468 return toReturn;
1469 }
1472 //=======================================================================
1473 //function : FindEdgeOrCreate
1474 //purpose :
1475 //=======================================================================
1477 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1478 const SMDS_MeshNode * node2)
1479 {
1480 if ( !node1 || !node2) return 0;
1481 SMDS_MeshEdge * toReturn=NULL;
1482 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1483 if(toReturn==NULL) {
1484 if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1485 toReturn=new SMDS_MeshEdge(node1,node2);
1486 myEdges.Add(toReturn);
1487 myInfo.myNbEdges++;
1488 }
1489 return toReturn;
1490 }
1493 //=======================================================================
1494 //function : FindEdge
1495 //purpose :
1496 //=======================================================================
1498 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1499 int idnode3) const
1500 {
1501 const SMDS_MeshNode * node1=FindNode(idnode1);
1502 const SMDS_MeshNode * node2=FindNode(idnode2);
1503 const SMDS_MeshNode * node3=FindNode(idnode3);
1504 return FindEdge(node1,node2,node3);
1505 }
1507 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1508 const SMDS_MeshNode * node2,
1509 const SMDS_MeshNode * node3)
1510 {
1511 if ( !node1 ) return 0;
1512 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1513 while(it1->more()) {
1514 const SMDS_MeshElement * e = it1->next();
1515 if ( e->NbNodes() == 3 ) {
1516 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1517 while(it2->more()) {
1518 const SMDS_MeshElement* n = it2->next();
1519 if( n!=node1 &&
1520 n!=node2 &&
1521 n!=node3 )
1522 {
1523 e = 0;
1524 break;
1525 }
1526 }
1527 if ( e )
1528 return static_cast<const SMDS_MeshEdge *> (e);
1529 }
1530 }
1531 return 0;
1532 }
1535 //=======================================================================
1536 //function : FindFace
1537 //purpose :
1538 //=======================================================================
1540 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1541 int idnode3) const
1542 {
1543 const SMDS_MeshNode * node1=FindNode(idnode1);
1544 const SMDS_MeshNode * node2=FindNode(idnode2);
1545 const SMDS_MeshNode * node3=FindNode(idnode3);
1546 return FindFace(node1, node2, node3);
1547 }
1549 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1550 const SMDS_MeshNode *node2,
1551 const SMDS_MeshNode *node3)
1552 {
1553 if ( !node1 ) return 0;
1554 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1555 while(it1->more()) {
1556 const SMDS_MeshElement * e = it1->next();
1557 if ( e->NbNodes() == 3 ) {
1558 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1559 while(it2->more()) {
1560 const SMDS_MeshElement* n = it2->next();
1561 if( n!=node1 &&
1562 n!=node2 &&
1563 n!=node3 )
1564 {
1565 e = 0;
1566 break;
1567 }
1568 }
1569 if ( e )
1570 return static_cast<const SMDS_MeshFace *> (e);
1571 }
1572 }
1573 return 0;
1574 }
1576 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1577 const SMDS_MeshNode *node2,
1578 const SMDS_MeshNode *node3)
1579 {
1580 SMDS_MeshFace * toReturn=NULL;
1581 toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1582 if(toReturn==NULL) {
1583 toReturn = createTriangle(node1,node2,node3);
1584 }
1585 return toReturn;
1586 }
1589 //=======================================================================
1590 //function : FindFace
1591 //purpose :
1592 //=======================================================================
1594 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1595 int idnode3, int idnode4) const
1596 {
1597 const SMDS_MeshNode * node1=FindNode(idnode1);
1598 const SMDS_MeshNode * node2=FindNode(idnode2);
1599 const SMDS_MeshNode * node3=FindNode(idnode3);
1600 const SMDS_MeshNode * node4=FindNode(idnode4);
1601 return FindFace(node1, node2, node3, node4);
1602 }
1604 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1605 const SMDS_MeshNode *node2,
1606 const SMDS_MeshNode *node3,
1607 const SMDS_MeshNode *node4)
1608 {
1609 if ( !node1 ) return 0;
1610 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1611 while(it1->more()) {
1612 const SMDS_MeshElement * e = it1->next();
1613 if ( e->NbNodes() == 4 ) {
1614 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1615 while(it2->more()) {
1616 const SMDS_MeshElement* n = it2->next();
1617 if( n!=node1 &&
1618 n!=node2 &&
1619 n!=node3 &&
1620 n!=node4 )
1621 {
1622 e = 0;
1623 break;
1624 }
1625 }
1626 if ( e )
1627 return static_cast<const SMDS_MeshFace *> (e);
1628 }
1629 }
1630 return 0;
1631 }
1633 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1634 const SMDS_MeshNode *node2,
1635 const SMDS_MeshNode *node3,
1636 const SMDS_MeshNode *node4)
1637 {
1638 SMDS_MeshFace * toReturn=NULL;
1639 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1640 if(toReturn==NULL) {
1641 toReturn=createQuadrangle(node1,node2,node3,node4);
1642 }
1643 return toReturn;
1644 }
1647 //=======================================================================
1648 //function : FindFace
1649 //purpose :quadratic triangle
1650 //=======================================================================
1652 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1653 int idnode3, int idnode4,
1654 int idnode5, int idnode6) const
1655 {
1656 const SMDS_MeshNode * node1 = FindNode(idnode1);
1657 const SMDS_MeshNode * node2 = FindNode(idnode2);
1658 const SMDS_MeshNode * node3 = FindNode(idnode3);
1659 const SMDS_MeshNode * node4 = FindNode(idnode4);
1660 const SMDS_MeshNode * node5 = FindNode(idnode5);
1661 const SMDS_MeshNode * node6 = FindNode(idnode6);
1662 return FindFace(node1, node2, node3, node4, node5, node6);
1663 }
1665 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1666 const SMDS_MeshNode *node2,
1667 const SMDS_MeshNode *node3,
1668 const SMDS_MeshNode *node4,
1669 const SMDS_MeshNode *node5,
1670 const SMDS_MeshNode *node6)
1671 {
1672 if ( !node1 ) return 0;
1673 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1674 while(it1->more()) {
1675 const SMDS_MeshElement * e = it1->next();
1676 if ( e->NbNodes() == 6 ) {
1677 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1678 while(it2->more()) {
1679 const SMDS_MeshElement* n = it2->next();
1680 if( n!=node1 &&
1681 n!=node2 &&
1682 n!=node3 &&
1683 n!=node4 &&
1684 n!=node5 &&
1685 n!=node6 )
1686 {
1687 e = 0;
1688 break;
1689 }
1690 }
1691 if ( e )
1692 return static_cast<const SMDS_MeshFace *> (e);
1693 }
1694 }
1695 return 0;
1696 }
1699 //=======================================================================
1700 //function : FindFace
1701 //purpose : quadratic quadrangle
1702 //=======================================================================
1704 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1705 int idnode3, int idnode4,
1706 int idnode5, int idnode6,
1707 int idnode7, int idnode8) const
1708 {
1709 const SMDS_MeshNode * node1 = FindNode(idnode1);
1710 const SMDS_MeshNode * node2 = FindNode(idnode2);
1711 const SMDS_MeshNode * node3 = FindNode(idnode3);
1712 const SMDS_MeshNode * node4 = FindNode(idnode4);
1713 const SMDS_MeshNode * node5 = FindNode(idnode5);
1714 const SMDS_MeshNode * node6 = FindNode(idnode6);
1715 const SMDS_MeshNode * node7 = FindNode(idnode7);
1716 const SMDS_MeshNode * node8 = FindNode(idnode8);
1717 return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1718 }
1720 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1721 const SMDS_MeshNode *node2,
1722 const SMDS_MeshNode *node3,
1723 const SMDS_MeshNode *node4,
1724 const SMDS_MeshNode *node5,
1725 const SMDS_MeshNode *node6,
1726 const SMDS_MeshNode *node7,
1727 const SMDS_MeshNode *node8)
1728 {
1729 if ( !node1 ) return 0;
1730 SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1731 while(it1->more()) {
1732 const SMDS_MeshElement * e = it1->next();
1733 if ( e->NbNodes() == 8 ) {
1734 SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1735 while(it2->more()) {
1736 const SMDS_MeshElement* n = it2->next();
1737 if( n!=node1 &&
1738 n!=node2 &&
1739 n!=node3 &&
1740 n!=node4 &&
1741 n!=node5 &&
1742 n!=node6 &&
1743 n!=node7 &&
1744 n!=node8 )
1745 {
1746 e = 0;
1747 break;
1748 }
1749 }
1750 if ( e )
1751 return static_cast<const SMDS_MeshFace *> (e);
1752 }
1753 }
1754 return 0;
1755 }
1758 //=======================================================================
1759 //function : FindElement
1760 //purpose :
1761 //=======================================================================
1763 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1764 {
1765 return myElementIDFactory->MeshElement(IDelem);
1766 }
1768 //=======================================================================
1769 //function : FindFace
1770 //purpose : find polygon
1771 //=======================================================================
1773 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1774 {
1775 int nbnodes = nodes_ids.size();
1776 std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1777 for (int inode = 0; inode < nbnodes; inode++) {
1778 const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1779 if (node == NULL) return NULL;
1780 poly_nodes[inode] = node;
1781 }
1782 return FindFace(poly_nodes);
1783 }
1785 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1786 {
1787 if ( nodes.size() > 2 && nodes[0] ) {
1788 SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1789 while (itF->more()) {
1790 const SMDS_MeshElement* f = itF->next();
1791 if ( f->NbNodes() == nodes.size() ) {
1792 SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1793 while(it2->more()) {
1794 if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1795 f = 0;
1796 break;
1797 }
1798 }
1799 if ( f )
1800 return static_cast<const SMDS_MeshFace *> (f);
1801 }
1802 }
1803 }
1804 return NULL;
1805 }
1807 //=======================================================================
1808 //function : DumpNodes
1809 //purpose :
1810 //=======================================================================
1812 void SMDS_Mesh::DumpNodes() const
1813 {
1814 MESSAGE("dump nodes of mesh : ");
1815 SMDS_NodeIteratorPtr itnode=nodesIterator();
1816 while(itnode->more()) MESSAGE(itnode->next());
1817 }
1819 //=======================================================================
1820 //function : Dump0DElements
1821 //purpose :
1822 //=======================================================================
1823 void SMDS_Mesh::Dump0DElements() const
1824 {
1825 MESSAGE("dump 0D elements of mesh : ");
1826 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
1827 while(it0d->more()) MESSAGE(it0d->next());
1828 }
1830 //=======================================================================
1831 //function : DumpEdges
1832 //purpose :
1833 //=======================================================================
1835 void SMDS_Mesh::DumpEdges() const
1836 {
1837 MESSAGE("dump edges of mesh : ");
1838 SMDS_EdgeIteratorPtr itedge=edgesIterator();
1839 while(itedge->more()) MESSAGE(itedge->next());
1840 }
1842 //=======================================================================
1843 //function : DumpFaces
1844 //purpose :
1845 //=======================================================================
1847 void SMDS_Mesh::DumpFaces() const
1848 {
1849 MESSAGE("dump faces of mesh : ");
1850 SMDS_FaceIteratorPtr itface=facesIterator();
1851 while(itface->more()) MESSAGE(itface->next());
1852 }
1854 //=======================================================================
1855 //function : DumpVolumes
1856 //purpose :
1857 //=======================================================================
1859 void SMDS_Mesh::DumpVolumes() const
1860 {
1861 MESSAGE("dump volumes of mesh : ");
1862 SMDS_VolumeIteratorPtr itvol=volumesIterator();
1863 while(itvol->more()) MESSAGE(itvol->next());
1864 }
1866 //=======================================================================
1867 //function : DebugStats
1868 //purpose :
1869 //=======================================================================
1871 void SMDS_Mesh::DebugStats() const
1872 {
1873 MESSAGE("Debug stats of mesh : ");
1875 MESSAGE("===== NODES ====="<<NbNodes());
1876 MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
1877 MESSAGE("===== EDGES ====="<<NbEdges());
1878 MESSAGE("===== FACES ====="<<NbFaces());
1879 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1881 MESSAGE("End Debug stats of mesh ");
1883 //#ifdef DEB
1885 SMDS_NodeIteratorPtr itnode=nodesIterator();
1886 int sizeofnodes = 0;
1887 int sizeoffaces = 0;
1889 while(itnode->more())
1890 {
1891 const SMDS_MeshNode *node = itnode->next();
1893 sizeofnodes += sizeof(*node);
1895 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1896 while(it->more())
1897 {
1898 const SMDS_MeshElement *me = it->next();
1899 sizeofnodes += sizeof(me);
1900 }
1901 }
1903 SMDS_FaceIteratorPtr itface=facesIterator();
1904 while(itface->more())
1905 {
1906 const SMDS_MeshElement *face = itface->next();
1907 sizeoffaces += sizeof(*face);
1908 }
1910 MESSAGE("total size of node elements = " << sizeofnodes);;
1911 MESSAGE("total size of face elements = " << sizeoffaces);;
1913 //#endif
1914 }
1916 ///////////////////////////////////////////////////////////////////////////////
1917 /// Return the number of nodes
1918 ///////////////////////////////////////////////////////////////////////////////
1919 int SMDS_Mesh::NbNodes() const
1920 {
1921 return myNodes.Size();
1922 }
1924 ///////////////////////////////////////////////////////////////////////////////
1925 /// Return the number of 0D elements
1926 ///////////////////////////////////////////////////////////////////////////////
1927 int SMDS_Mesh::Nb0DElements() const
1928 {
1929 return my0DElements.Size();
1930 }
1932 ///////////////////////////////////////////////////////////////////////////////
1933 /// Return the number of edges (including construction edges)
1934 ///////////////////////////////////////////////////////////////////////////////
1935 int SMDS_Mesh::NbEdges() const
1936 {
1937 return myEdges.Size();
1938 }
1940 ///////////////////////////////////////////////////////////////////////////////
1941 /// Return the number of faces (including construction faces)
1942 ///////////////////////////////////////////////////////////////////////////////
1943 int SMDS_Mesh::NbFaces() const
1944 {
1945 return myFaces.Size();
1946 }
1948 ///////////////////////////////////////////////////////////////////////////////
1949 /// Return the number of volumes
1950 ///////////////////////////////////////////////////////////////////////////////
1951 int SMDS_Mesh::NbVolumes() const
1952 {
1953 return myVolumes.Size();
1954 }
1956 ///////////////////////////////////////////////////////////////////////////////
1957 /// Return the number of child mesh of this mesh.
1958 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1959 /// (2003-09-08) of SMESH
1960 ///////////////////////////////////////////////////////////////////////////////
1961 int SMDS_Mesh::NbSubMesh() const
1962 {
1963 return myChildren.size();
1964 }
1966 ///////////////////////////////////////////////////////////////////////////////
1967 /// Destroy the mesh and all its elements
1968 /// All pointer on elements owned by this mesh become illegals.
1969 ///////////////////////////////////////////////////////////////////////////////
1970 SMDS_Mesh::~SMDS_Mesh()
1971 {
1972 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1973 while(itc!=myChildren.end())
1974 {
1975 delete *itc;
1976 itc++;
1977 }
1979 if(myParent==NULL)
1980 {
1981 delete myNodeIDFactory;
1982 delete myElementIDFactory;
1983 }
1984 else
1985 {
1986 SMDS_ElemIteratorPtr eIt = elementsIterator();
1987 while ( eIt->more() )
1988 myElementIDFactory->ReleaseID(eIt->next()->GetID());
1989 SMDS_NodeIteratorPtr itn = nodesIterator();
1990 while (itn->more())
1991 myNodeIDFactory->ReleaseID(itn->next()->GetID());
1992 }
1994 SetOfNodes::Iterator itn(myNodes);
1995 for (; itn.More(); itn.Next())
1996 delete itn.Value();
1998 SetOf0DElements::Iterator it0d (my0DElements);
1999 for (; it0d.More(); it0d.Next())
2000 {
2001 SMDS_MeshElement* elem = it0d.Value();
2002 delete elem;
2003 }
2005 SetOfEdges::Iterator ite(myEdges);
2006 for (; ite.More(); ite.Next())
2007 {
2008 SMDS_MeshElement* elem = ite.Value();
2009 delete elem;
2010 }
2012 SetOfFaces::Iterator itf(myFaces);
2013 for (; itf.More(); itf.Next())
2014 {
2015 SMDS_MeshElement* elem = itf.Value();
2016 delete elem;
2017 }
2019 SetOfVolumes::Iterator itv(myVolumes);
2020 for (; itv.More(); itv.Next())
2021 {
2022 SMDS_MeshElement* elem = itv.Value();
2023 delete elem;
2024 }
2025 }
2027 //================================================================================
2028 /*!
2029 * \brief Clear all data
2030 */
2031 //================================================================================
2033 void SMDS_Mesh::Clear()
2034 {
2035 if (myParent!=NULL) {
2036 SMDS_ElemIteratorPtr eIt = elementsIterator();
2037 while ( eIt->more() )
2038 myElementIDFactory->ReleaseID(eIt->next()->GetID());
2039 SMDS_NodeIteratorPtr itn = nodesIterator();
2040 while (itn->more())
2041 myNodeIDFactory->ReleaseID(itn->next()->GetID());
2042 }
2043 else {
2044 myNodeIDFactory->Clear();
2045 myElementIDFactory->Clear();
2046 }
2048 SMDS_VolumeIteratorPtr itv = volumesIterator();
2049 while (itv->more())
2050 delete itv->next();
2051 myVolumes.Clear();
2053 SMDS_FaceIteratorPtr itf = facesIterator();
2054 while (itf->more())
2055 delete itf->next();
2056 myFaces.Clear();
2058 SMDS_EdgeIteratorPtr ite = edgesIterator();
2059 while (ite->more())
2060 delete ite->next();
2061 myEdges.Clear();
2063 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2064 while (it0d->more())
2065 delete it0d->next();
2066 my0DElements.Clear();
2068 SMDS_NodeIteratorPtr itn = nodesIterator();
2069 while (itn->more())
2070 delete itn->next();
2071 myNodes.Clear();
2073 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2074 while(itc!=myChildren.end())
2075 (*itc)->Clear();
2077 myInfo.Clear();
2078 }
2080 ///////////////////////////////////////////////////////////////////////////////
2081 /// Return true if this mesh create faces with edges.
2082 /// A false returned value mean that faces are created with nodes. A concequence
2083 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2084 ///////////////////////////////////////////////////////////////////////////////
2085 bool SMDS_Mesh::hasConstructionEdges()
2086 {
2087 return myHasConstructionEdges;
2088 }
2090 ///////////////////////////////////////////////////////////////////////////////
2091 /// Return true if this mesh create volumes with faces
2092 /// A false returned value mean that volumes are created with nodes or edges.
2093 /// (see hasConstructionEdges)
2094 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2095 /// unavailable.
2096 ///////////////////////////////////////////////////////////////////////////////
2097 bool SMDS_Mesh::hasConstructionFaces()
2098 {
2099 return myHasConstructionFaces;
2100 }
2102 ///////////////////////////////////////////////////////////////////////////////
2103 /// Return true if nodes are linked to the finit elements, they are belonging to.
2104 /// Currently, It always return true.
2105 ///////////////////////////////////////////////////////////////////////////////
2106 bool SMDS_Mesh::hasInverseElements()
2107 {
2108 return myHasInverseElements;
2109 }
2111 ///////////////////////////////////////////////////////////////////////////////
2112 /// Make this mesh creating construction edges (see hasConstructionEdges)
2113 /// @param b true to have construction edges, else false.
2114 ///////////////////////////////////////////////////////////////////////////////
2115 void SMDS_Mesh::setConstructionEdges(bool b)
2116 {
2117 myHasConstructionEdges=b;
2118 }
2120 ///////////////////////////////////////////////////////////////////////////////
2121 /// Make this mesh creating construction faces (see hasConstructionFaces)
2122 /// @param b true to have construction faces, else false.
2123 ///////////////////////////////////////////////////////////////////////////////
2124 void SMDS_Mesh::setConstructionFaces(bool b)
2125 {
2126 myHasConstructionFaces=b;
2127 }
2129 ///////////////////////////////////////////////////////////////////////////////
2130 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2131 /// @param b true to link nodes to elements, else false.
2132 ///////////////////////////////////////////////////////////////////////////////
2133 void SMDS_Mesh::setInverseElements(bool b)
2134 {
2135 if(!b) MESSAGE("Error : inverseElement=false not implemented");
2136 myHasInverseElements=b;
2137 }
2139 ///////////////////////////////////////////////////////////////////////////////
2140 ///Iterator on NCollection_Map
2141 ///////////////////////////////////////////////////////////////////////////////
2142 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2143 struct MYNCollection_Map_Iterator: public FATHER
2144 {
2145 typename MAP::Iterator myIterator;
2147 MYNCollection_Map_Iterator(const MAP& map):myIterator(map){}
2149 bool more()
2150 {
2151 while(myIterator.More())
2152 {
2153 if(myIterator.Value()->GetID()!=-1)
2154 return true;
2155 myIterator.Next();
2156 }
2157 return false;
2158 }
2160 ELEM next()
2161 {
2162 ELEM current = (ELEM) myIterator.Value();
2163 myIterator.Next();
2164 return current;
2165 }
2166 };
2168 ///////////////////////////////////////////////////////////////////////////////
2169 /// Return an iterator on nodes of the current mesh factory
2170 ///////////////////////////////////////////////////////////////////////////////
2172 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2173 {
2174 //return SMDS_NodeIteratorPtr
2175 // (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2176 typedef MYNCollection_Map_Iterator
2177 < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2178 return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2179 }
2181 ///////////////////////////////////////////////////////////////////////////////
2182 ///Return an iterator on 0D elements of the current mesh.
2183 ///////////////////////////////////////////////////////////////////////////////
2185 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2186 {
2187 typedef MYNCollection_Map_Iterator
2188 < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2189 return SMDS_0DElementIteratorPtr(new TIterator(my0DElements));
2190 }
2192 ///////////////////////////////////////////////////////////////////////////////
2193 ///Return an iterator on edges of the current mesh.
2194 ///////////////////////////////////////////////////////////////////////////////
2196 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2197 {
2198 typedef MYNCollection_Map_Iterator
2199 < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2200 return SMDS_EdgeIteratorPtr(new TIterator(myEdges));
2201 }
2203 ///////////////////////////////////////////////////////////////////////////////
2204 ///Return an iterator on faces of the current mesh.
2205 ///////////////////////////////////////////////////////////////////////////////
2207 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2208 {
2209 typedef MYNCollection_Map_Iterator
2210 < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2211 return SMDS_FaceIteratorPtr(new TIterator(myFaces));
2212 }
2214 ///////////////////////////////////////////////////////////////////////////////
2215 ///Return an iterator on volumes of the current mesh.
2216 ///////////////////////////////////////////////////////////////////////////////
2218 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2219 {
2220 typedef MYNCollection_Map_Iterator
2221 < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2222 return SMDS_VolumeIteratorPtr(new TIterator(myVolumes));
2223 }
2225 ///////////////////////////////////////////////////////////////////////////////
2226 /// Return an iterator on elements of the current mesh factory
2227 ///////////////////////////////////////////////////////////////////////////////
2228 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2229 {
2230 switch (type) {
2231 case SMDSAbs_All:
2232 break;
2233 case SMDSAbs_Volume:
2234 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
2235 case SMDSAbs_Face:
2236 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
2237 case SMDSAbs_Edge:
2238 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
2239 case SMDSAbs_0DElement:
2240 return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements));
2241 case SMDSAbs_Node:
2242 return myNodeIDFactory->elementsIterator();
2243 default:;
2244 }
2245 return myElementIDFactory->elementsIterator();
2246 }
2248 ///////////////////////////////////////////////////////////////////////////////
2249 /// Do intersection of sets (more than 2)
2250 ///////////////////////////////////////////////////////////////////////////////
2251 static set<const SMDS_MeshElement*> * intersectionOfSets(
2252 set<const SMDS_MeshElement*> vs[], int numberOfSets)
2253 {
2254 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2255 set<const SMDS_MeshElement*>* rsetB;
2257 for(int i=0; i<numberOfSets-1; i++)
2258 {
2259 rsetB=new set<const SMDS_MeshElement*>();
2260 set_intersection(
2261 rsetA->begin(), rsetA->end(),
2262 vs[i+1].begin(), vs[i+1].end(),
2263 inserter(*rsetB, rsetB->begin()));
2264 delete rsetA;
2265 rsetA=rsetB;
2266 }
2267 return rsetA;
2268 }
2270 ///////////////////////////////////////////////////////////////////////////////
2271 /// Return the list of finit elements owning the given element
2272 ///////////////////////////////////////////////////////////////////////////////
2273 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2274 {
2275 int numberOfSets=element->NbNodes();
2276 set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2278 SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2280 int i=0;
2281 while(itNodes->more())
2282 {
2283 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2284 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2286 //initSet[i]=set<const SMDS_MeshElement*>();
2287 while(itFe->more())
2288 initSet[i].insert(itFe->next());
2290 i++;
2291 }
2292 set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2293 delete [] initSet;
2294 return retSet;
2295 }
2297 ///////////////////////////////////////////////////////////////////////////////
2298 /// Return the list of nodes used only by the given elements
2299 ///////////////////////////////////////////////////////////////////////////////
2300 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2301 set<const SMDS_MeshElement*>& elements)
2302 {
2303 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2304 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2306 while(itElements!=elements.end())
2307 {
2308 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2309 itElements++;
2311 while(itNodes->more())
2312 {
2313 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2314 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2315 set<const SMDS_MeshElement*> s;
2316 while(itFe->more())
2317 s.insert(itFe->next());
2318 if(s==elements) toReturn->insert(n);
2319 }
2320 }
2321 return toReturn;
2322 }
2324 ///////////////////////////////////////////////////////////////////////////////
2325 ///Find the children of an element that are made of given nodes
2326 ///@param setOfChildren The set in which matching children will be inserted
2327 ///@param element The element were to search matching children
2328 ///@param nodes The nodes that the children must have to be selected
2329 ///////////////////////////////////////////////////////////////////////////////
2330 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2331 const SMDS_MeshElement * element,
2332 set<const SMDS_MeshElement*>& nodes)
2333 {
2334 switch(element->GetType())
2335 {
2336 case SMDSAbs_Node:
2337 MESSAGE("Internal Error: This should not happend");
2338 break;
2339 case SMDSAbs_0DElement:
2340 {
2341 }
2342 break;
2343 case SMDSAbs_Edge:
2344 {
2345 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2346 while(itn->more())
2347 {
2348 const SMDS_MeshElement * e=itn->next();
2349 if(nodes.find(e)!=nodes.end())
2350 {
2351 setOfChildren.insert(element);
2352 break;
2353 }
2354 }
2355 } break;
2356 case SMDSAbs_Face:
2357 {
2358 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2359 while(itn->more())
2360 {
2361 const SMDS_MeshElement * e=itn->next();
2362 if(nodes.find(e)!=nodes.end())
2363 {
2364 setOfChildren.insert(element);
2365 break;
2366 }
2367 }
2368 if(hasConstructionEdges())
2369 {
2370 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2371 while(ite->more())
2372 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2373 }
2374 } break;
2375 case SMDSAbs_Volume:
2376 {
2377 if(hasConstructionFaces())
2378 {
2379 SMDS_ElemIteratorPtr ite=element->facesIterator();
2380 while(ite->more())
2381 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2382 }
2383 else if(hasConstructionEdges())
2384 {
2385 SMDS_ElemIteratorPtr ite=element->edgesIterator();
2386 while(ite->more())
2387 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2388 }
2389 }
2390 }
2391 }
2393 ///////////////////////////////////////////////////////////////////////////////
2394 ///@param elem The element to delete
2395 ///@param removenodes if true remaining nodes will be removed
2396 ///////////////////////////////////////////////////////////////////////////////
2397 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2398 const bool removenodes)
2399 {
2400 list<const SMDS_MeshElement *> removedElems;
2401 list<const SMDS_MeshElement *> removedNodes;
2402 RemoveElement( elem, removedElems, removedNodes, removenodes );
2403 }
2405 ///////////////////////////////////////////////////////////////////////////////
2406 ///@param elem The element to delete
2407 ///@param removedElems contains all removed elements
2408 ///@param removedNodes contains all removed nodes
2409 ///@param removenodes if true remaining nodes will be removed
2410 ///////////////////////////////////////////////////////////////////////////////
2411 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2412 list<const SMDS_MeshElement *>& removedElems,
2413 list<const SMDS_MeshElement *>& removedNodes,
2414 bool removenodes)
2415 {
2416 // get finite elements built on elem
2417 set<const SMDS_MeshElement*> * s1;
2418 if (elem->GetType() == SMDSAbs_0DElement ||
2419 elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2420 elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2421 elem->GetType() == SMDSAbs_Volume)
2422 {
2423 s1 = new set<const SMDS_MeshElement*>();
2424 s1->insert(elem);
2425 }
2426 else
2427 s1 = getFinitElements(elem);
2429 // get exclusive nodes (which would become free afterwards)
2430 set<const SMDS_MeshElement*> * s2;
2431 if (elem->GetType() == SMDSAbs_Node) // a node is removed
2432 {
2433 // do not remove nodes except elem
2434 s2 = new set<const SMDS_MeshElement*>();
2435 s2->insert(elem);
2436 removenodes = true;
2437 }
2438 else
2439 s2 = getExclusiveNodes(*s1);
2441 // form the set of finite and construction elements to remove
2442 set<const SMDS_MeshElement*> s3;
2443 set<const SMDS_MeshElement*>::iterator it=s1->begin();
2444 while(it!=s1->end())
2445 {
2446 addChildrenWithNodes(s3, *it ,*s2);
2447 s3.insert(*it);
2448 it++;
2449 }
2450 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2452 // remove finite and construction elements
2453 it=s3.begin();
2454 while(it!=s3.end())
2455 {
2456 // Remove element from <InverseElements> of its nodes
2457 SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2458 while(itn->more())
2459 {
2460 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2461 (const_cast<SMDS_MeshElement *>(itn->next()));
2462 n->RemoveInverseElement( (*it) );
2463 }
2465 switch((*it)->GetType())
2466 {
2467 case SMDSAbs_Node:
2468 MESSAGE("Internal Error: This should not happen");
2469 break;
2470 case SMDSAbs_0DElement:
2471 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2472 (const_cast<SMDS_MeshElement*>(*it)));
2473 //myInfo.Remove0DElement(*it);
2474 myInfo.remove(*it);
2475 break;
2476 case SMDSAbs_Edge:
2477 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2478 (const_cast<SMDS_MeshElement*>(*it)));
2479 myInfo.RemoveEdge(*it);
2480 break;
2481 case SMDSAbs_Face:
2482 myFaces.Remove(static_cast<SMDS_MeshFace*>
2483 (const_cast<SMDS_MeshElement*>(*it)));
2484 myInfo.RemoveFace(*it);
2485 break;
2486 case SMDSAbs_Volume:
2487 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2488 (const_cast<SMDS_MeshElement*>(*it)));
2489 myInfo.RemoveVolume(*it);
2490 break;
2491 }
2492 //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2493 removedElems.push_back( (*it) );
2494 myElementIDFactory->ReleaseID((*it)->GetID());
2495 delete (*it);
2496 it++;
2497 }
2499 // remove exclusive (free) nodes
2500 if(removenodes)
2501 {
2502 it=s2->begin();
2503 while(it!=s2->end())
2504 {
2505 //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2506 myNodes.Remove(static_cast<SMDS_MeshNode*>
2507 (const_cast<SMDS_MeshElement*>(*it)));
2508 myInfo.myNbNodes--;
2509 myNodeIDFactory->ReleaseID((*it)->GetID());
2510 removedNodes.push_back( (*it) );
2511 delete *it;
2512 it++;
2513 }
2514 }
2516 delete s2;
2517 delete s1;
2518 }
2521 ///////////////////////////////////////////////////////////////////////////////
2522 ///@param elem The element to delete
2523 ///////////////////////////////////////////////////////////////////////////////
2524 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2525 {
2526 SMDSAbs_ElementType aType = elem->GetType();
2527 if (aType == SMDSAbs_Node) {
2528 // only free node can be removed by this method
2529 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2530 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2531 if (!itFe->more()) { // free node
2532 myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2533 myInfo.myNbNodes--;
2534 myNodeIDFactory->ReleaseID(elem->GetID());
2535 delete elem;
2536 }
2537 } else {
2538 if (hasConstructionEdges() || hasConstructionFaces())
2539 // this methods is only for meshes without descendants
2540 return;
2542 // Remove element from <InverseElements> of its nodes
2543 SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2544 while (itn->more()) {
2545 SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2546 (const_cast<SMDS_MeshElement *>(itn->next()));
2547 n->RemoveInverseElement(elem);
2548 }
2550 // in meshes without descendants elements are always free
2551 switch (aType) {
2552 case SMDSAbs_0DElement:
2553 my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
2554 (const_cast<SMDS_MeshElement*>(elem)));
2555 //myInfo.Remove0DElement(elem);
2556 myInfo.remove(elem);
2557 break;
2558 case SMDSAbs_Edge:
2559 myEdges.Remove(static_cast<SMDS_MeshEdge*>
2560 (const_cast<SMDS_MeshElement*>(elem)));
2561 myInfo.RemoveEdge(elem);
2562 break;
2563 case SMDSAbs_Face:
2564 myFaces.Remove(static_cast<SMDS_MeshFace*>
2565 (const_cast<SMDS_MeshElement*>(elem)));
2566 myInfo.RemoveFace(elem);
2567 break;
2568 case SMDSAbs_Volume:
2569 myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2570 (const_cast<SMDS_MeshElement*>(elem)));
2571 myInfo.RemoveVolume(elem);
2572 break;
2573 default:
2574 break;
2575 }
2576 myElementIDFactory->ReleaseID(elem->GetID());
2577 delete elem;
2578 }
2579 }
2581 /*!
2582 * Checks if the element is present in mesh.
2583 * Useful to determine dead pointers.
2584 */
2585 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2586 {
2587 // we should not imply on validity of *elem, so iterate on containers
2588 // of all types in the hope of finding <elem> somewhere there
2589 SMDS_NodeIteratorPtr itn = nodesIterator();
2590 while (itn->more())
2591 if (elem == itn->next())
2592 return true;
2593 SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2594 while (it0d->more())
2595 if (elem == it0d->next())
2596 return true;
2597 SMDS_EdgeIteratorPtr ite = edgesIterator();
2598 while (ite->more())
2599 if (elem == ite->next())
2600 return true;
2601 SMDS_FaceIteratorPtr itf = facesIterator();
2602 while (itf->more())
2603 if (elem == itf->next())
2604 return true;
2605 SMDS_VolumeIteratorPtr itv = volumesIterator();
2606 while (itv->more())
2607 if (elem == itv->next())
2608 return true;
2609 return false;
2610 }
2612 //=======================================================================
2613 //function : MaxNodeID
2614 //purpose :
2615 //=======================================================================
2617 int SMDS_Mesh::MaxNodeID() const
2618 {
2619 return myNodeIDFactory->GetMaxID();
2620 }
2622 //=======================================================================
2623 //function : MinNodeID
2624 //purpose :
2625 //=======================================================================
2627 int SMDS_Mesh::MinNodeID() const
2628 {
2629 return myNodeIDFactory->GetMinID();
2630 }
2632 //=======================================================================
2633 //function : MaxElementID
2634 //purpose :
2635 //=======================================================================
2637 int SMDS_Mesh::MaxElementID() const
2638 {
2639 return myElementIDFactory->GetMaxID();
2640 }
2642 //=======================================================================
2643 //function : MinElementID
2644 //purpose :
2645 //=======================================================================
2647 int SMDS_Mesh::MinElementID() const
2648 {
2649 return myElementIDFactory->GetMinID();
2650 }
2652 //=======================================================================
2653 //function : Renumber
2654 //purpose : Renumber all nodes or elements.
2655 //=======================================================================
2657 void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
2658 {
2659 if ( deltaID == 0 )
2660 return;
2662 SMDS_MeshElementIDFactory * idFactory =
2663 isNodes ? myNodeIDFactory : myElementIDFactory;
2665 // get existing elements in the order of ID increasing
2666 map<int,SMDS_MeshElement*> elemMap;
2667 SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2668 while ( idElemIt->more() ) {
2669 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2670 int id = elem->GetID();
2671 elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2672 }
2673 // release their ids
2674 map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2675 idFactory->Clear();
2676 // for ( ; elemIt != elemMap.end(); elemIt++ )
2677 // {
2678 // int id = (*elemIt).first;
2679 // idFactory->ReleaseID( id );
2680 // }
2681 // set new IDs
2682 int ID = startID;
2683 elemIt = elemMap.begin();
2684 for ( ; elemIt != elemMap.end(); elemIt++ )
2685 {
2686 idFactory->BindID( ID, (*elemIt).second );
2687 ID += deltaID;
2688 }
2689 }
2691 //=======================================================================
2692 //function : GetElementType
2693 //purpose : Return type of element or node with id
2694 //=======================================================================
2696 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2697 {
2698 SMDS_MeshElement* elem = 0;
2699 if( iselem )
2700 elem = myElementIDFactory->MeshElement( id );
2701 else
2702 elem = myNodeIDFactory->MeshElement( id );
2704 if( !elem )
2705 {
2706 //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2707 return SMDSAbs_All;
2708 }
2709 else
2710 return elem->GetType();
2711 }
2715 //********************************************************************
2716 //********************************************************************
2717 //******** *********
2718 //***** Methods for addition of quadratic elements ******
2719 //******** *********
2720 //********************************************************************
2721 //********************************************************************
2723 //=======================================================================
2724 //function : AddEdgeWithID
2725 //purpose :
2726 //=======================================================================
2727 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2728 {
2729 return SMDS_Mesh::AddEdgeWithID
2730 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2731 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2732 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2733 ID);
2734 }
2736 //=======================================================================
2737 //function : AddEdge
2738 //purpose :
2739 //=======================================================================
2740 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2741 const SMDS_MeshNode* n2,
2742 const SMDS_MeshNode* n12)
2743 {
2744 return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2745 }
2747 //=======================================================================
2748 //function : AddEdgeWithID
2749 //purpose :
2750 //=======================================================================
2751 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2752 const SMDS_MeshNode * n2,
2753 const SMDS_MeshNode * n12,
2754 int ID)
2755 {
2756 if ( !n1 || !n2 || !n12 ) return 0;
2757 SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2758 if(myElementIDFactory->BindID(ID, edge)) {
2759 SMDS_MeshNode *node1,*node2, *node12;
2760 node1 = const_cast<SMDS_MeshNode*>(n1);
2761 node2 = const_cast<SMDS_MeshNode*>(n2);
2762 node12 = const_cast<SMDS_MeshNode*>(n12);
2763 node1->AddInverseElement(edge);
2764 node2->AddInverseElement(edge);
2765 node12->AddInverseElement(edge);
2766 myEdges.Add(edge);
2767 myInfo.myNbQuadEdges++;
2768 return edge;
2769 }
2770 else {
2771 delete edge;
2772 return NULL;
2773 }
2774 }
2777 //=======================================================================
2778 //function : AddFace
2779 //purpose :
2780 //=======================================================================
2781 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2782 const SMDS_MeshNode * n2,
2783 const SMDS_MeshNode * n3,
2784 const SMDS_MeshNode * n12,
2785 const SMDS_MeshNode * n23,
2786 const SMDS_MeshNode * n31)
2787 {
2788 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2789 myElementIDFactory->GetFreeID());
2790 }
2792 //=======================================================================
2793 //function : AddFaceWithID
2794 //purpose :
2795 //=======================================================================
2796 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2797 int n12,int n23,int n31, int ID)
2798 {
2799 return SMDS_Mesh::AddFaceWithID
2800 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2801 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2802 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2803 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2804 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2805 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2806 ID);
2807 }
2809 //=======================================================================
2810 //function : AddFaceWithID
2811 //purpose :
2812 //=======================================================================
2813 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2814 const SMDS_MeshNode * n2,
2815 const SMDS_MeshNode * n3,
2816 const SMDS_MeshNode * n12,
2817 const SMDS_MeshNode * n23,
2818 const SMDS_MeshNode * n31,
2819 int ID)
2820 {
2821 if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2822 if(hasConstructionEdges()) {
2823 // creation quadratic edges - not implemented
2824 return 0;
2825 }
2826 SMDS_QuadraticFaceOfNodes* face =
2827 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2828 myFaces.Add(face);
2829 myInfo.myNbQuadTriangles++;
2831 if (!registerElement(ID, face)) {
2832 RemoveElement(face, false);
2833 face = NULL;
2834 }
2835 return face;
2836 }
2839 //=======================================================================
2840 //function : AddFace
2841 //purpose :
2842 //=======================================================================
2843 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2844 const SMDS_MeshNode * n2,
2845 const SMDS_MeshNode * n3,
2846 const SMDS_MeshNode * n4,
2847 const SMDS_MeshNode * n12,
2848 const SMDS_MeshNode * n23,
2849 const SMDS_MeshNode * n34,
2850 const SMDS_MeshNode * n41)
2851 {
2852 return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2853 myElementIDFactory->GetFreeID());
2854 }
2856 //=======================================================================
2857 //function : AddFaceWithID
2858 //purpose :
2859 //=======================================================================
2860 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2861 int n12,int n23,int n34,int n41, int ID)
2862 {
2863 return SMDS_Mesh::AddFaceWithID
2864 ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2865 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2866 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2867 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2868 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2869 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2870 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2871 (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2872 ID);
2873 }
2875 //=======================================================================
2876 //function : AddFaceWithID
2877 //purpose :
2878 //=======================================================================
2879 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2880 const SMDS_MeshNode * n2,
2881 const SMDS_MeshNode * n3,
2882 const SMDS_MeshNode * n4,
2883 const SMDS_MeshNode * n12,
2884 const SMDS_MeshNode * n23,
2885 const SMDS_MeshNode * n34,
2886 const SMDS_MeshNode * n41,
2887 int ID)
2888 {
2889 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2890 if(hasConstructionEdges()) {
2891 // creation quadratic edges - not implemented
2892 }
2893 SMDS_QuadraticFaceOfNodes* face =
2894 new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2895 myFaces.Add(face);
2896 myInfo.myNbQuadQuadrangles++;
2898 if (!registerElement(ID, face)) {
2899 RemoveElement(face, false);
2900 face = NULL;
2901 }
2902 return face;
2903 }
2906 //=======================================================================
2907 //function : AddVolume
2908 //purpose :
2909 //=======================================================================
2910 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2911 const SMDS_MeshNode * n2,
2912 const SMDS_MeshNode * n3,
2913 const SMDS_MeshNode * n4,
2914 const SMDS_MeshNode * n12,
2915 const SMDS_MeshNode * n23,
2916 const SMDS_MeshNode * n31,
2917 const SMDS_MeshNode * n14,
2918 const SMDS_MeshNode * n24,
2919 const SMDS_MeshNode * n34)
2920 {
2921 int ID = myElementIDFactory->GetFreeID();
2922 SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2923 n31, n14, n24, n34, ID);
2924 if(v==NULL) myElementIDFactory->ReleaseID(ID);
2925 return v;
2926 }
2928 //=======================================================================
2929 //function : AddVolumeWithID
2930 //purpose :
2931 //=======================================================================
2932 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2933 int n12,int n23,int n31,
2934 int n14,int n24,int n34, int ID)
2935 {
2936 return SMDS_Mesh::AddVolumeWithID
2937 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2938 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2939 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2940 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2941 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2942 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2943 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2944 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2945 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2946 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2947 ID);
2948 }
2950 //=======================================================================
2951 //function : AddVolumeWithID
2952 //purpose : 2d order tetrahedron of 10 nodes
2953 //=======================================================================
2954 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2955 const SMDS_MeshNode * n2,
2956 const SMDS_MeshNode * n3,
2957 const SMDS_MeshNode * n4,
2958 const SMDS_MeshNode * n12,
2959 const SMDS_MeshNode * n23,
2960 const SMDS_MeshNode * n31,
2961 const SMDS_MeshNode * n14,
2962 const SMDS_MeshNode * n24,
2963 const SMDS_MeshNode * n34,
2964 int ID)
2965 {
2966 if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2967 return 0;
2968 if(hasConstructionFaces()) {
2969 // creation quadratic faces - not implemented
2970 return 0;
2971 }
2972 SMDS_QuadraticVolumeOfNodes * volume =
2973 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2974 myVolumes.Add(volume);
2975 myInfo.myNbQuadTetras++;
2977 if (!registerElement(ID, volume)) {
2978 RemoveElement(volume, false);
2979 volume = NULL;
2980 }
2981 return volume;
2982 }
2985 //=======================================================================
2986 //function : AddVolume
2987 //purpose :
2988 //=======================================================================
2989 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2990 const SMDS_MeshNode * n2,
2991 const SMDS_MeshNode * n3,
2992 const SMDS_MeshNode * n4,
2993 const SMDS_MeshNode * n5,
2994 const SMDS_MeshNode * n12,
2995 const SMDS_MeshNode * n23,
2996 const SMDS_MeshNode * n34,
2997 const SMDS_MeshNode * n41,
2998 const SMDS_MeshNode * n15,
2999 const SMDS_MeshNode * n25,
3000 const SMDS_MeshNode * n35,
3001 const SMDS_MeshNode * n45)
3002 {
3003 int ID = myElementIDFactory->GetFreeID();
3004 SMDS_MeshVolume * v =
3005 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3006 n15, n25, n35, n45, ID);
3007 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3008 return v;
3009 }
3011 //=======================================================================
3012 //function : AddVolumeWithID
3013 //purpose :
3014 //=======================================================================
3015 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3016 int n12,int n23,int n34,int n41,
3017 int n15,int n25,int n35,int n45, int ID)
3018 {
3019 return SMDS_Mesh::AddVolumeWithID
3020 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3021 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3022 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3023 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3024 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3025 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3026 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3027 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3028 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3029 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3030 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3031 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3032 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3033 ID);
3034 }
3036 //=======================================================================
3037 //function : AddVolumeWithID
3038 //purpose : 2d order pyramid of 13 nodes
3039 //=======================================================================
3040 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3041 const SMDS_MeshNode * n2,
3042 const SMDS_MeshNode * n3,
3043 const SMDS_MeshNode * n4,
3044 const SMDS_MeshNode * n5,
3045 const SMDS_MeshNode * n12,
3046 const SMDS_MeshNode * n23,
3047 const SMDS_MeshNode * n34,
3048 const SMDS_MeshNode * n41,
3049 const SMDS_MeshNode * n15,
3050 const SMDS_MeshNode * n25,
3051 const SMDS_MeshNode * n35,
3052 const SMDS_MeshNode * n45,
3053 int ID)
3054 {
3055 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3056 !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3057 return 0;
3058 if(hasConstructionFaces()) {
3059 // creation quadratic faces - not implemented
3060 return 0;
3061 }
3062 SMDS_QuadraticVolumeOfNodes * volume =
3063 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3064 n34,n41,n15,n25,n35,n45);
3065 myVolumes.Add(volume);
3066 myInfo.myNbQuadPyramids++;
3068 if (!registerElement(ID, volume)) {
3069 RemoveElement(volume, false);
3070 volume = NULL;
3071 }
3072 return volume;
3073 }
3076 //=======================================================================
3077 //function : AddVolume
3078 //purpose :
3079 //=======================================================================
3080 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3081 const SMDS_MeshNode * n2,
3082 const SMDS_MeshNode * n3,
3083 const SMDS_MeshNode * n4,
3084 const SMDS_MeshNode * n5,
3085 const SMDS_MeshNode * n6,
3086 const SMDS_MeshNode * n12,
3087 const SMDS_MeshNode * n23,
3088 const SMDS_MeshNode * n31,
3089 const SMDS_MeshNode * n45,
3090 const SMDS_MeshNode * n56,
3091 const SMDS_MeshNode * n64,
3092 const SMDS_MeshNode * n14,
3093 const SMDS_MeshNode * n25,
3094 const SMDS_MeshNode * n36)
3095 {
3096 int ID = myElementIDFactory->GetFreeID();
3097 SMDS_MeshVolume * v =
3098 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3099 n45, n56, n64, n14, n25, n36, ID);
3100 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3101 return v;
3102 }
3104 //=======================================================================
3105 //function : AddVolumeWithID
3106 //purpose :
3107 //=======================================================================
3108 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3109 int n4, int n5, int n6,
3110 int n12,int n23,int n31,
3111 int n45,int n56,int n64,
3112 int n14,int n25,int n36, int ID)
3113 {
3114 return SMDS_Mesh::AddVolumeWithID
3115 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3116 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3117 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3118 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3119 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3120 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3121 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3122 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3123 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3124 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3125 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3126 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3127 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3128 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3129 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3130 ID);
3131 }
3133 //=======================================================================
3134 //function : AddVolumeWithID
3135 //purpose : 2d order Pentahedron with 15 nodes
3136 //=======================================================================
3137 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3138 const SMDS_MeshNode * n2,
3139 const SMDS_MeshNode * n3,
3140 const SMDS_MeshNode * n4,
3141 const SMDS_MeshNode * n5,
3142 const SMDS_MeshNode * n6,
3143 const SMDS_MeshNode * n12,
3144 const SMDS_MeshNode * n23,
3145 const SMDS_MeshNode * n31,
3146 const SMDS_MeshNode * n45,
3147 const SMDS_MeshNode * n56,
3148 const SMDS_MeshNode * n64,
3149 const SMDS_MeshNode * n14,
3150 const SMDS_MeshNode * n25,
3151 const SMDS_MeshNode * n36,
3152 int ID)
3153 {
3154 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3155 !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3156 return 0;
3157 if(hasConstructionFaces()) {
3158 // creation quadratic faces - not implemented
3159 return 0;
3160 }
3161 SMDS_QuadraticVolumeOfNodes * volume =
3162 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3163 n45,n56,n64,n14,n25,n36);
3164 myVolumes.Add(volume);
3165 myInfo.myNbQuadPrisms++;
3167 if (!registerElement(ID, volume)) {
3168 RemoveElement(volume, false);
3169 volume = NULL;
3170 }
3171 return volume;
3172 }
3175 //=======================================================================
3176 //function : AddVolume
3177 //purpose :
3178 //=======================================================================
3179 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3180 const SMDS_MeshNode * n2,
3181 const SMDS_MeshNode * n3,
3182 const SMDS_MeshNode * n4,
3183 const SMDS_MeshNode * n5,
3184 const SMDS_MeshNode * n6,
3185 const SMDS_MeshNode * n7,
3186 const SMDS_MeshNode * n8,
3187 const SMDS_MeshNode * n12,
3188 const SMDS_MeshNode * n23,
3189 const SMDS_MeshNode * n34,
3190 const SMDS_MeshNode * n41,
3191 const SMDS_MeshNode * n56,
3192 const SMDS_MeshNode * n67,
3193 const SMDS_MeshNode * n78,
3194 const SMDS_MeshNode * n85,
3195 const SMDS_MeshNode * n15,
3196 const SMDS_MeshNode * n26,
3197 const SMDS_MeshNode * n37,
3198 const SMDS_MeshNode * n48)
3199 {
3200 int ID = myElementIDFactory->GetFreeID();
3201 SMDS_MeshVolume * v =
3202 SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3203 n56, n67, n78, n85, n15, n26, n37, n48, ID);
3204 if(v==NULL) myElementIDFactory->ReleaseID(ID);
3205 return v;
3206 }
3208 //=======================================================================
3209 //function : AddVolumeWithID
3210 //purpose :
3211 //=======================================================================
3212 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3213 int n5, int n6, int n7, int n8,
3214 int n12,int n23,int n34,int n41,
3215 int n56,int n67,int n78,int n85,
3216 int n15,int n26,int n37,int n48, int ID)
3217 {
3218 return SMDS_Mesh::AddVolumeWithID
3219 ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3220 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3221 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3222 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3223 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3224 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3225 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3226 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3227 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3228 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3229 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3230 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3231 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3232 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3233 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3234 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3235 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3236 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3237 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3238 (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3239 ID);
3240 }
3242 //=======================================================================
3243 //function : AddVolumeWithID
3244 //purpose : 2d order Hexahedrons with 20 nodes
3245 //=======================================================================
3246 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3247 const SMDS_MeshNode * n2,
3248 const SMDS_MeshNode * n3,
3249 const SMDS_MeshNode * n4,
3250 const SMDS_MeshNode * n5,
3251 const SMDS_MeshNode * n6,
3252 const SMDS_MeshNode * n7,
3253 const SMDS_MeshNode * n8,
3254 const SMDS_MeshNode * n12,
3255 const SMDS_MeshNode * n23,
3256 const SMDS_MeshNode * n34,
3257 const SMDS_MeshNode * n41,
3258 const SMDS_MeshNode * n56,
3259 const SMDS_MeshNode * n67,
3260 const SMDS_MeshNode * n78,
3261 const SMDS_MeshNode * n85,
3262 const SMDS_MeshNode * n15,
3263 const SMDS_MeshNode * n26,
3264 const SMDS_MeshNode * n37,
3265 const SMDS_MeshNode * n48,
3266 int ID)
3267 {
3268 if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3269 !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3270 return 0;
3271 if(hasConstructionFaces()) {
3272 return 0;
3273 // creation quadratic faces - not implemented
3274 }
3275 SMDS_QuadraticVolumeOfNodes * volume =
3276 new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3277 n56,n67,n78,n85,n15,n26,n37,n48);
3278 myVolumes.Add(volume);
3279 myInfo.myNbQuadHexas++;
3281 if (!registerElement(ID, volume)) {
3282 RemoveElement(volume, false);
3283 volume = NULL;
3284 }
3285 return volume;
3286 }
