Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/smesh.git] / src / SMDS / SMDS_MeshElement.cxx
1 //  Copyright (C) 2007-2010  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 //  SMESH SMDS : implementaion of Salome mesh data structure
24 //
25 #ifdef _MSC_VER
26 #pragma warning(disable:4786)
27 #endif
28
29 #include "SMDS_MeshElement.hxx"
30 #include "SMDS_MeshNode.hxx"
31 #include "SMDS_MeshEdge.hxx"
32 #include "SMDS_MeshFace.hxx"
33 #include "SMDS_MeshVolume.hxx"
34 #include "utilities.h"
35
36 using namespace std;
37
38 SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID)
39 {
40 }
41
42 void SMDS_MeshElement::Print(ostream & OS) const
43 {
44         OS << "dump of mesh element" << endl;
45 }
46
47 ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME)
48 {
49         ME->Print(OS);
50         return OS;
51 }
52
53 ///////////////////////////////////////////////////////////////////////////////
54 /// Create an iterator which iterate on nodes owned by the element.
55 /// This method call elementsIterator().
56 ///////////////////////////////////////////////////////////////////////////////
57 SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
58 {
59         return elementsIterator(SMDSAbs_Node);
60 }
61
62 ///////////////////////////////////////////////////////////////////////////////
63 /// Create an iterator which iterate on edges linked with or owned by the element.
64 /// This method call elementsIterator().
65 ///////////////////////////////////////////////////////////////////////////////
66 SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
67 {
68         return elementsIterator(SMDSAbs_Edge);
69 }
70
71 ///////////////////////////////////////////////////////////////////////////////
72 /// Create an iterator which iterate on faces linked with or owned by the element.
73 /// This method call elementsIterator().
74 ///////////////////////////////////////////////////////////////////////////////
75 SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
76 {
77         return elementsIterator(SMDSAbs_Face);
78 }
79
80 ///////////////////////////////////////////////////////////////////////////////
81 ///Return The number of nodes owned by the current element
82 ///////////////////////////////////////////////////////////////////////////////
83 int SMDS_MeshElement::NbNodes() const
84 {
85         int nbnodes=0;
86         SMDS_ElemIteratorPtr it=nodesIterator();
87         while(it->more())
88         {
89                 it->next();
90                 nbnodes++;
91         }
92         return nbnodes;
93 }
94
95 ///////////////////////////////////////////////////////////////////////////////
96 ///Return the number of edges owned by or linked with the current element
97 ///////////////////////////////////////////////////////////////////////////////
98 int SMDS_MeshElement::NbEdges() const
99 {
100         int nbedges=0;
101         SMDS_ElemIteratorPtr it=edgesIterator();
102         while(it->more())
103         {
104                 it->next();
105                 nbedges++;
106         }
107         return nbedges;
108 }
109
110 ///////////////////////////////////////////////////////////////////////////////
111 ///Return the number of faces owned by or linked with the current element
112 ///////////////////////////////////////////////////////////////////////////////
113 int SMDS_MeshElement::NbFaces() const
114 {
115         int nbfaces=0;
116         SMDS_ElemIteratorPtr it=facesIterator();
117         while(it->more())
118         {
119                 it->next();
120                 nbfaces++;
121         }
122         return nbfaces;
123 }
124
125 ///////////////////////////////////////////////////////////////////////////////
126 ///Create an iterator which iterate on elements linked with the current element.
127 ///@param type The of elements on which you want to iterate
128 ///@return A smart pointer to iterator, you are not to take care of freeing memory
129 ///////////////////////////////////////////////////////////////////////////////
130 class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
131 {
132   const SMDS_MeshElement * myElement;
133   bool myMore;
134  public:
135   SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element):
136     myElement(element),myMore(true) {}
137
138   bool more()
139   {
140     return myMore;
141   }
142
143   const SMDS_MeshElement* next()
144   {
145     myMore=false;
146     return myElement;   
147   }     
148 };
149 SMDS_ElemIteratorPtr SMDS_MeshElement::
150         elementsIterator(SMDSAbs_ElementType type) const
151 {
152         /** @todo Check that iterator in the child classes return elements
153         in the same order for each different implementation (i.e: SMDS_VolumeOfNodes
154         and SMDS_VolumeOfFaces */
155         
156         if(type==GetType())
157           return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this));
158         else 
159         {
160           MESSAGE("Iterator not implemented");
161           return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
162         }
163 }
164
165 ///////////////////////////////////////////////////////////////////////////////
166 ///Return the ID of the element
167 ///////////////////////////////////////////////////////////////////////////////
168 int SMDS_MeshElement::GetID() const
169 {
170         return myID;
171 }
172
173 bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
174 {
175         if(e1.GetType()!=e2.GetType()) return false;
176         switch(e1.GetType())
177         {
178         case SMDSAbs_Node:
179                 return static_cast<const SMDS_MeshNode &>(e1) <
180                         static_cast<const SMDS_MeshNode &>(e2);
181
182         case SMDSAbs_Edge:
183                 return static_cast<const SMDS_MeshEdge &>(e1) <
184                         static_cast<const SMDS_MeshEdge &>(e2);
185
186         case SMDSAbs_Face:
187                 return static_cast<const SMDS_MeshFace &>(e1) <
188                         static_cast<const SMDS_MeshFace &>(e2);
189
190         case SMDSAbs_Volume:
191                 return static_cast<const SMDS_MeshVolume &>(e1) <
192                         static_cast<const SMDS_MeshVolume &>(e2);
193
194         default : MESSAGE("Internal Error");
195         }
196         return false;
197 }
198
199 bool SMDS_MeshElement::IsValidIndex(const int ind) const
200 {
201   return ( ind>-1 && ind<NbNodes() );
202 }
203
204 const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const
205 {
206   if ( ind >= 0 ) {
207     SMDS_ElemIteratorPtr it = nodesIterator();
208     for ( int i = 0; i < ind; ++i )
209       it->next();
210     if ( it->more() )
211       return static_cast<const SMDS_MeshNode*> (it->next());
212   }
213   return 0;
214 }
215
216 bool SMDS_MeshElement::IsQuadratic() const
217 {
218   return false;
219 }
220
221 bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
222 {
223   return false;
224 }
225
226 //================================================================================
227 /*!
228  * \brief Return number of nodes excluding medium ones
229  */
230 //================================================================================
231
232 int SMDS_MeshElement::NbCornerNodes() const
233 {
234   return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes();
235 }
236
237 //================================================================================
238   /*!
239    * \brief Check if a node belongs to the element
240     * \param node - the node to check
241     * \retval int - node index within the element, -1 if not found
242    */
243 //================================================================================
244
245 int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const
246 {
247   SMDS_ElemIteratorPtr nIt = nodesIterator();
248   for ( int i = 0; nIt->more(); ++i )
249     if ( nIt->next() == node )
250       return i;
251   return -1;
252 }