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 //================================================================================
80 void SMESHDS_Mesh::SetPersistentId(int id)
85 //================================================================================
87 * \brief Return ID persistent during lifecycle
89 //================================================================================
91 int SMESHDS_Mesh::GetPersistentId() const
93 return myPersistentID;
96 //=======================================================================
97 //function : ShapeToMesh
99 //=======================================================================
100 void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
102 if ( !myShape.IsNull() && S.IsNull() )
104 // removal of a shape to mesh, delete ...
106 myShapeToHypothesis.Clear();
107 // - shape indices in SMDS_Position of nodes
108 map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
109 for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
110 if ( !i_sub->second->IsComplexSubmesh() ) {
111 SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
112 while ( nIt->more() )
113 i_sub->second->RemoveNode(nIt->next(), false);
117 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
118 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
120 myShapeIndexToSubMesh.clear();
121 myIndexToShape.Clear();
122 // - groups on geometry
123 set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
124 while ( gr != myGroups.end() ) {
125 if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
126 myGroups.erase( gr++ );
134 TopExp::MapShapes(myShape, myIndexToShape);
138 //=======================================================================
139 //function : AddHypothesis
141 //=======================================================================
143 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
144 const SMESHDS_Hypothesis * H)
146 if (!myShapeToHypothesis.IsBound(SS.Oriented(TopAbs_FORWARD))) {
147 list<const SMESHDS_Hypothesis *> aList;
148 myShapeToHypothesis.Bind(SS.Oriented(TopAbs_FORWARD), aList);
150 list<const SMESHDS_Hypothesis *>& alist =
151 myShapeToHypothesis(SS.Oriented(TopAbs_FORWARD)); // ignore orientation of SS
153 //Check if the Hypothesis is still present
154 list<const SMESHDS_Hypothesis*>::iterator ith = find(alist.begin(),alist.end(), H );
156 if (alist.end() != ith) return false;
162 //=======================================================================
163 //function : RemoveHypothesis
165 //=======================================================================
167 bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
168 const SMESHDS_Hypothesis * H)
170 if( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) )
172 list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis.ChangeFind( S.Oriented(TopAbs_FORWARD) );
173 list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
174 if (ith != alist.end())
183 //=======================================================================
186 //=======================================================================
187 SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
188 SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
189 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
193 SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
194 SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
195 if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
199 //=======================================================================
200 //function : MoveNode
202 //=======================================================================
203 void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
205 SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
207 myScript->MoveNode(n->GetID(), x, y, z);
210 //=======================================================================
211 //function : ChangeElementNodes
213 //=======================================================================
215 bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
216 const SMDS_MeshNode * nodes[],
219 //MESSAGE("SMESHDS_Mesh::ChangeElementNodes");
220 if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
223 vector<int> IDs( nbnodes );
224 for ( int i = 0; i < nbnodes; i++ )
225 IDs [ i ] = nodes[ i ]->GetID();
226 myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
231 //=======================================================================
232 //function : ChangePolygonNodes
234 //=======================================================================
235 bool SMESHDS_Mesh::ChangePolygonNodes
236 (const SMDS_MeshElement * elem,
237 vector<const SMDS_MeshNode*> nodes)
239 ASSERT(nodes.size() > 3);
241 return ChangeElementNodes(elem, &nodes[0], nodes.size());
244 //=======================================================================
245 //function : ChangePolyhedronNodes
247 //=======================================================================
248 bool SMESHDS_Mesh::ChangePolyhedronNodes
249 (const SMDS_MeshElement * elem,
250 std::vector<const SMDS_MeshNode*> nodes,
251 std::vector<int> quantities)
253 ASSERT(nodes.size() > 3);
255 if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
258 int i, len = nodes.size();
259 std::vector<int> nodes_ids (len);
260 for (i = 0; i < len; i++) {
261 nodes_ids[i] = nodes[i]->GetID();
263 myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
268 //=======================================================================
269 //function : Renumber
271 //=======================================================================
273 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
275 // TODO not possible yet to have node numbers not starting to O and continuous.
276 if (!this->isCompacted())
278 // SMDS_Mesh::Renumber( isNodes, startID, deltaID );
279 // myScript->Renumber( isNodes, startID, deltaID );
282 //=======================================================================
283 //function : Add0DElement
285 //=======================================================================
286 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
288 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
289 if (anElem) myScript->Add0DElement(ID, nodeID);
293 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
294 (const SMDS_MeshNode * node, int ID)
296 return Add0DElementWithID(node->GetID(), ID);
299 SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
301 SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
302 if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
306 //=======================================================================
307 //function :AddEdgeWithID
309 //=======================================================================
310 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
312 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
313 if(anElem) myScript->AddEdge(ID,n1,n2);
317 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
318 const SMDS_MeshNode * n2,
321 return AddEdgeWithID(n1->GetID(),
326 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
327 const SMDS_MeshNode * n2)
329 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
330 if(anElem) myScript->AddEdge(anElem->GetID(),
336 //=======================================================================
339 //=======================================================================
340 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
342 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
343 if(anElem) myScript->AddFace(ID,n1,n2,n3);
347 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
348 const SMDS_MeshNode * n2,
349 const SMDS_MeshNode * n3,
352 return AddFaceWithID(n1->GetID(),
358 SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
359 const SMDS_MeshNode * n2,
360 const SMDS_MeshNode * n3)
362 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
363 if(anElem) myScript->AddFace(anElem->GetID(),
370 //=======================================================================
373 //=======================================================================
374 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
376 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
377 if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
381 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
382 const SMDS_MeshNode * n2,
383 const SMDS_MeshNode * n3,
384 const SMDS_MeshNode * n4,
387 return AddFaceWithID(n1->GetID(),
394 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
395 const SMDS_MeshNode * n2,
396 const SMDS_MeshNode * n3,
397 const SMDS_MeshNode * n4)
399 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
400 if(anElem) myScript->AddFace(anElem->GetID(),
408 //=======================================================================
409 //function :AddVolume
411 //=======================================================================
412 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
414 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
415 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
419 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
420 const SMDS_MeshNode * n2,
421 const SMDS_MeshNode * n3,
422 const SMDS_MeshNode * n4,
425 return AddVolumeWithID(n1->GetID(),
432 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
433 const SMDS_MeshNode * n2,
434 const SMDS_MeshNode * n3,
435 const SMDS_MeshNode * n4)
437 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
438 if(anElem) myScript->AddVolume(anElem->GetID(),
446 //=======================================================================
447 //function :AddVolume
449 //=======================================================================
450 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
452 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
453 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
457 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
458 const SMDS_MeshNode * n2,
459 const SMDS_MeshNode * n3,
460 const SMDS_MeshNode * n4,
461 const SMDS_MeshNode * n5,
464 return AddVolumeWithID(n1->GetID(),
472 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
473 const SMDS_MeshNode * n2,
474 const SMDS_MeshNode * n3,
475 const SMDS_MeshNode * n4,
476 const SMDS_MeshNode * n5)
478 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
479 if(anElem) myScript->AddVolume(anElem->GetID(),
488 //=======================================================================
489 //function :AddVolume
491 //=======================================================================
492 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
494 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
495 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
499 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
500 const SMDS_MeshNode * n2,
501 const SMDS_MeshNode * n3,
502 const SMDS_MeshNode * n4,
503 const SMDS_MeshNode * n5,
504 const SMDS_MeshNode * n6,
507 return AddVolumeWithID(n1->GetID(),
516 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
517 const SMDS_MeshNode * n2,
518 const SMDS_MeshNode * n3,
519 const SMDS_MeshNode * n4,
520 const SMDS_MeshNode * n5,
521 const SMDS_MeshNode * n6)
523 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
524 if(anElem) myScript->AddVolume(anElem->GetID(),
534 //=======================================================================
535 //function :AddVolume
537 //=======================================================================
538 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
540 SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
541 if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
545 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
546 const SMDS_MeshNode * n2,
547 const SMDS_MeshNode * n3,
548 const SMDS_MeshNode * n4,
549 const SMDS_MeshNode * n5,
550 const SMDS_MeshNode * n6,
551 const SMDS_MeshNode * n7,
552 const SMDS_MeshNode * n8,
555 return AddVolumeWithID(n1->GetID(),
566 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
567 const SMDS_MeshNode * n2,
568 const SMDS_MeshNode * n3,
569 const SMDS_MeshNode * n4,
570 const SMDS_MeshNode * n5,
571 const SMDS_MeshNode * n6,
572 const SMDS_MeshNode * n7,
573 const SMDS_MeshNode * n8)
575 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
576 if(anElem) myScript->AddVolume(anElem->GetID(),
588 //=======================================================================
589 //function : AddPolygonalFace
591 //=======================================================================
592 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
595 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
597 myScript->AddPolygonalFace(ID, nodes_ids);
602 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
603 (const std::vector<const SMDS_MeshNode*>& nodes,
606 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
608 int i, len = nodes.size();
609 std::vector<int> nodes_ids (len);
610 for (i = 0; i < len; i++) {
611 nodes_ids[i] = nodes[i]->GetID();
613 myScript->AddPolygonalFace(ID, nodes_ids);
618 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
619 (const std::vector<const SMDS_MeshNode*>& nodes)
621 SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
623 int i, len = nodes.size();
624 std::vector<int> nodes_ids (len);
625 for (i = 0; i < len; i++) {
626 nodes_ids[i] = nodes[i]->GetID();
628 myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
633 //=======================================================================
634 //function : AddPolyhedralVolume
636 //=======================================================================
637 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
638 const std::vector<int>& quantities,
641 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
643 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
648 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
649 (const std::vector<const SMDS_MeshNode*>& nodes,
650 const std::vector<int>& quantities,
653 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
655 int i, len = nodes.size();
656 std::vector<int> nodes_ids (len);
657 for (i = 0; i < len; i++) {
658 nodes_ids[i] = nodes[i]->GetID();
660 myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
665 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
666 (const std::vector<const SMDS_MeshNode*>& nodes,
667 const std::vector<int>& quantities)
669 SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
671 int i, len = nodes.size();
672 std::vector<int> nodes_ids (len);
673 for (i = 0; i < len; i++) {
674 nodes_ids[i] = nodes[i]->GetID();
676 myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
681 //=======================================================================
682 //function : removeFromContainers
684 //=======================================================================
686 static void removeFromContainers (map<int,SMESHDS_SubMesh*>& theSubMeshes,
687 set<SMESHDS_GroupBase*>& theGroups,
688 list<const SMDS_MeshElement*>& theElems,
691 if ( theElems.empty() )
695 // Element can belong to several groups
696 if ( !theGroups.empty() )
698 set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
699 for ( ; GrIt != theGroups.end(); GrIt++ )
701 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
702 if ( !group || group->IsEmpty() ) continue;
704 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
705 for ( ; elIt != theElems.end(); elIt++ )
707 group->SMDSGroup().Remove( *elIt );
708 if ( group->IsEmpty() ) break;
713 const bool deleted=true;
715 // Rm from sub-meshes
716 // Element should belong to only one sub-mesh
717 if ( !theSubMeshes.empty() )
719 SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->getParent();
720 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
722 for ( ; elIt != theElems.end(); ++elIt )
723 if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
724 sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
727 for ( ; elIt != theElems.end(); ++elIt )
728 if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
729 sm->RemoveElement( *elIt, deleted );
734 //=======================================================================
735 //function : RemoveNode
737 //=======================================================================
738 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
740 if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
742 SMESHDS_SubMesh* subMesh=0;
743 map<int,SMESHDS_SubMesh*>::iterator SubIt =
744 myShapeIndexToSubMesh.find( n->getshapeId() );
745 if ( SubIt != myShapeIndexToSubMesh.end() )
746 subMesh = SubIt->second;
748 SubIt = myShapeIndexToSubMesh.begin();
749 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
750 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
751 subMesh = SubIt->second;
753 RemoveFreeNode( n, subMesh, true);
757 myScript->RemoveNode(n->GetID());
759 list<const SMDS_MeshElement *> removedElems;
760 list<const SMDS_MeshElement *> removedNodes;
762 SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
764 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
765 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
768 //=======================================================================
769 //function : RemoveFreeNode
771 //=======================================================================
772 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
773 SMESHDS_SubMesh * subMesh,
776 myScript->RemoveNode(n->GetID());
779 // Node can belong to several groups
780 if (fromGroups && !myGroups.empty()) {
781 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
782 for (; GrIt != myGroups.end(); GrIt++) {
783 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
784 if (!group || group->IsEmpty()) continue;
785 group->SMDSGroup().Remove(n);
790 // Node should belong to only one sub-mesh
792 subMesh->RemoveNode(n,/*deleted=*/false);
794 SMDS_Mesh::RemoveFreeElement(n);
797 //=======================================================================
798 //function : RemoveElement
800 //========================================================================
801 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
803 if (elt->GetType() == SMDSAbs_Node)
805 RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
808 if (!hasConstructionEdges() && !hasConstructionFaces())
810 SMESHDS_SubMesh* subMesh=0;
811 map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
812 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
813 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
814 subMesh = SubIt->second;
815 //MESSAGE("subMesh " << elt->getshapeId());
816 RemoveFreeElement( elt, subMesh, true);
820 myScript->RemoveElement(elt->GetID());
822 list<const SMDS_MeshElement *> removedElems;
823 list<const SMDS_MeshElement *> removedNodes;
825 SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
827 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
830 //=======================================================================
831 //function : RemoveFreeElement
833 //========================================================================
834 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
835 SMESHDS_SubMesh * subMesh,
838 //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
839 if (elt->GetType() == SMDSAbs_Node) {
840 RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
844 if (hasConstructionEdges() || hasConstructionFaces())
845 // this methods is only for meshes without descendants
848 myScript->RemoveElement(elt->GetID());
851 // Node can belong to several groups
852 if ( fromGroups && !myGroups.empty() ) {
853 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
854 for (; GrIt != myGroups.end(); GrIt++) {
855 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
856 if (group && !group->IsEmpty())
857 group->SMDSGroup().Remove(elt);
862 // Element should belong to only one sub-mesh
864 subMesh->RemoveElement(elt, /*deleted=*/false);
866 SMDS_Mesh::RemoveFreeElement(elt);
869 //================================================================================
871 * \brief Remove all data from the mesh
873 //================================================================================
875 void SMESHDS_Mesh::ClearMesh()
877 myScript->ClearMesh();
881 map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
882 for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
883 sub->second->Clear();
886 TGroups::iterator group, groupEnd = myGroups.end();
887 for ( group = myGroups.begin(); group != groupEnd; ++group ) {
888 if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
889 SMDSAbs_ElementType groupType = g->GetType();
891 g->SetType( groupType );
896 //================================================================================
898 * \brief return submesh by shape
899 * \param shape - the subshape
900 * \retval SMESHDS_SubMesh* - the found submesh
902 * search of submeshes is optimized
904 //================================================================================
906 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
908 if ( shape.IsNull() )
911 if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
914 getSubmesh( ShapeToIndex( shape ));
915 myCurSubShape = shape;
919 //================================================================================
921 * \brief return submesh by subshape index
922 * \param Index - the subshape index
923 * \retval SMESHDS_SubMesh* - the found submesh
924 * search of submeshes is optimized
926 //================================================================================
928 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
930 //Update or build submesh
931 if ( Index != myCurSubID ) {
932 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
933 if ( it == myShapeIndexToSubMesh.end() )
934 it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
935 myCurSubMesh = it->second;
937 myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
942 //================================================================================
944 * \brief Add element or node to submesh
945 * \param elem - element to add
946 * \param subMesh - submesh to be filled in
948 //================================================================================
950 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
952 if ( elem && subMesh ) {
953 if ( elem->GetType() == SMDSAbs_Node )
954 subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
956 subMesh->AddElement( elem );
962 //=======================================================================
963 //function : SetNodeOnVolume
965 //=======================================================================
966 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
967 const TopoDS_Shell & S)
969 if ( add( aNode, getSubmesh(S) ))
970 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
973 //=======================================================================
974 //function : SetNodeOnVolume
976 //=======================================================================
977 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
978 const TopoDS_Solid & S)
980 if ( add( aNode, getSubmesh(S) ))
981 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
984 //=======================================================================
985 //function : SetNodeOnFace
987 //=======================================================================
988 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
989 const TopoDS_Face & S,
993 if ( add( aNode, getSubmesh(S) ))
994 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
997 //=======================================================================
998 //function : SetNodeOnEdge
1000 //=======================================================================
1001 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
1002 const TopoDS_Edge & S,
1005 if ( add( aNode, getSubmesh(S) ))
1006 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1009 //=======================================================================
1010 //function : SetNodeOnVertex
1012 //=======================================================================
1013 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
1014 const TopoDS_Vertex & S)
1016 if ( add( aNode, getSubmesh(S) ))
1017 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1020 //=======================================================================
1021 //function : UnSetNodeOnShape
1023 //=======================================================================
1024 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1026 int shapeId = aNode->getshapeId();
1029 map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1030 if (it != myShapeIndexToSubMesh.end())
1031 it->second->RemoveNode(aNode, /*deleted=*/false);
1035 //=======================================================================
1036 //function : SetMeshElementOnShape
1038 //=======================================================================
1039 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1040 const TopoDS_Shape & S)
1042 add( anElement, getSubmesh(S) );
1045 //=======================================================================
1046 //function : UnSetMeshElementOnShape
1048 //=======================================================================
1049 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1050 const TopoDS_Shape & S)
1052 int Index = myIndexToShape.FindIndex(S);
1054 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1055 if ( it != myShapeIndexToSubMesh.end() )
1057 if (elem->GetType() == SMDSAbs_Node)
1058 it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1060 it->second->RemoveElement(elem, /*deleted=*/false);
1064 //=======================================================================
1065 //function : ShapeToMesh
1067 //=======================================================================
1068 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1073 //=======================================================================
1074 //function : IsGroupOfSubShapes
1075 //purpose : return true if at least one subshape of theShape is a subshape
1076 // of myShape or theShape == myShape
1077 //=======================================================================
1079 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1081 if ( myIndexToShape.Contains(theShape) )
1084 for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1085 if (IsGroupOfSubShapes( it.Value() ))
1091 ///////////////////////////////////////////////////////////////////////////////
1092 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1093 /// TopoDS_Shape is unknown
1094 ///////////////////////////////////////////////////////////////////////////////
1095 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1097 int Index = ShapeToIndex(S);
1098 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1099 if (anIter != myShapeIndexToSubMesh.end())
1100 return anIter->second;
1105 ///////////////////////////////////////////////////////////////////////////////
1106 /// Return the sub mesh by Id of shape it is linked to
1107 ///////////////////////////////////////////////////////////////////////////////
1108 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1110 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1111 if (anIter != myShapeIndexToSubMesh.end())
1112 return anIter->second;
1117 //=======================================================================
1118 //function : SubMeshIndices
1120 //=======================================================================
1121 list<int> SMESHDS_Mesh::SubMeshIndices() const
1123 list<int> anIndices;
1124 std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1125 for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1126 anIndices.push_back((*anIter).first);
1131 //=======================================================================
1132 //function : GetHypothesis
1134 //=======================================================================
1136 const list<const SMESHDS_Hypothesis*>&
1137 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1139 if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1140 return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1142 static list<const SMESHDS_Hypothesis*> empty;
1146 //=======================================================================
1147 //function : GetScript
1149 //=======================================================================
1150 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1155 //=======================================================================
1156 //function : ClearScript
1158 //=======================================================================
1159 void SMESHDS_Mesh::ClearScript()
1164 //=======================================================================
1165 //function : HasMeshElements
1167 //=======================================================================
1168 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1170 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1171 int Index = myIndexToShape.FindIndex(S);
1172 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1175 //=======================================================================
1176 //function : HasHypothesis
1178 //=======================================================================
1179 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1181 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1184 //=======================================================================
1185 //function : NewSubMesh
1187 //=======================================================================
1188 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1190 SMESHDS_SubMesh* SM = 0;
1191 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1192 if (anIter == myShapeIndexToSubMesh.end())
1194 SM = new SMESHDS_SubMesh(this, Index);
1195 myShapeIndexToSubMesh[Index]=SM;
1198 SM = anIter->second;
1202 //=======================================================================
1203 //function : AddCompoundSubmesh
1205 //=======================================================================
1207 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1208 TopAbs_ShapeEnum type)
1211 if ( IsGroupOfSubShapes( S ))
1213 aMainIndex = myIndexToShape.Add( S );
1214 bool all = ( type == TopAbs_SHAPE );
1215 if ( all ) // corresponding simple submesh may exist
1216 aMainIndex = -aMainIndex;
1217 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1218 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1219 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1221 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1222 int typeLimit = all ? TopAbs_VERTEX : type;
1223 for ( ; shapeType <= typeLimit; shapeType++ )
1225 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1226 for ( ; exp.More(); exp.Next() )
1228 int index = myIndexToShape.FindIndex( exp.Current() );
1230 aNewSub->AddSubMesh( NewSubMesh( index ));
1238 //=======================================================================
1239 //function : IndexToShape
1241 //=======================================================================
1242 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1246 return myIndexToShape.FindKey(ShapeIndex);
1248 catch ( Standard_OutOfRange )
1251 static TopoDS_Shape nullShape;
1255 //================================================================================
1257 * \brief Return max index of sub-mesh
1259 //================================================================================
1261 int SMESHDS_Mesh::MaxSubMeshIndex() const
1263 return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1266 //=======================================================================
1267 //function : ShapeToIndex
1269 //=======================================================================
1270 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1272 if (myShape.IsNull())
1273 MESSAGE("myShape is NULL");
1275 int index = myIndexToShape.FindIndex(S);
1280 //=======================================================================
1281 //function : SetNodeOnVolume
1283 //=======================================================================
1284 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1286 //add(aNode, getSubmesh(Index));
1287 if ( add( aNode, getSubmesh( Index )))
1288 ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1291 //=======================================================================
1292 //function : SetNodeOnFace
1294 //=======================================================================
1295 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1297 //Set Position on Node
1298 if ( add( aNode, getSubmesh( Index )))
1299 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1302 //=======================================================================
1303 //function : SetNodeOnEdge
1305 //=======================================================================
1306 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1310 //Set Position on Node
1311 if ( add( aNode, getSubmesh( Index )))
1312 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1315 //=======================================================================
1316 //function : SetNodeOnVertex
1318 //=======================================================================
1319 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1321 //Set Position on Node
1322 if ( add( aNode, getSubmesh( Index )))
1323 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1326 //=======================================================================
1327 //function : SetMeshElementOnShape
1329 //=======================================================================
1330 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1333 add( anElement, getSubmesh( Index ));
1336 //=======================================================================
1337 //function : ~SMESHDS_Mesh
1339 //=======================================================================
1340 SMESHDS_Mesh::~SMESHDS_Mesh()
1345 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1346 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1347 delete i_sm->second;
1351 //********************************************************************
1352 //********************************************************************
1353 //******** *********
1354 //***** Methods for addition of quadratic elements ******
1355 //******** *********
1356 //********************************************************************
1357 //********************************************************************
1359 //=======================================================================
1360 //function : AddEdgeWithID
1362 //=======================================================================
1363 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1365 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1366 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1370 //=======================================================================
1371 //function : AddEdge
1373 //=======================================================================
1374 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1375 const SMDS_MeshNode* n2,
1376 const SMDS_MeshNode* n12)
1378 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1379 if(anElem) myScript->AddEdge(anElem->GetID(),
1386 //=======================================================================
1387 //function : AddEdgeWithID
1389 //=======================================================================
1390 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1391 const SMDS_MeshNode * n2,
1392 const SMDS_MeshNode * n12,
1395 return AddEdgeWithID(n1->GetID(),
1402 //=======================================================================
1403 //function : AddFace
1405 //=======================================================================
1406 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1407 const SMDS_MeshNode * n2,
1408 const SMDS_MeshNode * n3,
1409 const SMDS_MeshNode * n12,
1410 const SMDS_MeshNode * n23,
1411 const SMDS_MeshNode * n31)
1413 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1414 if(anElem) myScript->AddFace(anElem->GetID(),
1415 n1->GetID(), n2->GetID(), n3->GetID(),
1416 n12->GetID(), n23->GetID(), n31->GetID());
1420 //=======================================================================
1421 //function : AddFaceWithID
1423 //=======================================================================
1424 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1425 int n12,int n23,int n31, int ID)
1427 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1428 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1432 //=======================================================================
1433 //function : AddFaceWithID
1435 //=======================================================================
1436 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1437 const SMDS_MeshNode * n2,
1438 const SMDS_MeshNode * n3,
1439 const SMDS_MeshNode * n12,
1440 const SMDS_MeshNode * n23,
1441 const SMDS_MeshNode * n31,
1444 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1445 n12->GetID(), n23->GetID(), n31->GetID(),
1450 //=======================================================================
1451 //function : AddFace
1453 //=======================================================================
1454 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1455 const SMDS_MeshNode * n2,
1456 const SMDS_MeshNode * n3,
1457 const SMDS_MeshNode * n4,
1458 const SMDS_MeshNode * n12,
1459 const SMDS_MeshNode * n23,
1460 const SMDS_MeshNode * n34,
1461 const SMDS_MeshNode * n41)
1463 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1464 if(anElem) myScript->AddFace(anElem->GetID(),
1465 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1466 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1470 //=======================================================================
1471 //function : AddFaceWithID
1473 //=======================================================================
1474 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1475 int n12,int n23,int n34,int n41, int ID)
1477 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1478 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1482 //=======================================================================
1483 //function : AddFaceWithID
1485 //=======================================================================
1486 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1487 const SMDS_MeshNode * n2,
1488 const SMDS_MeshNode * n3,
1489 const SMDS_MeshNode * n4,
1490 const SMDS_MeshNode * n12,
1491 const SMDS_MeshNode * n23,
1492 const SMDS_MeshNode * n34,
1493 const SMDS_MeshNode * n41,
1496 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1497 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1502 //=======================================================================
1503 //function : AddVolume
1505 //=======================================================================
1506 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1507 const SMDS_MeshNode * n2,
1508 const SMDS_MeshNode * n3,
1509 const SMDS_MeshNode * n4,
1510 const SMDS_MeshNode * n12,
1511 const SMDS_MeshNode * n23,
1512 const SMDS_MeshNode * n31,
1513 const SMDS_MeshNode * n14,
1514 const SMDS_MeshNode * n24,
1515 const SMDS_MeshNode * n34)
1517 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1518 if(anElem) myScript->AddVolume(anElem->GetID(),
1519 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1520 n12->GetID(), n23->GetID(), n31->GetID(),
1521 n14->GetID(), n24->GetID(), n34->GetID());
1525 //=======================================================================
1526 //function : AddVolumeWithID
1528 //=======================================================================
1529 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1530 int n12,int n23,int n31,
1531 int n14,int n24,int n34, int ID)
1533 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1534 n31,n14,n24,n34,ID);
1535 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1539 //=======================================================================
1540 //function : AddVolumeWithID
1541 //purpose : 2d order tetrahedron of 10 nodes
1542 //=======================================================================
1543 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1544 const SMDS_MeshNode * n2,
1545 const SMDS_MeshNode * n3,
1546 const SMDS_MeshNode * n4,
1547 const SMDS_MeshNode * n12,
1548 const SMDS_MeshNode * n23,
1549 const SMDS_MeshNode * n31,
1550 const SMDS_MeshNode * n14,
1551 const SMDS_MeshNode * n24,
1552 const SMDS_MeshNode * n34,
1555 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1556 n12->GetID(), n23->GetID(), n31->GetID(),
1557 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1561 //=======================================================================
1562 //function : AddVolume
1564 //=======================================================================
1565 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1566 const SMDS_MeshNode * n2,
1567 const SMDS_MeshNode * n3,
1568 const SMDS_MeshNode * n4,
1569 const SMDS_MeshNode * n5,
1570 const SMDS_MeshNode * n12,
1571 const SMDS_MeshNode * n23,
1572 const SMDS_MeshNode * n34,
1573 const SMDS_MeshNode * n41,
1574 const SMDS_MeshNode * n15,
1575 const SMDS_MeshNode * n25,
1576 const SMDS_MeshNode * n35,
1577 const SMDS_MeshNode * n45)
1579 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1582 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1583 n3->GetID(), n4->GetID(), n5->GetID(),
1584 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1585 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1589 //=======================================================================
1590 //function : AddVolumeWithID
1592 //=======================================================================
1593 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1594 int n12,int n23,int n34,int n41,
1595 int n15,int n25,int n35,int n45, int ID)
1597 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1599 n15,n25,n35,n45,ID);
1600 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1605 //=======================================================================
1606 //function : AddVolumeWithID
1607 //purpose : 2d order pyramid of 13 nodes
1608 //=======================================================================
1609 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1610 const SMDS_MeshNode * n2,
1611 const SMDS_MeshNode * n3,
1612 const SMDS_MeshNode * n4,
1613 const SMDS_MeshNode * n5,
1614 const SMDS_MeshNode * n12,
1615 const SMDS_MeshNode * n23,
1616 const SMDS_MeshNode * n34,
1617 const SMDS_MeshNode * n41,
1618 const SMDS_MeshNode * n15,
1619 const SMDS_MeshNode * n25,
1620 const SMDS_MeshNode * n35,
1621 const SMDS_MeshNode * n45,
1624 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1625 n4->GetID(), n5->GetID(),
1626 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1627 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1632 //=======================================================================
1633 //function : AddVolume
1635 //=======================================================================
1636 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1637 const SMDS_MeshNode * n2,
1638 const SMDS_MeshNode * n3,
1639 const SMDS_MeshNode * n4,
1640 const SMDS_MeshNode * n5,
1641 const SMDS_MeshNode * n6,
1642 const SMDS_MeshNode * n12,
1643 const SMDS_MeshNode * n23,
1644 const SMDS_MeshNode * n31,
1645 const SMDS_MeshNode * n45,
1646 const SMDS_MeshNode * n56,
1647 const SMDS_MeshNode * n64,
1648 const SMDS_MeshNode * n14,
1649 const SMDS_MeshNode * n25,
1650 const SMDS_MeshNode * n36)
1652 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1653 n45,n56,n64,n14,n25,n36);
1655 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1656 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1657 n12->GetID(), n23->GetID(), n31->GetID(),
1658 n45->GetID(), n56->GetID(), n64->GetID(),
1659 n14->GetID(), n25->GetID(), n36->GetID());
1663 //=======================================================================
1664 //function : AddVolumeWithID
1666 //=======================================================================
1667 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1668 int n4, int n5, int n6,
1669 int n12,int n23,int n31,
1670 int n45,int n56,int n64,
1671 int n14,int n25,int n36, int ID)
1673 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1677 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1678 n45,n56,n64,n14,n25,n36);
1682 //=======================================================================
1683 //function : AddVolumeWithID
1684 //purpose : 2d order Pentahedron with 15 nodes
1685 //=======================================================================
1686 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1687 const SMDS_MeshNode * n2,
1688 const SMDS_MeshNode * n3,
1689 const SMDS_MeshNode * n4,
1690 const SMDS_MeshNode * n5,
1691 const SMDS_MeshNode * n6,
1692 const SMDS_MeshNode * n12,
1693 const SMDS_MeshNode * n23,
1694 const SMDS_MeshNode * n31,
1695 const SMDS_MeshNode * n45,
1696 const SMDS_MeshNode * n56,
1697 const SMDS_MeshNode * n64,
1698 const SMDS_MeshNode * n14,
1699 const SMDS_MeshNode * n25,
1700 const SMDS_MeshNode * n36,
1703 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1704 n4->GetID(), n5->GetID(), n6->GetID(),
1705 n12->GetID(), n23->GetID(), n31->GetID(),
1706 n45->GetID(), n56->GetID(), n64->GetID(),
1707 n14->GetID(), n25->GetID(), n36->GetID(),
1712 //=======================================================================
1713 //function : AddVolume
1715 //=======================================================================
1716 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1717 const SMDS_MeshNode * n2,
1718 const SMDS_MeshNode * n3,
1719 const SMDS_MeshNode * n4,
1720 const SMDS_MeshNode * n5,
1721 const SMDS_MeshNode * n6,
1722 const SMDS_MeshNode * n7,
1723 const SMDS_MeshNode * n8,
1724 const SMDS_MeshNode * n12,
1725 const SMDS_MeshNode * n23,
1726 const SMDS_MeshNode * n34,
1727 const SMDS_MeshNode * n41,
1728 const SMDS_MeshNode * n56,
1729 const SMDS_MeshNode * n67,
1730 const SMDS_MeshNode * n78,
1731 const SMDS_MeshNode * n85,
1732 const SMDS_MeshNode * n15,
1733 const SMDS_MeshNode * n26,
1734 const SMDS_MeshNode * n37,
1735 const SMDS_MeshNode * n48)
1737 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1742 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1743 n3->GetID(), n4->GetID(), n5->GetID(),
1744 n6->GetID(), n7->GetID(), n8->GetID(),
1745 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1746 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1747 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1751 //=======================================================================
1752 //function : AddVolumeWithID
1754 //=======================================================================
1755 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1756 int n5, int n6, int n7, int n8,
1757 int n12,int n23,int n34,int n41,
1758 int n56,int n67,int n78,int n85,
1759 int n15,int n26,int n37,int n48, int ID)
1761 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1764 n15,n26,n37,n48,ID);
1765 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1766 n56,n67,n78,n85,n15,n26,n37,n48);
1770 //=======================================================================
1771 //function : AddVolumeWithID
1772 //purpose : 2d order Hexahedrons with 20 nodes
1773 //=======================================================================
1774 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1775 const SMDS_MeshNode * n2,
1776 const SMDS_MeshNode * n3,
1777 const SMDS_MeshNode * n4,
1778 const SMDS_MeshNode * n5,
1779 const SMDS_MeshNode * n6,
1780 const SMDS_MeshNode * n7,
1781 const SMDS_MeshNode * n8,
1782 const SMDS_MeshNode * n12,
1783 const SMDS_MeshNode * n23,
1784 const SMDS_MeshNode * n34,
1785 const SMDS_MeshNode * n41,
1786 const SMDS_MeshNode * n56,
1787 const SMDS_MeshNode * n67,
1788 const SMDS_MeshNode * n78,
1789 const SMDS_MeshNode * n85,
1790 const SMDS_MeshNode * n15,
1791 const SMDS_MeshNode * n26,
1792 const SMDS_MeshNode * n37,
1793 const SMDS_MeshNode * n48,
1796 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1797 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1798 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1799 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1800 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1804 void SMESHDS_Mesh::compactMesh()
1806 int newNodeSize = 0;
1807 int nbNodes = myNodes.size();
1808 int nbVtkNodes = myGrid->GetNumberOfPoints();
1809 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1810 int nbNodeTemp = nbVtkNodes;
1811 if (nbNodes > nbVtkNodes)
1812 nbNodeTemp = nbNodes;
1813 vector<int> idNodesOldToNew;
1814 idNodesOldToNew.clear();
1815 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1817 for (int i = 0; i < nbNodes; i++)
1821 int vtkid = myNodes[i]->getVtkId();
1822 idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
1826 bool areNodesModified = (newNodeSize < nbVtkNodes);
1827 MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
1828 areNodesModified = true;
1830 int newCellSize = 0;
1831 int nbCells = myCells.size();
1832 int nbVtkCells = myGrid->GetNumberOfCells();
1833 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1834 int nbCellTemp = nbVtkCells;
1835 if (nbCells > nbVtkCells)
1836 nbCellTemp = nbCells;
1837 vector<int> idCellsOldToNew;
1838 idCellsOldToNew.clear();
1839 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1841 for (int i = 0; i < nbCells; i++)
1845 // //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
1846 // int vtkid = myCells[i]->getVtkId();
1847 // idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
1851 if (areNodesModified)
1852 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1854 myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
1856 int nbVtkPts = myGrid->GetNumberOfPoints();
1857 nbVtkCells = myGrid->GetNumberOfCells();
1858 if (nbVtkPts != newNodeSize)
1860 MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
1861 if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
1863 if (nbVtkCells != newCellSize)
1865 MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
1866 if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
1869 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1871 if (areNodesModified)
1873 MESSAGE("-------------- modify myNodes");
1874 SetOfNodes newNodes;
1875 newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
1877 for (int i = 0; i < nbNodes; i++)
1881 newSmdsId++; // SMDS id start to 1
1882 int oldVtkId = myNodes[i]->getVtkId();
1883 int newVtkId = idNodesOldToNew[oldVtkId];
1884 //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
1885 myNodes[i]->setVtkId(newVtkId);
1886 myNodes[i]->setId(newSmdsId);
1887 newNodes[newSmdsId] = myNodes[i];
1888 //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
1891 myNodes.swap(newNodes);
1892 this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
1893 MESSAGE("myNodes.size " << myNodes.size());
1896 // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
1898 int vtkIndexSize = myCellIdVtkToSmds.size();
1900 for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
1902 int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
1905 int newVtkId = idCellsOldToNew[oldVtkId];
1906 if (newVtkId > maxVtkId)
1907 maxVtkId = newVtkId;
1908 //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
1909 myCells[oldSmdsId]->setVtkId(newVtkId);
1912 // MESSAGE("myCells.size()=" << myCells.size()
1913 // << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
1914 // << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1916 SetOfCells newCells;
1917 //vector<int> newSmdsToVtk;
1918 vector<int> newVtkToSmds;
1920 assert(maxVtkId < newCellSize);
1921 newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
1922 //newSmdsToVtk.resize(newCellSize+1, -1);
1923 newVtkToSmds.resize(newCellSize+1, -1);
1925 int myCellsSize = myCells.size();
1927 for (int i = 0; i < myCellsSize; i++)
1931 newSmdsId++; // SMDS id start to 1
1932 assert(newSmdsId <= newCellSize);
1933 newCells[newSmdsId] = myCells[i];
1934 newCells[newSmdsId]->setId(newSmdsId);
1935 //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
1936 int idvtk = myCells[i]->getVtkId();
1937 //newSmdsToVtk[newSmdsId] = idvtk;
1938 assert(idvtk < newCellSize);
1939 newVtkToSmds[idvtk] = newSmdsId;
1943 myCells.swap(newCells);
1944 //myCellIdSmdsToVtk.swap(newSmdsToVtk);
1945 myCellIdVtkToSmds.swap(newVtkToSmds);
1946 MESSAGE("myCells.size()=" << myCells.size()
1947 << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1948 this->myElementIDFactory->emptyPool(newSmdsId);
1950 this->myScript->SetModified(true); // notify GUI client for buildPrs when update
1952 // --- compact list myNodes and myElements in submeshes
1954 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1955 for(; it != myShapeIndexToSubMesh.end(); ++it)
1957 (*it).second->compactList();
1962 void SMESHDS_Mesh::CleanDownWardConnectivity()
1964 myGrid->CleanDownwardConnectivity();
1967 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
1969 myGrid->BuildDownwardConnectivity(withEdges);
1972 /*! change some nodes in cell without modifying type or internal connectivity.
1973 * Nodes inverse connectivity is maintained up to date.
1974 * @param vtkVolId vtk id of the cell.
1975 * @param localClonedNodeIds map old node id to new node id.
1976 * @return ok if success.
1978 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
1980 myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);