Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/smesh.git] / src / SMDS / SMDS_PolyhedralVolumeOfNodes.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 //
24 #ifdef _MSC_VER
25 #pragma warning(disable:4786)
26 #endif
27
28 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
29 #include "SMDS_MeshNode.hxx"
30 #include "SMDS_SetIterator.hxx"
31 #include "SMDS_VolumeTool.hxx"
32 #include "utilities.h"
33
34 #include <set>
35
36 using namespace std;
37
38 //=======================================================================
39 //function : Constructor
40 //purpose  : Create a volume of many faces
41 //=======================================================================
42 SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
43                                 (vector<const SMDS_MeshNode *> nodes,
44                                  vector<int>                   quantities)
45 : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
46 {
47   ChangeNodes(nodes, quantities);
48 }
49
50 //=======================================================================
51 //function : GetType
52 //purpose  : 
53 //=======================================================================
54 SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const
55 {
56 //  return SMDSAbs_PolyhedralVolume;
57   return SMDSAbs_Volume;
58 }
59
60 //=======================================================================
61 //function : ChangeNodes
62 //purpose  : 
63 //=======================================================================
64 bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const vector<const SMDS_MeshNode *>& nodes,
65                                                 const vector<int>&                   quantities)
66 {
67   myNodesByFaces = nodes;
68   myQuantities = quantities;
69
70   // Init fields of parent class, it allows to get only unique nodes(?)
71
72   set<const SMDS_MeshNode *> aSet;
73   aSet.insert( nodes.begin(), nodes.end());
74   //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes);
75   delete [] myNodes;
76   myNbNodes = aSet.size();
77   myNodes = new const SMDS_MeshNode* [myNbNodes];
78   set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
79   for (int k=0; anIter != aSet.end(); anIter++, k++)
80     myNodes[k] = *anIter;
81
82   return true;
83 }
84
85 //=======================================================================
86 //function : NbEdges
87 //purpose  : 
88 //=======================================================================
89 int SMDS_PolyhedralVolumeOfNodes::NbNodes() const
90 {
91   return myNodesByFaces.size();
92 }
93
94 //=======================================================================
95 //function : NbEdges
96 //purpose  : 
97 //=======================================================================
98 int SMDS_PolyhedralVolumeOfNodes::NbEdges() const
99 {
100   int nbEdges = 0;
101
102   for (int ifa = 0; ifa < myQuantities.size(); ifa++) {
103     nbEdges += myQuantities[ifa];
104   }
105   nbEdges /= 2;
106
107   return nbEdges;
108 }
109
110 //=======================================================================
111 //function : NbFaces
112 //purpose  : 
113 //=======================================================================
114 int SMDS_PolyhedralVolumeOfNodes::NbFaces() const
115 {
116   return myQuantities.size();
117 }
118
119 //=======================================================================
120 //function : NbFaceNodes
121 //purpose  : 
122 //=======================================================================
123 int SMDS_PolyhedralVolumeOfNodes::NbFaceNodes (const int face_ind) const
124 {
125   if (face_ind < 1 || myQuantities.size() < face_ind)
126     return 0;
127   return myQuantities[face_ind - 1];
128 }
129
130 //=======================================================================
131 //function : GetFaceNode
132 //purpose  : 
133 //=======================================================================
134 const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetFaceNode (const int face_ind,
135                                                                 const int node_ind) const
136 {
137   if (node_ind < 1 || NbFaceNodes(face_ind) < node_ind)
138     return NULL;
139
140   int i, first_node = 0;
141   for (i = 0; i < face_ind - 1; i++) {
142     first_node += myQuantities[i];
143   }
144
145   return myNodesByFaces[first_node + node_ind - 1];
146 }
147
148 //=======================================================================
149 //function : Print
150 //purpose  : 
151 //=======================================================================
152 void SMDS_PolyhedralVolumeOfNodes::Print (ostream & OS) const
153 {
154   OS << "polyhedral volume <" << GetID() << "> : ";
155
156   int faces_len = myQuantities.size();
157   //int nodes_len = myNodesByFaces.size();
158   int cur_first_node = 0;
159
160   int i, j;
161   for (i = 0; i < faces_len; i++) {
162     OS << "face_" << i << " (";
163     for (j = 0; j < myQuantities[i] - 1; j++) {
164       OS << myNodesByFaces[cur_first_node + j] << ",";
165     }
166     OS << myNodesByFaces[cur_first_node + j] << ") ";
167     cur_first_node += myQuantities[i];
168   }
169 }
170
171 //=======================================================================
172 //function : ChangeNodes
173 //purpose  : usage disabled
174 //=======================================================================
175 bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[],
176                                                 const int            nbNodes)
177 {
178   return false;
179 }
180
181 /// ===================================================================
182 /*!
183  * \brief Iterator on node of volume
184  */
185 /// ===================================================================
186
187 struct _MyIterator:public SMDS_NodeVectorElemIterator
188 {
189   _MyIterator(const vector<const SMDS_MeshNode *>& nodes):
190     SMDS_NodeVectorElemIterator( nodes.begin(), nodes.end()) {}
191 };
192
193 /// ===================================================================
194 /*!
195  * \brief Iterator on faces or edges of volume
196  */
197 /// ===================================================================
198
199 class _MySubIterator : public SMDS_ElemIterator
200 {
201   vector< const SMDS_MeshElement* > myElems;
202   int myIndex;
203 public:
204   _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) {
205     SMDS_VolumeTool vTool(vol);
206     if (type == SMDSAbs_Face)
207       vTool.GetAllExistingFaces( myElems );
208     else
209       vTool.GetAllExistingEdges( myElems );
210   }
211   /// Return true if and only if there are other object in this iterator
212   virtual bool more() { return myIndex < myElems.size(); }
213
214   /// Return the current object and step to the next one
215   virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
216 };
217
218 //================================================================================
219 /*!
220  * \brief Return Iterator of sub elements
221  */
222 //================================================================================
223
224 SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
225 {
226   switch(type)
227   {
228   case SMDSAbs_Volume:
229     return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
230   case SMDSAbs_Node:
231     return SMDS_ElemIteratorPtr(new _MyIterator(myNodesByFaces));
232   case SMDSAbs_Face:
233     return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
234   case SMDSAbs_Edge:
235     return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
236   default:
237     MESSAGE("ERROR : Iterator not implemented");
238     return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
239   }
240 }
241
242 //================================================================================
243 /*!
244  * \brief Return iterator on unique nodes
245  */
246 //================================================================================
247
248 SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const
249 {
250   return SMDS_ElemIteratorPtr
251     (new SMDS_NodeArrayElemIterator( myNodes, & myNodes[ myNbNodes ]));
252 }
253
254 //================================================================================
255 /*!
256  * \brief Return node by its index
257  */
258 //================================================================================
259
260 const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const
261 {
262   return myNodesByFaces[ WrappedIndex( ind )];
263 }