1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMESHDS : management of mesh data and SMESH document
24 // File : SMESH_Mesh.cxx
25 // Author : Yves FRICAUD, OCC
29 #include "SMESHDS_Mesh.hxx"
31 #include "SMESHDS_Group.hxx"
32 #include "SMDS_VertexPosition.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_SpacePosition.hxx"
36 #include "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 map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
718 for ( ; SubIt != theSubMeshes.end(); SubIt++ )
720 int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
721 if ( size == 0 ) continue;
723 list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
724 while ( elIt != theElems.end() )
726 bool removed = false;
728 removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
730 removed = (*SubIt).second->RemoveElement( *elIt, deleted );
734 elIt = theElems.erase( elIt );
735 if ( theElems.empty() )
736 return; // all elements are found and removed
746 //=======================================================================
747 //function : RemoveNode
749 //=======================================================================
750 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
752 if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
754 SMESHDS_SubMesh* subMesh=0;
755 map<int,SMESHDS_SubMesh*>::iterator SubIt =
756 myShapeIndexToSubMesh.find( n->getshapeId() );
757 if ( SubIt != myShapeIndexToSubMesh.end() )
758 subMesh = SubIt->second;
760 SubIt = myShapeIndexToSubMesh.begin();
761 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
762 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
763 subMesh = SubIt->second;
765 RemoveFreeNode( n, subMesh, true);
769 myScript->RemoveNode(n->GetID());
771 list<const SMDS_MeshElement *> removedElems;
772 list<const SMDS_MeshElement *> removedNodes;
774 SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
776 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
777 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
780 //=======================================================================
781 //function : RemoveFreeNode
783 //=======================================================================
784 void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
785 SMESHDS_SubMesh * subMesh,
788 myScript->RemoveNode(n->GetID());
791 // Node can belong to several groups
792 if (fromGroups && !myGroups.empty()) {
793 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
794 for (; GrIt != myGroups.end(); GrIt++) {
795 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
796 if (!group || group->IsEmpty()) continue;
797 group->SMDSGroup().Remove(n);
802 // Node should belong to only one sub-mesh
804 subMesh->RemoveNode(n,/*deleted=*/false);
806 SMDS_Mesh::RemoveFreeElement(n);
809 //=======================================================================
810 //function : RemoveElement
812 //========================================================================
813 void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
815 if (elt->GetType() == SMDSAbs_Node)
817 RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
820 if (!hasConstructionEdges() && !hasConstructionFaces())
822 SMESHDS_SubMesh* subMesh=0;
823 map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
824 for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
825 if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
826 subMesh = SubIt->second;
827 //MESSAGE("subMesh " << elt->getshapeId());
828 RemoveFreeElement( elt, subMesh, true);
832 myScript->RemoveElement(elt->GetID());
834 list<const SMDS_MeshElement *> removedElems;
835 list<const SMDS_MeshElement *> removedNodes;
837 SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
839 removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
842 //=======================================================================
843 //function : RemoveFreeElement
845 //========================================================================
846 void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
847 SMESHDS_SubMesh * subMesh,
850 //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
851 if (elt->GetType() == SMDSAbs_Node) {
852 RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
856 if (hasConstructionEdges() || hasConstructionFaces())
857 // this methods is only for meshes without descendants
860 myScript->RemoveElement(elt->GetID());
863 // Node can belong to several groups
864 if ( fromGroups && !myGroups.empty() ) {
865 set<SMESHDS_GroupBase*>::iterator GrIt = myGroups.begin();
866 for (; GrIt != myGroups.end(); GrIt++) {
867 SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>(*GrIt);
868 if (group && !group->IsEmpty())
869 group->SMDSGroup().Remove(elt);
874 // Element should belong to only one sub-mesh
876 subMesh->RemoveElement(elt, /*deleted=*/false);
878 SMDS_Mesh::RemoveFreeElement(elt);
881 //================================================================================
883 * \brief Remove all data from the mesh
885 //================================================================================
887 void SMESHDS_Mesh::ClearMesh()
889 myScript->ClearMesh();
893 map<int,SMESHDS_SubMesh*>::iterator sub, subEnd = myShapeIndexToSubMesh.end();
894 for ( sub = myShapeIndexToSubMesh.begin(); sub != subEnd; ++sub )
895 sub->second->Clear();
898 TGroups::iterator group, groupEnd = myGroups.end();
899 for ( group = myGroups.begin(); group != groupEnd; ++group ) {
900 if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>(*group)) {
901 SMDSAbs_ElementType groupType = g->GetType();
903 g->SetType( groupType );
908 //================================================================================
910 * \brief return submesh by shape
911 * \param shape - the subshape
912 * \retval SMESHDS_SubMesh* - the found submesh
914 * search of submeshes is optimized
916 //================================================================================
918 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
920 if ( shape.IsNull() )
923 if ( !myCurSubShape.IsNull() && shape.IsSame( myCurSubShape ))
926 getSubmesh( ShapeToIndex( shape ));
927 myCurSubShape = shape;
931 //================================================================================
933 * \brief return submesh by subshape index
934 * \param Index - the subshape index
935 * \retval SMESHDS_SubMesh* - the found submesh
936 * search of submeshes is optimized
938 //================================================================================
940 SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
942 //Update or build submesh
943 if ( Index != myCurSubID ) {
944 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
945 if ( it == myShapeIndexToSubMesh.end() )
946 it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
947 myCurSubMesh = it->second;
949 myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
954 //================================================================================
956 * \brief Add element or node to submesh
957 * \param elem - element to add
958 * \param subMesh - submesh to be filled in
960 //================================================================================
962 bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
964 if ( elem && subMesh ) {
965 if ( elem->GetType() == SMDSAbs_Node )
966 subMesh->AddNode( static_cast<const SMDS_MeshNode* >( elem ));
968 subMesh->AddElement( elem );
974 //=======================================================================
975 //function : SetNodeOnVolume
977 //=======================================================================
978 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
979 const TopoDS_Shell & S)
981 if ( add( aNode, getSubmesh(S) ))
982 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
985 //=======================================================================
986 //function : SetNodeOnVolume
988 //=======================================================================
989 void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode * aNode,
990 const TopoDS_Solid & S)
992 if ( add( aNode, getSubmesh(S) ))
993 aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
996 //=======================================================================
997 //function : SetNodeOnFace
999 //=======================================================================
1000 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode * aNode,
1001 const TopoDS_Face & S,
1005 if ( add( aNode, getSubmesh(S) ))
1006 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1009 //=======================================================================
1010 //function : SetNodeOnEdge
1012 //=======================================================================
1013 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode * aNode,
1014 const TopoDS_Edge & S,
1017 if ( add( aNode, getSubmesh(S) ))
1018 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1021 //=======================================================================
1022 //function : SetNodeOnVertex
1024 //=======================================================================
1025 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode * aNode,
1026 const TopoDS_Vertex & S)
1028 if ( add( aNode, getSubmesh(S) ))
1029 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1032 //=======================================================================
1033 //function : UnSetNodeOnShape
1035 //=======================================================================
1036 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
1038 int shapeId = aNode->getshapeId();
1041 map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
1042 if (it != myShapeIndexToSubMesh.end())
1043 it->second->RemoveNode(aNode, /*deleted=*/false);
1047 //=======================================================================
1048 //function : SetMeshElementOnShape
1050 //=======================================================================
1051 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
1052 const TopoDS_Shape & S)
1054 add( anElement, getSubmesh(S) );
1057 //=======================================================================
1058 //function : UnSetMeshElementOnShape
1060 //=======================================================================
1061 void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
1062 const TopoDS_Shape & S)
1064 int Index = myIndexToShape.FindIndex(S);
1066 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
1067 if ( it != myShapeIndexToSubMesh.end() )
1069 if (elem->GetType() == SMDSAbs_Node)
1070 it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
1072 it->second->RemoveElement(elem, /*deleted=*/false);
1076 //=======================================================================
1077 //function : ShapeToMesh
1079 //=======================================================================
1080 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
1085 //=======================================================================
1086 //function : IsGroupOfSubShapes
1087 //purpose : return true if at least one subshape of theShape is a subshape
1088 // of myShape or theShape == myShape
1089 //=======================================================================
1091 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
1093 if ( myIndexToShape.Contains(theShape) )
1096 for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
1097 if (IsGroupOfSubShapes( it.Value() ))
1103 ///////////////////////////////////////////////////////////////////////////////
1104 /// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
1105 /// TopoDS_Shape is unknown
1106 ///////////////////////////////////////////////////////////////////////////////
1107 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
1109 int Index = ShapeToIndex(S);
1110 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1111 if (anIter != myShapeIndexToSubMesh.end())
1112 return anIter->second;
1117 ///////////////////////////////////////////////////////////////////////////////
1118 /// Return the sub mesh by Id of shape it is linked to
1119 ///////////////////////////////////////////////////////////////////////////////
1120 SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
1122 TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
1123 if (anIter != myShapeIndexToSubMesh.end())
1124 return anIter->second;
1129 //=======================================================================
1130 //function : SubMeshIndices
1132 //=======================================================================
1133 list<int> SMESHDS_Mesh::SubMeshIndices() const
1135 list<int> anIndices;
1136 std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
1137 for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
1138 anIndices.push_back((*anIter).first);
1143 //=======================================================================
1144 //function : GetHypothesis
1146 //=======================================================================
1148 const list<const SMESHDS_Hypothesis*>&
1149 SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
1151 if ( myShapeToHypothesis.IsBound( S.Oriented(TopAbs_FORWARD) ) ) // ignore orientation of S
1152 return myShapeToHypothesis.Find( S.Oriented(TopAbs_FORWARD) );
1154 static list<const SMESHDS_Hypothesis*> empty;
1158 //=======================================================================
1159 //function : GetScript
1161 //=======================================================================
1162 SMESHDS_Script* SMESHDS_Mesh::GetScript()
1167 //=======================================================================
1168 //function : ClearScript
1170 //=======================================================================
1171 void SMESHDS_Mesh::ClearScript()
1176 //=======================================================================
1177 //function : HasMeshElements
1179 //=======================================================================
1180 bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
1182 if (myShape.IsNull()) MESSAGE("myShape is NULL");
1183 int Index = myIndexToShape.FindIndex(S);
1184 return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
1187 //=======================================================================
1188 //function : HasHypothesis
1190 //=======================================================================
1191 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
1193 return myShapeToHypothesis.IsBound(S.Oriented(TopAbs_FORWARD));
1196 //=======================================================================
1197 //function : NewSubMesh
1199 //=======================================================================
1200 SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
1202 SMESHDS_SubMesh* SM = 0;
1203 TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
1204 if (anIter == myShapeIndexToSubMesh.end())
1206 SM = new SMESHDS_SubMesh(this, Index);
1207 myShapeIndexToSubMesh[Index]=SM;
1210 SM = anIter->second;
1214 //=======================================================================
1215 //function : AddCompoundSubmesh
1217 //=======================================================================
1219 int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
1220 TopAbs_ShapeEnum type)
1223 if ( IsGroupOfSubShapes( S ))
1225 aMainIndex = myIndexToShape.Add( S );
1226 bool all = ( type == TopAbs_SHAPE );
1227 if ( all ) // corresponding simple submesh may exist
1228 aMainIndex = -aMainIndex;
1229 //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
1230 SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
1231 if ( !aNewSub->IsComplexSubmesh() ) // is empty
1233 int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
1234 int typeLimit = all ? TopAbs_VERTEX : type;
1235 for ( ; shapeType <= typeLimit; shapeType++ )
1237 TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
1238 for ( ; exp.More(); exp.Next() )
1240 int index = myIndexToShape.FindIndex( exp.Current() );
1242 aNewSub->AddSubMesh( NewSubMesh( index ));
1250 //=======================================================================
1251 //function : IndexToShape
1253 //=======================================================================
1254 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
1258 return myIndexToShape.FindKey(ShapeIndex);
1260 catch ( Standard_OutOfRange )
1263 static TopoDS_Shape nullShape;
1267 //================================================================================
1269 * \brief Return max index of sub-mesh
1271 //================================================================================
1273 int SMESHDS_Mesh::MaxSubMeshIndex() const
1275 return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
1278 //=======================================================================
1279 //function : ShapeToIndex
1281 //=======================================================================
1282 int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
1284 if (myShape.IsNull())
1285 MESSAGE("myShape is NULL");
1287 int index = myIndexToShape.FindIndex(S);
1292 //=======================================================================
1293 //function : SetNodeOnVolume
1295 //=======================================================================
1296 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
1298 //add(aNode, getSubmesh(Index));
1299 if ( add( aNode, getSubmesh( Index )))
1300 ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
1303 //=======================================================================
1304 //function : SetNodeOnFace
1306 //=======================================================================
1307 void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
1309 //Set Position on Node
1310 if ( add( aNode, getSubmesh( Index )))
1311 aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
1314 //=======================================================================
1315 //function : SetNodeOnEdge
1317 //=======================================================================
1318 void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
1322 //Set Position on Node
1323 if ( add( aNode, getSubmesh( Index )))
1324 aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
1327 //=======================================================================
1328 //function : SetNodeOnVertex
1330 //=======================================================================
1331 void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
1333 //Set Position on Node
1334 if ( add( aNode, getSubmesh( Index )))
1335 aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
1338 //=======================================================================
1339 //function : SetMeshElementOnShape
1341 //=======================================================================
1342 void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
1345 add( anElement, getSubmesh( Index ));
1348 //=======================================================================
1349 //function : ~SMESHDS_Mesh
1351 //=======================================================================
1352 SMESHDS_Mesh::~SMESHDS_Mesh()
1357 TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
1358 for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
1359 delete i_sm->second;
1363 //********************************************************************
1364 //********************************************************************
1365 //******** *********
1366 //***** Methods for addition of quadratic elements ******
1367 //******** *********
1368 //********************************************************************
1369 //********************************************************************
1371 //=======================================================================
1372 //function : AddEdgeWithID
1374 //=======================================================================
1375 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
1377 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,n12,ID);
1378 if(anElem) myScript->AddEdge(ID,n1,n2,n12);
1382 //=======================================================================
1383 //function : AddEdge
1385 //=======================================================================
1386 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
1387 const SMDS_MeshNode* n2,
1388 const SMDS_MeshNode* n12)
1390 SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
1391 if(anElem) myScript->AddEdge(anElem->GetID(),
1398 //=======================================================================
1399 //function : AddEdgeWithID
1401 //=======================================================================
1402 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
1403 const SMDS_MeshNode * n2,
1404 const SMDS_MeshNode * n12,
1407 return AddEdgeWithID(n1->GetID(),
1414 //=======================================================================
1415 //function : AddFace
1417 //=======================================================================
1418 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1419 const SMDS_MeshNode * n2,
1420 const SMDS_MeshNode * n3,
1421 const SMDS_MeshNode * n12,
1422 const SMDS_MeshNode * n23,
1423 const SMDS_MeshNode * n31)
1425 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
1426 if(anElem) myScript->AddFace(anElem->GetID(),
1427 n1->GetID(), n2->GetID(), n3->GetID(),
1428 n12->GetID(), n23->GetID(), n31->GetID());
1432 //=======================================================================
1433 //function : AddFaceWithID
1435 //=======================================================================
1436 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
1437 int n12,int n23,int n31, int ID)
1439 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,ID);
1440 if(anElem) myScript->AddFace(ID,n1,n2,n3,n12,n23,n31);
1444 //=======================================================================
1445 //function : AddFaceWithID
1447 //=======================================================================
1448 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1449 const SMDS_MeshNode * n2,
1450 const SMDS_MeshNode * n3,
1451 const SMDS_MeshNode * n12,
1452 const SMDS_MeshNode * n23,
1453 const SMDS_MeshNode * n31,
1456 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1457 n12->GetID(), n23->GetID(), n31->GetID(),
1462 //=======================================================================
1463 //function : AddFace
1465 //=======================================================================
1466 SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
1467 const SMDS_MeshNode * n2,
1468 const SMDS_MeshNode * n3,
1469 const SMDS_MeshNode * n4,
1470 const SMDS_MeshNode * n12,
1471 const SMDS_MeshNode * n23,
1472 const SMDS_MeshNode * n34,
1473 const SMDS_MeshNode * n41)
1475 SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
1476 if(anElem) myScript->AddFace(anElem->GetID(),
1477 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1478 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
1482 //=======================================================================
1483 //function : AddFaceWithID
1485 //=======================================================================
1486 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
1487 int n12,int n23,int n34,int n41, int ID)
1489 SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,ID);
1490 if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41);
1494 //=======================================================================
1495 //function : AddFaceWithID
1497 //=======================================================================
1498 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
1499 const SMDS_MeshNode * n2,
1500 const SMDS_MeshNode * n3,
1501 const SMDS_MeshNode * n4,
1502 const SMDS_MeshNode * n12,
1503 const SMDS_MeshNode * n23,
1504 const SMDS_MeshNode * n34,
1505 const SMDS_MeshNode * n41,
1508 return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1509 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1514 //=======================================================================
1515 //function : AddVolume
1517 //=======================================================================
1518 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1519 const SMDS_MeshNode * n2,
1520 const SMDS_MeshNode * n3,
1521 const SMDS_MeshNode * n4,
1522 const SMDS_MeshNode * n12,
1523 const SMDS_MeshNode * n23,
1524 const SMDS_MeshNode * n31,
1525 const SMDS_MeshNode * n14,
1526 const SMDS_MeshNode * n24,
1527 const SMDS_MeshNode * n34)
1529 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1530 if(anElem) myScript->AddVolume(anElem->GetID(),
1531 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1532 n12->GetID(), n23->GetID(), n31->GetID(),
1533 n14->GetID(), n24->GetID(), n34->GetID());
1537 //=======================================================================
1538 //function : AddVolumeWithID
1540 //=======================================================================
1541 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1542 int n12,int n23,int n31,
1543 int n14,int n24,int n34, int ID)
1545 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n12,n23,
1546 n31,n14,n24,n34,ID);
1547 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
1551 //=======================================================================
1552 //function : AddVolumeWithID
1553 //purpose : 2d order tetrahedron of 10 nodes
1554 //=======================================================================
1555 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1556 const SMDS_MeshNode * n2,
1557 const SMDS_MeshNode * n3,
1558 const SMDS_MeshNode * n4,
1559 const SMDS_MeshNode * n12,
1560 const SMDS_MeshNode * n23,
1561 const SMDS_MeshNode * n31,
1562 const SMDS_MeshNode * n14,
1563 const SMDS_MeshNode * n24,
1564 const SMDS_MeshNode * n34,
1567 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1568 n12->GetID(), n23->GetID(), n31->GetID(),
1569 n14->GetID(), n24->GetID(), n34->GetID(), ID);
1573 //=======================================================================
1574 //function : AddVolume
1576 //=======================================================================
1577 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1578 const SMDS_MeshNode * n2,
1579 const SMDS_MeshNode * n3,
1580 const SMDS_MeshNode * n4,
1581 const SMDS_MeshNode * n5,
1582 const SMDS_MeshNode * n12,
1583 const SMDS_MeshNode * n23,
1584 const SMDS_MeshNode * n34,
1585 const SMDS_MeshNode * n41,
1586 const SMDS_MeshNode * n15,
1587 const SMDS_MeshNode * n25,
1588 const SMDS_MeshNode * n35,
1589 const SMDS_MeshNode * n45)
1591 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n12,n23,n34,n41,
1594 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1595 n3->GetID(), n4->GetID(), n5->GetID(),
1596 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1597 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID());
1601 //=======================================================================
1602 //function : AddVolumeWithID
1604 //=======================================================================
1605 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
1606 int n12,int n23,int n34,int n41,
1607 int n15,int n25,int n35,int n45, int ID)
1609 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,
1611 n15,n25,n35,n45,ID);
1612 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n12,n23,n34,n41,
1617 //=======================================================================
1618 //function : AddVolumeWithID
1619 //purpose : 2d order pyramid of 13 nodes
1620 //=======================================================================
1621 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1622 const SMDS_MeshNode * n2,
1623 const SMDS_MeshNode * n3,
1624 const SMDS_MeshNode * n4,
1625 const SMDS_MeshNode * n5,
1626 const SMDS_MeshNode * n12,
1627 const SMDS_MeshNode * n23,
1628 const SMDS_MeshNode * n34,
1629 const SMDS_MeshNode * n41,
1630 const SMDS_MeshNode * n15,
1631 const SMDS_MeshNode * n25,
1632 const SMDS_MeshNode * n35,
1633 const SMDS_MeshNode * n45,
1636 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1637 n4->GetID(), n5->GetID(),
1638 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1639 n15->GetID(), n25->GetID(), n35->GetID(), n45->GetID(),
1644 //=======================================================================
1645 //function : AddVolume
1647 //=======================================================================
1648 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1649 const SMDS_MeshNode * n2,
1650 const SMDS_MeshNode * n3,
1651 const SMDS_MeshNode * n4,
1652 const SMDS_MeshNode * n5,
1653 const SMDS_MeshNode * n6,
1654 const SMDS_MeshNode * n12,
1655 const SMDS_MeshNode * n23,
1656 const SMDS_MeshNode * n31,
1657 const SMDS_MeshNode * n45,
1658 const SMDS_MeshNode * n56,
1659 const SMDS_MeshNode * n64,
1660 const SMDS_MeshNode * n14,
1661 const SMDS_MeshNode * n25,
1662 const SMDS_MeshNode * n36)
1664 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n12,n23,n31,
1665 n45,n56,n64,n14,n25,n36);
1667 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1668 n3->GetID(), n4->GetID(), n5->GetID(), n6->GetID(),
1669 n12->GetID(), n23->GetID(), n31->GetID(),
1670 n45->GetID(), n56->GetID(), n64->GetID(),
1671 n14->GetID(), n25->GetID(), n36->GetID());
1675 //=======================================================================
1676 //function : AddVolumeWithID
1678 //=======================================================================
1679 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
1680 int n4, int n5, int n6,
1681 int n12,int n23,int n31,
1682 int n45,int n56,int n64,
1683 int n14,int n25,int n36, int ID)
1685 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,
1689 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n12,n23,n31,
1690 n45,n56,n64,n14,n25,n36);
1694 //=======================================================================
1695 //function : AddVolumeWithID
1696 //purpose : 2d order Pentahedron with 15 nodes
1697 //=======================================================================
1698 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1699 const SMDS_MeshNode * n2,
1700 const SMDS_MeshNode * n3,
1701 const SMDS_MeshNode * n4,
1702 const SMDS_MeshNode * n5,
1703 const SMDS_MeshNode * n6,
1704 const SMDS_MeshNode * n12,
1705 const SMDS_MeshNode * n23,
1706 const SMDS_MeshNode * n31,
1707 const SMDS_MeshNode * n45,
1708 const SMDS_MeshNode * n56,
1709 const SMDS_MeshNode * n64,
1710 const SMDS_MeshNode * n14,
1711 const SMDS_MeshNode * n25,
1712 const SMDS_MeshNode * n36,
1715 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(),
1716 n4->GetID(), n5->GetID(), n6->GetID(),
1717 n12->GetID(), n23->GetID(), n31->GetID(),
1718 n45->GetID(), n56->GetID(), n64->GetID(),
1719 n14->GetID(), n25->GetID(), n36->GetID(),
1724 //=======================================================================
1725 //function : AddVolume
1727 //=======================================================================
1728 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1729 const SMDS_MeshNode * n2,
1730 const SMDS_MeshNode * n3,
1731 const SMDS_MeshNode * n4,
1732 const SMDS_MeshNode * n5,
1733 const SMDS_MeshNode * n6,
1734 const SMDS_MeshNode * n7,
1735 const SMDS_MeshNode * n8,
1736 const SMDS_MeshNode * n12,
1737 const SMDS_MeshNode * n23,
1738 const SMDS_MeshNode * n34,
1739 const SMDS_MeshNode * n41,
1740 const SMDS_MeshNode * n56,
1741 const SMDS_MeshNode * n67,
1742 const SMDS_MeshNode * n78,
1743 const SMDS_MeshNode * n85,
1744 const SMDS_MeshNode * n15,
1745 const SMDS_MeshNode * n26,
1746 const SMDS_MeshNode * n37,
1747 const SMDS_MeshNode * n48)
1749 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
1754 myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
1755 n3->GetID(), n4->GetID(), n5->GetID(),
1756 n6->GetID(), n7->GetID(), n8->GetID(),
1757 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1758 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1759 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID());
1763 //=======================================================================
1764 //function : AddVolumeWithID
1766 //=======================================================================
1767 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
1768 int n5, int n6, int n7, int n8,
1769 int n12,int n23,int n34,int n41,
1770 int n56,int n67,int n78,int n85,
1771 int n15,int n26,int n37,int n48, int ID)
1773 SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
1776 n15,n26,n37,n48,ID);
1777 if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
1778 n56,n67,n78,n85,n15,n26,n37,n48);
1782 //=======================================================================
1783 //function : AddVolumeWithID
1784 //purpose : 2d order Hexahedrons with 20 nodes
1785 //=======================================================================
1786 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1787 const SMDS_MeshNode * n2,
1788 const SMDS_MeshNode * n3,
1789 const SMDS_MeshNode * n4,
1790 const SMDS_MeshNode * n5,
1791 const SMDS_MeshNode * n6,
1792 const SMDS_MeshNode * n7,
1793 const SMDS_MeshNode * n8,
1794 const SMDS_MeshNode * n12,
1795 const SMDS_MeshNode * n23,
1796 const SMDS_MeshNode * n34,
1797 const SMDS_MeshNode * n41,
1798 const SMDS_MeshNode * n56,
1799 const SMDS_MeshNode * n67,
1800 const SMDS_MeshNode * n78,
1801 const SMDS_MeshNode * n85,
1802 const SMDS_MeshNode * n15,
1803 const SMDS_MeshNode * n26,
1804 const SMDS_MeshNode * n37,
1805 const SMDS_MeshNode * n48,
1808 return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
1809 n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
1810 n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
1811 n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
1812 n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
1816 void SMESHDS_Mesh::compactMesh()
1818 int newNodeSize = 0;
1819 int nbNodes = myNodes.size();
1820 int nbVtkNodes = myGrid->GetNumberOfPoints();
1821 MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
1822 int nbNodeTemp = nbVtkNodes;
1823 if (nbNodes > nbVtkNodes)
1824 nbNodeTemp = nbNodes;
1825 vector<int> idNodesOldToNew;
1826 idNodesOldToNew.clear();
1827 idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
1829 for (int i = 0; i < nbNodes; i++)
1833 int vtkid = myNodes[i]->getVtkId();
1834 idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
1838 bool areNodesModified = (newNodeSize < nbVtkNodes);
1839 MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
1840 areNodesModified = true;
1842 int newCellSize = 0;
1843 int nbCells = myCells.size();
1844 int nbVtkCells = myGrid->GetNumberOfCells();
1845 MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
1846 int nbCellTemp = nbVtkCells;
1847 if (nbCells > nbVtkCells)
1848 nbCellTemp = nbCells;
1849 vector<int> idCellsOldToNew;
1850 idCellsOldToNew.clear();
1851 idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
1853 for (int i = 0; i < nbCells; i++)
1857 // //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
1858 // int vtkid = myCells[i]->getVtkId();
1859 // idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
1863 if (areNodesModified)
1864 myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
1866 myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
1868 int nbVtkPts = myGrid->GetNumberOfPoints();
1869 nbVtkCells = myGrid->GetNumberOfCells();
1870 if (nbVtkPts != newNodeSize)
1872 MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
1873 if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
1875 if (nbVtkCells != newCellSize)
1877 MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
1878 if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
1881 // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
1883 if (areNodesModified)
1885 MESSAGE("-------------- modify myNodes");
1886 SetOfNodes newNodes;
1887 newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
1889 for (int i = 0; i < nbNodes; i++)
1893 newSmdsId++; // SMDS id start to 1
1894 int oldVtkId = myNodes[i]->getVtkId();
1895 int newVtkId = idNodesOldToNew[oldVtkId];
1896 //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
1897 myNodes[i]->setVtkId(newVtkId);
1898 myNodes[i]->setId(newSmdsId);
1899 newNodes[newSmdsId] = myNodes[i];
1900 //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
1903 myNodes.swap(newNodes);
1904 this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
1905 MESSAGE("myNodes.size " << myNodes.size());
1908 // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
1910 int vtkIndexSize = myCellIdVtkToSmds.size();
1912 for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
1914 int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
1917 int newVtkId = idCellsOldToNew[oldVtkId];
1918 if (newVtkId > maxVtkId)
1919 maxVtkId = newVtkId;
1920 //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
1921 myCells[oldSmdsId]->setVtkId(newVtkId);
1924 // MESSAGE("myCells.size()=" << myCells.size()
1925 // << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
1926 // << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1928 SetOfCells newCells;
1929 //vector<int> newSmdsToVtk;
1930 vector<int> newVtkToSmds;
1932 assert(maxVtkId < newCellSize);
1933 newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
1934 //newSmdsToVtk.resize(newCellSize+1, -1);
1935 newVtkToSmds.resize(newCellSize+1, -1);
1937 int myCellsSize = myCells.size();
1939 for (int i = 0; i < myCellsSize; i++)
1943 newSmdsId++; // SMDS id start to 1
1944 assert(newSmdsId <= newCellSize);
1945 newCells[newSmdsId] = myCells[i];
1946 newCells[newSmdsId]->setId(newSmdsId);
1947 //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
1948 int idvtk = myCells[i]->getVtkId();
1949 //newSmdsToVtk[newSmdsId] = idvtk;
1950 assert(idvtk < newCellSize);
1951 newVtkToSmds[idvtk] = newSmdsId;
1955 myCells.swap(newCells);
1956 //myCellIdSmdsToVtk.swap(newSmdsToVtk);
1957 myCellIdVtkToSmds.swap(newVtkToSmds);
1958 MESSAGE("myCells.size()=" << myCells.size()
1959 << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
1960 this->myElementIDFactory->emptyPool(newSmdsId);
1962 this->myScript->SetModified(true); // notify GUI client for buildPrs when update
1964 // --- compact list myNodes and myElements in submeshes
1966 map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
1967 for(; it != myShapeIndexToSubMesh.end(); ++it)
1969 (*it).second->compactList();
1974 void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
1976 myGrid->BuildDownwardConnectivity(withEdges);
1979 /*! change some nodes in cell without modifying type or internal connectivity.
1980 * Nodes inverse connectivity is maintained up to date.
1981 * @param vtkVolId vtk id of the cell.
1982 * @param localClonedNodeIds map old node id to new node id.
1983 * @return ok if success.
1985 bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
1987 myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
1991 /*! Create a volume (prism or hexahedron) by duplication of a face.
1992 * the nodes of the new face are already created.
1993 * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
1994 * @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume.
1995 * @return ok if success.
1997 bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds)
1999 //MESSAGE("extrudeVolumeFromFace " << vtkVolId);
2000 vector<vtkIdType> orderedNodes;
2001 orderedNodes.clear();
2002 map<int, int>::const_iterator it = localClonedNodeIds.begin();
2003 for (; it != localClonedNodeIds.end(); ++it)
2004 orderedNodes.push_back(it->first);
2006 int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedNodes);
2007 for (int i=0; i<nbNodes; i++)
2008 orderedNodes.push_back(localClonedNodeIds[orderedNodes[i]]);
2009 SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
2011 // TODO update subshape list of elements and nodes