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