1 // SMESH SMDS : implementaion of Salome mesh data structure
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 #include "utilities.h"
23 #include "SMDS_Mesh.hxx"
24 #include "SMDS_VolumeOfNodes.hxx"
25 #include "SMDS_VolumeOfFaces.hxx"
26 #include "SMDS_FaceOfNodes.hxx"
27 #include "SMDS_FaceOfEdges.hxx"
29 ///////////////////////////////////////////////////////////////////////////////
30 /// Create a new mesh object
31 ///////////////////////////////////////////////////////////////////////////////
32 SMDS_Mesh::SMDS_Mesh()
33 :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
34 myElementIDFactory(new SMDS_MeshElementIDFactory()),
35 myHasConstructionEdges(false), myHasConstructionFaces(false),
36 myHasInverseElements(true)
40 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
43 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
44 myElementIDFactory(parent->myElementIDFactory),
45 myHasConstructionEdges(false), myHasConstructionFaces(false),
46 myHasInverseElements(true)
50 ///////////////////////////////////////////////////////////////////////////////
51 ///Create a submesh and add it to the current mesh
52 ///////////////////////////////////////////////////////////////////////////////
54 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
56 SMDS_Mesh *submesh = new SMDS_Mesh(this);
57 myChildren.insert(myChildren.end(), submesh);
61 ///////////////////////////////////////////////////////////////////////////////
62 ///create a MeshNode and add it to the current Mesh
63 ///@return : The created node
64 ///////////////////////////////////////////////////////////////////////////////
66 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
68 return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
71 ///////////////////////////////////////////////////////////////////////////////
72 ///create a MeshNode and add it to the current Mesh
73 ///@param ID : The ID of the MeshNode to create
74 ///@return : The created node or NULL if a node with this ID already exists
75 ///////////////////////////////////////////////////////////////////////////////
76 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
78 // find the MeshNode corresponding to ID
79 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
83 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
85 myNodeIDFactory->BindID(ID,node);
92 ///////////////////////////////////////////////////////////////////////////////
93 ///create a MeshEdge and add it to the current Mesh
94 ///@return : The created MeshEdge
95 ///////////////////////////////////////////////////////////////////////////////
97 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
99 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
100 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
101 if((node1==NULL)||(node2==NULL)) return NULL;
102 return AddEdgeWithID(node1, node2, ID);
105 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
106 const SMDS_MeshNode * node2)
108 return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
110 ///////////////////////////////////////////////////////////////////////////////
111 ///Create a new edge and at it to the mesh
112 ///@param idnode1 ID of the first node
113 ///@param idnode2 ID of the second node
114 ///@param ID ID of the edge to create
115 ///@return The created edge or NULL if an edge with this ID already exists or
116 ///if input nodes are not found.
117 ///////////////////////////////////////////////////////////////////////////////
119 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
120 const SMDS_MeshNode * n2, int ID)
122 SMDS_MeshNode *node1,*node2;
123 node1=const_cast<SMDS_MeshNode*>(n1);
124 node2=const_cast<SMDS_MeshNode*>(n2);
126 SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2);
127 if(myElementIDFactory->BindID(ID, edge))
129 node1->AddInverseElement(edge);
130 node2->AddInverseElement(edge);
131 myEdges.insert(edge);
141 ///////////////////////////////////////////////////////////////////////////////
142 /// Add a triangle defined by its nodes. An ID is automatically affected to the
144 ///////////////////////////////////////////////////////////////////////////////
146 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
147 const SMDS_MeshNode * n2,
148 const SMDS_MeshNode * n3)
150 return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
153 ///////////////////////////////////////////////////////////////////////////////
154 /// Add a quadrangle defined by its nodes IDs
155 ///////////////////////////////////////////////////////////////////////////////
157 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
159 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
160 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
161 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
162 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
163 return AddFaceWithID(node1, node2, node3, ID);
166 ///////////////////////////////////////////////////////////////////////////////
167 /// Add a quadrangle defined by its nodes
168 ///////////////////////////////////////////////////////////////////////////////
170 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(
171 const SMDS_MeshNode * n1,
172 const SMDS_MeshNode * n2,
173 const SMDS_MeshNode * n3, int ID)
175 SMDS_MeshNode *node1, *node2, *node3;
176 node1=const_cast<SMDS_MeshNode*>(n1),
177 node2=const_cast<SMDS_MeshNode*>(n2),
178 node3=const_cast<SMDS_MeshNode*>(n3);
179 SMDS_MeshFace * face=createTriangle(node1, node2, node3);
181 if(myElementIDFactory->BindID(ID, face))
183 node1->AddInverseElement(face);
184 node2->AddInverseElement(face);
185 node3->AddInverseElement(face);
195 ///////////////////////////////////////////////////////////////////////////////
196 /// Add a triangle defined by its nodes. An ID is automatically affected to the
198 ///////////////////////////////////////////////////////////////////////////////
200 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
201 const SMDS_MeshNode * n2,
202 const SMDS_MeshNode * n3,
203 const SMDS_MeshNode * n4)
205 return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
208 ///////////////////////////////////////////////////////////////////////////////
209 /// Add a quadrangle defined by its nodes IDs
210 ///////////////////////////////////////////////////////////////////////////////
212 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3,
215 SMDS_MeshNode *node1, *node2, *node3, *node4;
216 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
217 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
218 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
219 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
220 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
221 return AddFaceWithID(node1, node2, node3, node4, ID);
224 ///////////////////////////////////////////////////////////////////////////////
225 /// Add a quadrangle defined by its nodes
226 ///////////////////////////////////////////////////////////////////////////////
228 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
229 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
230 const SMDS_MeshNode * n4, int ID)
232 SMDS_MeshNode *node1, *node2, *node3, *node4;
233 node1=const_cast<SMDS_MeshNode*>(n1),
234 node2=const_cast<SMDS_MeshNode*>(n2),
235 node3=const_cast<SMDS_MeshNode*>(n3);
236 node4=const_cast<SMDS_MeshNode*>(n4);
237 SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4);
239 if(myElementIDFactory->BindID(ID, face))
241 node1->AddInverseElement(face);
242 node2->AddInverseElement(face);
243 node3->AddInverseElement(face);
244 node4->AddInverseElement(face);
254 ///////////////////////////////////////////////////////////////////////////////
255 ///Create a new tetrahedron and add it to the mesh.
256 ///@return The created tetrahedron or NULL if an edge with this ID already exists
257 ///or if input nodes are not found.
258 ///////////////////////////////////////////////////////////////////////////////
260 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
261 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
262 const SMDS_MeshNode * n4)
264 int ID = myElementIDFactory->GetFreeID();
265 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID);
266 if(v==NULL) myElementIDFactory->ReleaseID(ID);
270 ///////////////////////////////////////////////////////////////////////////////
271 ///Create a new tetrahedron and add it to the mesh.
272 ///@param ID The ID of the new volume
273 ///@return The created tetrahedron or NULL if an edge with this ID already exists
274 ///or if input nodes are not found.
275 ///////////////////////////////////////////////////////////////////////////////
277 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
278 int idnode3, int idnode4, int ID)
280 SMDS_MeshNode *node1, *node2, *node3, *node4;
281 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
282 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
283 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
284 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
285 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
286 return AddVolumeWithID(node1, node2, node3, node4, ID);
289 ///////////////////////////////////////////////////////////////////////////////
290 ///Create a new tetrahedron and add it to the mesh.
291 ///@param ID The ID of the new volume
292 ///@return The created tetrahedron or NULL if an edge with this ID already exists
293 ///or if input nodes are not found.
294 ///////////////////////////////////////////////////////////////////////////////
296 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
297 const SMDS_MeshNode * n1,
298 const SMDS_MeshNode * n2,
299 const SMDS_MeshNode * n3,
300 const SMDS_MeshNode * n4, int ID)
302 SMDS_MeshNode *node1, *node2, *node3, *node4;
303 node1=const_cast<SMDS_MeshNode*>(n1),
304 node2=const_cast<SMDS_MeshNode*>(n2),
305 node3=const_cast<SMDS_MeshNode*>(n3);
306 node4=const_cast<SMDS_MeshNode*>(n4);
307 SMDS_MeshVolume* volume;
308 if(hasConstructionFaces())
310 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
311 SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
312 SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
313 SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
314 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
315 myVolumes.insert(volume);
317 else if(hasConstructionEdges())
319 MESSAGE("Error : Not implemented");
324 MESSAGE("Error : Not implemented");
328 if(myElementIDFactory->BindID(ID, volume))
330 node1->AddInverseElement(volume);
331 node2->AddInverseElement(volume);
332 node3->AddInverseElement(volume);
333 node4->AddInverseElement(volume);
338 RemoveVolume(volume);
343 ///////////////////////////////////////////////////////////////////////////////
344 ///Create a new pyramid and add it to the mesh.
345 ///Nodes 1,2,3 and 4 define the base of the pyramid
346 ///@return The created pyramid or NULL if an edge with this ID already exists
347 ///or if input nodes are not found.
348 ///////////////////////////////////////////////////////////////////////////////
350 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
351 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
352 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5)
354 int ID = myElementIDFactory->GetFreeID();
355 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID);
356 if(v==NULL) myElementIDFactory->ReleaseID(ID);
360 ///////////////////////////////////////////////////////////////////////////////
361 ///Create a new pyramid and add it to the mesh.
362 ///Nodes 1,2,3 and 4 define the base of the pyramid
363 ///@param ID The ID of the new volume
364 ///@return The created pyramid or NULL if an edge with this ID already exists
365 ///or if input nodes are not found.
366 ///////////////////////////////////////////////////////////////////////////////
368 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
369 int idnode3, int idnode4, int idnode5, int ID)
371 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
372 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
373 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
374 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
375 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
376 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
377 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
380 return AddVolumeWithID(node1, node2, node3, node4, node5, ID);
383 ///////////////////////////////////////////////////////////////////////////////
384 ///Create a new pyramid and add it to the mesh.
385 ///Nodes 1,2,3 and 4 define the base of the pyramid
386 ///@param ID The ID of the new volume
387 ///@return The created pyramid or NULL if an edge with this ID already exists
388 ///or if input nodes are not found.
389 ///////////////////////////////////////////////////////////////////////////////
391 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
392 const SMDS_MeshNode * n1,
393 const SMDS_MeshNode * n2,
394 const SMDS_MeshNode * n3,
395 const SMDS_MeshNode * n4,
396 const SMDS_MeshNode * n5, int ID)
398 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
399 node1=const_cast<SMDS_MeshNode*>(n1),
400 node2=const_cast<SMDS_MeshNode*>(n2),
401 node3=const_cast<SMDS_MeshNode*>(n3);
402 node4=const_cast<SMDS_MeshNode*>(n4);
403 node5=const_cast<SMDS_MeshNode*>(n5);
404 SMDS_MeshVolume* volume;
405 if(hasConstructionFaces())
407 SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
408 SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
409 SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
410 SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
411 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
412 myVolumes.insert(volume);
414 else if(hasConstructionEdges())
416 MESSAGE("Error : Not implemented");
421 MESSAGE("Error : Not implemented");
425 if(myElementIDFactory->BindID(ID, volume))
427 node1->AddInverseElement(volume);
428 node2->AddInverseElement(volume);
429 node3->AddInverseElement(volume);
430 node4->AddInverseElement(volume);
431 node5->AddInverseElement(volume);
436 RemoveVolume(volume);
441 ///////////////////////////////////////////////////////////////////////////////
442 ///Create a new prism and add it to the mesh.
443 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
444 ///@return The created prism or NULL if an edge with this ID already exists
445 ///or if input nodes are not found.
446 ///////////////////////////////////////////////////////////////////////////////
448 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
449 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
450 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
451 const SMDS_MeshNode * n6)
453 int ID = myElementIDFactory->GetFreeID();
454 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
455 if(v==NULL) myElementIDFactory->ReleaseID(ID);
459 ///////////////////////////////////////////////////////////////////////////////
460 ///Create a new prism and add it to the mesh.
461 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
462 ///@param ID The ID of the new volume
463 ///@return The created prism or NULL if an edge with this ID already exists
464 ///or if input nodes are not found.
465 ///////////////////////////////////////////////////////////////////////////////
467 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
468 int idnode3, int idnode4, int idnode5, int idnode6, int ID)
470 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
471 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
472 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
473 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
474 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
475 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
476 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
477 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
478 (node5==NULL)||(node6=NULL))
480 return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
483 ///////////////////////////////////////////////////////////////////////////////
484 ///Create a new prism and add it to the mesh.
485 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
486 ///@param ID The ID of the new volume
487 ///@return The created prism or NULL if an edge with this ID already exists
488 ///or if input nodes are not found.
489 ///////////////////////////////////////////////////////////////////////////////
491 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
492 const SMDS_MeshNode * n1,
493 const SMDS_MeshNode * n2,
494 const SMDS_MeshNode * n3,
495 const SMDS_MeshNode * n4,
496 const SMDS_MeshNode * n5,
497 const SMDS_MeshNode * n6, int ID)
499 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
500 node1=const_cast<SMDS_MeshNode*>(n1),
501 node2=const_cast<SMDS_MeshNode*>(n2),
502 node3=const_cast<SMDS_MeshNode*>(n3);
503 node4=const_cast<SMDS_MeshNode*>(n4);
504 node5=const_cast<SMDS_MeshNode*>(n5);
505 node6=const_cast<SMDS_MeshNode*>(n6);
506 SMDS_MeshVolume* volume;
507 if(hasConstructionFaces())
509 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
510 SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
511 SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
512 SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
513 SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
514 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
515 myVolumes.insert(volume);
517 else if(hasConstructionEdges())
519 MESSAGE("Error : Not implemented");
524 MESSAGE("Error : Not implemented");
528 if(myElementIDFactory->BindID(ID, volume))
530 node1->AddInverseElement(volume);
531 node2->AddInverseElement(volume);
532 node3->AddInverseElement(volume);
533 node4->AddInverseElement(volume);
534 node5->AddInverseElement(volume);
535 node6->AddInverseElement(volume);
540 RemoveVolume(volume);
545 ///////////////////////////////////////////////////////////////////////////////
546 ///Create a new hexahedron and add it to the mesh.
547 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
548 ///@return The created hexahedron or NULL if an edge with this ID already exists
549 ///or if input nodes are not found.
550 ///////////////////////////////////////////////////////////////////////////////
552 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
553 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
554 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
555 const SMDS_MeshNode * n6, const SMDS_MeshNode * n7,
556 const SMDS_MeshNode * n8)
558 int ID = myElementIDFactory->GetFreeID();
559 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
560 if(v==NULL) myElementIDFactory->ReleaseID(ID);
564 ///////////////////////////////////////////////////////////////////////////////
565 ///Create a new hexahedron and add it to the mesh.
566 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
567 ///@param ID The ID of the new volume
568 ///@return The created hexahedron or NULL if an edge with this ID already exists
569 ///or if input nodes are not found.
570 ///////////////////////////////////////////////////////////////////////////////
572 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
573 int idnode3, int idnode4, int idnode5, int idnode6, int idnode7,
576 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
577 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
578 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
579 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
580 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
581 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
582 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
583 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
584 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
585 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
586 (node5==NULL)||(node6=NULL)||(node7==NULL)||(node8=NULL))
588 return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7,
592 ///////////////////////////////////////////////////////////////////////////////
593 ///Create a new prism and add it to the mesh.
594 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
595 ///@param ID The ID of the new volume
596 ///@return The created prism or NULL if an edge with this ID already exists
597 ///or if input nodes are not found.
598 ///////////////////////////////////////////////////////////////////////////////
600 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
601 const SMDS_MeshNode * n1,
602 const SMDS_MeshNode * n2,
603 const SMDS_MeshNode * n3,
604 const SMDS_MeshNode * n4,
605 const SMDS_MeshNode * n5,
606 const SMDS_MeshNode * n6,
607 const SMDS_MeshNode * n7,
608 const SMDS_MeshNode * n8, int ID)
610 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
611 node1=const_cast<SMDS_MeshNode*>(n1),
612 node2=const_cast<SMDS_MeshNode*>(n2),
613 node3=const_cast<SMDS_MeshNode*>(n3);
614 node4=const_cast<SMDS_MeshNode*>(n4);
615 node5=const_cast<SMDS_MeshNode*>(n5);
616 node6=const_cast<SMDS_MeshNode*>(n6);
617 node7=const_cast<SMDS_MeshNode*>(n7);
618 node8=const_cast<SMDS_MeshNode*>(n8);
619 SMDS_MeshVolume* volume;
620 if(hasConstructionFaces())
622 SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
623 SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
624 SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
625 SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
626 SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
627 SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
628 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
629 myVolumes.insert(volume);
631 else if(hasConstructionEdges())
633 MESSAGE("Error : Not implemented");
638 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6,
640 myVolumes.insert(volume);
643 if(myElementIDFactory->BindID(ID, volume))
645 node1->AddInverseElement(volume);
646 node2->AddInverseElement(volume);
647 node3->AddInverseElement(volume);
648 node4->AddInverseElement(volume);
649 node5->AddInverseElement(volume);
650 node6->AddInverseElement(volume);
651 node7->AddInverseElement(volume);
652 node8->AddInverseElement(volume);
657 RemoveVolume(volume);
662 //=======================================================================
663 //function : FindNode
665 //=======================================================================
667 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
669 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
672 ///////////////////////////////////////////////////////////////////////////////
673 ///Create a triangle and add it to the current mesh. This methode do not bind a
674 ///ID to the create triangle.
675 ///////////////////////////////////////////////////////////////////////////////
676 SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
677 SMDS_MeshNode * node2, SMDS_MeshNode * node3)
679 if(hasConstructionEdges())
681 SMDS_MeshEdge *edge1, *edge2, *edge3;
682 edge1=FindEdgeOrCreate(node1,node2);
683 edge2=FindEdgeOrCreate(node2,node3);
684 edge3=FindEdgeOrCreate(node3,node1);
686 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
687 myFaces.insert(face);
692 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
693 myFaces.insert(face);
698 ///////////////////////////////////////////////////////////////////////////////
699 ///Create a quadrangle and add it to the current mesh. This methode do not bind
700 ///a ID to the create triangle.
701 ///////////////////////////////////////////////////////////////////////////////
702 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
703 SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
705 if(hasConstructionEdges())
707 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
708 edge1=FindEdgeOrCreate(node1,node2);
709 edge2=FindEdgeOrCreate(node2,node3);
710 edge3=FindEdgeOrCreate(node3,node4);
711 edge4=FindEdgeOrCreate(node4,node1);
713 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
714 myFaces.insert(face);
719 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
720 myFaces.insert(face);
726 //=======================================================================
727 //function : RemoveNode
729 //=======================================================================
731 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
733 SMDS_Iterator<const SMDS_MeshElement *> * it=
734 node->GetInverseElementIterator();
735 while(it->more()) RemoveElement(it->next(),true);
736 myNodeIDFactory->ReleaseID(node->GetID());
737 myNodes.erase(const_cast<SMDS_MeshNode*>(node));
740 //=======================================================================
741 //function : RemoveEdge
743 //=======================================================================
745 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
747 /** @todo to be fix */
748 myEdges.erase(const_cast<SMDS_MeshEdge*>(edge));
749 //removeElementDependencies(edge);
753 //=======================================================================
754 //function : RemoveFace
756 //=======================================================================
758 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
760 /** @todo to be fix */
761 myFaces.erase(const_cast<SMDS_MeshFace*>(face));
762 //removeElementDependencies(face);
766 //=======================================================================
767 //function : RemoveVolume
769 //=======================================================================
771 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
773 /** @todo to be fix */
774 myVolumes.erase(const_cast<SMDS_MeshVolume*>(volume));
775 //removeElementDependencies(volume);
778 ///////////////////////////////////////////////////////////////////////////////
779 /// Remove no longer used sub element of an element. Unbind the element ID
780 ///////////////////////////////////////////////////////////////////////////////
781 void SMDS_Mesh::removeElementDependencies(SMDS_MeshElement * element)
783 /** @todo to be fix */
784 myElementIDFactory->ReleaseID(element->GetID());
785 SMDS_Iterator<const SMDS_MeshElement*> * it=element->nodesIterator();
788 SMDS_MeshNode * node=static_cast<SMDS_MeshNode*>(
789 const_cast<SMDS_MeshElement*>(it->next()));
790 node->RemoveInverseElement(element);
791 if(node->emptyInverseElements()) RemoveNode(node);
795 //=======================================================================
796 //function : RemoveElement
798 //=======================================================================
800 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
801 const bool removenodes)
803 /** @todo to be fix */
804 switch(elem->GetType())
807 RemoveNode((const SMDS_MeshNode*)elem);
810 RemoveEdge((const SMDS_MeshEdge*)elem);
813 RemoveFace((const SMDS_MeshFace*)elem);
816 RemoveVolume((const SMDS_MeshVolume*)elem);
819 MESSAGE("remove function : unknown type");
823 SMDS_Iterator<const SMDS_MeshNode*> * it=elem->nodesIterator();
826 const SMDS_MeshNode * node=it->next();
831 //=======================================================================
832 //function : RemoveFromParent
834 //=======================================================================
836 bool SMDS_Mesh::RemoveFromParent()
838 if (myParent==NULL) return false;
839 else return (myParent->RemoveSubMesh(this));
842 //=======================================================================
843 //function : RemoveSubMesh
845 //=======================================================================
847 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
851 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
852 for (; itmsh!=myChildren.end() && !found; itmsh++)
854 SMDS_Mesh * submesh = *itmsh;
855 if (submesh == aMesh)
858 myChildren.erase(itmsh);
866 //=======================================================================
867 //function : FindEdge
869 //=======================================================================
871 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
873 const SMDS_MeshNode * node1=FindNode(idnode1);
874 const SMDS_MeshNode * node2=FindNode(idnode2);
875 if((node1==NULL)||(node2==NULL)) return NULL;
876 return FindEdge(node1,node2);
879 ///////////////////////////////////////////////////////////////////////////////
881 ///////////////////////////////////////////////////////////////////////////////
882 //#include "Profiler.h"
883 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
884 const SMDS_MeshNode * node2) const
886 const SMDS_MeshEdge * toReturn=NULL;
889 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->edgesIterator();
894 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
896 SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
899 if(it2->next()->GetID()==node2->GetID())
913 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
914 const SMDS_MeshNode * node2)
916 SMDS_MeshEdge * toReturn=NULL;
917 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
920 toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
921 const_cast<SMDS_MeshNode*>(node2));
922 myEdges.insert(toReturn);
927 //=======================================================================
928 //function : FindFace
930 //=======================================================================
932 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
935 const SMDS_MeshNode * node1=FindNode(idnode1);
936 const SMDS_MeshNode * node2=FindNode(idnode2);
937 const SMDS_MeshNode * node3=FindNode(idnode3);
938 const SMDS_MeshFace * face;
939 const SMDS_MeshElement * node;
940 bool node2found, node3found;
941 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
943 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
946 face=static_cast<const SMDS_MeshFace*>(it1->next());
947 if(face->NbNodes()!=3) continue;
948 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
954 if(node->GetID()==idnode2) node2found=true;
955 if(node->GetID()==idnode3) node3found=true;
958 if(node2found&&node3found)
968 //=======================================================================
969 //function : FindFace
971 //=======================================================================
973 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
976 const SMDS_MeshNode * node1=FindNode(idnode1);
977 const SMDS_MeshNode * node2=FindNode(idnode2);
978 const SMDS_MeshNode * node3=FindNode(idnode3);
979 const SMDS_MeshNode * node4=FindNode(idnode4);
980 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
981 return FindFace(node1, node2, node3, node4);
984 const SMDS_MeshFace* SMDS_Mesh::FindFace(
985 const SMDS_MeshNode *node1,
986 const SMDS_MeshNode *node2,
987 const SMDS_MeshNode *node3,
988 const SMDS_MeshNode *node4) const
990 const SMDS_MeshFace * face;
991 const SMDS_MeshElement * node;
992 bool node2found, node3found, node4found;
993 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
996 face=static_cast<const SMDS_MeshFace *>(it1->next());
997 if(face->NbNodes()!=4) continue;
998 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
1005 if(node->GetID()==node2->GetID()) node2found=true;
1006 if(node->GetID()==node3->GetID()) node3found=true;
1007 if(node->GetID()==node4->GetID()) node4found=true;
1010 if(node2found&&node3found&&node4found)
1020 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1021 const SMDS_MeshNode *node1,
1022 const SMDS_MeshNode *node2,
1023 const SMDS_MeshNode *node3,
1024 const SMDS_MeshNode *node4)
1026 SMDS_MeshFace * toReturn=NULL;
1027 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1030 toReturn=createQuadrangle(
1031 const_cast<SMDS_MeshNode *>(node1),
1032 const_cast<SMDS_MeshNode *>(node2),
1033 const_cast<SMDS_MeshNode *>(node3),
1034 const_cast<SMDS_MeshNode *>(node4)
1040 //=======================================================================
1041 //function : FindElement
1043 //=======================================================================
1045 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1047 return myElementIDFactory->MeshElement(IDelem);
1050 //=======================================================================
1051 //function : DumpNodes
1053 //=======================================================================
1055 void SMDS_Mesh::DumpNodes() const
1057 MESSAGE("dump nodes of mesh : ");
1058 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1059 while(itnode->more()) MESSAGE(itnode->next());
1063 //=======================================================================
1064 //function : DumpEdges
1066 //=======================================================================
1068 void SMDS_Mesh::DumpEdges() const
1070 MESSAGE("dump edges of mesh : ");
1071 SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
1072 while(itedge->more()) MESSAGE(itedge->next());
1076 //=======================================================================
1077 //function : DumpFaces
1079 //=======================================================================
1081 void SMDS_Mesh::DumpFaces() const
1083 MESSAGE("dump faces of mesh : ");
1084 SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
1085 while(itface->more()) MESSAGE(itface->next());
1089 //=======================================================================
1090 //function : DumpVolumes
1092 //=======================================================================
1094 void SMDS_Mesh::DumpVolumes() const
1096 MESSAGE("dump volumes of mesh : ");
1097 SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
1098 while(itvol->more()) MESSAGE(itvol->next());
1102 //=======================================================================
1103 //function : DebugStats
1105 //=======================================================================
1107 void SMDS_Mesh::DebugStats() const
1109 MESSAGE("Debug stats of mesh : ");
1111 MESSAGE("===== NODES ====="<<NbNodes());
1112 MESSAGE("===== EDGES ====="<<NbEdges());
1113 MESSAGE("===== FACES ====="<<NbFaces());
1114 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1116 MESSAGE("End Debug stats of mesh ");
1120 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1121 int sizeofnodes = 0;
1122 int sizeoffaces = 0;
1124 while(itnode->more())
1126 const SMDS_MeshNode *node = itnode->next();
1128 sizeofnodes += sizeof(*node);
1130 SMDS_Iterator<const SMDS_MeshElement *> * it=
1131 node->GetInverseElementIterator();
1134 const SMDS_MeshElement *me = it->next();
1135 sizeofnodes += sizeof(me);
1141 SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
1143 while(itface->more())
1145 const SMDS_MeshElement *face = itface->next();
1146 sizeoffaces += sizeof(*face);
1149 MESSAGE("total size of node elements = " << sizeofnodes);;
1150 MESSAGE("total size of face elements = " << sizeoffaces);;
1156 int SMDS_Mesh::NbNodes() const
1158 return myNodes.size();
1161 int SMDS_Mesh::NbEdges() const
1163 return myEdges.size();
1166 int SMDS_Mesh::NbFaces() const
1168 return myFaces.size();
1171 int SMDS_Mesh::NbVolumes() const
1173 return myVolumes.size();
1176 int SMDS_Mesh::NbSubMesh() const
1178 return myChildren.size();
1181 SMDS_Mesh::~SMDS_Mesh()
1185 delete myNodeIDFactory;
1186 delete myElementIDFactory;
1189 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1190 while(itc!=myChildren.end())
1196 SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1203 set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1204 while(ite!=myEdges.end())
1210 set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1211 while(itf!=myFaces.end())
1217 set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1218 while(itv!=myVolumes.end())
1226 bool SMDS_Mesh::hasConstructionEdges()
1228 return myHasConstructionEdges;
1231 bool SMDS_Mesh::hasConstructionFaces()
1233 return myHasConstructionFaces;
1236 bool SMDS_Mesh::hasInverseElements()
1238 return myHasInverseElements;
1241 void SMDS_Mesh::setConstructionEdges(bool b)
1243 myHasConstructionEdges=b;
1246 void SMDS_Mesh::setConstructionFaces(bool b)
1248 myHasConstructionFaces=b;
1251 void SMDS_Mesh::setInverseElements(bool b)
1253 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1254 myHasInverseElements=b;
1257 ///////////////////////////////////////////////////////////////////////////////
1258 ///Return an iterator on nodes of the current mesh. Once used this iterator
1259 ///must be free by the caller
1260 ///////////////////////////////////////////////////////////////////////////////
1261 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1263 class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1265 const SetOfNodes& mySet;
1266 SetOfNodes::iterator myIterator;
1268 MyIterator(const SetOfNodes& s):mySet(s)
1270 myIterator=mySet.begin();
1275 return myIterator!=mySet.end();
1278 const SMDS_MeshNode* next()
1280 const SMDS_MeshNode* current=*myIterator;
1285 return new MyIterator(myNodes);
1288 ///////////////////////////////////////////////////////////////////////////////
1289 ///Return an iterator on volumes of the current mesh. Once used this iterator
1290 ///must be free by the caller
1291 ///////////////////////////////////////////////////////////////////////////////
1292 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1294 class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1296 const SetOfEdges& mySet;
1297 const SMDS_MeshEdge * myEdge;
1298 SetOfEdges::iterator myIterator;
1300 MyIterator(const SetOfEdges& s):mySet(s)
1302 myIterator=mySet.begin();
1307 while((myIterator!=mySet.end()))
1309 if((*myIterator)->GetID()!=-1)
1316 const SMDS_MeshEdge* next()
1318 const SMDS_MeshEdge* current=*myIterator;
1323 return new MyIterator(myEdges);
1326 ///////////////////////////////////////////////////////////////////////////////
1327 ///Return an iterator on faces of the current mesh. Once used this iterator
1328 ///must be free by the caller
1329 ///////////////////////////////////////////////////////////////////////////////
1330 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1332 class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1334 const SetOfFaces& mySet;
1335 set<SMDS_MeshFace*>::iterator myIterator;
1337 MyIterator(const SetOfFaces& s):mySet(s)
1339 myIterator=mySet.begin();
1344 while((myIterator!=mySet.end()))
1346 if((*myIterator)->GetID()!=-1)
1353 const SMDS_MeshFace* next()
1355 const SMDS_MeshFace* current=*myIterator;
1360 return new MyIterator(myFaces);
1363 ///////////////////////////////////////////////////////////////////////////////
1364 ///Return an iterator on volumes of the current mesh. Once used this iterator
1365 ///must be free by the caller
1366 ///////////////////////////////////////////////////////////////////////////////
1367 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1369 class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1371 const SetOfVolumes& mySet;
1372 SetOfVolumes::iterator myIterator;
1374 MyIterator(const SetOfVolumes& s):mySet(s)
1376 myIterator=mySet.begin();
1381 return myIterator!=mySet.end();
1384 const SMDS_MeshVolume* next()
1386 const SMDS_MeshVolume* current=*myIterator;
1391 return new MyIterator(myVolumes);