]> SALOME platform Git repositories - modules/multipr.git/blob - src/MULTIPR/MULTIPR_Nodes.cxx
Salome HOME
a499c9595f324d41dee930cfe8d1cb3c66fc4d32
[modules/multipr.git] / src / MULTIPR / MULTIPR_Nodes.cxx
1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
3
4 /**
5  * \file    MULTIPR_Nodes.cxx
6  *
7  * \brief   see MULTIPR_Nodes.hxx
8  *
9  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
10  * 
11  * \date    01/2007
12  */
13
14 //*****************************************************************************
15 // Includes section
16 //*****************************************************************************
17
18 #include "MULTIPR_Nodes.hxx"
19 #include "MULTIPR_Exceptions.hxx"
20
21 #include <iostream>
22
23 using namespace std;
24
25
26 namespace multipr
27 {
28
29
30 //*****************************************************************************
31 // Class Nodes implementation
32 //*****************************************************************************
33
34 Nodes::Nodes() 
35 {
36         mId           = NULL;
37         mFamIdent     = NULL;
38         mNames        = NULL;
39         mCoo          = NULL;
40         mNamesCoo     = NULL;
41         mNamesUnitCoo = NULL;
42         
43         reset(); 
44 }
45
46
47 Nodes::~Nodes()  
48
49         reset();  
50 }
51
52
53 void Nodes::reset() 
54
55         mNum         = 0;
56         mDim         = 0;
57         mCoordSystem = MED_CART;
58         
59         if (mId           != NULL) { delete[] mId;           mId           = NULL; }
60         if (mFamIdent     != NULL) { delete[] mFamIdent;     mFamIdent     = NULL; }
61         if (mNames        != NULL) { delete[] mNames;        mNames        = NULL; }
62         if (mCoo          != NULL) { delete[] mCoo;          mCoo          = NULL; }
63         if (mNamesCoo     != NULL) { delete[] mNamesCoo;     mNamesCoo     = NULL; }
64         if (mNamesUnitCoo != NULL) { delete[] mNamesUnitCoo; mNamesUnitCoo = NULL; }
65         
66         mFlagPrintAll = false;
67 }
68
69
70 const med_float* Nodes::getCoordinates(med_int pIndexNode) const 
71
72         if ((pIndexNode < 0) || (pIndexNode >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
73         
74         return mCoo + pIndexNode * mDim; 
75 }
76
77
78 med_int Nodes::getFamIdent(med_int pIndexNode) const 
79
80         if ((pIndexNode < 0) || (pIndexNode >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
81         
82         return mFamIdent[pIndexNode]; 
83 }
84
85
86 void Nodes::getBBox(med_float pMin[3], med_float pMax[3]) const
87 {
88         //---------------------------------------------------------------------
89         // Special case: no nodes => bbox = [0 ; 0] x [0 ; 0] x [0 ; 0]
90         //---------------------------------------------------------------------
91         if (mNum == 0)
92         {
93                 for (int itDim = 0 ; itDim < mDim ; itDim++) 
94                 { 
95                         pMin[itDim] = med_float(0.0);
96                         pMax[itDim] = med_float(0.0);
97                 }
98                 
99                 return;
100         }
101         
102         //---------------------------------------------------------------------
103         // Compute axis-aligned bounding box
104         //---------------------------------------------------------------------
105         for (int itDim = 0 ; itDim < mDim ; itDim++) 
106         { 
107                 pMin[itDim] = numeric_limits<med_float>::max();
108                 pMax[itDim] = -pMin[itDim];
109         }
110         for (int itNode = 0 ; itNode < mNum ; itNode++)
111         {       
112                 for (int itDim = 0 ; itDim < mDim ; itDim++)
113                 {
114                         med_float coord = mCoo[itNode * mDim + itDim];
115                         if (coord < pMin[itDim]) pMin[itDim] = coord;
116                         if (coord > pMax[itDim]) pMax[itDim] = coord;
117                 }
118         }
119 }
120
121
122 set<med_int> Nodes::getSetOfFamilies() const
123 {
124         set<med_int> setOfFamilies;
125         
126         // for each node, ad its family to the set
127         for (int itNode = 0 ; itNode < mNum ; itNode++)
128         {
129                 setOfFamilies.insert(mFamIdent[itNode]);
130         }
131         
132         return setOfFamilies;
133 }
134
135
136 Nodes* Nodes::extractSubSet(const set<med_int>& pSetIndices) const
137 {
138         Nodes* subset = new Nodes();
139         
140         subset->mNum         = pSetIndices.size();
141         subset->mDim         = mDim;
142         subset->mCoordSystem = mCoordSystem;
143         
144         //---------------------------------------------------------------------
145         // Allocate arrays
146         //---------------------------------------------------------------------
147         subset->mFamIdent     = new med_int[subset->mNum];      
148         subset->mCoo          = new med_float[subset->mDim * subset->mNum];
149         subset->mNamesCoo     = new char[subset->mDim * MED_TAILLE_PNOM + 1];
150         subset->mNamesUnitCoo = new char[subset->mDim * MED_TAILLE_PNOM + 1];
151         
152         memcpy(subset->mNamesCoo, mNamesCoo, subset->mDim * MED_TAILLE_PNOM + 1);
153         memcpy(subset->mNamesUnitCoo, mNamesUnitCoo, subset->mDim * MED_TAILLE_PNOM + 1);
154         
155         //---------------------------------------------------------------------
156         // Copy subset of familys id and coords.
157         //---------------------------------------------------------------------
158         set<med_int>::iterator itSet = pSetIndices.begin();
159         for (int i = 0 ; i < subset->mNum; i++)
160         {
161                 
162                 med_int srcIndex = (*itSet) - 1; // MED index start at 1
163                 subset->mFamIdent[i] = mFamIdent[srcIndex];
164                 
165                 med_float* srcCoo = mCoo + srcIndex * mDim;
166                 med_float* destCoo = subset->mCoo + i * subset->mDim;
167                 for (int itDim = 0 ; itDim < mDim ; itDim++)
168                 {
169                         destCoo[itDim] = srcCoo[itDim];
170                 }
171                 
172                 itSet++;
173         }
174         
175         //---------------------------------------------------------------------
176         // Copy subset of identifiers if necessary
177         //---------------------------------------------------------------------
178         if (isIdentifiers())  
179         { 
180                 itSet = pSetIndices.begin();
181                 subset->mId = new med_int[subset->mNum]; 
182                 for (int i = 0 ; i < subset->mNum; i++)
183                 {
184                         med_int srcIndex = (*itSet) - 1; // MED index start at 1
185                         subset->mId[i] = mId[srcIndex];
186                         
187                         itSet++;
188                 }
189         }
190         
191         //---------------------------------------------------------------------
192         // Copy subset of names if necessary
193         //---------------------------------------------------------------------
194         if (isNames())       
195         { 
196                 subset->mNames = new char[MED_TAILLE_PNOM * subset->mNum + 1]; 
197                 char* destPtr = subset->mNames;
198                 itSet = pSetIndices.begin();
199                 for (int i = 0 ; i < subset->mNum; i++)
200                 {
201                         med_int srcIndex = (*itSet) - 1; // MED index start at 1
202                         char* srcPtr = mNames + srcIndex * MED_TAILLE_PNOM;
203                         memcpy(destPtr, srcPtr, MED_TAILLE_PNOM);
204                         destPtr += MED_TAILLE_PNOM;
205                         
206                         itSet++;
207                 }
208                 subset->mNames[MED_TAILLE_PNOM * subset->mNum] = '\0';
209         }
210         
211         return subset;
212 }
213
214
215 void Nodes::readMED(med_idt pMEDfile, char* pMeshName, med_int pDim)
216 {
217         if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
218         if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
219         if (pDim != 3) throw IllegalArgumentException("", __FILE__, __LINE__);
220         
221         reset();
222         
223         mDim = pDim;
224         mNum = MEDnEntMaa(
225                 pMEDfile, 
226                 pMeshName, 
227                 MED_COOR, 
228                 MED_NOEUD, 
229                 med_geometrie_element(0), 
230                 med_connectivite(0));
231         
232         if (mNum <= 0) throw IOException("", __FILE__, __LINE__);
233         
234         mId           = new med_int[mNum];
235         mFamIdent     = new med_int[mNum];      
236         mNames        = new char[MED_TAILLE_PNOM * mNum + 1];
237         mCoo          = new med_float[mDim * mNum];
238         mNamesCoo     = new char[mDim * MED_TAILLE_PNOM + 1];
239         mNamesUnitCoo = new char[mDim * MED_TAILLE_PNOM + 1];
240         
241         mNames[0] = '\0';
242         mNamesCoo[0] = '\0';
243         mNamesUnitCoo[0] = '\0';
244         
245         med_booleen isIdentifiers;
246         med_booleen isNames;
247         
248         med_err ret = MEDnoeudsLire(
249                 pMEDfile, 
250                 pMeshName, 
251                 mDim,
252                 mCoo, 
253                 MED_FULL_INTERLACE,
254                 &mCoordSystem, 
255                 mNamesCoo, 
256                 mNamesUnitCoo,
257                 mNames, 
258                 &isNames, 
259                 mId, 
260                 &isIdentifiers,
261                 mFamIdent,    
262                 mNum);
263                 
264         if (ret != 0) throw IOException("", __FILE__, __LINE__);
265         
266         // check if coordinates system is CARTESIAN
267         if (mCoordSystem != MED_CART) throw IllegalStateException("", __FILE__, __LINE__);
268         
269         if (!isNames)
270         {
271                 delete[] mNames;
272                 mNames = NULL;
273         }
274         
275         if (!isIdentifiers)
276         {
277                 delete[] mId;
278                 mId = NULL;
279         }
280 }
281
282
283 void Nodes::writeMED(med_idt pMEDfile, char* pMeshName) const
284 {
285         if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
286         if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
287         if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
288         if ((mDim < 1) || (mDim > 3)) throw IllegalStateException("", __FILE__, __LINE__);
289         if (mFamIdent == NULL) throw IllegalStateException("", __FILE__, __LINE__);
290         if (mCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
291         if (mNamesCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
292         if (mNamesUnitCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
293         
294         // special case: if no nodes => do nothing
295         if (mNum == 0) return;
296         
297         med_err ret = MEDnoeudsEcr(
298                 pMEDfile,
299                 pMeshName,
300                 mDim,
301                 mCoo,
302                 MED_FULL_INTERLACE,
303                 mCoordSystem,
304                 mNamesCoo,
305                 mNamesUnitCoo,
306                 mNames,
307                 isNames()?MED_VRAI:MED_FAUX,
308                 mId,
309                 isIdentifiers()?MED_VRAI:MED_FAUX,
310                 mFamIdent,
311                 mNum);
312         
313         if (ret != 0) throw IOException("i/o error while writing nodes", __FILE__, __LINE__);
314         
315 }
316
317
318 ostream& operator<<(ostream& pOs, Nodes& pN)
319 {
320         char strCoordSystem[16];
321         switch (pN.mCoordSystem) 
322         {
323                 case MED_CART:  strcpy(strCoordSystem, "CARTESIAN"); break;
324                 case MED_CYL:   strcpy(strCoordSystem, "CYLINDRIC"); break;
325                 case MED_SPHER: strcpy(strCoordSystem, "SPHERIC"); break;
326                 default:        strcpy(strCoordSystem, "UNKNOWN"); break;
327         }
328         
329         pOs << "Nodes: " << endl;
330         pOs << "    #number      =" << pN.mNum << endl;
331         pOs << "    Dimension    =" << pN.mDim << endl;
332         pOs << "    Coord. system=" << strCoordSystem << endl;
333         pOs << "    Has names    ?" << (pN.isNames()?"yes":"no") << endl;
334         pOs << "    Has id       ?" << (pN.isIdentifiers()?"yes":"no") << endl;
335         pOs << "    Axis names   =" << "|" << pN.mNamesCoo << "|" << endl;
336         pOs << "    Unit axis    =" << "|" << pN.mNamesUnitCoo << "|" << endl;
337         
338         {
339                 set<med_int> setOfFam = pN.getSetOfFamilies();
340                 if (setOfFam.size() == 0)
341                 {
342                         pOs << "    Families: #fam=0" << endl;
343                 }
344                 else
345                 {
346                         set<med_int>::iterator itFam = setOfFam.end();
347                         itFam--;
348                         pOs << "    Families: #fam=" << setOfFam.size() << " id_min=" << (*(setOfFam.begin())) << " id_max=" << (*itFam) << endl;
349                 }
350                 
351                 if (pN.mFlagPrintAll)
352                 {
353                         for (int itNode = 0 ; itNode < pN.mNum; itNode++)
354                         {
355                                 pOs << "        Node " << (itNode+1) << ": " << pN.mFamIdent[itNode] << endl;
356                         }
357                 }
358         }
359         
360         med_float bboxMin[3], bboxMax[3];
361         pN.getBBox(bboxMin, bboxMax);
362         pOs << "    BBox: [" << bboxMin[0] << " ; " << bboxMax[0] << "] x [" << bboxMin[1] << " ; " << bboxMax[1] << "] x [" << bboxMin[2] << " ; " << bboxMax[2] << "]" << endl; 
363         
364         if (pN.mFlagPrintAll)
365         {
366                 pOs << "    Coordinates: " << endl;
367                 for (int itNode = 0 ; itNode < pN.mNum ; itNode++)
368                 {
369                         pOs << "        Node " << (itNode+1) << ": ";
370                         for (int itDim = 0 ; itDim < pN.mDim ; itDim++)
371                         {
372                                 pOs << pN.mCoo[itNode * pN.mDim + itDim] << " ";
373                         }
374                         pOs << endl;
375                 }
376                 
377                 if (pN.isIdentifiers())
378                 {
379                         pOs << "    Num: " << endl;
380                         for (int itNode = 0 ; itNode < pN.mNum; itNode++)
381                         {
382                                 pOs << "        Node " << (itNode+1) << ": " << pN.mId[itNode] << endl;
383                         }
384                 }
385                 
386                 if (pN.isNames())
387                 {
388                         pN.mNames[MED_TAILLE_PNOM * pN.mNum] = '\0';
389                         pOs << "    Names: |" << pN.mNames << "|" << endl;
390                 }
391                 
392         }
393         
394         return pOs;
395 }
396
397
398 } // namespace  multipr
399
400 // EOF