1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH SMESHDS : management of mesh data and SMESH document
23 // File : SMESH_Mesh.cxx
24 // Author : Yves FRICAUD, OCC
28 #include "SMESHDS_Mesh.hxx"
30 #include "SMESHDS_Group.hxx"
31 #include "SMDS_VertexPosition.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_FacePosition.hxx"
34 #include "SMDS_SpacePosition.hxx"
35 #include "SMESHDS_GroupOnGeom.hxx"
37 #include <TopExp_Explorer.hxx>
39 #include <TopoDS_Iterator.hxx>
41 #include "utilities.h"
45 /*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 )
47 return S1.IsSame( S2 );
50 //=======================================================================
53 //=======================================================================
54 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
56 myIsEmbeddedMode(theIsEmbeddedMode),
59 myScript = new SMESHDS_Script(theIsEmbeddedMode);
63 //=======================================================================
64 bool SMESHDS_Mesh::IsEmbeddedMode()
66 return myIsEmbeddedMode;
69 //=======================================================================
70 //function : ShapeToMesh
72 //=======================================================================
73 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
75 if ( !myShape.IsNull() && S.IsNull() )
77 // removal of a shape to mesh, delete ...
79 myShapeToHypothesis.Clear();
80 // - shape indices in SMDS_Position of nodes
81 map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
82 for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
83 if ( !i_sub->second->IsComplexSubmesh() ) {
84 SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
86 nIt->next()->GetPosition()->SetShapeId( 0 );
90 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
91 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
93 myShapeIndexToSubMesh.clear();
94 myIndexToShape.Clear();
95 // - groups on geometry
96 set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
97 while ( gr != myGroups.end() ) {
98 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
99 myGroups.erase( gr++ );
107 TopExp::MapShapes(myShape, myIndexToShape);
111 //=======================================================================
112 //function : AddHypothesis
114 //=======================================================================
116 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
117 const SMESHDS_Hypothesis * H)
119 if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
120 list<const SMESHDS_Hypothesis *> aList;
121 myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
123 list<const SMESHDS_Hypothesis *>& alist =
124 myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
126 //Check if the Hypothesis is still present
127 list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
129 if (alist.end() != ith) return false;
135 //=======================================================================
136 //function : RemoveHypothesis
138 //=======================================================================
140 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
141 const SMESHDS_Hypothesis * H)
143 if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
145 list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
146 list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
147 if (ith != alist.end())
156 //=======================================================================
159 //=======================================================================
160 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
161 SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
162 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
166 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
167 SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
168 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
172 //=======================================================================
173 //function : MoveNode
175 //=======================================================================
176 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
178 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
180 myScript->MoveNode(n->GetID(), x, y, z);
183 //=======================================================================
184 //function : ChangeElementNodes
186 //=======================================================================
188 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
189 const SMDS_MeshNode * nodes[],
192 if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
195 vector<int> IDs( nbnodes );
196 for ( int i = 0; i < nbnodes; i++ )
197 IDs [ i ] = nodes[ i ]->GetID();
198 myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
203 //=======================================================================
204 //function : ChangePolygonNodes
206 //=======================================================================
207 bool SMESHDS_Mesh::ChangePolygonNodes
208 (const SMDS_MeshElement * elem,
209 vector<const SMDS_MeshNode*> nodes)
211 ASSERT(nodes.size() > 3);
213 return ChangeElementNodes(elem, &nodes[0], nodes.size());
216 //=======================================================================
217 //function : ChangePolyhedronNodes
219 //=======================================================================
220 bool SMESHDS_Mesh::ChangePolyhedronNodes
221 (const SMDS_MeshElement * elem,
222 std::vector<const SMDS_MeshNode*> nodes,
223 std::vector<int> quantities)
225 ASSERT(nodes.size() > 3);
227 if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
230 int i, len = nodes.size();
231 std::vector<int> nodes_ids (len);
232 for (i = 0; i < len; i++) {
233 nodes_ids[i] = nodes[i]->GetID();
235 myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
240 //=======================================================================
241 //function : Renumber
243 //=======================================================================
245 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
247 SMDS_Mesh::Renumber( isNodes, startID, deltaID );
248 myScript->Renumber( isNodes, startID, deltaID );
251 //=======================================================================
252 //function : Add0DElement
254 //=======================================================================
255 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
257 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
258 if (anElem) myScript->Add0DElement(ID, nodeID);
262 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
263 (const SMDS_MeshNode * node, int ID)
265 return Add0DElementWithID(node->GetID(), ID);
268 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
270 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
271 if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
275 //=======================================================================
276 //function :AddEdgeWithID
278 //=======================================================================
279 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
281 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
282 if(anElem) myScript->AddEdge(ID,n1,n2);
286 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
287 const SMDS_MeshNode * n2,
290 return AddEdgeWithID(n1->GetID(),
295 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
296 const SMDS_MeshNode * n2)
298 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
299 if(anElem) myScript->AddEdge(anElem->GetID(),
305 //=======================================================================
308 //=======================================================================
309 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
311 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
312 if(anElem) myScript->AddFace(ID,n1,n2,n3);
316 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
317 const SMDS_MeshNode * n2,
318 const SMDS_MeshNode * n3,
321 return AddFaceWithID(n1->GetID(),
327 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
328 const SMDS_MeshNode * n2,
329 const SMDS_MeshNode * n3)
331 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
332 if(anElem) myScript->AddFace(anElem->GetID(),
339 //=======================================================================
342 //=======================================================================
343 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
345 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
346 if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
350 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
351 const SMDS_MeshNode * n2,
352 const SMDS_MeshNode * n3,
353 const SMDS_MeshNode * n4,
356 return AddFaceWithID(n1->GetID(),
363 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
364 const SMDS_MeshNode * n2,
365 const SMDS_MeshNode * n3,
366 const SMDS_MeshNode * n4)
368 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
369 if(anElem) myScript->AddFace(anElem->GetID(),
377 //=======================================================================
378 //function :AddVolume
380 //=======================================================================
381 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
383 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
384 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
388 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
389 const SMDS_MeshNode * n2,
390 const SMDS_MeshNode * n3,
391 const SMDS_MeshNode * n4,
394 return AddVolumeWithID(n1->GetID(),
401 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
402 const SMDS_MeshNode * n2,
403 const SMDS_MeshNode * n3,
404 const SMDS_MeshNode * n4)
406 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
407 if(anElem) myScript->AddVolume(anElem->GetID(),
415 //=======================================================================
416 //function :AddVolume
418 //=======================================================================
419 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
421 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
422 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
426 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
427 const SMDS_MeshNode * n2,
428 const SMDS_MeshNode * n3,
429 const SMDS_MeshNode * n4,
430 const SMDS_MeshNode * n5,
433 return AddVolumeWithID(n1->GetID(),
441 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
442 const SMDS_MeshNode * n2,
443 const SMDS_MeshNode * n3,
444 const SMDS_MeshNode * n4,
445 const SMDS_MeshNode * n5)
447 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
448 if(anElem) myScript->AddVolume(anElem->GetID(),
457 //=======================================================================
458 //function :AddVolume
460 //=======================================================================
461 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
463 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
464 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
468 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
469 const SMDS_MeshNode * n2,
470 const SMDS_MeshNode * n3,
471 const SMDS_MeshNode * n4,
472 const SMDS_MeshNode * n5,
473 const SMDS_MeshNode * n6,
476 return AddVolumeWithID(n1->GetID(),
485 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
486 const SMDS_MeshNode * n2,
487 const SMDS_MeshNode * n3,
488 const SMDS_MeshNode * n4,
489 const SMDS_MeshNode * n5,
490 const SMDS_MeshNode * n6)
492 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
493 if(anElem) myScript->AddVolume(anElem->GetID(),
503 //=======================================================================
504 //function :AddVolume
506 //=======================================================================
507 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
509 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
510 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
514 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
515 const SMDS_MeshNode * n2,
516 const SMDS_MeshNode * n3,
517 const SMDS_MeshNode * n4,
518 const SMDS_MeshNode * n5,
519 const SMDS_MeshNode * n6,
520 const SMDS_MeshNode * n7,
521 const SMDS_MeshNode * n8,
524 return AddVolumeWithID(n1->GetID(),
535 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
536 const SMDS_MeshNode * n2,
537 const SMDS_MeshNode * n3,
538 const SMDS_MeshNode * n4,
539 const SMDS_MeshNode * n5,
540 const SMDS_MeshNode * n6,
541 const SMDS_MeshNode * n7,
542 const SMDS_MeshNode * n8)
544 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
545 if(anElem) myScript->AddVolume(anElem->GetID(),
557 //=======================================================================
558 //function : AddPolygonalFace
560 //=======================================================================
561 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
564 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
566 myScript->AddPolygonalFace(ID, nodes_ids);
571 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
572 (std::vector<const SMDS_MeshNode*> nodes,
575 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
577 int i, len = nodes.size();
578 std::vector<int> nodes_ids (len);
579 for (i = 0; i < len; i++) {
580 nodes_ids[i] = nodes[i]->GetID();
582 myScript->AddPolygonalFace(ID, nodes_ids);
587 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
588 (std::vector<const SMDS_MeshNode*> nodes)
590 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
592 int i, len = nodes.size();
593 std::vector<int> nodes_ids (len);
594 for (i = 0; i < len; i++) {
595 nodes_ids[i] = nodes[i]->GetID();
597 myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
602 //=======================================================================
603 //function : AddPolyhedralVolume
605 //=======================================================================
606 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
607 std::vector<int> quantities,
610 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
612 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
617 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
618 (std::vector<const SMDS_MeshNode*> nodes,
619 std::vector<int> quantities,
622 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
624 int i, len = nodes.size();
625 std::vector<int> nodes_ids (len);
626 for (i = 0; i < len; i++) {
627 nodes_ids[i] = nodes[i]->GetID();
629 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
634 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
635 (std::vector<const SMDS_MeshNode*> nodes,
636 std::vector<int> quantities)
638 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
640 int i, len = nodes.size();
641 std::vector<int> nodes_ids (len);
642 for (i = 0; i < len; i++) {
643 nodes_ids[i] = nodes[i]->GetID();
645 myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
650 //=======================================================================
651 //function : removeFromContainers
653 //=======================================================================
655 static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
656 set<SMESHDS_GroupBase*>& theGroups,
657 list<const SMDS_MeshElement*>& theElems,
660 if ( theElems.empty() )
664 // Element can belong to several groups
665 if ( !theGroups.empty() )
667 set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
668 for ( ; GrIt != theGroups.end(); GrIt++ )
670 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
671 if ( !group || group->IsEmpty() ) continue;
673 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
674 for ( ; elIt != theElems.end(); elIt++ )
676 group->SMDSGroup().Remove( *elIt );
677 if ( group->IsEmpty() ) break;
682 const bool deleted=true;
684 // Rm from sub-meshes
685 // Element should belong to only one sub-mesh
686 map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
687 for ( ; SubIt != theSubMeshes.end(); SubIt++ )
689 int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
690 if ( size == 0 ) continue;
692 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
693 while ( elIt != theElems.end() )
695 bool removed = false;
697 removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
699 removed = (*SubIt).second->RemoveElement( *elIt, deleted );
703 elIt = theElems.erase( elIt );
704 if ( theElems.empty() )
705 return; // all elements are found and removed
715 //=======================================================================
716 //function : RemoveNode
718 //=======================================================================
719 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
721 if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
723 SMESHDS_SubMesh* subMesh=0;
724 map<int,SMESHDS_SubMesh*>::iterator SubIt =
725 myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
726 if ( SubIt != myShapeIndexToSubMesh.end() )
727 subMesh = SubIt->second;
729 SubIt = myShapeIndexToSubMesh.begin();
730 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
731 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
732 subMesh = SubIt->second;
734 RemoveFreeNode( n, subMesh, true);
738 myScript->RemoveNode(n->GetID());
740 list<const SMDS_MeshElement *> removedElems;
741 list<const SMDS_MeshElement *> removedNodes;
743 SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
745 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
746 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
749 //=======================================================================
750 //function : RemoveFreeNode
752 //=======================================================================
753 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
754 SMESHDS_SubMesh * subMesh,
757 myScript->RemoveNode(n->GetID());
760 // Node can belong to several groups
761 if (fromGroups && !myGroups.empty()) {
762 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
763 for (; GrIt != myGroups.end(); GrIt++) {
764 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
765 if (!group || group->IsEmpty()) continue;
766 group->SMDSGroup().Remove(n);
771 // Node should belong to only one sub-mesh
773 subMesh->RemoveNode(n,/*deleted=*/false);
775 SMDS_Mesh::RemoveFreeElement(n);
778 //=======================================================================
779 //function : RemoveElement
781 //========================================================================
782 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
784 if (elt->GetType() == SMDSAbs_Node)
786 RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
789 if (!hasConstructionEdges() && !hasConstructionFaces())
791 SMESHDS_SubMesh* subMesh=0;
792 map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
793 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
794 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
795 subMesh = SubIt->second;
797 RemoveFreeElement( elt, subMesh, true);
801 myScript->RemoveElement(elt->GetID());
803 list<const SMDS_MeshElement *> removedElems;
804 list<const SMDS_MeshElement *> removedNodes;
806 SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
808 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
811 //=======================================================================
812 //function : RemoveFreeElement
814 //========================================================================
815 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
816 SMESHDS_SubMesh * subMesh,
819 //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
820 if (elt->GetType() == SMDSAbs_Node) {
821 RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
825 if (hasConstructionEdges() || hasConstructionFaces())
826 // this methods is only for meshes without descendants
829 myScript->RemoveElement(elt->GetID());
832 // Node can belong to several groups
833 if ( fromGroups && !myGroups.empty() ) {
834 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
835 for (; GrIt != myGroups.end(); GrIt++) {
836 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
837 if (group && !group->IsEmpty())
838 group->SMDSGroup().Remove(elt);
843 // Element should belong to only one sub-mesh
845 subMesh->RemoveElement(elt, /*deleted=*/false);
847 SMDS_Mesh::RemoveFreeElement(elt);
850 //================================================================================
852 * \brief Remove all data from the mesh
854 //================================================================================
856 void SMESHDS_Mesh::ClearMesh()
858 myScript->ClearMesh();
862 map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
863 for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
864 sub->second->Clear();
867 TGroups::iterator group, groupEnd = myGroups.end();
868 for ( group = myGroups.begin(); group != groupEnd; ++group ) {
869 if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
870 SMDSAbs_ElementType groupType = g->GetType();
872 g->SetType( groupType );
877 //================================================================================
879 * \brief return submesh by shape
880 * \param shape - the subshape
881 * \retval SMESHDS_SubMesh* - the found submesh
883 * search of submeshes is optimized
885 //================================================================================
887 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
889 if ( shape.IsNull() )
892 if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
895 getSubmesh( ShapeToIndex( shape ));
896 myCurSubShape = shape;
900 //================================================================================
902 * \brief return submesh by subshape index
903 * \param Index - the subshape index
904 * \retval SMESHDS_SubMesh* - the found submesh
905 * search of submeshes is optimized
907 //================================================================================
909 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
911 //Update or build submesh
912 if ( Index != myCurSubID ) {
913 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
914 if ( it == myShapeIndexToSubMesh.end() )
915 it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
916 myCurSubMesh = it->second;
918 myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
923 //================================================================================
925 * \brief Add element or node to submesh
926 * \param elem - element to add
927 * \param subMesh - submesh to be filled in
929 //================================================================================
931 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
933 if ( elem && subMesh ) {
934 if ( elem->GetType() == SMDSAbs_Node )
935 subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
937 subMesh->AddElement( elem );
945 //================================================================================
947 * \brief Creates a node position in volume
949 //================================================================================
951 inline SMDS_PositionPtr volumePosition(int volId)
953 SMDS_SpacePosition* pos = new SMDS_SpacePosition();
954 pos->SetShapeId( volId );
955 return SMDS_PositionPtr(pos);
959 //=======================================================================
960 //function : SetNodeOnVolume
962 //=======================================================================
963 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
964 const TopoDS_Shell & S)
966 if ( add( aNode, getSubmesh(S) ))
967 aNode->SetPosition ( volumePosition( myCurSubID ));
969 //=======================================================================
970 //function : SetNodeOnVolume
972 //=======================================================================
973 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
974 const TopoDS_Solid & S)
976 if ( add( aNode, getSubmesh(S) ))
977 aNode->SetPosition ( volumePosition( myCurSubID ));
980 //=======================================================================
981 //function : SetNodeOnFace
983 //=======================================================================
984 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
985 const TopoDS_Face & S,
989 if ( add( aNode, getSubmesh(S) ))
990 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
993 //=======================================================================
994 //function : SetNodeOnEdge
996 //=======================================================================
997 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
998 const TopoDS_Edge & S,
1001 if ( add( aNode, getSubmesh(S) ))
1002 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
1005 //=======================================================================
1006 //function : SetNodeOnVertex
1008 //=======================================================================
1009 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
1010 const TopoDS_Vertex & S)
1012 if ( add( aNode, getSubmesh(S) ))
1013 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
1016 //=======================================================================
1017 //function : UnSetNodeOnShape
1019 //=======================================================================
1020 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1022 if ( aNode && aNode->GetPosition() ) {
1023 map<int,SMESHDS_SubMesh*>::iterator it =
1024 myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
1025 if ( it != myShapeIndexToSubMesh.end() )
1026 it->second->RemoveNode( aNode, /*deleted=*/false );
1030 //=======================================================================
1031 //function : SetMeshElementOnShape
1033 //=======================================================================
1034 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1035 const TopoDS_Shape & S)
1037 add( anElement, getSubmesh(S) );
1040 //=======================================================================
1041 //function : UnSetMeshElementOnShape
1043 //=======================================================================
1044 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1045 const TopoDS_Shape & S)
1047 int Index = myIndexToShape.FindIndex(S);
1049 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1050 if ( it != myShapeIndexToSubMesh.end() )
1051 if ( elem->GetType() == SMDSAbs_Node )
1052 it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ), /*deleted=*/false );
1054 it->second->RemoveElement( elem, /*deleted=*/false );
1057 //=======================================================================
1058 //function : ShapeToMesh
1060 //=======================================================================
1061 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1066 //=======================================================================
1067 //function : IsGroupOfSubShapes
1068 //purpose : return true if at least one subshape of theShape is a subshape
1069 // of myShape or theShape == myShape
1070 //=======================================================================
1072 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1074 if ( myShape.IsSame( theShape ))
1077 for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
1078 if (myIndexToShape.Contains( it.Value() ) ||
1079 IsGroupOfSubShapes( it.Value() ))
1086 ///////////////////////////////////////////////////////////////////////////////
1087 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1088 /// TopoDS_Shape is unknown
1089 ///////////////////////////////////////////////////////////////////////////////
1090 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1092 int Index = ShapeToIndex(S);
1093 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1094 if (anIter != myShapeIndexToSubMesh.end())
1095 return anIter->second;
1100 ///////////////////////////////////////////////////////////////////////////////
1101 /// Return the sub mesh by Id of shape it is linked to
1102 ///////////////////////////////////////////////////////////////////////////////
1103 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
1105 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1106 if (anIter != myShapeIndexToSubMesh.end())
1107 return anIter->second;
1112 //=======================================================================
1113 //function : SubMeshIndices
1115 //=======================================================================
1116 list<int> SMESHDS_Mesh::SubMeshIndices()
1118 list<int> anIndices;
1119 std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1120 for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1121 anIndices.push_back((*anIter).first);
1126 //=======================================================================
1127 //function : GetHypothesis
1129 //=======================================================================
1131 const list<const SMESHDS_Hypothesis*>&
1132 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1134 if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1135 return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1137 static list<const SMESHDS_Hypothesis*> empty;
1141 //=======================================================================
1142 //function : GetScript
1144 //=======================================================================
1145 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1150 //=======================================================================
1151 //function : ClearScript
1153 //=======================================================================
1154 void SMESHDS_Mesh::ClearScript()
1159 //=======================================================================
1160 //function : HasMeshElements
1162 //=======================================================================
1163 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1165 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1166 int Index = myIndexToShape.FindIndex(S);
1167 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1170 //=======================================================================
1171 //function : HasHypothesis
1173 //=======================================================================
1174 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1176 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1179 //=======================================================================
1180 //function : NewSubMesh
1182 //=======================================================================
1183 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1185 SMESHDS_SubMesh* SM = 0;
1186 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1187 if (anIter == myShapeIndexToSubMesh.end())
1189 SM = new SMESHDS_SubMesh();
1190 myShapeIndexToSubMesh[Index]=SM;
1193 SM = anIter->second;
1197 //=======================================================================
1198 //function : AddCompoundSubmesh
1200 //=======================================================================
1202 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1203 TopAbs_ShapeEnum type)
1206 if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1208 aMainIndex = myIndexToShape.Add( S );
1209 bool all = ( type == TopAbs_SHAPE );
1210 if ( all ) // corresponding simple submesh may exist
1211 aMainIndex = -aMainIndex;
1212 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1213 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1214 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1216 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1217 int typeLimit = all ? TopAbs_VERTEX : type;
1218 for ( ; shapeType <= typeLimit; shapeType++ )
1220 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1221 for ( ; exp.More(); exp.Next() )
1223 int index = myIndexToShape.FindIndex( exp.Current() );
1225 aNewSub->AddSubMesh( NewSubMesh( index ));
1233 //=======================================================================
1234 //function : IndexToShape
1236 //=======================================================================
1237 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1239 return myIndexToShape.FindKey(ShapeIndex);
1242 //=======================================================================
1243 //function : ShapeToIndex
1245 //=======================================================================
1246 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1248 if (myShape.IsNull())
1249 MESSAGE("myShape is NULL");
1251 int index = myIndexToShape.FindIndex(S);
1256 //=======================================================================
1257 //function : SetNodeOnVolume
1259 //=======================================================================
1260 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1262 if ( add( aNode, getSubmesh( Index )))
1263 ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
1266 //=======================================================================
1267 //function : SetNodeOnFace
1269 //=======================================================================
1270 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1272 //Set Position on Node
1273 if ( add( aNode, getSubmesh( Index )))
1274 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1277 //=======================================================================
1278 //function : SetNodeOnEdge
1280 //=======================================================================
1281 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1285 //Set Position on Node
1286 if ( add( aNode, getSubmesh( Index )))
1287 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1290 //=======================================================================
1291 //function : SetNodeOnVertex
1293 //=======================================================================
1294 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1296 //Set Position on Node
1297 if ( add( aNode, getSubmesh( Index )))
1298 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1301 //=======================================================================
1302 //function : SetMeshElementOnShape
1304 //=======================================================================
1305 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1308 add( anElement, getSubmesh( Index ));
1311 //=======================================================================
1312 //function : ~SMESHDS_Mesh
1314 //=======================================================================
1315 SMESHDS_Mesh::~SMESHDS_Mesh()
1320 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1321 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1322 delete i_sm->second;
1326 //********************************************************************
1327 //********************************************************************
1328 //******** *********
1329 //***** Methods for addition of quadratic elements ******
1330 //******** *********
1331 //********************************************************************
1332 //********************************************************************
1334 //=======================================================================
1335 //function : AddEdgeWithID
1337 //=======================================================================
1338 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1340 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1341 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1345 //=======================================================================
1346 //function : AddEdge
1348 //=======================================================================
1349 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1350 const SMDS_MeshNode* n2,
1351 const SMDS_MeshNode* n12)
1353 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1354 if(anElem) myScript->AddEdge(anElem->GetID(),
1361 //=======================================================================
1362 //function : AddEdgeWithID
1364 //=======================================================================
1365 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1366 const SMDS_MeshNode * n2,
1367 const SMDS_MeshNode * n12,
1370 return AddEdgeWithID(n1->GetID(),
1377 //=======================================================================
1378 //function : AddFace
1380 //=======================================================================
1381 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1382 const SMDS_MeshNode * n2,
1383 const SMDS_MeshNode * n3,
1384 const SMDS_MeshNode * n12,
1385 const SMDS_MeshNode * n23,
1386 const SMDS_MeshNode * n31)
1388 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1389 if(anElem) myScript->AddFace(anElem->GetID(),
1390 n1->GetID(), n2->GetID(), n3->GetID(),
1391 n12->GetID(), n23->GetID(), n31->GetID());
1395 //=======================================================================
1396 //function : AddFaceWithID
1398 //=======================================================================
1399 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1400 int n12,int n23,int n31, int ID)
1402 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1403 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1407 //=======================================================================
1408 //function : AddFaceWithID
1410 //=======================================================================
1411 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1412 const SMDS_MeshNode * n2,
1413 const SMDS_MeshNode * n3,
1414 const SMDS_MeshNode * n12,
1415 const SMDS_MeshNode * n23,
1416 const SMDS_MeshNode * n31,
1419 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1420 n12->GetID(), n23->GetID(), n31->GetID(),
1425 //=======================================================================
1426 //function : AddFace
1428 //=======================================================================
1429 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1430 const SMDS_MeshNode * n2,
1431 const SMDS_MeshNode * n3,
1432 const SMDS_MeshNode * n4,
1433 const SMDS_MeshNode * n12,
1434 const SMDS_MeshNode * n23,
1435 const SMDS_MeshNode * n34,
1436 const SMDS_MeshNode * n41)
1438 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1439 if(anElem) myScript->AddFace(anElem->GetID(),
1440 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1441 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1445 //=======================================================================
1446 //function : AddFaceWithID
1448 //=======================================================================
1449 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1450 int n12,int n23,int n34,int n41, int ID)
1452 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1453 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1457 //=======================================================================
1458 //function : AddFaceWithID
1460 //=======================================================================
1461 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1462 const SMDS_MeshNode * n2,
1463 const SMDS_MeshNode * n3,
1464 const SMDS_MeshNode * n4,
1465 const SMDS_MeshNode * n12,
1466 const SMDS_MeshNode * n23,
1467 const SMDS_MeshNode * n34,
1468 const SMDS_MeshNode * n41,
1471 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1472 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1477 //=======================================================================
1478 //function : AddVolume
1480 //=======================================================================
1481 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1482 const SMDS_MeshNode * n2,
1483 const SMDS_MeshNode * n3,
1484 const SMDS_MeshNode * n4,
1485 const SMDS_MeshNode * n12,
1486 const SMDS_MeshNode * n23,
1487 const SMDS_MeshNode * n31,
1488 const SMDS_MeshNode * n14,
1489 const SMDS_MeshNode * n24,
1490 const SMDS_MeshNode * n34)
1492 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1493 if(anElem) myScript->AddVolume(anElem->GetID(),
1494 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1495 n12->GetID(), n23->GetID(), n31->GetID(),
1496 n14->GetID(), n24->GetID(), n34->GetID());
1500 //=======================================================================
1501 //function : AddVolumeWithID
1503 //=======================================================================
1504 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1505 int n12,int n23,int n31,
1506 int n14,int n24,int n34, int ID)
1508 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1509 n31,n14,n24,n34,ID);
1510 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1514 //=======================================================================
1515 //function : AddVolumeWithID
1516 //purpose : 2d order tetrahedron of 10 nodes
1517 //=======================================================================
1518 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1519 const SMDS_MeshNode * n2,
1520 const SMDS_MeshNode * n3,
1521 const SMDS_MeshNode * n4,
1522 const SMDS_MeshNode * n12,
1523 const SMDS_MeshNode * n23,
1524 const SMDS_MeshNode * n31,
1525 const SMDS_MeshNode * n14,
1526 const SMDS_MeshNode * n24,
1527 const SMDS_MeshNode * n34,
1530 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1531 n12->GetID(), n23->GetID(), n31->GetID(),
1532 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1536 //=======================================================================
1537 //function : AddVolume
1539 //=======================================================================
1540 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1541 const SMDS_MeshNode * n2,
1542 const SMDS_MeshNode * n3,
1543 const SMDS_MeshNode * n4,
1544 const SMDS_MeshNode * n5,
1545 const SMDS_MeshNode * n12,
1546 const SMDS_MeshNode * n23,
1547 const SMDS_MeshNode * n34,
1548 const SMDS_MeshNode * n41,
1549 const SMDS_MeshNode * n15,
1550 const SMDS_MeshNode * n25,
1551 const SMDS_MeshNode * n35,
1552 const SMDS_MeshNode * n45)
1554 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1557 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1558 n3->GetID(), n4->GetID(), n5->GetID(),
1559 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1560 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1564 //=======================================================================
1565 //function : AddVolumeWithID
1567 //=======================================================================
1568 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1569 int n12,int n23,int n34,int n41,
1570 int n15,int n25,int n35,int n45, int ID)
1572 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1574 n15,n25,n35,n45,ID);
1575 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1580 //=======================================================================
1581 //function : AddVolumeWithID
1582 //purpose : 2d order pyramid of 13 nodes
1583 //=======================================================================
1584 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1585 const SMDS_MeshNode * n2,
1586 const SMDS_MeshNode * n3,
1587 const SMDS_MeshNode * n4,
1588 const SMDS_MeshNode * n5,
1589 const SMDS_MeshNode * n12,
1590 const SMDS_MeshNode * n23,
1591 const SMDS_MeshNode * n34,
1592 const SMDS_MeshNode * n41,
1593 const SMDS_MeshNode * n15,
1594 const SMDS_MeshNode * n25,
1595 const SMDS_MeshNode * n35,
1596 const SMDS_MeshNode * n45,
1599 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1600 n4->GetID(), n5->GetID(),
1601 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1602 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1607 //=======================================================================
1608 //function : AddVolume
1610 //=======================================================================
1611 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1612 const SMDS_MeshNode * n2,
1613 const SMDS_MeshNode * n3,
1614 const SMDS_MeshNode * n4,
1615 const SMDS_MeshNode * n5,
1616 const SMDS_MeshNode * n6,
1617 const SMDS_MeshNode * n12,
1618 const SMDS_MeshNode * n23,
1619 const SMDS_MeshNode * n31,
1620 const SMDS_MeshNode * n45,
1621 const SMDS_MeshNode * n56,
1622 const SMDS_MeshNode * n64,
1623 const SMDS_MeshNode * n14,
1624 const SMDS_MeshNode * n25,
1625 const SMDS_MeshNode * n36)
1627 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1628 n45,n56,n64,n14,n25,n36);
1630 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1631 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1632 n12->GetID(), n23->GetID(), n31->GetID(),
1633 n45->GetID(), n56->GetID(), n64->GetID(),
1634 n14->GetID(), n25->GetID(), n36->GetID());
1638 //=======================================================================
1639 //function : AddVolumeWithID
1641 //=======================================================================
1642 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1643 int n4, int n5, int n6,
1644 int n12,int n23,int n31,
1645 int n45,int n56,int n64,
1646 int n14,int n25,int n36, int ID)
1648 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1652 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1653 n45,n56,n64,n14,n25,n36);
1657 //=======================================================================
1658 //function : AddVolumeWithID
1659 //purpose : 2d order Pentahedron with 15 nodes
1660 //=======================================================================
1661 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1662 const SMDS_MeshNode * n2,
1663 const SMDS_MeshNode * n3,
1664 const SMDS_MeshNode * n4,
1665 const SMDS_MeshNode * n5,
1666 const SMDS_MeshNode * n6,
1667 const SMDS_MeshNode * n12,
1668 const SMDS_MeshNode * n23,
1669 const SMDS_MeshNode * n31,
1670 const SMDS_MeshNode * n45,
1671 const SMDS_MeshNode * n56,
1672 const SMDS_MeshNode * n64,
1673 const SMDS_MeshNode * n14,
1674 const SMDS_MeshNode * n25,
1675 const SMDS_MeshNode * n36,
1678 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1679 n4->GetID(), n5->GetID(), n6->GetID(),
1680 n12->GetID(), n23->GetID(), n31->GetID(),
1681 n45->GetID(), n56->GetID(), n64->GetID(),
1682 n14->GetID(), n25->GetID(), n36->GetID(),
1687 //=======================================================================
1688 //function : AddVolume
1690 //=======================================================================
1691 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1692 const SMDS_MeshNode * n2,
1693 const SMDS_MeshNode * n3,
1694 const SMDS_MeshNode * n4,
1695 const SMDS_MeshNode * n5,
1696 const SMDS_MeshNode * n6,
1697 const SMDS_MeshNode * n7,
1698 const SMDS_MeshNode * n8,
1699 const SMDS_MeshNode * n12,
1700 const SMDS_MeshNode * n23,
1701 const SMDS_MeshNode * n34,
1702 const SMDS_MeshNode * n41,
1703 const SMDS_MeshNode * n56,
1704 const SMDS_MeshNode * n67,
1705 const SMDS_MeshNode * n78,
1706 const SMDS_MeshNode * n85,
1707 const SMDS_MeshNode * n15,
1708 const SMDS_MeshNode * n26,
1709 const SMDS_MeshNode * n37,
1710 const SMDS_MeshNode * n48)
1712 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1717 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1718 n3->GetID(), n4->GetID(), n5->GetID(),
1719 n6->GetID(), n7->GetID(), n8->GetID(),
1720 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1721 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1722 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1726 //=======================================================================
1727 //function : AddVolumeWithID
1729 //=======================================================================
1730 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1731 int n5, int n6, int n7, int n8,
1732 int n12,int n23,int n34,int n41,
1733 int n56,int n67,int n78,int n85,
1734 int n15,int n26,int n37,int n48, int ID)
1736 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1739 n15,n26,n37,n48,ID);
1740 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1741 n56,n67,n78,n85,n15,n26,n37,n48);
1745 //=======================================================================
1746 //function : AddVolumeWithID
1747 //purpose : 2d order Hexahedrons with 20 nodes
1748 //=======================================================================
1749 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1750 const SMDS_MeshNode * n2,
1751 const SMDS_MeshNode * n3,
1752 const SMDS_MeshNode * n4,
1753 const SMDS_MeshNode * n5,
1754 const SMDS_MeshNode * n6,
1755 const SMDS_MeshNode * n7,
1756 const SMDS_MeshNode * n8,
1757 const SMDS_MeshNode * n12,
1758 const SMDS_MeshNode * n23,
1759 const SMDS_MeshNode * n34,
1760 const SMDS_MeshNode * n41,
1761 const SMDS_MeshNode * n56,
1762 const SMDS_MeshNode * n67,
1763 const SMDS_MeshNode * n78,
1764 const SMDS_MeshNode * n85,
1765 const SMDS_MeshNode * n15,
1766 const SMDS_MeshNode * n26,
1767 const SMDS_MeshNode * n37,
1768 const SMDS_MeshNode * n48,
1771 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1772 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1773 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1774 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1775 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1779 void SMESHDS_Mesh::compactMesh()
1781 int newNodeSize = 0;
1782 int nbNodes = myNodes.size();
1783 int nbVtkNodes = myGrid->GetNumberOfPoints();
1784 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1785 int nbNodeTemp = nbVtkNodes;
1786 if (nbNodes > nbVtkNodes) nbNodeTemp = nbNodes;
1787 vector<int> idNodesOldToNew;
1788 idNodesOldToNew.clear();
1789 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1791 bool areNodesModified = ! myNodeIDFactory->isPoolIdEmpty();
1792 MESSAGE("------------------------------------------------- SMESHDS_Mesh::compactMesh " << areNodesModified);
1793 if (areNodesModified)
1795 for (int i=0; i<nbNodes; i++)
1799 idNodesOldToNew[i] = i; // all valid id are >= 0
1806 for (int i=0; i<nbNodes; i++)
1807 idNodesOldToNew[i] = i;
1808 if (nbNodes > nbVtkNodes)
1809 newNodeSize = nbVtkNodes; // else 0 means nothing to change (no need to compact vtkPoints)
1812 int newCellSize = 0;
1813 int nbCells = myCells.size();
1814 int nbVtkCells = myGrid->GetNumberOfCells();
1815 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1816 int nbCellTemp = nbVtkCells;
1817 if (nbCells > nbVtkCells) nbCellTemp = nbCells;
1818 vector<int> idCellsOldToNew;
1819 idCellsOldToNew.clear();
1820 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1822 for (int i=0; i<nbCells; i++)
1826 idCellsOldToNew[i] = myVtkIndex[i]; // valid vtk indexes are > = 0
1830 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1832 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1834 if (areNodesModified)
1836 MESSAGE("-------------- modify myNodes");
1837 SetOfNodes newNodes;
1838 newNodes.resize(newNodeSize);
1840 for (int i=0; i<nbNodes; i++)
1844 int newid = idNodesOldToNew[i];
1845 //MESSAGE(i << " --> " << newid);;
1846 myNodes[i]->setId(newid);
1847 newNodes[newid] = myNodes[i];
1850 myNodes.swap(newNodes);
1851 this->myNodeIDFactory->emptyPool(newNodeSize);
1854 // --- SMDS_MeshCell, myIDElements and myVtkIndex (myCells and myElementIdFactory are not compacted)
1856 int vtkIndexSize = myVtkIndex.size();
1858 for (int oldVtkId=0; oldVtkId<vtkIndexSize; oldVtkId++)
1860 int smdsId = this->myVtkIndex[oldVtkId];
1863 int newVtkId = idCellsOldToNew[oldVtkId];
1864 if (newVtkId > maxVtkId) maxVtkId = newVtkId;
1865 //MESSAGE("===========> smdsId newVtkId " << smdsId << " " << newVtkId);
1866 myCells[smdsId]->setVtkId(newVtkId);
1867 myIDElements[smdsId] = newVtkId;
1868 myVtkIndex[newVtkId] = smdsId;
1872 MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
1873 MESSAGE("maxVtkId=" << maxVtkId);
1875 SetOfCells newCells;
1876 vector<int> newSmdsToVtk;
1877 vector<int> newVtkToSmds;
1879 newCells.resize(maxVtkId,0);
1880 newSmdsToVtk.resize(maxVtkId,-1);
1881 newVtkToSmds.resize(maxVtkId,-1);
1883 int myCellsSize = myCells.size();
1885 for (int i=0; i<myCellsSize; i++)
1889 //MESSAGE(newSmdsId << " " << i);
1890 newCells[newSmdsId] = myCells[i];
1891 int idvtk = myCells[i]->getVtkId();
1892 newSmdsToVtk[newSmdsId] = idvtk;
1893 assert(idvtk < maxVtkId);
1894 newVtkToSmds[idvtk] = newSmdsId;
1895 myCells[i]->setId(newSmdsId);
1897 assert(newSmdsId <= maxVtkId);
1901 myCells.swap(newCells);
1902 myIDElements.swap(newSmdsToVtk);
1903 myVtkIndex.swap(newVtkToSmds);
1904 MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
1908 // ---TODO: myNodes, myElements in submeshes
1910 // map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1911 // for(; it != myShapeIndexToSubMesh.end(); ++it)
1913 // (*it).second->compactList(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);