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