Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/smesh.git] / src / SMDS / SMDS_QuadraticFaceOfNodes.cxx
1 //  Copyright (C) 2007-2008  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 //  SMESH SMDS : implementaion of Salome mesh data structure
23 // File:      SMDS_QuadraticFaceOfNodes.cxx
24 // Created:   16.01.06 17:12:58
25 // Author:    Sergey KUUL
26 //
27 #include "SMDS_QuadraticFaceOfNodes.hxx"
28
29 #include "SMDS_SetIterator.hxx"
30 #include "SMDS_IteratorOfElements.hxx"
31 #include "SMDS_MeshNode.hxx"
32 #include "SMDS_Mesh.hxx"
33
34 #include "utilities.h"
35
36 using namespace std;
37
38
39 //=======================================================================
40 //function : SMDS_QuadraticFaceOfNodes()
41 //purpose  : Constructor
42 //=======================================================================
43
44 SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
45                                                      const SMDS_MeshNode * n2,
46                                                      const SMDS_MeshNode * n3,
47                                                      const SMDS_MeshNode * n12,
48                                                      const SMDS_MeshNode * n23,
49                                                      const SMDS_MeshNode * n31)
50 {
51   myNodes.resize( 6 );
52   myNodes[ 0 ] = n1;
53   myNodes[ 1 ] = n2;
54   myNodes[ 2 ] = n3;
55   myNodes[ 3 ] = n12;
56   myNodes[ 4 ] = n23;
57   myNodes[ 5 ] = n31;
58 }
59
60
61 //=======================================================================
62 //function : SMDS_QuadraticFaceOfNodes()
63 //purpose  : Constructor
64 //=======================================================================
65
66 SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
67                                                      const SMDS_MeshNode * n2,
68                                                      const SMDS_MeshNode * n3,
69                                                      const SMDS_MeshNode * n4,
70                                                      const SMDS_MeshNode * n12,
71                                                      const SMDS_MeshNode * n23,
72                                                      const SMDS_MeshNode * n34,
73                                                      const SMDS_MeshNode * n41)
74 {
75   myNodes.resize( 8 );
76   myNodes[ 0 ] = n1;
77   myNodes[ 1 ] = n2;
78   myNodes[ 2 ] = n3;
79   myNodes[ 3 ] = n4;
80   myNodes[ 4 ] = n12;
81   myNodes[ 5 ] = n23;
82   myNodes[ 6 ] = n34;
83   myNodes[ 7 ] = n41;
84 }
85
86
87 //=======================================================================
88 //function : IsMediumNode
89 //purpose  : 
90 //=======================================================================
91
92 bool SMDS_QuadraticFaceOfNodes::IsMediumNode(const SMDS_MeshNode * node) const
93 {
94   int i=NbNodes()/2;
95   for(; i<NbNodes(); i++) {
96     if(myNodes[i]==node) return true;
97   }
98   return false;
99 }
100
101
102 //=======================================================================
103 //function : ChangeNodes
104 //purpose  : 
105 //=======================================================================
106
107 bool SMDS_QuadraticFaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
108                                             const int            nbNodes)
109 {
110   if( nbNodes==6 || nbNodes==8 ) {
111     myNodes.resize(nbNodes);
112     int i=0;
113     for(; i<nbNodes; i++) {
114       myNodes[i] = nodes[i];
115     }
116     return true;
117   }
118   return false;
119 }
120
121
122 //=======================================================================
123 //function : NbNodes
124 //purpose  : 
125 //=======================================================================
126 int SMDS_QuadraticFaceOfNodes::NbNodes() const
127 {
128   return myNodes.size();
129 }
130
131
132 //=======================================================================
133 //function : NbEdges
134 //purpose  : 
135 //=======================================================================
136 int SMDS_QuadraticFaceOfNodes::NbEdges() const
137 {
138   return NbNodes()/2;
139 }
140
141
142 //=======================================================================
143 //function : NbFaces
144 //purpose  : 
145 //=======================================================================
146 int SMDS_QuadraticFaceOfNodes::NbFaces() const
147 {
148   return 1;
149 }
150
151 //=======================================================================
152 //function : Print
153 //purpose  : 
154 //=======================================================================
155 void SMDS_QuadraticFaceOfNodes::Print(ostream & OS) const
156 {
157   OS << "quadratic face <" << GetID() << " > : ";
158   int i, nbNodes = myNodes.size();
159   for (i = 0; i < nbNodes - 1; i++)
160     OS << myNodes[i] << ",";
161   OS << myNodes[i] << ") " << endl;
162 }
163
164 namespace {
165
166   //=======================================================================
167   //class : _MyInterlacedNodeIterator
168   //purpose  : 
169   //=======================================================================
170
171   class _MyInterlacedNodeIterator:public SMDS_NodeIterator
172   {
173     const vector<const SMDS_MeshNode *>& mySet;
174     int myIndex;
175     const int * myInterlace;
176   public:
177     _MyInterlacedNodeIterator(const vector<const SMDS_MeshNode *>& s,
178                               const int * interlace):
179       mySet(s),myIndex(0),myInterlace(interlace) {}
180
181     bool more()
182     {
183       return myIndex < mySet.size();
184     }
185
186     const SMDS_MeshNode* next()
187     {
188       return mySet[ myInterlace[ myIndex++ ]];
189     }
190   };
191
192   //=======================================================================
193   //class : _MyInterlacedNodeElemIterator
194   //purpose  : 
195   //=======================================================================
196
197   class _MyInterlacedNodeElemIterator : public SMDS_ElemIterator
198   {
199     SMDS_NodeIteratorPtr myItr;
200   public:
201     _MyInterlacedNodeElemIterator(SMDS_NodeIteratorPtr interlacedNodeItr):
202       myItr( interlacedNodeItr ) {}
203     bool more()                    { return myItr->more(); }
204     const SMDS_MeshElement* next() { return myItr->next(); }
205   };
206
207   //=======================================================================
208   //class : _MyNodeIterator
209   //purpose  : 
210   //=======================================================================
211
212   class _MyNodeIterator : public SMDS_NodeVectorElemIterator
213   {
214   public:
215     _MyNodeIterator(const vector<const SMDS_MeshNode *>& s):
216       SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
217   };
218   
219 }
220
221 //=======================================================================
222 //function : interlacedNodesIterator
223 //purpose  : 
224 //=======================================================================
225
226 SMDS_NodeIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesIterator() const
227 {
228   static int triaInterlace [] = { 0, 3, 1, 4, 2, 5 };
229   static int quadInterlace [] = { 0, 4, 1, 5, 2, 6, 3, 7 };
230   return SMDS_NodeIteratorPtr
231     (new _MyInterlacedNodeIterator (myNodes, myNodes.size()==6 ? triaInterlace : quadInterlace));
232 }
233
234 //=======================================================================
235 //function : interlacedNodesElemIterator
236 //purpose  : 
237 //=======================================================================
238
239 SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesElemIterator() const
240 {
241   return SMDS_ElemIteratorPtr
242     (new _MyInterlacedNodeElemIterator ( interlacedNodesIterator() ));
243 }
244 /// ===================================================================
245 /*!
246  * \brief Iterator on edges of face
247  */
248 /// ===================================================================
249
250 class _MyEdgeIterator : public SMDS_ElemIterator
251 {
252   vector< const SMDS_MeshElement* > myElems;
253   int myIndex;
254 public:
255   _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) {
256     myElems.reserve( face->NbNodes() );
257     SMDS_ElemIteratorPtr nIt = face->interlacedNodesElemIterator();
258     const SMDS_MeshNode* n0 = face->GetNode( -1 );
259     while ( nIt->more() ) {
260       const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nIt->next() );
261       const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 );
262       if ( edge )
263         myElems.push_back( edge );
264       n0 = n1;
265     }
266   }
267   /// Return true if and only if there are other object in this iterator
268   virtual bool more() { return myIndex < myElems.size(); }
269
270   /// Return the current object and step to the next one
271   virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
272 };
273
274 //=======================================================================
275 //function : elementsIterator
276 //purpose  : 
277 //=======================================================================
278
279 SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator
280                                          (SMDSAbs_ElementType type) const
281 {
282   switch(type)
283   {
284   case SMDSAbs_Face:
285     return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
286   case SMDSAbs_Node:
287     return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes));
288   case SMDSAbs_Edge:
289     return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
290     break;
291   default:
292     return SMDS_ElemIteratorPtr
293       (new SMDS_IteratorOfElements
294        (this,type,SMDS_ElemIteratorPtr (new _MyNodeIterator(myNodes))));
295   }
296   return SMDS_ElemIteratorPtr();
297 }
298
299 /*!
300  * \brief Return node by its index
301  * \param ind - node index
302  * \retval const SMDS_MeshNode* - the node
303  * 
304  * Index is wrapped if it is out of a valid range
305  */
306 const SMDS_MeshNode* SMDS_QuadraticFaceOfNodes::GetNode(const int ind) const
307 {
308   return myNodes[ WrappedIndex( ind )];
309 }
310