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