1 // Copyright (C) 2007-2010 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
23 // SMESH SMESHDS : management of mesh data and SMESH document
24 // File : SMESH_Mesh.cxx
25 // Author : Yves FRICAUD, OCC
29 #include "SMESHDS_Mesh.hxx"
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_SpacePosition.hxx"
36 #include "SMESHDS_GroupOnGeom.hxx"
38 #include <Standard_ErrorHandler.hxx>
39 #include <Standard_OutOfRange.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopoDS_Iterator.hxx>
44 #include "utilities.h"
48 /*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 )
50 return S1.IsSame( S2 );
53 //=======================================================================
56 //=======================================================================
57 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
59 myIsEmbeddedMode(theIsEmbeddedMode),
62 myScript = new SMESHDS_Script(theIsEmbeddedMode);
66 //=======================================================================
67 bool SMESHDS_Mesh::IsEmbeddedMode()
69 return myIsEmbeddedMode;
72 //=======================================================================
73 //function : ShapeToMesh
75 //=======================================================================
76 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
78 if ( !myShape.IsNull() && S.IsNull() )
80 // removal of a shape to mesh, delete ...
82 myShapeToHypothesis.Clear();
83 // - shape indices in SMDS_Position of nodes
84 map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
85 for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
86 if ( !i_sub->second->IsComplexSubmesh() ) {
87 SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
89 nIt->next()->GetPosition()->SetShapeId( 0 );
93 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
94 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
96 myShapeIndexToSubMesh.clear();
97 myIndexToShape.Clear();
98 // - groups on geometry
99 set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
100 while ( gr != myGroups.end() ) {
101 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
102 myGroups.erase( gr++ );
110 TopExp::MapShapes(myShape, myIndexToShape);
114 //=======================================================================
115 //function : AddHypothesis
117 //=======================================================================
119 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
120 const SMESHDS_Hypothesis * H)
122 if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
123 list<const SMESHDS_Hypothesis *> aList;
124 myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
126 list<const SMESHDS_Hypothesis *>& alist =
127 myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
129 //Check if the Hypothesis is still present
130 list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
132 if (alist.end() != ith) return false;
138 //=======================================================================
139 //function : RemoveHypothesis
141 //=======================================================================
143 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
144 const SMESHDS_Hypothesis * H)
146 if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
148 list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
149 list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
150 if (ith != alist.end())
159 //=======================================================================
162 //=======================================================================
163 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
164 SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
165 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
169 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
170 SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
171 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
175 //=======================================================================
176 //function : MoveNode
178 //=======================================================================
179 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
181 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
183 myScript->MoveNode(n->GetID(), x, y, z);
186 //=======================================================================
187 //function : ChangeElementNodes
189 //=======================================================================
191 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
192 const SMDS_MeshNode * nodes[],
195 if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
198 vector<int> IDs( nbnodes );
199 for ( int i = 0; i < nbnodes; i++ )
200 IDs [ i ] = nodes[ i ]->GetID();
201 myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
206 //=======================================================================
207 //function : ChangePolygonNodes
209 //=======================================================================
210 bool SMESHDS_Mesh::ChangePolygonNodes
211 (const SMDS_MeshElement * elem,
212 vector<const SMDS_MeshNode*> nodes)
214 ASSERT(nodes.size() > 3);
216 return ChangeElementNodes(elem, &nodes[0], nodes.size());
219 //=======================================================================
220 //function : ChangePolyhedronNodes
222 //=======================================================================
223 bool SMESHDS_Mesh::ChangePolyhedronNodes
224 (const SMDS_MeshElement * elem,
225 std::vector<const SMDS_MeshNode*> nodes,
226 std::vector<int> quantities)
228 ASSERT(nodes.size() > 3);
230 if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
233 int i, len = nodes.size();
234 std::vector<int> nodes_ids (len);
235 for (i = 0; i < len; i++) {
236 nodes_ids[i] = nodes[i]->GetID();
238 myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
243 //=======================================================================
244 //function : Renumber
246 //=======================================================================
248 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
250 SMDS_Mesh::Renumber( isNodes, startID, deltaID );
251 myScript->Renumber( isNodes, startID, deltaID );
254 //=======================================================================
255 //function : Add0DElement
257 //=======================================================================
258 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
260 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
261 if (anElem) myScript->Add0DElement(ID, nodeID);
265 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
266 (const SMDS_MeshNode * node, int ID)
268 return Add0DElementWithID(node->GetID(), ID);
271 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
273 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
274 if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
278 //=======================================================================
279 //function :AddEdgeWithID
281 //=======================================================================
282 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
284 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
285 if(anElem) myScript->AddEdge(ID,n1,n2);
289 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
290 const SMDS_MeshNode * n2,
293 return AddEdgeWithID(n1->GetID(),
298 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
299 const SMDS_MeshNode * n2)
301 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
302 if(anElem) myScript->AddEdge(anElem->GetID(),
308 //=======================================================================
311 //=======================================================================
312 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
314 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
315 if(anElem) myScript->AddFace(ID,n1,n2,n3);
319 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
320 const SMDS_MeshNode * n2,
321 const SMDS_MeshNode * n3,
324 return AddFaceWithID(n1->GetID(),
330 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
331 const SMDS_MeshNode * n2,
332 const SMDS_MeshNode * n3)
334 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
335 if(anElem) myScript->AddFace(anElem->GetID(),
342 //=======================================================================
345 //=======================================================================
346 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
348 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
349 if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
353 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
354 const SMDS_MeshNode * n2,
355 const SMDS_MeshNode * n3,
356 const SMDS_MeshNode * n4,
359 return AddFaceWithID(n1->GetID(),
366 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
367 const SMDS_MeshNode * n2,
368 const SMDS_MeshNode * n3,
369 const SMDS_MeshNode * n4)
371 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
372 if(anElem) myScript->AddFace(anElem->GetID(),
380 //=======================================================================
381 //function :AddVolume
383 //=======================================================================
384 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
386 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
387 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
391 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
392 const SMDS_MeshNode * n2,
393 const SMDS_MeshNode * n3,
394 const SMDS_MeshNode * n4,
397 return AddVolumeWithID(n1->GetID(),
404 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
405 const SMDS_MeshNode * n2,
406 const SMDS_MeshNode * n3,
407 const SMDS_MeshNode * n4)
409 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
410 if(anElem) myScript->AddVolume(anElem->GetID(),
418 //=======================================================================
419 //function :AddVolume
421 //=======================================================================
422 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
424 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
425 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
429 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
430 const SMDS_MeshNode * n2,
431 const SMDS_MeshNode * n3,
432 const SMDS_MeshNode * n4,
433 const SMDS_MeshNode * n5,
436 return AddVolumeWithID(n1->GetID(),
444 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
445 const SMDS_MeshNode * n2,
446 const SMDS_MeshNode * n3,
447 const SMDS_MeshNode * n4,
448 const SMDS_MeshNode * n5)
450 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
451 if(anElem) myScript->AddVolume(anElem->GetID(),
460 //=======================================================================
461 //function :AddVolume
463 //=======================================================================
464 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
466 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
467 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
471 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
472 const SMDS_MeshNode * n2,
473 const SMDS_MeshNode * n3,
474 const SMDS_MeshNode * n4,
475 const SMDS_MeshNode * n5,
476 const SMDS_MeshNode * n6,
479 return AddVolumeWithID(n1->GetID(),
488 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
489 const SMDS_MeshNode * n2,
490 const SMDS_MeshNode * n3,
491 const SMDS_MeshNode * n4,
492 const SMDS_MeshNode * n5,
493 const SMDS_MeshNode * n6)
495 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
496 if(anElem) myScript->AddVolume(anElem->GetID(),
506 //=======================================================================
507 //function :AddVolume
509 //=======================================================================
510 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
512 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
513 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
517 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
518 const SMDS_MeshNode * n2,
519 const SMDS_MeshNode * n3,
520 const SMDS_MeshNode * n4,
521 const SMDS_MeshNode * n5,
522 const SMDS_MeshNode * n6,
523 const SMDS_MeshNode * n7,
524 const SMDS_MeshNode * n8,
527 return AddVolumeWithID(n1->GetID(),
538 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
539 const SMDS_MeshNode * n2,
540 const SMDS_MeshNode * n3,
541 const SMDS_MeshNode * n4,
542 const SMDS_MeshNode * n5,
543 const SMDS_MeshNode * n6,
544 const SMDS_MeshNode * n7,
545 const SMDS_MeshNode * n8)
547 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
548 if(anElem) myScript->AddVolume(anElem->GetID(),
560 //=======================================================================
561 //function : AddPolygonalFace
563 //=======================================================================
564 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
567 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
569 myScript->AddPolygonalFace(ID, nodes_ids);
574 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
575 (std::vector<const SMDS_MeshNode*> nodes,
578 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
580 int i, len = nodes.size();
581 std::vector<int> nodes_ids (len);
582 for (i = 0; i < len; i++) {
583 nodes_ids[i] = nodes[i]->GetID();
585 myScript->AddPolygonalFace(ID, nodes_ids);
590 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
591 (std::vector<const SMDS_MeshNode*> nodes)
593 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
595 int i, len = nodes.size();
596 std::vector<int> nodes_ids (len);
597 for (i = 0; i < len; i++) {
598 nodes_ids[i] = nodes[i]->GetID();
600 myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
605 //=======================================================================
606 //function : AddPolyhedralVolume
608 //=======================================================================
609 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
610 std::vector<int> quantities,
613 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
615 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
620 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
621 (std::vector<const SMDS_MeshNode*> nodes,
622 std::vector<int> quantities,
625 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
627 int i, len = nodes.size();
628 std::vector<int> nodes_ids (len);
629 for (i = 0; i < len; i++) {
630 nodes_ids[i] = nodes[i]->GetID();
632 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
637 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
638 (std::vector<const SMDS_MeshNode*> nodes,
639 std::vector<int> quantities)
641 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
643 int i, len = nodes.size();
644 std::vector<int> nodes_ids (len);
645 for (i = 0; i < len; i++) {
646 nodes_ids[i] = nodes[i]->GetID();
648 myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
653 //=======================================================================
654 //function : removeFromContainers
656 //=======================================================================
658 static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
659 set<SMESHDS_GroupBase*>& theGroups,
660 list<const SMDS_MeshElement*>& theElems,
663 if ( theElems.empty() )
667 // Element can belong to several groups
668 if ( !theGroups.empty() )
670 set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
671 for ( ; GrIt != theGroups.end(); GrIt++ )
673 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
674 if ( !group || group->IsEmpty() ) continue;
676 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
677 for ( ; elIt != theElems.end(); elIt++ )
679 group->SMDSGroup().Remove( *elIt );
680 if ( group->IsEmpty() ) break;
685 const bool deleted=true;
687 // Rm from sub-meshes
688 // Element should belong to only one sub-mesh
689 map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
690 for ( ; SubIt != theSubMeshes.end(); SubIt++ )
692 int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
693 if ( size == 0 ) continue;
695 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
696 while ( elIt != theElems.end() )
698 bool removed = false;
700 removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
702 removed = (*SubIt).second->RemoveElement( *elIt, deleted );
706 elIt = theElems.erase( elIt );
707 if ( theElems.empty() )
708 return; // all elements are found and removed
718 //=======================================================================
719 //function : RemoveNode
721 //=======================================================================
722 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
724 if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
726 SMESHDS_SubMesh* subMesh=0;
727 map<int,SMESHDS_SubMesh*>::iterator SubIt =
728 myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
729 if ( SubIt != myShapeIndexToSubMesh.end() )
730 subMesh = SubIt->second;
732 SubIt = myShapeIndexToSubMesh.begin();
733 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
734 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
735 subMesh = SubIt->second;
737 RemoveFreeNode( n, subMesh, true);
741 myScript->RemoveNode(n->GetID());
743 list<const SMDS_MeshElement *> removedElems;
744 list<const SMDS_MeshElement *> removedNodes;
746 SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
748 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
749 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
752 //=======================================================================
753 //function : RemoveFreeNode
755 //=======================================================================
756 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
757 SMESHDS_SubMesh * subMesh,
760 myScript->RemoveNode(n->GetID());
763 // Node can belong to several groups
764 if (fromGroups && !myGroups.empty()) {
765 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
766 for (; GrIt != myGroups.end(); GrIt++) {
767 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
768 if (!group || group->IsEmpty()) continue;
769 group->SMDSGroup().Remove(n);
774 // Node should belong to only one sub-mesh
776 subMesh->RemoveNode(n,/*deleted=*/false);
778 SMDS_Mesh::RemoveFreeElement(n);
781 //=======================================================================
782 //function : RemoveElement
784 //========================================================================
785 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
787 if (elt->GetType() == SMDSAbs_Node)
789 RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
792 if (!hasConstructionEdges() && !hasConstructionFaces())
794 SMESHDS_SubMesh* subMesh=0;
795 map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
796 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
797 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
798 subMesh = SubIt->second;
800 RemoveFreeElement( elt, subMesh, true);
804 myScript->RemoveElement(elt->GetID());
806 list<const SMDS_MeshElement *> removedElems;
807 list<const SMDS_MeshElement *> removedNodes;
809 SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
811 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
814 //=======================================================================
815 //function : RemoveFreeElement
817 //========================================================================
818 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
819 SMESHDS_SubMesh * subMesh,
822 //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
823 if (elt->GetType() == SMDSAbs_Node) {
824 RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
828 if (hasConstructionEdges() || hasConstructionFaces())
829 // this methods is only for meshes without descendants
832 myScript->RemoveElement(elt->GetID());
835 // Node can belong to several groups
836 if ( fromGroups && !myGroups.empty() ) {
837 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
838 for (; GrIt != myGroups.end(); GrIt++) {
839 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
840 if (group && !group->IsEmpty())
841 group->SMDSGroup().Remove(elt);
846 // Element should belong to only one sub-mesh
848 subMesh->RemoveElement(elt, /*deleted=*/false);
850 SMDS_Mesh::RemoveFreeElement(elt);
853 //================================================================================
855 * \brief Remove all data from the mesh
857 //================================================================================
859 void SMESHDS_Mesh::ClearMesh()
861 myScript->ClearMesh();
865 map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
866 for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
867 sub->second->Clear();
870 TGroups::iterator group, groupEnd = myGroups.end();
871 for ( group = myGroups.begin(); group != groupEnd; ++group ) {
872 if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
873 SMDSAbs_ElementType groupType = g->GetType();
875 g->SetType( groupType );
880 //================================================================================
882 * \brief return submesh by shape
883 * \param shape - the subshape
884 * \retval SMESHDS_SubMesh* - the found submesh
886 * search of submeshes is optimized
888 //================================================================================
890 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
892 if ( shape.IsNull() )
895 if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
898 getSubmesh( ShapeToIndex( shape ));
899 myCurSubShape = shape;
903 //================================================================================
905 * \brief return submesh by subshape index
906 * \param Index - the subshape index
907 * \retval SMESHDS_SubMesh* - the found submesh
908 * search of submeshes is optimized
910 //================================================================================
912 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
914 //Update or build submesh
915 if ( Index != myCurSubID ) {
916 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
917 if ( it == myShapeIndexToSubMesh.end() )
918 it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
919 myCurSubMesh = it->second;
921 myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
926 //================================================================================
928 * \brief Add element or node to submesh
929 * \param elem - element to add
930 * \param subMesh - submesh to be filled in
932 //================================================================================
934 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
936 if ( elem && subMesh ) {
937 if ( elem->GetType() == SMDSAbs_Node )
938 subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
940 subMesh->AddElement( elem );
948 //================================================================================
950 * \brief Creates a node position in volume
952 //================================================================================
954 inline SMDS_PositionPtr volumePosition(int volId)
956 SMDS_SpacePosition* pos = new SMDS_SpacePosition();
957 pos->SetShapeId( volId );
958 return SMDS_PositionPtr(pos);
962 //=======================================================================
963 //function : SetNodeOnVolume
965 //=======================================================================
966 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
967 const TopoDS_Shell & S)
969 if ( add( aNode, getSubmesh(S) ))
970 aNode->SetPosition ( volumePosition( myCurSubID ));
972 //=======================================================================
973 //function : SetNodeOnVolume
975 //=======================================================================
976 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
977 const TopoDS_Solid & S)
979 if ( add( aNode, getSubmesh(S) ))
980 aNode->SetPosition ( volumePosition( myCurSubID ));
983 //=======================================================================
984 //function : SetNodeOnFace
986 //=======================================================================
987 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
988 const TopoDS_Face & S,
992 if ( add( aNode, getSubmesh(S) ))
993 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
996 //=======================================================================
997 //function : SetNodeOnEdge
999 //=======================================================================
1000 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
1001 const TopoDS_Edge & S,
1004 if ( add( aNode, getSubmesh(S) ))
1005 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
1008 //=======================================================================
1009 //function : SetNodeOnVertex
1011 //=======================================================================
1012 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
1013 const TopoDS_Vertex & S)
1015 if ( add( aNode, getSubmesh(S) ))
1016 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
1019 //=======================================================================
1020 //function : UnSetNodeOnShape
1022 //=======================================================================
1023 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1025 if ( aNode && aNode->GetPosition() ) {
1026 map<int,SMESHDS_SubMesh*>::iterator it =
1027 myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
1028 if ( it != myShapeIndexToSubMesh.end() )
1029 it->second->RemoveNode( aNode, /*deleted=*/false );
1033 //=======================================================================
1034 //function : SetMeshElementOnShape
1036 //=======================================================================
1037 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1038 const TopoDS_Shape & S)
1040 add( anElement, getSubmesh(S) );
1043 //=======================================================================
1044 //function : UnSetMeshElementOnShape
1046 //=======================================================================
1047 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1048 const TopoDS_Shape & S)
1050 int Index = myIndexToShape.FindIndex(S);
1052 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1053 if ( it != myShapeIndexToSubMesh.end() )
1054 if ( elem->GetType() == SMDSAbs_Node )
1055 it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ), /*deleted=*/false );
1057 it->second->RemoveElement( elem, /*deleted=*/false );
1060 //=======================================================================
1061 //function : ShapeToMesh
1063 //=======================================================================
1064 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1069 //=======================================================================
1070 //function : IsGroupOfSubShapes
1071 //purpose : return true if at least one subshape of theShape is a subshape
1072 // of myShape or theShape == myShape
1073 //=======================================================================
1075 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1077 if ( myShape.IsSame( theShape ))
1080 for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
1081 if (myIndexToShape.Contains( it.Value() ) ||
1082 IsGroupOfSubShapes( it.Value() ))
1089 ///////////////////////////////////////////////////////////////////////////////
1090 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1091 /// TopoDS_Shape is unknown
1092 ///////////////////////////////////////////////////////////////////////////////
1093 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1095 int Index = ShapeToIndex(S);
1096 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1097 if (anIter != myShapeIndexToSubMesh.end())
1098 return anIter->second;
1103 ///////////////////////////////////////////////////////////////////////////////
1104 /// Return the sub mesh by Id of shape it is linked to
1105 ///////////////////////////////////////////////////////////////////////////////
1106 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
1108 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1109 if (anIter != myShapeIndexToSubMesh.end())
1110 return anIter->second;
1115 //=======================================================================
1116 //function : SubMeshIndices
1118 //=======================================================================
1119 list<int> SMESHDS_Mesh::SubMeshIndices()
1121 list<int> anIndices;
1122 std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
1123 for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1124 anIndices.push_back((*anIter).first);
1129 //=======================================================================
1130 //function : GetHypothesis
1132 //=======================================================================
1134 const list<const SMESHDS_Hypothesis*>&
1135 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1137 if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1138 return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1140 static list<const SMESHDS_Hypothesis*> empty;
1144 //=======================================================================
1145 //function : GetScript
1147 //=======================================================================
1148 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1153 //=======================================================================
1154 //function : ClearScript
1156 //=======================================================================
1157 void SMESHDS_Mesh::ClearScript()
1162 //=======================================================================
1163 //function : HasMeshElements
1165 //=======================================================================
1166 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
1168 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1169 int Index = myIndexToShape.FindIndex(S);
1170 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1173 //=======================================================================
1174 //function : HasHypothesis
1176 //=======================================================================
1177 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1179 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1182 //=======================================================================
1183 //function : NewSubMesh
1185 //=======================================================================
1186 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1188 SMESHDS_SubMesh* SM = 0;
1189 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1190 if (anIter == myShapeIndexToSubMesh.end())
1192 SM = new SMESHDS_SubMesh();
1193 myShapeIndexToSubMesh[Index]=SM;
1196 SM = anIter->second;
1200 //=======================================================================
1201 //function : AddCompoundSubmesh
1203 //=======================================================================
1205 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1206 TopAbs_ShapeEnum type)
1209 if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
1211 aMainIndex = myIndexToShape.Add( S );
1212 bool all = ( type == TopAbs_SHAPE );
1213 if ( all ) // corresponding simple submesh may exist
1214 aMainIndex = -aMainIndex;
1215 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1216 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1217 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1219 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1220 int typeLimit = all ? TopAbs_VERTEX : type;
1221 for ( ; shapeType <= typeLimit; shapeType++ )
1223 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1224 for ( ; exp.More(); exp.Next() )
1226 int index = myIndexToShape.FindIndex( exp.Current() );
1228 aNewSub->AddSubMesh( NewSubMesh( index ));
1236 //=======================================================================
1237 //function : IndexToShape
1239 //=======================================================================
1240 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1244 return myIndexToShape.FindKey(ShapeIndex);
1246 catch ( Standard_OutOfRange )
1249 static TopoDS_Shape nullShape;
1253 //=======================================================================
1254 //function : ShapeToIndex
1256 //=======================================================================
1257 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1259 if (myShape.IsNull())
1260 MESSAGE("myShape is NULL");
1262 int index = myIndexToShape.FindIndex(S);
1267 //=======================================================================
1268 //function : SetNodeOnVolume
1270 //=======================================================================
1271 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1273 if ( add( aNode, getSubmesh( Index )))
1274 ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
1277 //=======================================================================
1278 //function : SetNodeOnFace
1280 //=======================================================================
1281 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1283 //Set Position on Node
1284 if ( add( aNode, getSubmesh( Index )))
1285 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
1288 //=======================================================================
1289 //function : SetNodeOnEdge
1291 //=======================================================================
1292 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1296 //Set Position on Node
1297 if ( add( aNode, getSubmesh( Index )))
1298 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
1301 //=======================================================================
1302 //function : SetNodeOnVertex
1304 //=======================================================================
1305 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1307 //Set Position on Node
1308 if ( add( aNode, getSubmesh( Index )))
1309 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
1312 //=======================================================================
1313 //function : SetMeshElementOnShape
1315 //=======================================================================
1316 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1319 add( anElement, getSubmesh( Index ));
1322 //=======================================================================
1323 //function : ~SMESHDS_Mesh
1325 //=======================================================================
1326 SMESHDS_Mesh::~SMESHDS_Mesh()
1331 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1332 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1333 delete i_sm->second;
1337 //********************************************************************
1338 //********************************************************************
1339 //******** *********
1340 //***** Methods for addition of quadratic elements ******
1341 //******** *********
1342 //********************************************************************
1343 //********************************************************************
1345 //=======================================================================
1346 //function : AddEdgeWithID
1348 //=======================================================================
1349 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1351 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1352 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1356 //=======================================================================
1357 //function : AddEdge
1359 //=======================================================================
1360 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1361 const SMDS_MeshNode* n2,
1362 const SMDS_MeshNode* n12)
1364 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1365 if(anElem) myScript->AddEdge(anElem->GetID(),
1372 //=======================================================================
1373 //function : AddEdgeWithID
1375 //=======================================================================
1376 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1377 const SMDS_MeshNode * n2,
1378 const SMDS_MeshNode * n12,
1381 return AddEdgeWithID(n1->GetID(),
1388 //=======================================================================
1389 //function : AddFace
1391 //=======================================================================
1392 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1393 const SMDS_MeshNode * n2,
1394 const SMDS_MeshNode * n3,
1395 const SMDS_MeshNode * n12,
1396 const SMDS_MeshNode * n23,
1397 const SMDS_MeshNode * n31)
1399 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1400 if(anElem) myScript->AddFace(anElem->GetID(),
1401 n1->GetID(), n2->GetID(), n3->GetID(),
1402 n12->GetID(), n23->GetID(), n31->GetID());
1406 //=======================================================================
1407 //function : AddFaceWithID
1409 //=======================================================================
1410 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1411 int n12,int n23,int n31, int ID)
1413 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1414 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1418 //=======================================================================
1419 //function : AddFaceWithID
1421 //=======================================================================
1422 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1423 const SMDS_MeshNode * n2,
1424 const SMDS_MeshNode * n3,
1425 const SMDS_MeshNode * n12,
1426 const SMDS_MeshNode * n23,
1427 const SMDS_MeshNode * n31,
1430 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1431 n12->GetID(), n23->GetID(), n31->GetID(),
1436 //=======================================================================
1437 //function : AddFace
1439 //=======================================================================
1440 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1441 const SMDS_MeshNode * n2,
1442 const SMDS_MeshNode * n3,
1443 const SMDS_MeshNode * n4,
1444 const SMDS_MeshNode * n12,
1445 const SMDS_MeshNode * n23,
1446 const SMDS_MeshNode * n34,
1447 const SMDS_MeshNode * n41)
1449 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1450 if(anElem) myScript->AddFace(anElem->GetID(),
1451 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1452 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1456 //=======================================================================
1457 //function : AddFaceWithID
1459 //=======================================================================
1460 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1461 int n12,int n23,int n34,int n41, int ID)
1463 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1464 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1468 //=======================================================================
1469 //function : AddFaceWithID
1471 //=======================================================================
1472 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1473 const SMDS_MeshNode * n2,
1474 const SMDS_MeshNode * n3,
1475 const SMDS_MeshNode * n4,
1476 const SMDS_MeshNode * n12,
1477 const SMDS_MeshNode * n23,
1478 const SMDS_MeshNode * n34,
1479 const SMDS_MeshNode * n41,
1482 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1483 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1488 //=======================================================================
1489 //function : AddVolume
1491 //=======================================================================
1492 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1493 const SMDS_MeshNode * n2,
1494 const SMDS_MeshNode * n3,
1495 const SMDS_MeshNode * n4,
1496 const SMDS_MeshNode * n12,
1497 const SMDS_MeshNode * n23,
1498 const SMDS_MeshNode * n31,
1499 const SMDS_MeshNode * n14,
1500 const SMDS_MeshNode * n24,
1501 const SMDS_MeshNode * n34)
1503 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1504 if(anElem) myScript->AddVolume(anElem->GetID(),
1505 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1506 n12->GetID(), n23->GetID(), n31->GetID(),
1507 n14->GetID(), n24->GetID(), n34->GetID());
1511 //=======================================================================
1512 //function : AddVolumeWithID
1514 //=======================================================================
1515 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1516 int n12,int n23,int n31,
1517 int n14,int n24,int n34, int ID)
1519 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1520 n31,n14,n24,n34,ID);
1521 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1525 //=======================================================================
1526 //function : AddVolumeWithID
1527 //purpose : 2d order tetrahedron of 10 nodes
1528 //=======================================================================
1529 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1530 const SMDS_MeshNode * n2,
1531 const SMDS_MeshNode * n3,
1532 const SMDS_MeshNode * n4,
1533 const SMDS_MeshNode * n12,
1534 const SMDS_MeshNode * n23,
1535 const SMDS_MeshNode * n31,
1536 const SMDS_MeshNode * n14,
1537 const SMDS_MeshNode * n24,
1538 const SMDS_MeshNode * n34,
1541 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1542 n12->GetID(), n23->GetID(), n31->GetID(),
1543 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1547 //=======================================================================
1548 //function : AddVolume
1550 //=======================================================================
1551 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1552 const SMDS_MeshNode * n2,
1553 const SMDS_MeshNode * n3,
1554 const SMDS_MeshNode * n4,
1555 const SMDS_MeshNode * n5,
1556 const SMDS_MeshNode * n12,
1557 const SMDS_MeshNode * n23,
1558 const SMDS_MeshNode * n34,
1559 const SMDS_MeshNode * n41,
1560 const SMDS_MeshNode * n15,
1561 const SMDS_MeshNode * n25,
1562 const SMDS_MeshNode * n35,
1563 const SMDS_MeshNode * n45)
1565 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1568 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1569 n3->GetID(), n4->GetID(), n5->GetID(),
1570 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1571 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1575 //=======================================================================
1576 //function : AddVolumeWithID
1578 //=======================================================================
1579 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1580 int n12,int n23,int n34,int n41,
1581 int n15,int n25,int n35,int n45, int ID)
1583 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1585 n15,n25,n35,n45,ID);
1586 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1591 //=======================================================================
1592 //function : AddVolumeWithID
1593 //purpose : 2d order pyramid of 13 nodes
1594 //=======================================================================
1595 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1596 const SMDS_MeshNode * n2,
1597 const SMDS_MeshNode * n3,
1598 const SMDS_MeshNode * n4,
1599 const SMDS_MeshNode * n5,
1600 const SMDS_MeshNode * n12,
1601 const SMDS_MeshNode * n23,
1602 const SMDS_MeshNode * n34,
1603 const SMDS_MeshNode * n41,
1604 const SMDS_MeshNode * n15,
1605 const SMDS_MeshNode * n25,
1606 const SMDS_MeshNode * n35,
1607 const SMDS_MeshNode * n45,
1610 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1611 n4->GetID(), n5->GetID(),
1612 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1613 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1618 //=======================================================================
1619 //function : AddVolume
1621 //=======================================================================
1622 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1623 const SMDS_MeshNode * n2,
1624 const SMDS_MeshNode * n3,
1625 const SMDS_MeshNode * n4,
1626 const SMDS_MeshNode * n5,
1627 const SMDS_MeshNode * n6,
1628 const SMDS_MeshNode * n12,
1629 const SMDS_MeshNode * n23,
1630 const SMDS_MeshNode * n31,
1631 const SMDS_MeshNode * n45,
1632 const SMDS_MeshNode * n56,
1633 const SMDS_MeshNode * n64,
1634 const SMDS_MeshNode * n14,
1635 const SMDS_MeshNode * n25,
1636 const SMDS_MeshNode * n36)
1638 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1639 n45,n56,n64,n14,n25,n36);
1641 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1642 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1643 n12->GetID(), n23->GetID(), n31->GetID(),
1644 n45->GetID(), n56->GetID(), n64->GetID(),
1645 n14->GetID(), n25->GetID(), n36->GetID());
1649 //=======================================================================
1650 //function : AddVolumeWithID
1652 //=======================================================================
1653 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1654 int n4, int n5, int n6,
1655 int n12,int n23,int n31,
1656 int n45,int n56,int n64,
1657 int n14,int n25,int n36, int ID)
1659 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1663 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1664 n45,n56,n64,n14,n25,n36);
1668 //=======================================================================
1669 //function : AddVolumeWithID
1670 //purpose : 2d order Pentahedron with 15 nodes
1671 //=======================================================================
1672 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1673 const SMDS_MeshNode * n2,
1674 const SMDS_MeshNode * n3,
1675 const SMDS_MeshNode * n4,
1676 const SMDS_MeshNode * n5,
1677 const SMDS_MeshNode * n6,
1678 const SMDS_MeshNode * n12,
1679 const SMDS_MeshNode * n23,
1680 const SMDS_MeshNode * n31,
1681 const SMDS_MeshNode * n45,
1682 const SMDS_MeshNode * n56,
1683 const SMDS_MeshNode * n64,
1684 const SMDS_MeshNode * n14,
1685 const SMDS_MeshNode * n25,
1686 const SMDS_MeshNode * n36,
1689 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1690 n4->GetID(), n5->GetID(), n6->GetID(),
1691 n12->GetID(), n23->GetID(), n31->GetID(),
1692 n45->GetID(), n56->GetID(), n64->GetID(),
1693 n14->GetID(), n25->GetID(), n36->GetID(),
1698 //=======================================================================
1699 //function : AddVolume
1701 //=======================================================================
1702 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1703 const SMDS_MeshNode * n2,
1704 const SMDS_MeshNode * n3,
1705 const SMDS_MeshNode * n4,
1706 const SMDS_MeshNode * n5,
1707 const SMDS_MeshNode * n6,
1708 const SMDS_MeshNode * n7,
1709 const SMDS_MeshNode * n8,
1710 const SMDS_MeshNode * n12,
1711 const SMDS_MeshNode * n23,
1712 const SMDS_MeshNode * n34,
1713 const SMDS_MeshNode * n41,
1714 const SMDS_MeshNode * n56,
1715 const SMDS_MeshNode * n67,
1716 const SMDS_MeshNode * n78,
1717 const SMDS_MeshNode * n85,
1718 const SMDS_MeshNode * n15,
1719 const SMDS_MeshNode * n26,
1720 const SMDS_MeshNode * n37,
1721 const SMDS_MeshNode * n48)
1723 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1728 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1729 n3->GetID(), n4->GetID(), n5->GetID(),
1730 n6->GetID(), n7->GetID(), n8->GetID(),
1731 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1732 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1733 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1737 //=======================================================================
1738 //function : AddVolumeWithID
1740 //=======================================================================
1741 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1742 int n5, int n6, int n7, int n8,
1743 int n12,int n23,int n34,int n41,
1744 int n56,int n67,int n78,int n85,
1745 int n15,int n26,int n37,int n48, int ID)
1747 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1750 n15,n26,n37,n48,ID);
1751 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1752 n56,n67,n78,n85,n15,n26,n37,n48);
1756 //=======================================================================
1757 //function : AddVolumeWithID
1758 //purpose : 2d order Hexahedrons with 20 nodes
1759 //=======================================================================
1760 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1761 const SMDS_MeshNode * n2,
1762 const SMDS_MeshNode * n3,
1763 const SMDS_MeshNode * n4,
1764 const SMDS_MeshNode * n5,
1765 const SMDS_MeshNode * n6,
1766 const SMDS_MeshNode * n7,
1767 const SMDS_MeshNode * n8,
1768 const SMDS_MeshNode * n12,
1769 const SMDS_MeshNode * n23,
1770 const SMDS_MeshNode * n34,
1771 const SMDS_MeshNode * n41,
1772 const SMDS_MeshNode * n56,
1773 const SMDS_MeshNode * n67,
1774 const SMDS_MeshNode * n78,
1775 const SMDS_MeshNode * n85,
1776 const SMDS_MeshNode * n15,
1777 const SMDS_MeshNode * n26,
1778 const SMDS_MeshNode * n37,
1779 const SMDS_MeshNode * n48,
1782 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1783 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1784 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1785 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1786 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1790 void SMESHDS_Mesh::compactMesh()
1792 int newNodeSize = 0;
1793 int nbNodes = myNodes.size();
1794 int nbVtkNodes = myGrid->GetNumberOfPoints();
1795 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1796 int nbNodeTemp = nbVtkNodes;
1797 if (nbNodes > nbVtkNodes) nbNodeTemp = nbNodes;
1798 vector<int> idNodesOldToNew;
1799 idNodesOldToNew.clear();
1800 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1802 bool areNodesModified = ! myNodeIDFactory->isPoolIdEmpty();
1803 MESSAGE("------------------------------------------------- SMESHDS_Mesh::compactMesh " << areNodesModified);
1804 if (areNodesModified)
1806 for (int i=0; i<nbNodes; i++)
1810 idNodesOldToNew[i] = i; // all valid id are >= 0
1817 for (int i=0; i<nbNodes; i++)
1818 idNodesOldToNew[i] = i;
1819 if (nbNodes > nbVtkNodes)
1820 newNodeSize = nbVtkNodes; // else 0 means nothing to change (no need to compact vtkPoints)
1823 int newCellSize = 0;
1824 int nbCells = myCells.size();
1825 int nbVtkCells = myGrid->GetNumberOfCells();
1826 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1827 int nbCellTemp = nbVtkCells;
1828 if (nbCells > nbVtkCells) nbCellTemp = nbCells;
1829 vector<int> idCellsOldToNew;
1830 idCellsOldToNew.clear();
1831 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1833 for (int i=0; i<nbCells; i++)
1837 idCellsOldToNew[i] = myVtkIndex[i]; // valid vtk indexes are > = 0
1841 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1843 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1845 if (areNodesModified)
1847 MESSAGE("-------------- modify myNodes");
1848 SetOfNodes newNodes;
1849 newNodes.resize(newNodeSize);
1851 for (int i=0; i<nbNodes; i++)
1855 int newid = idNodesOldToNew[i];
1856 //MESSAGE(i << " --> " << newid);;
1857 myNodes[i]->setId(newid);
1858 newNodes[newid] = myNodes[i];
1861 myNodes.swap(newNodes);
1862 this->myNodeIDFactory->emptyPool(newNodeSize);
1865 // --- SMDS_MeshCell, myIDElements and myVtkIndex (myCells and myElementIdFactory are not compacted)
1867 int vtkIndexSize = myVtkIndex.size();
1869 for (int oldVtkId=0; oldVtkId<vtkIndexSize; oldVtkId++)
1871 int smdsId = this->myVtkIndex[oldVtkId];
1874 int newVtkId = idCellsOldToNew[oldVtkId];
1875 if (newVtkId > maxVtkId) maxVtkId = newVtkId;
1876 //MESSAGE("===========> smdsId newVtkId " << smdsId << " " << newVtkId);
1877 myCells[smdsId]->setVtkId(newVtkId);
1878 myIDElements[smdsId] = newVtkId;
1879 myVtkIndex[newVtkId] = smdsId;
1883 MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
1884 MESSAGE("maxVtkId=" << maxVtkId);
1886 SetOfCells newCells;
1887 vector<int> newSmdsToVtk;
1888 vector<int> newVtkToSmds;
1890 newCells.resize(maxVtkId,0);
1891 newSmdsToVtk.resize(maxVtkId,-1);
1892 newVtkToSmds.resize(maxVtkId,-1);
1894 int myCellsSize = myCells.size();
1896 for (int i=0; i<myCellsSize; i++)
1900 //MESSAGE(newSmdsId << " " << i);
1901 newCells[newSmdsId] = myCells[i];
1902 int idvtk = myCells[i]->getVtkId();
1903 newSmdsToVtk[newSmdsId] = idvtk;
1904 assert(idvtk < maxVtkId);
1905 newVtkToSmds[idvtk] = newSmdsId;
1906 myCells[i]->setId(newSmdsId);
1908 assert(newSmdsId <= maxVtkId);
1912 myCells.swap(newCells);
1913 myIDElements.swap(newSmdsToVtk);
1914 myVtkIndex.swap(newVtkToSmds);
1915 MESSAGE("myCells.size()=" << myCells.size() << " myIDElements.size()=" << myIDElements.size() << " myVtkIndex.size()=" << myVtkIndex.size() );
1919 // ---TODO: myNodes, myElements in submeshes
1921 // map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1922 // for(; it != myShapeIndexToSubMesh.end(); ++it)
1924 // (*it).second->compactList(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);