Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/smesh.git] / src / SMESHDS / SMESHDS_GroupOnFilter.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SMESHDS_GroupOnFilter.cxx
24 //  Module : SMESH
25 //
26 #include "SMESHDS_GroupOnFilter.hxx"
27
28 #include "SMESHDS_Mesh.hxx"
29 #include "SMDS_SetIterator.hxx"
30
31 using namespace std;
32
33 //=============================================================================
34 /*!
35  * Creates a group based on thePredicate
36  */
37 //=============================================================================
38
39 SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int                 theID,
40                                               const SMESHDS_Mesh*       theMesh,
41                                               const SMDSAbs_ElementType theType,
42                                               const SMESH_PredicatePtr& thePredicate)
43   : SMESHDS_GroupBase(theID,theMesh,theType), myMeshModifTime(0), myPredicateTic(0)
44 {
45   setChanged();
46   SetPredicate( thePredicate );
47 }
48
49 //================================================================================
50 /*!
51  * \brief Sets a new predicate
52  */
53 //================================================================================
54
55 void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate)
56 {
57   myPredicate = thePredicate;
58   ++myPredicateTic;
59   setChanged();
60   if ( myPredicate )
61     myPredicate->SetMesh( GetMesh() );
62 }
63
64 //================================================================================
65 /*!
66  * \brief Returns nb of elements
67  */
68 //================================================================================
69
70 int SMESHDS_GroupOnFilter::Extent() const
71 {
72   update();
73   return myElements.size();
74 }
75
76 //================================================================================
77 /*!
78  * \brief Checks if the element belongs to the group
79  */
80 //================================================================================
81
82 bool SMESHDS_GroupOnFilter::Contains (const int theID)
83 {
84   return myPredicate ? myPredicate->IsSatisfy( theID ) : false;
85 }
86
87 //================================================================================
88 /*!
89  * \brief Checks if the element belongs to the group
90  */
91 //================================================================================
92
93 bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem)
94 {
95   return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false;
96 }
97
98 //================================================================================
99 /*!
100  * \brief Return iterator on all elements
101  */
102 //================================================================================
103
104 SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
105 {
106   update();
107   return SMDS_ElemIteratorPtr
108     ( new SMDS_ElementVectorIterator( myElements.begin(), myElements.end() ));
109 }
110
111 //================================================================================
112 /*!
113  * \brief return ID of theIndex-th element
114  *  \param theIndex - index countered from 1
115  *  \retval int - element ID
116  */
117 //================================================================================
118
119 int SMESHDS_GroupOnFilter::GetID (const int theIndex)
120 {
121   update();
122   if ( theIndex < 1 || theIndex > myElements.size() )
123     return -1;
124   return myElements[ theIndex-1 ]->GetID();
125 }
126
127 //================================================================================
128 /*!
129  * \brief Return a value allowing to find out if a group has changed or not
130  */
131 //================================================================================
132
133 int SMESHDS_GroupOnFilter::GetTic() const
134 {
135   return GetMesh()->GetMTime() * myPredicateTic;
136 }
137
138 //================================================================================
139 /*!
140  * \brief Return false if update() is needed
141  */
142 //================================================================================
143
144 bool SMESHDS_GroupOnFilter::IsUpToDate() const
145 {
146   return !( myMeshModifTime < GetMesh()->GetMTime() );
147 }
148
149 //================================================================================
150 /*!
151  * \brief Updates myElements if necessary
152  */
153 //================================================================================
154
155 void SMESHDS_GroupOnFilter::update() const
156 {
157   if ( !IsUpToDate() )
158   {
159     SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
160     me->myElements.clear();
161     if ( myPredicate )
162     {
163       myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary
164       me->myElements.reserve( GetMesh()->GetMeshInfo().NbElements(GetType()));
165       SMDS_ElemIteratorPtr elIt = GetMesh()->elementsIterator(GetType());
166       while ( elIt->more() )
167       {
168         const SMDS_MeshElement* e = elIt->next();
169         if ( myPredicate->IsSatisfy( e->GetID() ))
170           me->myElements.push_back( e );
171       }
172       vector< const SMDS_MeshElement*> elems( me->myElements.begin(), me->myElements.end() );
173       me->myElements.swap( elems );
174     }
175     me->setChanged( false );
176   }
177 }
178
179 //================================================================================
180 /*!
181  * \brief Sets myMeshModifTime according to modification state
182  */
183 //================================================================================
184
185 void SMESHDS_GroupOnFilter::setChanged(bool changed)
186 {
187   myMeshModifTime = GetMesh()->GetMTime();
188   if ( changed && myMeshModifTime != 0 )
189     --myMeshModifTime;
190 }