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_Tria3OfNodes.hxx"
28 #include "SMDS_HexahedronOfNodes.hxx"
29 #include "SMDS_FaceOfEdges.hxx"
34 ///////////////////////////////////////////////////////////////////////////////
35 /// Create a new mesh object
36 ///////////////////////////////////////////////////////////////////////////////
37 SMDS_Mesh::SMDS_Mesh()
38 :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
39 myElementIDFactory(new SMDS_MeshElementIDFactory()),
40 myHasConstructionEdges(false), myHasConstructionFaces(false),
41 myHasInverseElements(true)
45 ///////////////////////////////////////////////////////////////////////////////
46 /// Create a new child mesh
47 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
48 /// (2003-09-08) of SMESH
49 ///////////////////////////////////////////////////////////////////////////////
50 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
51 :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
52 myElementIDFactory(parent->myElementIDFactory),
53 myHasConstructionEdges(false), myHasConstructionFaces(false),
54 myHasInverseElements(true)
58 ///////////////////////////////////////////////////////////////////////////////
59 ///Create a submesh and add it to the current mesh
60 ///////////////////////////////////////////////////////////////////////////////
62 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
64 SMDS_Mesh *submesh = new SMDS_Mesh(this);
65 myChildren.insert(myChildren.end(), submesh);
69 ///////////////////////////////////////////////////////////////////////////////
70 ///create a MeshNode and add it to the current Mesh
71 ///An ID is automatically assigned to the node.
72 ///@return : The created node
73 ///////////////////////////////////////////////////////////////////////////////
75 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
77 return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
80 ///////////////////////////////////////////////////////////////////////////////
81 ///create a MeshNode and add it to the current Mesh
82 ///@param ID : The ID of the MeshNode to create
83 ///@return : The created node or NULL if a node with this ID already exists
84 ///////////////////////////////////////////////////////////////////////////////
85 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
87 // find the MeshNode corresponding to ID
88 const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
92 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
94 myNodeIDFactory->BindID(ID,node);
101 ///////////////////////////////////////////////////////////////////////////////
102 /// create a MeshEdge and add it to the current Mesh
103 /// @return : The created MeshEdge
104 ///////////////////////////////////////////////////////////////////////////////
106 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
108 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
109 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
110 if((node1==NULL)||(node2==NULL)) return NULL;
111 return AddEdgeWithID(node1, node2, ID);
114 ///////////////////////////////////////////////////////////////////////////////
115 /// create a MeshEdge and add it to the current Mesh
116 /// @return : The created MeshEdge
117 ///////////////////////////////////////////////////////////////////////////////
119 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
120 const SMDS_MeshNode * node2)
122 return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
125 ///////////////////////////////////////////////////////////////////////////////
126 /// Create a new edge and at it to the mesh
127 /// @param idnode1 ID of the first node
128 /// @param idnode2 ID of the second node
129 /// @param ID ID of the edge to create
130 /// @return The created edge or NULL if an edge with this ID already exists or
131 /// if input nodes are not found.
132 ///////////////////////////////////////////////////////////////////////////////
134 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
135 const SMDS_MeshNode * n2, int ID)
137 SMDS_MeshNode *node1,*node2;
138 node1=const_cast<SMDS_MeshNode*>(n1);
139 node2=const_cast<SMDS_MeshNode*>(n2);
141 SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2);
142 if(myElementIDFactory->BindID(ID, edge))
144 node1->AddInverseElement(edge);
145 node2->AddInverseElement(edge);
146 myEdges.insert(edge);
156 ///////////////////////////////////////////////////////////////////////////////
157 /// Add a triangle defined by its nodes. An ID is automatically affected to the
159 ///////////////////////////////////////////////////////////////////////////////
161 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
162 const SMDS_MeshNode * n2,
163 const SMDS_MeshNode * n3)
165 return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
168 ///////////////////////////////////////////////////////////////////////////////
169 /// Add a quadrangle defined by its nodes IDs
170 ///////////////////////////////////////////////////////////////////////////////
172 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
174 SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
175 SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
176 SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
177 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
178 return AddFaceWithID(node1, node2, node3, ID);
181 ///////////////////////////////////////////////////////////////////////////////
182 /// Add a quadrangle defined by its nodes
183 ///////////////////////////////////////////////////////////////////////////////
185 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(
186 const SMDS_MeshNode * n1,
187 const SMDS_MeshNode * n2,
188 const SMDS_MeshNode * n3, int ID)
190 SMDS_MeshNode *node1, *node2, *node3;
191 node1=const_cast<SMDS_MeshNode*>(n1),
192 node2=const_cast<SMDS_MeshNode*>(n2),
193 node3=const_cast<SMDS_MeshNode*>(n3);
194 SMDS_MeshFace * face=createTriangle(node1, node2, node3);
196 if(myElementIDFactory->BindID(ID, face))
198 node1->AddInverseElement(face);
199 node2->AddInverseElement(face);
200 node3->AddInverseElement(face);
210 ///////////////////////////////////////////////////////////////////////////////
211 /// Add a triangle defined by its nodes. An ID is automatically affected to the
213 ///////////////////////////////////////////////////////////////////////////////
215 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
216 const SMDS_MeshNode * n2,
217 const SMDS_MeshNode * n3,
218 const SMDS_MeshNode * n4)
220 return AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
223 ///////////////////////////////////////////////////////////////////////////////
224 /// Add a quadrangle defined by its nodes IDs
225 ///////////////////////////////////////////////////////////////////////////////
227 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3,
230 SMDS_MeshNode *node1, *node2, *node3, *node4;
231 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
232 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
233 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
234 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
235 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
236 return AddFaceWithID(node1, node2, node3, node4, ID);
239 ///////////////////////////////////////////////////////////////////////////////
240 /// Add a quadrangle defined by its nodes
241 ///////////////////////////////////////////////////////////////////////////////
243 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
244 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
245 const SMDS_MeshNode * n4, int ID)
247 SMDS_MeshNode *node1, *node2, *node3, *node4;
248 node1=const_cast<SMDS_MeshNode*>(n1),
249 node2=const_cast<SMDS_MeshNode*>(n2),
250 node3=const_cast<SMDS_MeshNode*>(n3);
251 node4=const_cast<SMDS_MeshNode*>(n4);
252 SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4);
254 if(myElementIDFactory->BindID(ID, face))
256 node1->AddInverseElement(face);
257 node2->AddInverseElement(face);
258 node3->AddInverseElement(face);
259 node4->AddInverseElement(face);
269 ///////////////////////////////////////////////////////////////////////////////
270 ///Create a new tetrahedron and add it to the mesh.
271 ///@return The created tetrahedron
272 ///////////////////////////////////////////////////////////////////////////////
274 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
275 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
276 const SMDS_MeshNode * n4)
278 int ID = myElementIDFactory->GetFreeID();
279 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID);
280 if(v==NULL) myElementIDFactory->ReleaseID(ID);
284 ///////////////////////////////////////////////////////////////////////////////
285 ///Create a new tetrahedron and add it to the mesh.
286 ///@param ID The ID of the new volume
287 ///@return The created tetrahedron or NULL if an edge with this ID already exists
288 ///or if input nodes are not found.
289 ///////////////////////////////////////////////////////////////////////////////
291 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
292 int idnode3, int idnode4, int ID)
294 SMDS_MeshNode *node1, *node2, *node3, *node4;
295 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
296 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
297 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
298 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
299 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
300 return AddVolumeWithID(node1, node2, node3, node4, ID);
303 ///////////////////////////////////////////////////////////////////////////////
304 ///Create a new tetrahedron and add it to the mesh.
305 ///@param ID The ID of the new volume
306 ///@return The created tetrahedron
307 ///////////////////////////////////////////////////////////////////////////////
309 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
310 const SMDS_MeshNode * n1,
311 const SMDS_MeshNode * n2,
312 const SMDS_MeshNode * n3,
313 const SMDS_MeshNode * n4, int ID)
315 SMDS_MeshNode *node1, *node2, *node3, *node4;
316 node1=const_cast<SMDS_MeshNode*>(n1),
317 node2=const_cast<SMDS_MeshNode*>(n2),
318 node3=const_cast<SMDS_MeshNode*>(n3);
319 node4=const_cast<SMDS_MeshNode*>(n4);
320 SMDS_MeshVolume* volume;
321 if(hasConstructionFaces())
323 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
324 SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
325 SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
326 SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
327 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
328 myVolumes.insert(volume);
330 else if(hasConstructionEdges())
332 MESSAGE("Error : Not implemented");
337 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4);
338 myVolumes.insert(volume);
341 if(myElementIDFactory->BindID(ID, volume))
343 node1->AddInverseElement(volume);
344 node2->AddInverseElement(volume);
345 node3->AddInverseElement(volume);
346 node4->AddInverseElement(volume);
351 RemoveVolume(volume);
356 ///////////////////////////////////////////////////////////////////////////////
357 ///Create a new pyramid and add it to the mesh.
358 ///Nodes 1,2,3 and 4 define the base of the pyramid
359 ///@return The created pyramid
360 ///////////////////////////////////////////////////////////////////////////////
362 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
363 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
364 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5)
366 int ID = myElementIDFactory->GetFreeID();
367 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID);
368 if(v==NULL) myElementIDFactory->ReleaseID(ID);
372 ///////////////////////////////////////////////////////////////////////////////
373 ///Create a new pyramid and add it to the mesh.
374 ///Nodes 1,2,3 and 4 define the base of the pyramid
375 ///@param ID The ID of the new volume
376 ///@return The created pyramid or NULL if a pyramid with this ID already exists
377 ///or if input nodes are not found.
378 ///////////////////////////////////////////////////////////////////////////////
380 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
381 int idnode3, int idnode4, int idnode5, int ID)
383 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
384 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
385 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
386 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
387 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
388 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
389 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
392 return AddVolumeWithID(node1, node2, node3, node4, node5, ID);
395 ///////////////////////////////////////////////////////////////////////////////
396 ///Create a new pyramid and add it to the mesh.
397 ///Nodes 1,2,3 and 4 define the base of the pyramid
398 ///@param ID The ID of the new volume
399 ///@return The created pyramid
400 ///////////////////////////////////////////////////////////////////////////////
402 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
403 const SMDS_MeshNode * n1,
404 const SMDS_MeshNode * n2,
405 const SMDS_MeshNode * n3,
406 const SMDS_MeshNode * n4,
407 const SMDS_MeshNode * n5, int ID)
409 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
410 node1=const_cast<SMDS_MeshNode*>(n1),
411 node2=const_cast<SMDS_MeshNode*>(n2),
412 node3=const_cast<SMDS_MeshNode*>(n3);
413 node4=const_cast<SMDS_MeshNode*>(n4);
414 node5=const_cast<SMDS_MeshNode*>(n5);
415 SMDS_MeshVolume* volume;
416 if(hasConstructionFaces())
418 SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
419 SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
420 SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
421 SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
422 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
423 myVolumes.insert(volume);
425 else if(hasConstructionEdges())
427 MESSAGE("Error : Not implemented");
432 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5);
433 myVolumes.insert(volume);
436 if(myElementIDFactory->BindID(ID, volume))
438 node1->AddInverseElement(volume);
439 node2->AddInverseElement(volume);
440 node3->AddInverseElement(volume);
441 node4->AddInverseElement(volume);
442 node5->AddInverseElement(volume);
447 RemoveVolume(volume);
452 ///////////////////////////////////////////////////////////////////////////////
453 ///Create a new prism and add it to the mesh.
454 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
455 ///@return The created prism
456 ///////////////////////////////////////////////////////////////////////////////
458 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
459 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
460 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
461 const SMDS_MeshNode * n6)
463 int ID = myElementIDFactory->GetFreeID();
464 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
465 if(v==NULL) myElementIDFactory->ReleaseID(ID);
469 ///////////////////////////////////////////////////////////////////////////////
470 ///Create a new prism and add it to the mesh.
471 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
472 ///@param ID The ID of the new volume
473 ///@return The created prism or NULL if a prism with this ID already exists
474 ///or if input nodes are not found.
475 ///////////////////////////////////////////////////////////////////////////////
477 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
478 int idnode3, int idnode4, int idnode5, int idnode6, int ID)
480 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
481 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
482 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
483 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
484 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
485 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
486 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
487 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
488 (node5==NULL)||(node6=NULL))
490 return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
493 ///////////////////////////////////////////////////////////////////////////////
494 ///Create a new prism and add it to the mesh.
495 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
496 ///@param ID The ID of the new volume
497 ///@return The created prism
498 ///////////////////////////////////////////////////////////////////////////////
500 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
501 const SMDS_MeshNode * n1,
502 const SMDS_MeshNode * n2,
503 const SMDS_MeshNode * n3,
504 const SMDS_MeshNode * n4,
505 const SMDS_MeshNode * n5,
506 const SMDS_MeshNode * n6, int ID)
508 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
509 node1=const_cast<SMDS_MeshNode*>(n1),
510 node2=const_cast<SMDS_MeshNode*>(n2),
511 node3=const_cast<SMDS_MeshNode*>(n3);
512 node4=const_cast<SMDS_MeshNode*>(n4);
513 node5=const_cast<SMDS_MeshNode*>(n5);
514 node6=const_cast<SMDS_MeshNode*>(n6);
515 SMDS_MeshVolume* volume;
516 if(hasConstructionFaces())
518 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
519 SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
520 SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
521 SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
522 SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
523 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
524 myVolumes.insert(volume);
526 else if(hasConstructionEdges())
528 MESSAGE("Error : Not implemented");
533 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6);
534 myVolumes.insert(volume);
537 if(myElementIDFactory->BindID(ID, volume))
539 node1->AddInverseElement(volume);
540 node2->AddInverseElement(volume);
541 node3->AddInverseElement(volume);
542 node4->AddInverseElement(volume);
543 node5->AddInverseElement(volume);
544 node6->AddInverseElement(volume);
549 RemoveVolume(volume);
554 ///////////////////////////////////////////////////////////////////////////////
555 ///Create a new hexahedron and add it to the mesh.
556 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
557 ///@return The created hexahedron
558 ///////////////////////////////////////////////////////////////////////////////
560 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
561 const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
562 const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
563 const SMDS_MeshNode * n6, const SMDS_MeshNode * n7,
564 const SMDS_MeshNode * n8)
566 int ID = myElementIDFactory->GetFreeID();
567 SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
568 if(v==NULL) myElementIDFactory->ReleaseID(ID);
572 ///////////////////////////////////////////////////////////////////////////////
573 ///Create a new hexahedron and add it to the mesh.
574 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
575 ///@param ID The ID of the new volume
576 ///@return The created hexahedron or NULL if an hexahedron with this ID already
577 ///exists or if input nodes are not found.
578 ///////////////////////////////////////////////////////////////////////////////
580 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
581 int idnode3, int idnode4, int idnode5, int idnode6, int idnode7,
584 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
585 node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
586 node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
587 node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
588 node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
589 node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
590 node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
591 node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
592 node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
593 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)||
594 (node5==NULL)||(node6==NULL)||(node7==NULL)||(node8==NULL))
596 return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7,
600 ///////////////////////////////////////////////////////////////////////////////
601 ///Create a new hexahedron and add it to the mesh.
602 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
603 ///@param ID The ID of the new volume
604 ///@return The created prism or NULL if an hexadron with this ID already exists
605 ///or if input nodes are not found.
606 ///////////////////////////////////////////////////////////////////////////////
608 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
609 const SMDS_MeshNode * n1,
610 const SMDS_MeshNode * n2,
611 const SMDS_MeshNode * n3,
612 const SMDS_MeshNode * n4,
613 const SMDS_MeshNode * n5,
614 const SMDS_MeshNode * n6,
615 const SMDS_MeshNode * n7,
616 const SMDS_MeshNode * n8, int ID)
618 SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
619 node1=const_cast<SMDS_MeshNode*>(n1),
620 node2=const_cast<SMDS_MeshNode*>(n2),
621 node3=const_cast<SMDS_MeshNode*>(n3);
622 node4=const_cast<SMDS_MeshNode*>(n4);
623 node5=const_cast<SMDS_MeshNode*>(n5);
624 node6=const_cast<SMDS_MeshNode*>(n6);
625 node7=const_cast<SMDS_MeshNode*>(n7);
626 node8=const_cast<SMDS_MeshNode*>(n8);
627 SMDS_MeshVolume* volume;
628 if(hasConstructionFaces())
630 SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
631 SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
632 SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
633 SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
634 SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
635 SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
636 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
637 myVolumes.insert(volume);
639 else if(hasConstructionEdges())
641 MESSAGE("Error : Not implemented");
646 volume=new SMDS_HexahedronOfNodes(node1,node2,node3,node4,node5,node6,
648 myVolumes.insert(volume);
651 if(myElementIDFactory->BindID(ID, volume))
653 node1->AddInverseElement(volume);
654 node2->AddInverseElement(volume);
655 node3->AddInverseElement(volume);
656 node4->AddInverseElement(volume);
657 node5->AddInverseElement(volume);
658 node6->AddInverseElement(volume);
659 node7->AddInverseElement(volume);
660 node8->AddInverseElement(volume);
665 RemoveVolume(volume);
670 ///////////////////////////////////////////////////////////////////////////////
671 /// Return the node whose ID is 'ID'.
672 ///////////////////////////////////////////////////////////////////////////////
673 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
675 return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
678 ///////////////////////////////////////////////////////////////////////////////
679 ///Create a triangle and add it to the current mesh. This methode do not bind a
680 ///ID to the create triangle.
681 ///////////////////////////////////////////////////////////////////////////////
682 SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
683 SMDS_MeshNode * node2, SMDS_MeshNode * node3)
685 if(hasConstructionEdges())
687 SMDS_MeshEdge *edge1, *edge2, *edge3;
688 edge1=FindEdgeOrCreate(node1,node2);
689 edge2=FindEdgeOrCreate(node2,node3);
690 edge3=FindEdgeOrCreate(node3,node1);
692 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
693 myFaces.insert(face);
698 SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3);
699 myFaces.insert(face);
704 ///////////////////////////////////////////////////////////////////////////////
705 ///Create a quadrangle and add it to the current mesh. This methode do not bind
706 ///a ID to the create triangle.
707 ///////////////////////////////////////////////////////////////////////////////
708 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
709 SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
711 if(hasConstructionEdges())
713 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
714 edge1=FindEdgeOrCreate(node1,node2);
715 edge2=FindEdgeOrCreate(node2,node3);
716 edge3=FindEdgeOrCreate(node3,node4);
717 edge4=FindEdgeOrCreate(node4,node1);
719 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
720 myFaces.insert(face);
725 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
726 myFaces.insert(face);
731 ///////////////////////////////////////////////////////////////////////////////
732 /// Remove a node and all the elements which own this node
733 ///////////////////////////////////////////////////////////////////////////////
735 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
737 RemoveElement(node, true);
740 ///////////////////////////////////////////////////////////////////////////////
741 /// Remove an edge and all the elements which own this edge
742 ///////////////////////////////////////////////////////////////////////////////
744 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
746 RemoveElement(edge,true);
749 ///////////////////////////////////////////////////////////////////////////////
750 /// Remove an face and all the elements which own this face
751 ///////////////////////////////////////////////////////////////////////////////
753 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
755 RemoveElement(face, true);
758 ///////////////////////////////////////////////////////////////////////////////
760 ///////////////////////////////////////////////////////////////////////////////
762 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
764 RemoveElement(volume, true);
767 //=======================================================================
768 //function : RemoveFromParent
770 //=======================================================================
772 bool SMDS_Mesh::RemoveFromParent()
774 if (myParent==NULL) return false;
775 else return (myParent->RemoveSubMesh(this));
778 //=======================================================================
779 //function : RemoveSubMesh
781 //=======================================================================
783 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
787 list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
788 for (; itmsh!=myChildren.end() && !found; itmsh++)
790 SMDS_Mesh * submesh = *itmsh;
791 if (submesh == aMesh)
794 myChildren.erase(itmsh);
802 //=======================================================================
803 //function : FindEdge
805 //=======================================================================
807 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
809 const SMDS_MeshNode * node1=FindNode(idnode1);
810 const SMDS_MeshNode * node2=FindNode(idnode2);
811 if((node1==NULL)||(node2==NULL)) return NULL;
812 return FindEdge(node1,node2);
815 ///////////////////////////////////////////////////////////////////////////////
817 ///////////////////////////////////////////////////////////////////////////////
818 //#include "Profiler.h"
819 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
820 const SMDS_MeshNode * node2) const
822 const SMDS_MeshEdge * toReturn=NULL;
825 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->edgesIterator();
830 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
832 SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
835 if(it2->next()->GetID()==node2->GetID())
849 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
850 const SMDS_MeshNode * node2)
852 SMDS_MeshEdge * toReturn=NULL;
853 toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
856 toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
857 const_cast<SMDS_MeshNode*>(node2));
858 myEdges.insert(toReturn);
863 //=======================================================================
864 //function : FindFace
866 //=======================================================================
868 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
871 const SMDS_MeshNode * node1=FindNode(idnode1);
872 const SMDS_MeshNode * node2=FindNode(idnode2);
873 const SMDS_MeshNode * node3=FindNode(idnode3);
874 const SMDS_MeshFace * face;
875 const SMDS_MeshElement * node;
876 bool node2found, node3found;
877 if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
879 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
882 face=static_cast<const SMDS_MeshFace*>(it1->next());
883 if(face->NbNodes()!=3) continue;
884 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
890 if(node->GetID()==idnode2) node2found=true;
891 if(node->GetID()==idnode3) node3found=true;
894 if(node2found&&node3found)
904 //=======================================================================
905 //function : FindFace
907 //=======================================================================
909 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
912 const SMDS_MeshNode * node1=FindNode(idnode1);
913 const SMDS_MeshNode * node2=FindNode(idnode2);
914 const SMDS_MeshNode * node3=FindNode(idnode3);
915 const SMDS_MeshNode * node4=FindNode(idnode4);
916 if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
917 return FindFace(node1, node2, node3, node4);
920 const SMDS_MeshFace* SMDS_Mesh::FindFace(
921 const SMDS_MeshNode *node1,
922 const SMDS_MeshNode *node2,
923 const SMDS_MeshNode *node3,
924 const SMDS_MeshNode *node4) const
926 const SMDS_MeshFace * face;
927 const SMDS_MeshElement * node;
928 bool node2found, node3found, node4found;
929 SMDS_Iterator<const SMDS_MeshElement *>* it1=node1->facesIterator();
932 face=static_cast<const SMDS_MeshFace *>(it1->next());
933 if(face->NbNodes()!=4) continue;
934 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
941 if(node->GetID()==node2->GetID()) node2found=true;
942 if(node->GetID()==node3->GetID()) node3found=true;
943 if(node->GetID()==node4->GetID()) node4found=true;
946 if(node2found&&node3found&&node4found)
956 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
957 const SMDS_MeshNode *node1,
958 const SMDS_MeshNode *node2,
959 const SMDS_MeshNode *node3,
960 const SMDS_MeshNode *node4)
962 SMDS_MeshFace * toReturn=NULL;
963 toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
966 toReturn=createQuadrangle(
967 const_cast<SMDS_MeshNode *>(node1),
968 const_cast<SMDS_MeshNode *>(node2),
969 const_cast<SMDS_MeshNode *>(node3),
970 const_cast<SMDS_MeshNode *>(node4)
976 //=======================================================================
977 //function : FindElement
979 //=======================================================================
981 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
983 return myElementIDFactory->MeshElement(IDelem);
986 //=======================================================================
987 //function : DumpNodes
989 //=======================================================================
991 void SMDS_Mesh::DumpNodes() const
993 MESSAGE("dump nodes of mesh : ");
994 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
995 while(itnode->more()) MESSAGE(itnode->next());
999 //=======================================================================
1000 //function : DumpEdges
1002 //=======================================================================
1004 void SMDS_Mesh::DumpEdges() const
1006 MESSAGE("dump edges of mesh : ");
1007 SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
1008 while(itedge->more()) MESSAGE(itedge->next());
1012 //=======================================================================
1013 //function : DumpFaces
1015 //=======================================================================
1017 void SMDS_Mesh::DumpFaces() const
1019 MESSAGE("dump faces of mesh : ");
1020 SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
1021 while(itface->more()) MESSAGE(itface->next());
1025 //=======================================================================
1026 //function : DumpVolumes
1028 //=======================================================================
1030 void SMDS_Mesh::DumpVolumes() const
1032 MESSAGE("dump volumes of mesh : ");
1033 SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
1034 while(itvol->more()) MESSAGE(itvol->next());
1038 //=======================================================================
1039 //function : DebugStats
1041 //=======================================================================
1043 void SMDS_Mesh::DebugStats() const
1045 MESSAGE("Debug stats of mesh : ");
1047 MESSAGE("===== NODES ====="<<NbNodes());
1048 MESSAGE("===== EDGES ====="<<NbEdges());
1049 MESSAGE("===== FACES ====="<<NbFaces());
1050 MESSAGE("===== VOLUMES ====="<<NbVolumes());
1052 MESSAGE("End Debug stats of mesh ");
1056 SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1057 int sizeofnodes = 0;
1058 int sizeoffaces = 0;
1060 while(itnode->more())
1062 const SMDS_MeshNode *node = itnode->next();
1064 sizeofnodes += sizeof(*node);
1066 SMDS_Iterator<const SMDS_MeshElement *> * it=
1067 node->GetInverseElementIterator();
1070 const SMDS_MeshElement *me = it->next();
1071 sizeofnodes += sizeof(me);
1077 SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
1079 while(itface->more())
1081 const SMDS_MeshElement *face = itface->next();
1082 sizeoffaces += sizeof(*face);
1085 MESSAGE("total size of node elements = " << sizeofnodes);;
1086 MESSAGE("total size of face elements = " << sizeoffaces);;
1092 ///////////////////////////////////////////////////////////////////////////////
1093 /// Return the number of nodes
1094 ///////////////////////////////////////////////////////////////////////////////
1095 int SMDS_Mesh::NbNodes() const
1097 return myNodes.size();
1100 ///////////////////////////////////////////////////////////////////////////////
1101 /// Return the number of edges (including construction edges)
1102 ///////////////////////////////////////////////////////////////////////////////
1103 int SMDS_Mesh::NbEdges() const
1105 return myEdges.size();
1108 ///////////////////////////////////////////////////////////////////////////////
1109 /// Return the number of faces (including construction faces)
1110 ///////////////////////////////////////////////////////////////////////////////
1111 int SMDS_Mesh::NbFaces() const
1113 return myFaces.size();
1116 ///////////////////////////////////////////////////////////////////////////////
1117 /// Return the number of volumes
1118 ///////////////////////////////////////////////////////////////////////////////
1119 int SMDS_Mesh::NbVolumes() const
1121 return myVolumes.size();
1124 ///////////////////////////////////////////////////////////////////////////////
1125 /// Return the number of child mesh of this mesh.
1126 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1127 /// (2003-09-08) of SMESH
1128 ///////////////////////////////////////////////////////////////////////////////
1129 int SMDS_Mesh::NbSubMesh() const
1131 return myChildren.size();
1134 ///////////////////////////////////////////////////////////////////////////////
1135 /// Destroy the mesh and all its elements
1136 /// All pointer on elements owned by this mesh become illegals.
1137 ///////////////////////////////////////////////////////////////////////////////
1138 SMDS_Mesh::~SMDS_Mesh()
1142 delete myNodeIDFactory;
1143 delete myElementIDFactory;
1146 list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1147 while(itc!=myChildren.end())
1153 SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1160 set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1161 while(ite!=myEdges.end())
1167 set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1168 while(itf!=myFaces.end())
1174 set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1175 while(itv!=myVolumes.end())
1183 ///////////////////////////////////////////////////////////////////////////////
1184 /// Return true if this mesh create faces with edges.
1185 /// A false returned value mean that faces are created with nodes. A concequence
1186 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1187 ///////////////////////////////////////////////////////////////////////////////
1188 bool SMDS_Mesh::hasConstructionEdges()
1190 return myHasConstructionEdges;
1193 ///////////////////////////////////////////////////////////////////////////////
1194 /// Return true if this mesh create volumes with faces
1195 /// A false returned value mean that volumes are created with nodes or edges.
1196 /// (see hasConstructionEdges)
1197 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1199 ///////////////////////////////////////////////////////////////////////////////
1200 bool SMDS_Mesh::hasConstructionFaces()
1202 return myHasConstructionFaces;
1205 ///////////////////////////////////////////////////////////////////////////////
1206 /// Return true if nodes are linked to the finit elements, they are belonging to.
1207 /// Currently, It always return true.
1208 ///////////////////////////////////////////////////////////////////////////////
1209 bool SMDS_Mesh::hasInverseElements()
1211 return myHasInverseElements;
1214 ///////////////////////////////////////////////////////////////////////////////
1215 /// Make this mesh creating construction edges (see hasConstructionEdges)
1216 /// @param b true to have construction edges, else false.
1217 ///////////////////////////////////////////////////////////////////////////////
1218 void SMDS_Mesh::setConstructionEdges(bool b)
1220 myHasConstructionEdges=b;
1223 ///////////////////////////////////////////////////////////////////////////////
1224 /// Make this mesh creating construction faces (see hasConstructionFaces)
1225 /// @param b true to have construction faces, else false.
1226 ///////////////////////////////////////////////////////////////////////////////
1227 void SMDS_Mesh::setConstructionFaces(bool b)
1229 myHasConstructionFaces=b;
1232 ///////////////////////////////////////////////////////////////////////////////
1233 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1234 /// @param b true to link nodes to elements, else false.
1235 ///////////////////////////////////////////////////////////////////////////////
1236 void SMDS_Mesh::setInverseElements(bool b)
1238 if(!b) MESSAGE("Error : inverseElement=false not implemented");
1239 myHasInverseElements=b;
1242 ///////////////////////////////////////////////////////////////////////////////
1243 /// Return an iterator on nodes of the current mesh. Once used this iterator
1244 /// must be free by the caller
1245 ///////////////////////////////////////////////////////////////////////////////
1246 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1248 class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1250 const SetOfNodes& mySet;
1251 SetOfNodes::iterator myIterator;
1253 MyIterator(const SetOfNodes& s):mySet(s)
1255 myIterator=mySet.begin();
1260 return myIterator!=mySet.end();
1263 const SMDS_MeshNode* next()
1265 const SMDS_MeshNode* current=*myIterator;
1270 return new MyIterator(myNodes);
1273 ///////////////////////////////////////////////////////////////////////////////
1274 ///Return an iterator on egdes of the current mesh. Once used this iterator
1275 ///must be free by the caller
1276 ///////////////////////////////////////////////////////////////////////////////
1277 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1279 class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1281 const SetOfEdges& mySet;
1282 const SMDS_MeshEdge * myEdge;
1283 SetOfEdges::iterator myIterator;
1285 MyIterator(const SetOfEdges& s):mySet(s)
1287 myIterator=mySet.begin();
1292 while((myIterator!=mySet.end()))
1294 if((*myIterator)->GetID()!=-1)
1301 const SMDS_MeshEdge* next()
1303 const SMDS_MeshEdge* current=*myIterator;
1308 return new MyIterator(myEdges);
1311 ///////////////////////////////////////////////////////////////////////////////
1312 ///Return an iterator on faces of the current mesh. Once used this iterator
1313 ///must be free by the caller
1314 ///////////////////////////////////////////////////////////////////////////////
1315 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1317 class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1319 const SetOfFaces& mySet;
1320 set<SMDS_MeshFace*>::iterator myIterator;
1322 MyIterator(const SetOfFaces& s):mySet(s)
1324 myIterator=mySet.begin();
1329 while((myIterator!=mySet.end()))
1331 if((*myIterator)->GetID()!=-1)
1338 const SMDS_MeshFace* next()
1340 const SMDS_MeshFace* current=*myIterator;
1345 return new MyIterator(myFaces);
1348 ///////////////////////////////////////////////////////////////////////////////
1349 ///Return an iterator on volumes of the current mesh. Once used this iterator
1350 ///must be free by the caller
1351 ///////////////////////////////////////////////////////////////////////////////
1352 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1354 class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1356 const SetOfVolumes& mySet;
1357 SetOfVolumes::iterator myIterator;
1359 MyIterator(const SetOfVolumes& s):mySet(s)
1361 myIterator=mySet.begin();
1366 return myIterator!=mySet.end();
1369 const SMDS_MeshVolume* next()
1371 const SMDS_MeshVolume* current=*myIterator;
1376 return new MyIterator(myVolumes);
1379 ///////////////////////////////////////////////////////////////////////////////
1380 /// Do intersection of sets (more than 2)
1381 ///////////////////////////////////////////////////////////////////////////////
1382 set<const SMDS_MeshElement*> * intersectionOfSets(
1383 set<const SMDS_MeshElement*> vs[], int numberOfSets)
1385 set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1386 set<const SMDS_MeshElement*>* rsetB;
1388 for(int i=0; i<numberOfSets-1; i++)
1390 rsetB=new set<const SMDS_MeshElement*>();
1392 rsetA->begin(), rsetA->end(),
1393 vs[i+1].begin(), vs[i+1].end(),
1394 inserter(*rsetB, rsetB->begin()));
1401 ///////////////////////////////////////////////////////////////////////////////
1402 /// Return the list of finit elements owning the given element
1403 ///////////////////////////////////////////////////////////////////////////////
1404 set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1406 int numberOfSets=element->NbNodes();
1407 set<const SMDS_MeshElement*> initSet[numberOfSets];
1409 SMDS_Iterator<const SMDS_MeshElement*> * itNodes=element->nodesIterator();
1412 while(itNodes->more())
1414 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1415 SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
1417 //initSet[i]=set<const SMDS_MeshElement*>();
1418 while(itFe->more()) initSet[i].insert(itFe->next());
1425 return intersectionOfSets(initSet, numberOfSets);
1428 ///////////////////////////////////////////////////////////////////////////////
1429 /// Return the list of nodes used only by the given elements
1430 ///////////////////////////////////////////////////////////////////////////////
1431 set<const SMDS_MeshElement*> * getExclusiveNodes(
1432 set<const SMDS_MeshElement*>& elements)
1434 set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1435 set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1437 while(itElements!=elements.end())
1439 SMDS_Iterator<const SMDS_MeshElement*> * itNodes=
1440 (*itElements)->nodesIterator();
1443 while(itNodes->more())
1445 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1446 SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
1447 set<const SMDS_MeshElement*> s;
1448 while(itFe->more()) s.insert(itFe->next());
1450 if(s==elements) toReturn->insert(n);
1457 ///////////////////////////////////////////////////////////////////////////////
1458 ///Find the children of an element that are made of given nodes
1459 ///@param setOfChildren The set in which matching children will be inserted
1460 ///@param element The element were to search matching children
1461 ///@param nodes The nodes that the children must have to be selected
1462 ///////////////////////////////////////////////////////////////////////////////
1463 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
1464 const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1467 switch(element->GetType())
1470 MESSAGE("Internal Error: This should not append");
1474 SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
1477 const SMDS_MeshElement * e=itn->next();
1478 if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
1484 SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
1487 const SMDS_MeshElement * e=itn->next();
1488 if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
1491 if(hasConstructionEdges())
1493 SMDS_Iterator<const SMDS_MeshElement*>* ite=element->edgesIterator();
1495 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1499 case SMDSAbs_Volume:
1501 if(hasConstructionFaces())
1503 SMDS_Iterator<const SMDS_MeshElement*> * ite=element->facesIterator();
1505 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1508 else if(hasConstructionEdges())
1510 SMDS_Iterator<const SMDS_MeshElement*> * ite=element->edgesIterator();
1512 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1519 ///////////////////////////////////////////////////////////////////////////////
1520 ///@param elem The element to delete
1521 ///@param removenodes if true remaining nodes will be removed
1522 ///////////////////////////////////////////////////////////////////////////////
1523 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1524 const bool removenodes)
1526 set<const SMDS_MeshElement*> * s1=getFinitElements(elem);
1528 set<const SMDS_MeshElement*> * s2=getExclusiveNodes(*s1);
1529 set<const SMDS_MeshElement*> s3;
1530 set<const SMDS_MeshElement*>::iterator it=s1->begin();
1531 while(it!=s1->end())
1533 addChildrenWithNodes(s3, *it ,*s2);
1537 if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1541 switch((*it)->GetType())
1544 MESSAGE("Internal Error: This should not happen");
1547 myEdges.erase(static_cast<SMDS_MeshEdge*>(
1548 const_cast<SMDS_MeshElement*>(*it)));
1551 myFaces.erase(static_cast<SMDS_MeshFace*>(
1552 const_cast<SMDS_MeshElement*>(*it)));
1554 case SMDSAbs_Volume:
1555 myVolumes.erase(static_cast<SMDS_MeshVolume*>(
1556 const_cast<SMDS_MeshElement*>(*it)));
1565 while(it!=s2->end())
1567 myNodes.erase(static_cast<SMDS_MeshNode*>(
1568 const_cast<SMDS_MeshElement*>(*it)));
1579 * Concat the coordinates of all nodes in an array.
1580 * Its used to display the mesh.
1581 * @return A array of size 3*NbNodes() containing the coordinates of nodes.
1583 double * SMDS_Mesh::getNodesCoordinates()
1585 double * toReturn=new double[3*NbNodes()];
1586 SMDS_Iterator<const SMDS_MeshNode*> * it=nodesIterator();
1590 const SMDS_MeshNode * n=it->next();
1603 * Concat the id of all nodes in an array.
1604 * Its used to display the mesh.
1605 * @return A array of size NbNodes() containing the ids of nodes.
1607 long * SMDS_Mesh::getNodesID()
1609 long * toReturn=new long[NbNodes()];
1610 SMDS_Iterator<const SMDS_MeshNode*> * it=nodesIterator();
1614 const SMDS_MeshNode * n=it->next();
1615 toReturn[i]=n->GetID();
1623 * Concat the id of nodes of edges in an array.
1624 * Array format is {edge_id, node1_id, node2_id}
1625 * Its used to display the mesh.
1626 * @return A array of size 3*NbEdges() containing the edges.
1628 long * SMDS_Mesh::getEdgesIndices()
1630 long * toReturn=new long[NbEdges()*3];
1631 SMDS_Iterator<const SMDS_MeshEdge*> * it=edgesIterator();
1636 const SMDS_MeshEdge * e=it->next();
1637 toReturn[i]=e->GetID();
1639 SMDS_Iterator<const SMDS_MeshElement*> * itn=e->nodesIterator();
1642 const SMDS_MeshElement * n=itn->next();
1643 toReturn[i]=n->GetID();
1653 * Concat the id of nodes of triangles in an array.
1654 * Array format is {tria_id, node1_id, node2_id, node3_id}
1655 * Its used to display the mesh.
1656 * @return A array of size 4*NbTriangles() containing the edges.
1658 long * SMDS_Mesh::getTrianglesIndices()
1660 long * toReturn=new long[NbTriangles()*4];
1661 SMDS_Iterator<const SMDS_MeshFace*> * it=facesIterator();
1665 const SMDS_MeshFace * f=it->next();
1668 toReturn[i]=f->GetID();
1670 SMDS_Iterator<const SMDS_MeshElement*> * itn=f->nodesIterator();
1673 const SMDS_MeshElement * n=itn->next();
1674 toReturn[i]=n->GetID();
1685 * Return the number of 3 nodes faces in the mesh.
1686 * This method run in O(n).
1687 * @return The number of face whose number of nodes is 3
1689 int SMDS_Mesh::NbTriangles() const
1691 SMDS_Iterator<const SMDS_MeshFace*> * it=facesIterator();
1695 const SMDS_MeshFace * f=it->next();
1696 if(f->NbNodes()==3) toReturn++;