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