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