]> SALOME platform Git repositories - modules/multipr.git/blob - src/MULTIPR/MULTIPR_Nodes.cxx
Salome HOME
*** empty log message ***
[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