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 //=======================================================================
1149 //function : GetScript
1151 //=======================================================================
1152 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1157 //=======================================================================
1158 //function : ClearScript
1160 //=======================================================================
1161 void SMESHDS_Mesh::ClearScript()
1166 //=======================================================================
1167 //function : HasMeshElements
1169 //=======================================================================
1170 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1172 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1173 int Index = myIndexToShape.FindIndex(S);
1174 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1177 //=======================================================================
1178 //function : HasHypothesis
1180 //=======================================================================
1181 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1183 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1186 //=======================================================================
1187 //function : NewSubMesh
1189 //=======================================================================
1190 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1192 SMESHDS_SubMesh* SM = 0;
1193 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1194 if (anIter == myShapeIndexToSubMesh.end())
1196 SM = new SMESHDS_SubMesh(this, Index);
1197 myShapeIndexToSubMesh[Index]=SM;
1200 SM = anIter->second;
1204 //=======================================================================
1205 //function : AddCompoundSubmesh
1207 //=======================================================================
1209 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1210 TopAbs_ShapeEnum type)
1213 if ( IsGroupOfSubShapes( S ))
1215 aMainIndex = myIndexToShape.Add( S );
1216 bool all = ( type == TopAbs_SHAPE );
1217 if ( all ) // corresponding simple submesh may exist
1218 aMainIndex = -aMainIndex;
1219 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1220 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1221 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1223 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1224 int typeLimit = all ? TopAbs_VERTEX : type;
1225 for ( ; shapeType <= typeLimit; shapeType++ )
1227 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1228 for ( ; exp.More(); exp.Next() )
1230 int index = myIndexToShape.FindIndex( exp.Current() );
1232 aNewSub->AddSubMesh( NewSubMesh( index ));
1240 //=======================================================================
1241 //function : IndexToShape
1243 //=======================================================================
1244 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1248 return myIndexToShape.FindKey(ShapeIndex);
1250 catch ( Standard_OutOfRange )
1253 static TopoDS_Shape nullShape;
1257 //================================================================================
1259 * \brief Return max index of sub-mesh
1261 //================================================================================
1263 int SMESHDS_Mesh::MaxSubMeshIndex() const
1265 return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1268 //=======================================================================
1269 //function : ShapeToIndex
1271 //=======================================================================
1272 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1274 if (myShape.IsNull())
1275 MESSAGE("myShape is NULL");
1277 int index = myIndexToShape.FindIndex(S);
1282 //=======================================================================
1283 //function : SetNodeOnVolume
1285 //=======================================================================
1286 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1288 //add(aNode, getSubmesh(Index));
1289 if ( add( aNode, getSubmesh( Index )))
1290 ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1293 //=======================================================================
1294 //function : SetNodeOnFace
1296 //=======================================================================
1297 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1299 //Set Position on Node
1300 if ( add( aNode, getSubmesh( Index )))
1301 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1304 //=======================================================================
1305 //function : SetNodeOnEdge
1307 //=======================================================================
1308 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1312 //Set Position on Node
1313 if ( add( aNode, getSubmesh( Index )))
1314 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1317 //=======================================================================
1318 //function : SetNodeOnVertex
1320 //=======================================================================
1321 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1323 //Set Position on Node
1324 if ( add( aNode, getSubmesh( Index )))
1325 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1328 //=======================================================================
1329 //function : SetMeshElementOnShape
1331 //=======================================================================
1332 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1335 add( anElement, getSubmesh( Index ));
1338 //=======================================================================
1339 //function : ~SMESHDS_Mesh
1341 //=======================================================================
1342 SMESHDS_Mesh::~SMESHDS_Mesh()
1347 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1348 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1349 delete i_sm->second;
1353 //********************************************************************
1354 //********************************************************************
1355 //******** *********
1356 //***** Methods for addition of quadratic elements ******
1357 //******** *********
1358 //********************************************************************
1359 //********************************************************************
1361 //=======================================================================
1362 //function : AddEdgeWithID
1364 //=======================================================================
1365 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1367 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1368 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1372 //=======================================================================
1373 //function : AddEdge
1375 //=======================================================================
1376 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1377 const SMDS_MeshNode* n2,
1378 const SMDS_MeshNode* n12)
1380 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1381 if(anElem) myScript->AddEdge(anElem->GetID(),
1388 //=======================================================================
1389 //function : AddEdgeWithID
1391 //=======================================================================
1392 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1393 const SMDS_MeshNode * n2,
1394 const SMDS_MeshNode * n12,
1397 return AddEdgeWithID(n1->GetID(),
1404 //=======================================================================
1405 //function : AddFace
1407 //=======================================================================
1408 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1409 const SMDS_MeshNode * n2,
1410 const SMDS_MeshNode * n3,
1411 const SMDS_MeshNode * n12,
1412 const SMDS_MeshNode * n23,
1413 const SMDS_MeshNode * n31)
1415 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1416 if(anElem) myScript->AddFace(anElem->GetID(),
1417 n1->GetID(), n2->GetID(), n3->GetID(),
1418 n12->GetID(), n23->GetID(), n31->GetID());
1422 //=======================================================================
1423 //function : AddFaceWithID
1425 //=======================================================================
1426 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1427 int n12,int n23,int n31, int ID)
1429 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1430 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1434 //=======================================================================
1435 //function : AddFaceWithID
1437 //=======================================================================
1438 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1439 const SMDS_MeshNode * n2,
1440 const SMDS_MeshNode * n3,
1441 const SMDS_MeshNode * n12,
1442 const SMDS_MeshNode * n23,
1443 const SMDS_MeshNode * n31,
1446 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1447 n12->GetID(), n23->GetID(), n31->GetID(),
1452 //=======================================================================
1453 //function : AddFace
1455 //=======================================================================
1456 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1457 const SMDS_MeshNode * n2,
1458 const SMDS_MeshNode * n3,
1459 const SMDS_MeshNode * n4,
1460 const SMDS_MeshNode * n12,
1461 const SMDS_MeshNode * n23,
1462 const SMDS_MeshNode * n34,
1463 const SMDS_MeshNode * n41)
1465 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1466 if(anElem) myScript->AddFace(anElem->GetID(),
1467 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1468 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1472 //=======================================================================
1473 //function : AddFaceWithID
1475 //=======================================================================
1476 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1477 int n12,int n23,int n34,int n41, int ID)
1479 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1480 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1484 //=======================================================================
1485 //function : AddFaceWithID
1487 //=======================================================================
1488 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1489 const SMDS_MeshNode * n2,
1490 const SMDS_MeshNode * n3,
1491 const SMDS_MeshNode * n4,
1492 const SMDS_MeshNode * n12,
1493 const SMDS_MeshNode * n23,
1494 const SMDS_MeshNode * n34,
1495 const SMDS_MeshNode * n41,
1498 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1499 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1504 //=======================================================================
1505 //function : AddVolume
1507 //=======================================================================
1508 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1509 const SMDS_MeshNode * n2,
1510 const SMDS_MeshNode * n3,
1511 const SMDS_MeshNode * n4,
1512 const SMDS_MeshNode * n12,
1513 const SMDS_MeshNode * n23,
1514 const SMDS_MeshNode * n31,
1515 const SMDS_MeshNode * n14,
1516 const SMDS_MeshNode * n24,
1517 const SMDS_MeshNode * n34)
1519 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1520 if(anElem) myScript->AddVolume(anElem->GetID(),
1521 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1522 n12->GetID(), n23->GetID(), n31->GetID(),
1523 n14->GetID(), n24->GetID(), n34->GetID());
1527 //=======================================================================
1528 //function : AddVolumeWithID
1530 //=======================================================================
1531 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1532 int n12,int n23,int n31,
1533 int n14,int n24,int n34, int ID)
1535 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1536 n31,n14,n24,n34,ID);
1537 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1541 //=======================================================================
1542 //function : AddVolumeWithID
1543 //purpose : 2d order tetrahedron of 10 nodes
1544 //=======================================================================
1545 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1546 const SMDS_MeshNode * n2,
1547 const SMDS_MeshNode * n3,
1548 const SMDS_MeshNode * n4,
1549 const SMDS_MeshNode * n12,
1550 const SMDS_MeshNode * n23,
1551 const SMDS_MeshNode * n31,
1552 const SMDS_MeshNode * n14,
1553 const SMDS_MeshNode * n24,
1554 const SMDS_MeshNode * n34,
1557 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1558 n12->GetID(), n23->GetID(), n31->GetID(),
1559 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1563 //=======================================================================
1564 //function : AddVolume
1566 //=======================================================================
1567 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1568 const SMDS_MeshNode * n2,
1569 const SMDS_MeshNode * n3,
1570 const SMDS_MeshNode * n4,
1571 const SMDS_MeshNode * n5,
1572 const SMDS_MeshNode * n12,
1573 const SMDS_MeshNode * n23,
1574 const SMDS_MeshNode * n34,
1575 const SMDS_MeshNode * n41,
1576 const SMDS_MeshNode * n15,
1577 const SMDS_MeshNode * n25,
1578 const SMDS_MeshNode * n35,
1579 const SMDS_MeshNode * n45)
1581 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1584 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1585 n3->GetID(), n4->GetID(), n5->GetID(),
1586 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1587 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1591 //=======================================================================
1592 //function : AddVolumeWithID
1594 //=======================================================================
1595 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1596 int n12,int n23,int n34,int n41,
1597 int n15,int n25,int n35,int n45, int ID)
1599 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1601 n15,n25,n35,n45,ID);
1602 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1607 //=======================================================================
1608 //function : AddVolumeWithID
1609 //purpose : 2d order pyramid of 13 nodes
1610 //=======================================================================
1611 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1612 const SMDS_MeshNode * n2,
1613 const SMDS_MeshNode * n3,
1614 const SMDS_MeshNode * n4,
1615 const SMDS_MeshNode * n5,
1616 const SMDS_MeshNode * n12,
1617 const SMDS_MeshNode * n23,
1618 const SMDS_MeshNode * n34,
1619 const SMDS_MeshNode * n41,
1620 const SMDS_MeshNode * n15,
1621 const SMDS_MeshNode * n25,
1622 const SMDS_MeshNode * n35,
1623 const SMDS_MeshNode * n45,
1626 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1627 n4->GetID(), n5->GetID(),
1628 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1629 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1634 //=======================================================================
1635 //function : AddVolume
1637 //=======================================================================
1638 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1639 const SMDS_MeshNode * n2,
1640 const SMDS_MeshNode * n3,
1641 const SMDS_MeshNode * n4,
1642 const SMDS_MeshNode * n5,
1643 const SMDS_MeshNode * n6,
1644 const SMDS_MeshNode * n12,
1645 const SMDS_MeshNode * n23,
1646 const SMDS_MeshNode * n31,
1647 const SMDS_MeshNode * n45,
1648 const SMDS_MeshNode * n56,
1649 const SMDS_MeshNode * n64,
1650 const SMDS_MeshNode * n14,
1651 const SMDS_MeshNode * n25,
1652 const SMDS_MeshNode * n36)
1654 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1655 n45,n56,n64,n14,n25,n36);
1657 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1658 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1659 n12->GetID(), n23->GetID(), n31->GetID(),
1660 n45->GetID(), n56->GetID(), n64->GetID(),
1661 n14->GetID(), n25->GetID(), n36->GetID());
1665 //=======================================================================
1666 //function : AddVolumeWithID
1668 //=======================================================================
1669 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1670 int n4, int n5, int n6,
1671 int n12,int n23,int n31,
1672 int n45,int n56,int n64,
1673 int n14,int n25,int n36, int ID)
1675 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1679 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1680 n45,n56,n64,n14,n25,n36);
1684 //=======================================================================
1685 //function : AddVolumeWithID
1686 //purpose : 2d order Pentahedron with 15 nodes
1687 //=======================================================================
1688 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1689 const SMDS_MeshNode * n2,
1690 const SMDS_MeshNode * n3,
1691 const SMDS_MeshNode * n4,
1692 const SMDS_MeshNode * n5,
1693 const SMDS_MeshNode * n6,
1694 const SMDS_MeshNode * n12,
1695 const SMDS_MeshNode * n23,
1696 const SMDS_MeshNode * n31,
1697 const SMDS_MeshNode * n45,
1698 const SMDS_MeshNode * n56,
1699 const SMDS_MeshNode * n64,
1700 const SMDS_MeshNode * n14,
1701 const SMDS_MeshNode * n25,
1702 const SMDS_MeshNode * n36,
1705 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1706 n4->GetID(), n5->GetID(), n6->GetID(),
1707 n12->GetID(), n23->GetID(), n31->GetID(),
1708 n45->GetID(), n56->GetID(), n64->GetID(),
1709 n14->GetID(), n25->GetID(), n36->GetID(),
1714 //=======================================================================
1715 //function : AddVolume
1717 //=======================================================================
1718 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1719 const SMDS_MeshNode * n2,
1720 const SMDS_MeshNode * n3,
1721 const SMDS_MeshNode * n4,
1722 const SMDS_MeshNode * n5,
1723 const SMDS_MeshNode * n6,
1724 const SMDS_MeshNode * n7,
1725 const SMDS_MeshNode * n8,
1726 const SMDS_MeshNode * n12,
1727 const SMDS_MeshNode * n23,
1728 const SMDS_MeshNode * n34,
1729 const SMDS_MeshNode * n41,
1730 const SMDS_MeshNode * n56,
1731 const SMDS_MeshNode * n67,
1732 const SMDS_MeshNode * n78,
1733 const SMDS_MeshNode * n85,
1734 const SMDS_MeshNode * n15,
1735 const SMDS_MeshNode * n26,
1736 const SMDS_MeshNode * n37,
1737 const SMDS_MeshNode * n48)
1739 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1744 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1745 n3->GetID(), n4->GetID(), n5->GetID(),
1746 n6->GetID(), n7->GetID(), n8->GetID(),
1747 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1748 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1749 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1753 //=======================================================================
1754 //function : AddVolumeWithID
1756 //=======================================================================
1757 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1758 int n5, int n6, int n7, int n8,
1759 int n12,int n23,int n34,int n41,
1760 int n56,int n67,int n78,int n85,
1761 int n15,int n26,int n37,int n48, int ID)
1763 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1766 n15,n26,n37,n48,ID);
1767 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1768 n56,n67,n78,n85,n15,n26,n37,n48);
1772 //=======================================================================
1773 //function : AddVolumeWithID
1774 //purpose : 2d order Hexahedrons with 20 nodes
1775 //=======================================================================
1776 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1777 const SMDS_MeshNode * n2,
1778 const SMDS_MeshNode * n3,
1779 const SMDS_MeshNode * n4,
1780 const SMDS_MeshNode * n5,
1781 const SMDS_MeshNode * n6,
1782 const SMDS_MeshNode * n7,
1783 const SMDS_MeshNode * n8,
1784 const SMDS_MeshNode * n12,
1785 const SMDS_MeshNode * n23,
1786 const SMDS_MeshNode * n34,
1787 const SMDS_MeshNode * n41,
1788 const SMDS_MeshNode * n56,
1789 const SMDS_MeshNode * n67,
1790 const SMDS_MeshNode * n78,
1791 const SMDS_MeshNode * n85,
1792 const SMDS_MeshNode * n15,
1793 const SMDS_MeshNode * n26,
1794 const SMDS_MeshNode * n37,
1795 const SMDS_MeshNode * n48,
1798 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1799 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1800 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1801 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1802 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1806 void SMESHDS_Mesh::compactMesh()
1808 int newNodeSize = 0;
1809 int nbNodes = myNodes.size();
1810 int nbVtkNodes = myGrid->GetNumberOfPoints();
1811 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1812 int nbNodeTemp = nbVtkNodes;
1813 if (nbNodes > nbVtkNodes)
1814 nbNodeTemp = nbNodes;
1815 vector<int> idNodesOldToNew;
1816 idNodesOldToNew.clear();
1817 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1819 for (int i = 0; i < nbNodes; i++)
1823 int vtkid = myNodes[i]->getVtkId();
1824 idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
1828 bool areNodesModified = (newNodeSize < nbVtkNodes);
1829 MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
1830 areNodesModified = true;
1832 int newCellSize = 0;
1833 int nbCells = myCells.size();
1834 int nbVtkCells = myGrid->GetNumberOfCells();
1835 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1836 int nbCellTemp = nbVtkCells;
1837 if (nbCells > nbVtkCells)
1838 nbCellTemp = nbCells;
1839 vector<int> idCellsOldToNew;
1840 idCellsOldToNew.clear();
1841 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1843 for (int i = 0; i < nbCells; i++)
1847 // //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
1848 // int vtkid = myCells[i]->getVtkId();
1849 // idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
1853 if (areNodesModified)
1854 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1856 myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
1858 int nbVtkPts = myGrid->GetNumberOfPoints();
1859 nbVtkCells = myGrid->GetNumberOfCells();
1860 if (nbVtkPts != newNodeSize)
1862 MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
1863 if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
1865 if (nbVtkCells != newCellSize)
1867 MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
1868 if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
1871 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1873 if (areNodesModified)
1875 MESSAGE("-------------- modify myNodes");
1876 SetOfNodes newNodes;
1877 newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
1879 for (int i = 0; i < nbNodes; i++)
1883 newSmdsId++; // SMDS id start to 1
1884 int oldVtkId = myNodes[i]->getVtkId();
1885 int newVtkId = idNodesOldToNew[oldVtkId];
1886 //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
1887 myNodes[i]->setVtkId(newVtkId);
1888 myNodes[i]->setId(newSmdsId);
1889 newNodes[newSmdsId] = myNodes[i];
1890 //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
1893 myNodes.swap(newNodes);
1894 this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
1895 MESSAGE("myNodes.size " << myNodes.size());
1898 // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
1900 int vtkIndexSize = myCellIdVtkToSmds.size();
1902 for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
1904 int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
1907 int newVtkId = idCellsOldToNew[oldVtkId];
1908 if (newVtkId > maxVtkId)
1909 maxVtkId = newVtkId;
1910 //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
1911 myCells[oldSmdsId]->setVtkId(newVtkId);
1914 // MESSAGE("myCells.size()=" << myCells.size()
1915 // << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
1916 // << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1918 SetOfCells newCells;
1919 //vector<int> newSmdsToVtk;
1920 vector<int> newVtkToSmds;
1922 assert(maxVtkId < newCellSize);
1923 newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
1924 //newSmdsToVtk.resize(newCellSize+1, -1);
1925 newVtkToSmds.resize(newCellSize+1, -1);
1927 int myCellsSize = myCells.size();
1929 for (int i = 0; i < myCellsSize; i++)
1933 newSmdsId++; // SMDS id start to 1
1934 assert(newSmdsId <= newCellSize);
1935 newCells[newSmdsId] = myCells[i];
1936 newCells[newSmdsId]->setId(newSmdsId);
1937 //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
1938 int idvtk = myCells[i]->getVtkId();
1939 //newSmdsToVtk[newSmdsId] = idvtk;
1940 assert(idvtk < newCellSize);
1941 newVtkToSmds[idvtk] = newSmdsId;
1945 myCells.swap(newCells);
1946 //myCellIdSmdsToVtk.swap(newSmdsToVtk);
1947 myCellIdVtkToSmds.swap(newVtkToSmds);
1948 MESSAGE("myCells.size()=" << myCells.size()
1949 << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1950 this->myElementIDFactory->emptyPool(newSmdsId);
1952 this->myScript->SetModified(true); // notify GUI client for buildPrs when update
1954 // --- compact list myNodes and myElements in submeshes
1956 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1957 for(; it != myShapeIndexToSubMesh.end(); ++it)
1959 (*it).second->compactList();
1964 void SMESHDS_Mesh::CleanDownWardConnectivity()
1966 myGrid->CleanDownwardConnectivity();
1969 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
1971 myGrid->BuildDownwardConnectivity(withEdges);
1974 /*! change some nodes in cell without modifying type or internal connectivity.
1975 * Nodes inverse connectivity is maintained up to date.
1976 * @param vtkVolId vtk id of the cell.
1977 * @param localClonedNodeIds map old node id to new node id.
1978 * @return ok if success.
1980 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
1982 myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);