Salome HOME
Merge branch V7_3_1_BR
[modules/smesh.git] / src / SMDS / SMDS_MeshElement.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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)
39 {
40   init(ID);
41 }
42
43 SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, LongType shapeId)
44 {
45   init(id, meshId, shapeId);
46 }
47
48 void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId )
49 {
50   myID = id;
51   myMeshId = meshId;
52   myShapeId = shapeId;
53   myIdInShape = -1;
54 }
55
56 void SMDS_MeshElement::Print(ostream & OS) const
57 {
58         OS << "dump of mesh element" << endl;
59 }
60
61 ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME)
62 {
63         ME->Print(OS);
64         return OS;
65 }
66
67 ///////////////////////////////////////////////////////////////////////////////
68 /// Create an iterator which iterate on nodes owned by the element.
69 /// This method call elementsIterator().
70 ///////////////////////////////////////////////////////////////////////////////
71 SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
72 {
73         return elementsIterator(SMDSAbs_Node);
74 }
75
76 ///////////////////////////////////////////////////////////////////////////////
77 /// Create an iterator which iterate on edges linked with or owned by the element.
78 /// This method call elementsIterator().
79 ///////////////////////////////////////////////////////////////////////////////
80 SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
81 {
82         return elementsIterator(SMDSAbs_Edge);
83 }
84
85 ///////////////////////////////////////////////////////////////////////////////
86 /// Create an iterator which iterate on faces linked with or owned by the element.
87 /// This method call elementsIterator().
88 ///////////////////////////////////////////////////////////////////////////////
89 SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
90 {
91         return elementsIterator(SMDSAbs_Face);
92 }
93
94 ///////////////////////////////////////////////////////////////////////////////
95 ///Return The number of nodes owned by the current element
96 ///////////////////////////////////////////////////////////////////////////////
97 int SMDS_MeshElement::NbNodes() const
98 {
99         int nbnodes=0;
100         SMDS_ElemIteratorPtr it=nodesIterator();
101         while(it->more())
102         {
103                 it->next();
104                 nbnodes++;
105         }
106         return nbnodes;
107 }
108
109 ///////////////////////////////////////////////////////////////////////////////
110 ///Return the number of edges owned by or linked with the current element
111 ///////////////////////////////////////////////////////////////////////////////
112 int SMDS_MeshElement::NbEdges() const
113 {
114         int nbedges=0;
115         SMDS_ElemIteratorPtr it=edgesIterator();
116         while(it->more())
117         {
118                 it->next();
119                 nbedges++;
120         }
121         return nbedges;
122 }
123
124 ///////////////////////////////////////////////////////////////////////////////
125 ///Return the number of faces owned by or linked with the current element
126 ///////////////////////////////////////////////////////////////////////////////
127 int SMDS_MeshElement::NbFaces() const
128 {
129         int nbfaces=0;
130         SMDS_ElemIteratorPtr it=facesIterator();
131         while(it->more())
132         {
133                 it->next();
134                 nbfaces++;
135         }
136         return nbfaces;
137 }
138
139 ///////////////////////////////////////////////////////////////////////////////
140 ///Create an iterator which iterate on elements linked with the current element.
141 ///@param type The of elements on which you want to iterate
142 ///@return A smart pointer to iterator, you are not to take care of freeing memory
143 ///////////////////////////////////////////////////////////////////////////////
144 class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
145 {
146   const SMDS_MeshElement * myElement;
147   bool myMore;
148  public:
149   SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element):
150     myElement(element),myMore(true) {}
151
152   bool more()
153   {
154     return myMore;
155   }
156
157   const SMDS_MeshElement* next()
158   {
159     myMore=false;
160     return myElement;   
161   }     
162 };
163
164 SMDS_ElemIteratorPtr
165 SMDS_MeshElement::elementsIterator(SMDSAbs_ElementType type) const
166 {
167   /** @todo Check that iterator in the child classes return elements
168       in the same order for each different implementation (i.e: SMDS_VolumeOfNodes
169       and SMDS_VolumeOfFaces */
170   if(type==GetType())
171     return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this));
172   else
173   {
174     MESSAGE("Iterator not implemented");
175     return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
176   }
177 }
178
179 //! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
180 SMDS_NodeIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const
181 {
182   return nodeIterator();
183 }
184
185 //! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
186 SMDS_NodeIteratorPtr SMDS_MeshElement::interlacedNodesIterator() const
187 {
188   return nodeIterator();
189 }
190
191 namespace
192 {
193   //=======================================================================
194   //class : _MyNodeIteratorFromElemIterator
195   //=======================================================================
196   class _MyNodeIteratorFromElemIterator : public SMDS_NodeIterator
197   {
198     SMDS_ElemIteratorPtr myItr;
199   public:
200     _MyNodeIteratorFromElemIterator(SMDS_ElemIteratorPtr elemItr):myItr( elemItr ) {}
201     bool                 more() { return myItr->more(); }
202     const SMDS_MeshNode* next() { return static_cast< const SMDS_MeshNode*>( myItr->next() ); }
203   };
204   //=======================================================================
205   //class : _MyElemIteratorFromNodeIterator
206   //=======================================================================
207   class _MyElemIteratorFromNodeIterator : public SMDS_ElemIterator
208   {
209     SMDS_NodeIteratorPtr myItr;
210   public:
211     _MyElemIteratorFromNodeIterator(SMDS_NodeIteratorPtr nodeItr): myItr( nodeItr ) {}
212     bool more()                    { return myItr->more(); }
213     const SMDS_MeshElement* next() { return myItr->next(); }
214   };
215 }
216
217 SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const
218 {
219   return SMDS_ElemIteratorPtr
220     ( new _MyElemIteratorFromNodeIterator( interlacedNodesIterator() ));
221 }
222
223 SMDS_NodeIteratorPtr SMDS_MeshElement::nodeIterator() const
224 {
225   return SMDS_NodeIteratorPtr
226     ( new _MyNodeIteratorFromElemIterator( nodesIterator() ));
227 }
228
229 bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
230 {
231         if(e1.GetType()!=e2.GetType()) return false;
232         switch(e1.GetType())
233         {
234         case SMDSAbs_Node:
235                 return static_cast<const SMDS_MeshNode &>(e1) <
236                         static_cast<const SMDS_MeshNode &>(e2);
237
238         case SMDSAbs_Edge:
239                 return static_cast<const SMDS_MeshEdge &>(e1) <
240                         static_cast<const SMDS_MeshEdge &>(e2);
241
242         case SMDSAbs_Face:
243                 return static_cast<const SMDS_MeshFace &>(e1) <
244                         static_cast<const SMDS_MeshFace &>(e2);
245
246         case SMDSAbs_Volume:
247                 return static_cast<const SMDS_MeshVolume &>(e1) <
248                         static_cast<const SMDS_MeshVolume &>(e2);
249
250         default : MESSAGE("Internal Error");
251         }
252         return false;
253 }
254
255 bool SMDS_MeshElement::IsValidIndex(const int ind) const
256 {
257   return ( ind>-1 && ind<NbNodes() );
258 }
259
260 const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const
261 {
262   if ( ind >= 0 ) {
263     SMDS_ElemIteratorPtr it = nodesIterator();
264     for ( int i = 0; i < ind; ++i )
265       it->next();
266     if ( it->more() )
267       return static_cast<const SMDS_MeshNode*> (it->next());
268   }
269   return 0;
270 }
271
272 bool SMDS_MeshElement::IsQuadratic() const
273 {
274   return false;
275 }
276
277 bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
278 {
279   return false;
280 }
281
282 //================================================================================
283 /*!
284  * \brief Return number of nodes excluding medium ones
285  */
286 //================================================================================
287
288 int SMDS_MeshElement::NbCornerNodes() const
289 {
290   return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes();
291 }
292
293 //================================================================================
294   /*!
295    * \brief Check if a node belongs to the element
296     * \param node - the node to check
297     * \retval int - node index within the element, -1 if not found
298    */
299 //================================================================================
300
301 int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const
302 {
303   SMDS_ElemIteratorPtr nIt = nodesIterator();
304   for ( int i = 0; nIt->more(); ++i )
305     if ( nIt->next() == node )
306       return i;
307   return -1;
308 }