1 // Copyright (C) 2007-2011 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 "SMDS_Downward.hxx"
37 #include "SMESHDS_GroupOnGeom.hxx"
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_OutOfRange.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopoDS_Iterator.hxx>
45 #include "utilities.h"
49 /*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 )
51 return S1.IsSame( S2 );
54 //=======================================================================
57 //=======================================================================
58 SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
60 myIsEmbeddedMode(theIsEmbeddedMode),
63 myScript = new SMESHDS_Script(theIsEmbeddedMode);
65 SetPersistentId(theMeshID);
68 //=======================================================================
69 bool SMESHDS_Mesh::IsEmbeddedMode()
71 return myIsEmbeddedMode;
74 //================================================================================
76 * \brief Store ID persistent during lifecycle
78 * Initially it was used to have a persistent reference to the mesh from the hypothesis
80 //================================================================================
82 void SMESHDS_Mesh::SetPersistentId(int id)
87 //================================================================================
89 * \brief Return ID persistent during lifecycle
91 //================================================================================
93 int SMESHDS_Mesh::GetPersistentId() const
95 return myPersistentID;
98 //=======================================================================
99 //function : ShapeToMesh
101 //=======================================================================
102 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
104 if ( !myShape.IsNull() && S.IsNull() )
106 // removal of a shape to mesh, delete ...
108 myShapeToHypothesis.Clear();
109 // - shape indices in SMDS_Position of nodes
110 map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
111 for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
112 if ( !i_sub->second->IsComplexSubmesh() ) {
113 SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
114 while ( nIt->more() )
115 i_sub->second->RemoveNode(nIt->next(), false);
119 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
120 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
122 myShapeIndexToSubMesh.clear();
123 myIndexToShape.Clear();
124 // - groups on geometry
125 set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
126 while ( gr != myGroups.end() ) {
127 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
128 myGroups.erase( gr++ );
136 TopExp::MapShapes(myShape, myIndexToShape);
140 //=======================================================================
141 //function : AddHypothesis
143 //=======================================================================
145 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
146 const SMESHDS_Hypothesis * H)
148 if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
149 list<const SMESHDS_Hypothesis *> aList;
150 myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
152 list<const SMESHDS_Hypothesis *>& alist =
153 myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
155 //Check if the Hypothesis is still present
156 list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
158 if (alist.end() != ith) return false;
164 //=======================================================================
165 //function : RemoveHypothesis
167 //=======================================================================
169 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
170 const SMESHDS_Hypothesis * H)
172 if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
174 list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
175 list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
176 if (ith != alist.end())
185 //=======================================================================
188 //=======================================================================
189 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
190 SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
191 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
195 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
196 SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
197 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
201 //=======================================================================
202 //function : MoveNode
204 //=======================================================================
205 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
207 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
209 myScript->MoveNode(n->GetID(), x, y, z);
212 //=======================================================================
213 //function : ChangeElementNodes
215 //=======================================================================
217 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
218 const SMDS_MeshNode * nodes[],
221 //MESSAGE("SMESHDS_Mesh::ChangeElementNodes");
222 if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
225 vector<int> IDs( nbnodes );
226 for ( int i = 0; i < nbnodes; i++ )
227 IDs [ i ] = nodes[ i ]->GetID();
228 myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
233 //=======================================================================
234 //function : ChangePolygonNodes
236 //=======================================================================
237 bool SMESHDS_Mesh::ChangePolygonNodes
238 (const SMDS_MeshElement * elem,
239 vector<const SMDS_MeshNode*> nodes)
241 ASSERT(nodes.size() > 3);
243 return ChangeElementNodes(elem, &nodes[0], nodes.size());
246 //=======================================================================
247 //function : ChangePolyhedronNodes
249 //=======================================================================
250 bool SMESHDS_Mesh::ChangePolyhedronNodes
251 (const SMDS_MeshElement * elem,
252 std::vector<const SMDS_MeshNode*> nodes,
253 std::vector<int> quantities)
255 ASSERT(nodes.size() > 3);
257 if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
260 int i, len = nodes.size();
261 std::vector<int> nodes_ids (len);
262 for (i = 0; i < len; i++) {
263 nodes_ids[i] = nodes[i]->GetID();
265 myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
270 //=======================================================================
271 //function : Renumber
273 //=======================================================================
275 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
277 // TODO not possible yet to have node numbers not starting to O and continuous.
278 if (!this->isCompacted())
280 // SMDS_Mesh::Renumber( isNodes, startID, deltaID );
281 // myScript->Renumber( isNodes, startID, deltaID );
284 //=======================================================================
285 //function : Add0DElement
287 //=======================================================================
288 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
290 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
291 if (anElem) myScript->Add0DElement(ID, nodeID);
295 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
296 (const SMDS_MeshNode * node, int ID)
298 return Add0DElementWithID(node->GetID(), ID);
301 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
303 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
304 if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
308 //=======================================================================
309 //function :AddEdgeWithID
311 //=======================================================================
312 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
314 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
315 if(anElem) myScript->AddEdge(ID,n1,n2);
319 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
320 const SMDS_MeshNode * n2,
323 return AddEdgeWithID(n1->GetID(),
328 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
329 const SMDS_MeshNode * n2)
331 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
332 if(anElem) myScript->AddEdge(anElem->GetID(),
338 //=======================================================================
341 //=======================================================================
342 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
344 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
345 if(anElem) myScript->AddFace(ID,n1,n2,n3);
349 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
350 const SMDS_MeshNode * n2,
351 const SMDS_MeshNode * n3,
354 return AddFaceWithID(n1->GetID(),
360 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
361 const SMDS_MeshNode * n2,
362 const SMDS_MeshNode * n3)
364 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
365 if(anElem) myScript->AddFace(anElem->GetID(),
372 //=======================================================================
375 //=======================================================================
376 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
378 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
379 if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
383 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
384 const SMDS_MeshNode * n2,
385 const SMDS_MeshNode * n3,
386 const SMDS_MeshNode * n4,
389 return AddFaceWithID(n1->GetID(),
396 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
397 const SMDS_MeshNode * n2,
398 const SMDS_MeshNode * n3,
399 const SMDS_MeshNode * n4)
401 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
402 if(anElem) myScript->AddFace(anElem->GetID(),
410 //=======================================================================
411 //function :AddVolume
413 //=======================================================================
414 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
416 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
417 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
421 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
422 const SMDS_MeshNode * n2,
423 const SMDS_MeshNode * n3,
424 const SMDS_MeshNode * n4,
427 return AddVolumeWithID(n1->GetID(),
434 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
435 const SMDS_MeshNode * n2,
436 const SMDS_MeshNode * n3,
437 const SMDS_MeshNode * n4)
439 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
440 if(anElem) myScript->AddVolume(anElem->GetID(),
448 //=======================================================================
449 //function :AddVolume
451 //=======================================================================
452 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
454 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
455 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
459 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
460 const SMDS_MeshNode * n2,
461 const SMDS_MeshNode * n3,
462 const SMDS_MeshNode * n4,
463 const SMDS_MeshNode * n5,
466 return AddVolumeWithID(n1->GetID(),
474 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
475 const SMDS_MeshNode * n2,
476 const SMDS_MeshNode * n3,
477 const SMDS_MeshNode * n4,
478 const SMDS_MeshNode * n5)
480 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
481 if(anElem) myScript->AddVolume(anElem->GetID(),
490 //=======================================================================
491 //function :AddVolume
493 //=======================================================================
494 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
496 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
497 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
501 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
502 const SMDS_MeshNode * n2,
503 const SMDS_MeshNode * n3,
504 const SMDS_MeshNode * n4,
505 const SMDS_MeshNode * n5,
506 const SMDS_MeshNode * n6,
509 return AddVolumeWithID(n1->GetID(),
518 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
519 const SMDS_MeshNode * n2,
520 const SMDS_MeshNode * n3,
521 const SMDS_MeshNode * n4,
522 const SMDS_MeshNode * n5,
523 const SMDS_MeshNode * n6)
525 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
526 if(anElem) myScript->AddVolume(anElem->GetID(),
536 //=======================================================================
537 //function :AddVolume
539 //=======================================================================
540 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
542 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
543 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
547 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
548 const SMDS_MeshNode * n2,
549 const SMDS_MeshNode * n3,
550 const SMDS_MeshNode * n4,
551 const SMDS_MeshNode * n5,
552 const SMDS_MeshNode * n6,
553 const SMDS_MeshNode * n7,
554 const SMDS_MeshNode * n8,
557 return AddVolumeWithID(n1->GetID(),
568 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
569 const SMDS_MeshNode * n2,
570 const SMDS_MeshNode * n3,
571 const SMDS_MeshNode * n4,
572 const SMDS_MeshNode * n5,
573 const SMDS_MeshNode * n6,
574 const SMDS_MeshNode * n7,
575 const SMDS_MeshNode * n8)
577 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
578 if(anElem) myScript->AddVolume(anElem->GetID(),
590 //=======================================================================
591 //function : AddPolygonalFace
593 //=======================================================================
594 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
597 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
599 myScript->AddPolygonalFace(ID, nodes_ids);
604 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
605 (const std::vector<const SMDS_MeshNode*>& nodes,
608 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
610 int i, len = nodes.size();
611 std::vector<int> nodes_ids (len);
612 for (i = 0; i < len; i++) {
613 nodes_ids[i] = nodes[i]->GetID();
615 myScript->AddPolygonalFace(ID, nodes_ids);
620 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
621 (const std::vector<const SMDS_MeshNode*>& nodes)
623 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
625 int i, len = nodes.size();
626 std::vector<int> nodes_ids (len);
627 for (i = 0; i < len; i++) {
628 nodes_ids[i] = nodes[i]->GetID();
630 myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
635 //=======================================================================
636 //function : AddPolyhedralVolume
638 //=======================================================================
639 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
640 const std::vector<int>& quantities,
643 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
645 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
650 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
651 (const std::vector<const SMDS_MeshNode*>& nodes,
652 const std::vector<int>& quantities,
655 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
657 int i, len = nodes.size();
658 std::vector<int> nodes_ids (len);
659 for (i = 0; i < len; i++) {
660 nodes_ids[i] = nodes[i]->GetID();
662 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
667 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
668 (const std::vector<const SMDS_MeshNode*>& nodes,
669 const std::vector<int>& quantities)
671 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
673 int i, len = nodes.size();
674 std::vector<int> nodes_ids (len);
675 for (i = 0; i < len; i++) {
676 nodes_ids[i] = nodes[i]->GetID();
678 myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
683 //=======================================================================
684 //function : removeFromContainers
686 //=======================================================================
688 static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
689 set<SMESHDS_GroupBase*>& theGroups,
690 list<const SMDS_MeshElement*>& theElems,
693 if ( theElems.empty() )
697 // Element can belong to several groups
698 if ( !theGroups.empty() )
700 set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
701 for ( ; GrIt != theGroups.end(); GrIt++ )
703 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
704 if ( !group || group->IsEmpty() ) continue;
706 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
707 for ( ; elIt != theElems.end(); elIt++ )
709 group->SMDSGroup().Remove( *elIt );
710 if ( group->IsEmpty() ) break;
715 const bool deleted=true;
717 // Rm from sub-meshes
718 // Element should belong to only one sub-mesh
719 if ( !theSubMeshes.empty() )
721 SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->getParent();
722 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
724 for ( ; elIt != theElems.end(); ++elIt )
725 if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
726 sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
729 for ( ; elIt != theElems.end(); ++elIt )
730 if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
731 sm->RemoveElement( *elIt, deleted );
736 //=======================================================================
737 //function : RemoveNode
739 //=======================================================================
740 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
742 if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
744 SMESHDS_SubMesh* subMesh=0;
745 map<int,SMESHDS_SubMesh*>::iterator SubIt =
746 myShapeIndexToSubMesh.find( n->getshapeId() );
747 if ( SubIt != myShapeIndexToSubMesh.end() )
748 subMesh = SubIt->second;
750 SubIt = myShapeIndexToSubMesh.begin();
751 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
752 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
753 subMesh = SubIt->second;
755 RemoveFreeNode( n, subMesh, true);
759 myScript->RemoveNode(n->GetID());
761 list<const SMDS_MeshElement *> removedElems;
762 list<const SMDS_MeshElement *> removedNodes;
764 SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
766 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
767 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
770 //=======================================================================
771 //function : RemoveFreeNode
773 //=======================================================================
774 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
775 SMESHDS_SubMesh * subMesh,
778 myScript->RemoveNode(n->GetID());
781 // Node can belong to several groups
782 if (fromGroups && !myGroups.empty()) {
783 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
784 for (; GrIt != myGroups.end(); GrIt++) {
785 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
786 if (!group || group->IsEmpty()) continue;
787 group->SMDSGroup().Remove(n);
792 // Node should belong to only one sub-mesh
794 subMesh->RemoveNode(n,/*deleted=*/false);
796 SMDS_Mesh::RemoveFreeElement(n);
799 //=======================================================================
800 //function : RemoveElement
802 //========================================================================
803 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
805 if (elt->GetType() == SMDSAbs_Node)
807 RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
810 if (!hasConstructionEdges() && !hasConstructionFaces())
812 SMESHDS_SubMesh* subMesh=0;
813 map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
814 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
815 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
816 subMesh = SubIt->second;
817 //MESSAGE("subMesh " << elt->getshapeId());
818 RemoveFreeElement( elt, subMesh, true);
822 myScript->RemoveElement(elt->GetID());
824 list<const SMDS_MeshElement *> removedElems;
825 list<const SMDS_MeshElement *> removedNodes;
827 SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
829 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
832 //=======================================================================
833 //function : RemoveFreeElement
835 //========================================================================
836 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
837 SMESHDS_SubMesh * subMesh,
840 //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
841 if (elt->GetType() == SMDSAbs_Node) {
842 RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
846 if (hasConstructionEdges() || hasConstructionFaces())
847 // this methods is only for meshes without descendants
850 myScript->RemoveElement(elt->GetID());
853 // Node can belong to several groups
854 if ( fromGroups && !myGroups.empty() ) {
855 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
856 for (; GrIt != myGroups.end(); GrIt++) {
857 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
858 if (group && !group->IsEmpty())
859 group->SMDSGroup().Remove(elt);
864 // Element should belong to only one sub-mesh
866 subMesh->RemoveElement(elt, /*deleted=*/false);
868 SMDS_Mesh::RemoveFreeElement(elt);
871 //================================================================================
873 * \brief Remove all data from the mesh
875 //================================================================================
877 void SMESHDS_Mesh::ClearMesh()
879 myScript->ClearMesh();
883 map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
884 for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
885 sub->second->Clear();
888 TGroups::iterator group, groupEnd = myGroups.end();
889 for ( group = myGroups.begin(); group != groupEnd; ++group ) {
890 if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
891 SMDSAbs_ElementType groupType = g->GetType();
893 g->SetType( groupType );
898 //================================================================================
900 * \brief return submesh by shape
901 * \param shape - the subshape
902 * \retval SMESHDS_SubMesh* - the found submesh
904 * search of submeshes is optimized
906 //================================================================================
908 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
910 if ( shape.IsNull() )
913 if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
916 getSubmesh( ShapeToIndex( shape ));
917 myCurSubShape = shape;
921 //================================================================================
923 * \brief return submesh by subshape index
924 * \param Index - the subshape index
925 * \retval SMESHDS_SubMesh* - the found submesh
926 * search of submeshes is optimized
928 //================================================================================
930 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
932 //Update or build submesh
933 if ( Index != myCurSubID ) {
934 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
935 if ( it == myShapeIndexToSubMesh.end() )
936 it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
937 myCurSubMesh = it->second;
939 myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
944 //================================================================================
946 * \brief Add element or node to submesh
947 * \param elem - element to add
948 * \param subMesh - submesh to be filled in
950 //================================================================================
952 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
954 if ( elem && subMesh ) {
955 if ( elem->GetType() == SMDSAbs_Node )
956 subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
958 subMesh->AddElement( elem );
964 //=======================================================================
965 //function : SetNodeOnVolume
967 //=======================================================================
968 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
969 const TopoDS_Shell & S)
971 if ( add( aNode, getSubmesh(S) ))
972 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
975 //=======================================================================
976 //function : SetNodeOnVolume
978 //=======================================================================
979 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
980 const TopoDS_Solid & S)
982 if ( add( aNode, getSubmesh(S) ))
983 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
986 //=======================================================================
987 //function : SetNodeOnFace
989 //=======================================================================
990 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
991 const TopoDS_Face & S,
995 if ( add( aNode, getSubmesh(S) ))
996 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
999 //=======================================================================
1000 //function : SetNodeOnEdge
1002 //=======================================================================
1003 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
1004 const TopoDS_Edge & S,
1007 if ( add( aNode, getSubmesh(S) ))
1008 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1011 //=======================================================================
1012 //function : SetNodeOnVertex
1014 //=======================================================================
1015 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
1016 const TopoDS_Vertex & S)
1018 if ( add( aNode, getSubmesh(S) ))
1019 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1022 //=======================================================================
1023 //function : UnSetNodeOnShape
1025 //=======================================================================
1026 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1028 int shapeId = aNode->getshapeId();
1031 map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1032 if (it != myShapeIndexToSubMesh.end())
1033 it->second->RemoveNode(aNode, /*deleted=*/false);
1037 //=======================================================================
1038 //function : SetMeshElementOnShape
1040 //=======================================================================
1041 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1042 const TopoDS_Shape & S)
1044 add( anElement, getSubmesh(S) );
1047 //=======================================================================
1048 //function : UnSetMeshElementOnShape
1050 //=======================================================================
1051 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1052 const TopoDS_Shape & S)
1054 int Index = myIndexToShape.FindIndex(S);
1056 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1057 if ( it != myShapeIndexToSubMesh.end() )
1059 if (elem->GetType() == SMDSAbs_Node)
1060 it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1062 it->second->RemoveElement(elem, /*deleted=*/false);
1066 //=======================================================================
1067 //function : ShapeToMesh
1069 //=======================================================================
1070 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1075 //=======================================================================
1076 //function : IsGroupOfSubShapes
1077 //purpose : return true if at least one subshape of theShape is a subshape
1078 // of myShape or theShape == myShape
1079 //=======================================================================
1081 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1083 if ( myIndexToShape.Contains(theShape) )
1086 for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1087 if (IsGroupOfSubShapes( it.Value() ))
1093 ///////////////////////////////////////////////////////////////////////////////
1094 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1095 /// TopoDS_Shape is unknown
1096 ///////////////////////////////////////////////////////////////////////////////
1097 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1099 int Index = ShapeToIndex(S);
1100 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1101 if (anIter != myShapeIndexToSubMesh.end())
1102 return anIter->second;
1107 ///////////////////////////////////////////////////////////////////////////////
1108 /// Return the sub mesh by Id of shape it is linked to
1109 ///////////////////////////////////////////////////////////////////////////////
1110 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1112 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1113 if (anIter != myShapeIndexToSubMesh.end())
1114 return anIter->second;
1119 //=======================================================================
1120 //function : SubMeshIndices
1122 //=======================================================================
1123 list<int> SMESHDS_Mesh::SubMeshIndices() const
1125 list<int> anIndices;
1126 std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1127 for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1128 anIndices.push_back((*anIter).first);
1133 //=======================================================================
1134 //function : GetHypothesis
1136 //=======================================================================
1138 const list<const SMESHDS_Hypothesis*>&
1139 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1141 if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1142 return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1144 static list<const SMESHDS_Hypothesis*> empty;
1148 //================================================================================
1150 * \brief returns true if the hypothesis is assigned to any sub-shape
1152 //================================================================================
1154 bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const
1156 ShapeToHypothesis::Iterator s2h( myShapeToHypothesis );
1157 for ( ; s2h.More(); s2h.Next() )
1158 if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() )
1163 //=======================================================================
1164 //function : GetScript
1166 //=======================================================================
1167 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1172 //=======================================================================
1173 //function : ClearScript
1175 //=======================================================================
1176 void SMESHDS_Mesh::ClearScript()
1181 //=======================================================================
1182 //function : HasMeshElements
1184 //=======================================================================
1185 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1187 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1188 int Index = myIndexToShape.FindIndex(S);
1189 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1192 //=======================================================================
1193 //function : HasHypothesis
1195 //=======================================================================
1196 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1198 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1201 //=======================================================================
1202 //function : NewSubMesh
1204 //=======================================================================
1205 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1207 SMESHDS_SubMesh* SM = 0;
1208 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1209 if (anIter == myShapeIndexToSubMesh.end())
1211 SM = new SMESHDS_SubMesh(this, Index);
1212 myShapeIndexToSubMesh[Index]=SM;
1215 SM = anIter->second;
1219 //=======================================================================
1220 //function : AddCompoundSubmesh
1222 //=======================================================================
1224 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1225 TopAbs_ShapeEnum type)
1228 if ( IsGroupOfSubShapes( S ))
1230 aMainIndex = myIndexToShape.Add( S );
1231 bool all = ( type == TopAbs_SHAPE );
1232 if ( all ) // corresponding simple submesh may exist
1233 aMainIndex = -aMainIndex;
1234 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1235 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1236 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1238 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1239 int typeLimit = all ? TopAbs_VERTEX : type;
1240 for ( ; shapeType <= typeLimit; shapeType++ )
1242 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1243 for ( ; exp.More(); exp.Next() )
1245 int index = myIndexToShape.FindIndex( exp.Current() );
1247 aNewSub->AddSubMesh( NewSubMesh( index ));
1255 //=======================================================================
1256 //function : IndexToShape
1258 //=======================================================================
1259 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1263 return myIndexToShape.FindKey(ShapeIndex);
1265 catch ( Standard_OutOfRange )
1268 static TopoDS_Shape nullShape;
1272 //================================================================================
1274 * \brief Return max index of sub-mesh
1276 //================================================================================
1278 int SMESHDS_Mesh::MaxSubMeshIndex() const
1280 return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1283 //=======================================================================
1284 //function : ShapeToIndex
1286 //=======================================================================
1287 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1289 if (myShape.IsNull())
1290 MESSAGE("myShape is NULL");
1292 int index = myIndexToShape.FindIndex(S);
1297 //=======================================================================
1298 //function : SetNodeOnVolume
1300 //=======================================================================
1301 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1303 //add(aNode, getSubmesh(Index));
1304 if ( add( aNode, getSubmesh( Index )))
1305 ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1308 //=======================================================================
1309 //function : SetNodeOnFace
1311 //=======================================================================
1312 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1314 //Set Position on Node
1315 if ( add( aNode, getSubmesh( Index )))
1316 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1319 //=======================================================================
1320 //function : SetNodeOnEdge
1322 //=======================================================================
1323 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1327 //Set Position on Node
1328 if ( add( aNode, getSubmesh( Index )))
1329 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1332 //=======================================================================
1333 //function : SetNodeOnVertex
1335 //=======================================================================
1336 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1338 //Set Position on Node
1339 if ( add( aNode, getSubmesh( Index )))
1340 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1343 //=======================================================================
1344 //function : SetMeshElementOnShape
1346 //=======================================================================
1347 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1350 add( anElement, getSubmesh( Index ));
1353 //=======================================================================
1354 //function : ~SMESHDS_Mesh
1356 //=======================================================================
1357 SMESHDS_Mesh::~SMESHDS_Mesh()
1362 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1363 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1364 delete i_sm->second;
1368 //********************************************************************
1369 //********************************************************************
1370 //******** *********
1371 //***** Methods for addition of quadratic elements ******
1372 //******** *********
1373 //********************************************************************
1374 //********************************************************************
1376 //=======================================================================
1377 //function : AddEdgeWithID
1379 //=======================================================================
1380 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1382 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1383 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1387 //=======================================================================
1388 //function : AddEdge
1390 //=======================================================================
1391 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1392 const SMDS_MeshNode* n2,
1393 const SMDS_MeshNode* n12)
1395 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1396 if(anElem) myScript->AddEdge(anElem->GetID(),
1403 //=======================================================================
1404 //function : AddEdgeWithID
1406 //=======================================================================
1407 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1408 const SMDS_MeshNode * n2,
1409 const SMDS_MeshNode * n12,
1412 return AddEdgeWithID(n1->GetID(),
1419 //=======================================================================
1420 //function : AddFace
1422 //=======================================================================
1423 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1424 const SMDS_MeshNode * n2,
1425 const SMDS_MeshNode * n3,
1426 const SMDS_MeshNode * n12,
1427 const SMDS_MeshNode * n23,
1428 const SMDS_MeshNode * n31)
1430 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1431 if(anElem) myScript->AddFace(anElem->GetID(),
1432 n1->GetID(), n2->GetID(), n3->GetID(),
1433 n12->GetID(), n23->GetID(), n31->GetID());
1437 //=======================================================================
1438 //function : AddFaceWithID
1440 //=======================================================================
1441 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1442 int n12,int n23,int n31, int ID)
1444 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1445 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1449 //=======================================================================
1450 //function : AddFaceWithID
1452 //=======================================================================
1453 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1454 const SMDS_MeshNode * n2,
1455 const SMDS_MeshNode * n3,
1456 const SMDS_MeshNode * n12,
1457 const SMDS_MeshNode * n23,
1458 const SMDS_MeshNode * n31,
1461 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1462 n12->GetID(), n23->GetID(), n31->GetID(),
1467 //=======================================================================
1468 //function : AddFace
1470 //=======================================================================
1471 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1472 const SMDS_MeshNode * n2,
1473 const SMDS_MeshNode * n3,
1474 const SMDS_MeshNode * n4,
1475 const SMDS_MeshNode * n12,
1476 const SMDS_MeshNode * n23,
1477 const SMDS_MeshNode * n34,
1478 const SMDS_MeshNode * n41)
1480 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1481 if(anElem) myScript->AddFace(anElem->GetID(),
1482 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1483 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1487 //=======================================================================
1488 //function : AddFaceWithID
1490 //=======================================================================
1491 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1492 int n12,int n23,int n34,int n41, int ID)
1494 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1495 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1499 //=======================================================================
1500 //function : AddFaceWithID
1502 //=======================================================================
1503 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1504 const SMDS_MeshNode * n2,
1505 const SMDS_MeshNode * n3,
1506 const SMDS_MeshNode * n4,
1507 const SMDS_MeshNode * n12,
1508 const SMDS_MeshNode * n23,
1509 const SMDS_MeshNode * n34,
1510 const SMDS_MeshNode * n41,
1513 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1514 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1519 //=======================================================================
1520 //function : AddVolume
1522 //=======================================================================
1523 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1524 const SMDS_MeshNode * n2,
1525 const SMDS_MeshNode * n3,
1526 const SMDS_MeshNode * n4,
1527 const SMDS_MeshNode * n12,
1528 const SMDS_MeshNode * n23,
1529 const SMDS_MeshNode * n31,
1530 const SMDS_MeshNode * n14,
1531 const SMDS_MeshNode * n24,
1532 const SMDS_MeshNode * n34)
1534 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1535 if(anElem) myScript->AddVolume(anElem->GetID(),
1536 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1537 n12->GetID(), n23->GetID(), n31->GetID(),
1538 n14->GetID(), n24->GetID(), n34->GetID());
1542 //=======================================================================
1543 //function : AddVolumeWithID
1545 //=======================================================================
1546 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1547 int n12,int n23,int n31,
1548 int n14,int n24,int n34, int ID)
1550 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1551 n31,n14,n24,n34,ID);
1552 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1556 //=======================================================================
1557 //function : AddVolumeWithID
1558 //purpose : 2d order tetrahedron of 10 nodes
1559 //=======================================================================
1560 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1561 const SMDS_MeshNode * n2,
1562 const SMDS_MeshNode * n3,
1563 const SMDS_MeshNode * n4,
1564 const SMDS_MeshNode * n12,
1565 const SMDS_MeshNode * n23,
1566 const SMDS_MeshNode * n31,
1567 const SMDS_MeshNode * n14,
1568 const SMDS_MeshNode * n24,
1569 const SMDS_MeshNode * n34,
1572 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1573 n12->GetID(), n23->GetID(), n31->GetID(),
1574 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1578 //=======================================================================
1579 //function : AddVolume
1581 //=======================================================================
1582 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1583 const SMDS_MeshNode * n2,
1584 const SMDS_MeshNode * n3,
1585 const SMDS_MeshNode * n4,
1586 const SMDS_MeshNode * n5,
1587 const SMDS_MeshNode * n12,
1588 const SMDS_MeshNode * n23,
1589 const SMDS_MeshNode * n34,
1590 const SMDS_MeshNode * n41,
1591 const SMDS_MeshNode * n15,
1592 const SMDS_MeshNode * n25,
1593 const SMDS_MeshNode * n35,
1594 const SMDS_MeshNode * n45)
1596 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1599 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1600 n3->GetID(), n4->GetID(), n5->GetID(),
1601 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1602 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1606 //=======================================================================
1607 //function : AddVolumeWithID
1609 //=======================================================================
1610 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1611 int n12,int n23,int n34,int n41,
1612 int n15,int n25,int n35,int n45, int ID)
1614 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1616 n15,n25,n35,n45,ID);
1617 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1622 //=======================================================================
1623 //function : AddVolumeWithID
1624 //purpose : 2d order pyramid of 13 nodes
1625 //=======================================================================
1626 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1627 const SMDS_MeshNode * n2,
1628 const SMDS_MeshNode * n3,
1629 const SMDS_MeshNode * n4,
1630 const SMDS_MeshNode * n5,
1631 const SMDS_MeshNode * n12,
1632 const SMDS_MeshNode * n23,
1633 const SMDS_MeshNode * n34,
1634 const SMDS_MeshNode * n41,
1635 const SMDS_MeshNode * n15,
1636 const SMDS_MeshNode * n25,
1637 const SMDS_MeshNode * n35,
1638 const SMDS_MeshNode * n45,
1641 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1642 n4->GetID(), n5->GetID(),
1643 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1644 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1649 //=======================================================================
1650 //function : AddVolume
1652 //=======================================================================
1653 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1654 const SMDS_MeshNode * n2,
1655 const SMDS_MeshNode * n3,
1656 const SMDS_MeshNode * n4,
1657 const SMDS_MeshNode * n5,
1658 const SMDS_MeshNode * n6,
1659 const SMDS_MeshNode * n12,
1660 const SMDS_MeshNode * n23,
1661 const SMDS_MeshNode * n31,
1662 const SMDS_MeshNode * n45,
1663 const SMDS_MeshNode * n56,
1664 const SMDS_MeshNode * n64,
1665 const SMDS_MeshNode * n14,
1666 const SMDS_MeshNode * n25,
1667 const SMDS_MeshNode * n36)
1669 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1670 n45,n56,n64,n14,n25,n36);
1672 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1673 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1674 n12->GetID(), n23->GetID(), n31->GetID(),
1675 n45->GetID(), n56->GetID(), n64->GetID(),
1676 n14->GetID(), n25->GetID(), n36->GetID());
1680 //=======================================================================
1681 //function : AddVolumeWithID
1683 //=======================================================================
1684 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1685 int n4, int n5, int n6,
1686 int n12,int n23,int n31,
1687 int n45,int n56,int n64,
1688 int n14,int n25,int n36, int ID)
1690 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1694 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1695 n45,n56,n64,n14,n25,n36);
1699 //=======================================================================
1700 //function : AddVolumeWithID
1701 //purpose : 2d order Pentahedron with 15 nodes
1702 //=======================================================================
1703 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1704 const SMDS_MeshNode * n2,
1705 const SMDS_MeshNode * n3,
1706 const SMDS_MeshNode * n4,
1707 const SMDS_MeshNode * n5,
1708 const SMDS_MeshNode * n6,
1709 const SMDS_MeshNode * n12,
1710 const SMDS_MeshNode * n23,
1711 const SMDS_MeshNode * n31,
1712 const SMDS_MeshNode * n45,
1713 const SMDS_MeshNode * n56,
1714 const SMDS_MeshNode * n64,
1715 const SMDS_MeshNode * n14,
1716 const SMDS_MeshNode * n25,
1717 const SMDS_MeshNode * n36,
1720 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1721 n4->GetID(), n5->GetID(), n6->GetID(),
1722 n12->GetID(), n23->GetID(), n31->GetID(),
1723 n45->GetID(), n56->GetID(), n64->GetID(),
1724 n14->GetID(), n25->GetID(), n36->GetID(),
1729 //=======================================================================
1730 //function : AddVolume
1732 //=======================================================================
1733 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1734 const SMDS_MeshNode * n2,
1735 const SMDS_MeshNode * n3,
1736 const SMDS_MeshNode * n4,
1737 const SMDS_MeshNode * n5,
1738 const SMDS_MeshNode * n6,
1739 const SMDS_MeshNode * n7,
1740 const SMDS_MeshNode * n8,
1741 const SMDS_MeshNode * n12,
1742 const SMDS_MeshNode * n23,
1743 const SMDS_MeshNode * n34,
1744 const SMDS_MeshNode * n41,
1745 const SMDS_MeshNode * n56,
1746 const SMDS_MeshNode * n67,
1747 const SMDS_MeshNode * n78,
1748 const SMDS_MeshNode * n85,
1749 const SMDS_MeshNode * n15,
1750 const SMDS_MeshNode * n26,
1751 const SMDS_MeshNode * n37,
1752 const SMDS_MeshNode * n48)
1754 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1759 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1760 n3->GetID(), n4->GetID(), n5->GetID(),
1761 n6->GetID(), n7->GetID(), n8->GetID(),
1762 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1763 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1764 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1768 //=======================================================================
1769 //function : AddVolumeWithID
1771 //=======================================================================
1772 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1773 int n5, int n6, int n7, int n8,
1774 int n12,int n23,int n34,int n41,
1775 int n56,int n67,int n78,int n85,
1776 int n15,int n26,int n37,int n48, int ID)
1778 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1781 n15,n26,n37,n48,ID);
1782 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1783 n56,n67,n78,n85,n15,n26,n37,n48);
1787 //=======================================================================
1788 //function : AddVolumeWithID
1789 //purpose : 2d order Hexahedrons with 20 nodes
1790 //=======================================================================
1791 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1792 const SMDS_MeshNode * n2,
1793 const SMDS_MeshNode * n3,
1794 const SMDS_MeshNode * n4,
1795 const SMDS_MeshNode * n5,
1796 const SMDS_MeshNode * n6,
1797 const SMDS_MeshNode * n7,
1798 const SMDS_MeshNode * n8,
1799 const SMDS_MeshNode * n12,
1800 const SMDS_MeshNode * n23,
1801 const SMDS_MeshNode * n34,
1802 const SMDS_MeshNode * n41,
1803 const SMDS_MeshNode * n56,
1804 const SMDS_MeshNode * n67,
1805 const SMDS_MeshNode * n78,
1806 const SMDS_MeshNode * n85,
1807 const SMDS_MeshNode * n15,
1808 const SMDS_MeshNode * n26,
1809 const SMDS_MeshNode * n37,
1810 const SMDS_MeshNode * n48,
1813 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1814 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1815 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1816 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1817 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1821 void SMESHDS_Mesh::compactMesh()
1823 int newNodeSize = 0;
1824 int nbNodes = myNodes.size();
1825 int nbVtkNodes = myGrid->GetNumberOfPoints();
1826 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1827 int nbNodeTemp = nbVtkNodes;
1828 if (nbNodes > nbVtkNodes)
1829 nbNodeTemp = nbNodes;
1830 vector<int> idNodesOldToNew;
1831 idNodesOldToNew.clear();
1832 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1834 for (int i = 0; i < nbNodes; i++)
1838 int vtkid = myNodes[i]->getVtkId();
1839 idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
1843 bool areNodesModified = (newNodeSize < nbVtkNodes);
1844 MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
1845 areNodesModified = true;
1847 int newCellSize = 0;
1848 int nbCells = myCells.size();
1849 int nbVtkCells = myGrid->GetNumberOfCells();
1850 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1851 int nbCellTemp = nbVtkCells;
1852 if (nbCells > nbVtkCells)
1853 nbCellTemp = nbCells;
1854 vector<int> idCellsOldToNew;
1855 idCellsOldToNew.clear();
1856 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1858 for (int i = 0; i < nbCells; i++)
1862 // //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
1863 // int vtkid = myCells[i]->getVtkId();
1864 // idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
1868 if (areNodesModified)
1869 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1871 myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
1873 int nbVtkPts = myGrid->GetNumberOfPoints();
1874 nbVtkCells = myGrid->GetNumberOfCells();
1875 if (nbVtkPts != newNodeSize)
1877 MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
1878 if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
1880 if (nbVtkCells != newCellSize)
1882 MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
1883 if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
1886 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1888 if (areNodesModified)
1890 MESSAGE("-------------- modify myNodes");
1891 SetOfNodes newNodes;
1892 newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
1894 for (int i = 0; i < nbNodes; i++)
1898 newSmdsId++; // SMDS id start to 1
1899 int oldVtkId = myNodes[i]->getVtkId();
1900 int newVtkId = idNodesOldToNew[oldVtkId];
1901 //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
1902 myNodes[i]->setVtkId(newVtkId);
1903 myNodes[i]->setId(newSmdsId);
1904 newNodes[newSmdsId] = myNodes[i];
1905 //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
1908 myNodes.swap(newNodes);
1909 this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
1910 MESSAGE("myNodes.size " << myNodes.size());
1913 // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
1915 int vtkIndexSize = myCellIdVtkToSmds.size();
1917 for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
1919 int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
1922 int newVtkId = idCellsOldToNew[oldVtkId];
1923 if (newVtkId > maxVtkId)
1924 maxVtkId = newVtkId;
1925 //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
1926 myCells[oldSmdsId]->setVtkId(newVtkId);
1929 // MESSAGE("myCells.size()=" << myCells.size()
1930 // << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
1931 // << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1933 SetOfCells newCells;
1934 //vector<int> newSmdsToVtk;
1935 vector<int> newVtkToSmds;
1937 assert(maxVtkId < newCellSize);
1938 newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
1939 //newSmdsToVtk.resize(newCellSize+1, -1);
1940 newVtkToSmds.resize(newCellSize+1, -1);
1942 int myCellsSize = myCells.size();
1944 for (int i = 0; i < myCellsSize; i++)
1948 newSmdsId++; // SMDS id start to 1
1949 assert(newSmdsId <= newCellSize);
1950 newCells[newSmdsId] = myCells[i];
1951 newCells[newSmdsId]->setId(newSmdsId);
1952 //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
1953 int idvtk = myCells[i]->getVtkId();
1954 //newSmdsToVtk[newSmdsId] = idvtk;
1955 assert(idvtk < newCellSize);
1956 newVtkToSmds[idvtk] = newSmdsId;
1960 myCells.swap(newCells);
1961 //myCellIdSmdsToVtk.swap(newSmdsToVtk);
1962 myCellIdVtkToSmds.swap(newVtkToSmds);
1963 MESSAGE("myCells.size()=" << myCells.size()
1964 << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1965 this->myElementIDFactory->emptyPool(newSmdsId);
1967 this->myScript->SetModified(true); // notify GUI client for buildPrs when update
1969 // --- compact list myNodes and myElements in submeshes
1971 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1972 for(; it != myShapeIndexToSubMesh.end(); ++it)
1974 (*it).second->compactList();
1979 void SMESHDS_Mesh::CleanDownWardConnectivity()
1981 myGrid->CleanDownwardConnectivity();
1984 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
1986 myGrid->BuildDownwardConnectivity(withEdges);
1989 /*! change some nodes in cell without modifying type or internal connectivity.
1990 * Nodes inverse connectivity is maintained up to date.
1991 * @param vtkVolId vtk id of the cell.
1992 * @param localClonedNodeIds map old node id to new node id.
1993 * @return ok if success.
1995 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
1997 myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);