Salome HOME
Copyright update 2022
[modules/smesh.git] / src / MEDWrapper / MED_Structures.cxx
1 // Copyright (C) 2007-2022  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 #include "MED_Structures.hxx"
24 #include "MED_Utilities.hxx"
25
26 #include <cstring>
27
28 namespace MED
29 {
30   std::string
31   GetString(TInt theId,
32             TInt theStep,
33             const TString& theString)
34   {
35     const char* aPos = &theString[theId*theStep];
36     TInt aSize = std::min(TInt(strlen(aPos)),theStep);
37     return std::string(aPos,aSize);
38   }
39
40   void
41   SetString(TInt theId,
42             TInt theStep,
43             TString& theString,
44             const std::string& theValue)
45   {
46     TInt aSize = std::min(TInt(theValue.size()+1),theStep);
47     char* aPos = &theString[theId*theStep];
48     strncpy(aPos,theValue.c_str(),aSize);
49   }
50
51   void
52   SetString(TInt theId,
53             TInt theStep,
54             TString& theString,
55             const TString& theValue)
56   {
57     TInt aSize = std::min(TInt(theValue.size()+1),theStep);
58     char* aPos = &theString[theId*theStep];
59     const char* aValue = &theValue[0];
60     strncpy(aPos,aValue,aSize);
61   }
62
63   TInt
64   GetDimGaussCoord(EGeometrieElement theGeom)
65   {
66     return theGeom/100;
67   }
68
69   TInt
70   GetNbRefCoord(EGeometrieElement theGeom)
71   {
72     return (theGeom%100);
73   }
74
75   //---------------------------------------------------------------
76   PFloatTimeStampValue
77   CastToFloatTimeStampValue(const PTimeStampValueBase& theTimeStampValue)
78   {
79     return theTimeStampValue;
80   }
81
82   PIntTimeStampValue
83   CastToIntTimeStampValue(const PTimeStampValueBase& theTimeStampValue)
84   {
85     return theTimeStampValue;
86   }
87
88   //---------------------------------------------------------------
89   TInt
90   TFamilyInfo
91   ::GetAttrId(TInt theId) const
92   {
93     return myAttrId[theId];
94   }
95
96   TInt
97   TFamilyInfo
98   ::GetAttrVal(TInt theId) const
99   {
100     return myAttrVal[theId];
101   }
102
103   void
104   TFamilyInfo
105   ::SetAttrId(TInt theId,TInt theVal)
106   {
107     myAttrId[theId] = theVal;
108   }
109
110   void
111   TFamilyInfo
112   ::SetAttrVal(TInt theId,TInt theVal)
113   {
114     myAttrVal[theId] = theVal;
115   }
116
117   //---------------------------------------------------------------
118   TInt
119   TElemInfo
120   ::GetFamNum(TInt theId) const
121   {
122     return (*myFamNum)[theId];
123   }
124
125   void
126   TElemInfo
127   ::SetFamNum(TInt theId, TInt theVal)
128   {
129     (*myFamNum)[theId] = theVal;
130     myIsFamNum = eVRAI;
131   }
132
133   TInt
134   TElemInfo
135   ::GetElemNum(TInt theId) const
136   {
137     return (*myElemNum)[theId];
138   }
139
140   void
141   TElemInfo
142   ::SetElemNum(TInt theId, TInt theVal)
143   {
144     if ( IsElemNum() )
145       (*myElemNum)[theId] = theVal;
146   }
147
148   //---------------------------------------------------------------
149   TCCoordSlice
150   TNodeInfo
151   ::GetCoordSlice(TInt theId) const
152   {
153     TInt aDim = myMeshInfo->GetSpaceDim();
154     if(GetModeSwitch() == eFULL_INTERLACE)
155       return TCCoordSlice(*myCoord, std::slice(theId*aDim, aDim, 1));
156     else
157       return TCCoordSlice(*myCoord, std::slice(theId, aDim, aDim));
158   }
159
160   TCoordSlice
161   TNodeInfo
162   ::GetCoordSlice(TInt theId)
163   {
164     TInt aDim = myMeshInfo->GetSpaceDim();
165     if(GetModeSwitch() == eFULL_INTERLACE)
166       return TCoordSlice(*myCoord, std::slice(theId*aDim,aDim,1));
167     else
168       return TCoordSlice(*myCoord, std::slice(theId,aDim,aDim));
169   }
170
171   //---------------------------------------------------------------
172   TCConnSlice
173   TCellInfo
174   ::GetConnSlice(TInt theElemId) const
175   {
176     if(GetModeSwitch() == eFULL_INTERLACE)
177       return TCConnSlice(*myConn, std::slice(GetConnDim()*theElemId, GetNbNodes(myGeom), 1));
178     else
179       return TCConnSlice(*myConn, std::slice(theElemId, GetNbNodes(myGeom), GetConnDim()));
180   }
181
182   TConnSlice
183   TCellInfo
184   ::GetConnSlice(TInt theElemId)
185   {
186     if(GetModeSwitch() == eFULL_INTERLACE)
187       return TConnSlice(*myConn, std::slice(GetConnDim()*theElemId, GetNbNodes(myGeom), 1));
188     else
189       return TConnSlice(*myConn, std::slice(theElemId, GetNbNodes(myGeom), GetConnDim()));
190   }
191
192   //---------------------------------------------------------------
193   TInt
194   TPolygoneInfo
195   ::GetNbConn(TInt theElemId) const
196   {
197     return (*myIndex)[theElemId + 1] - (*myIndex)[theElemId];
198   }
199
200   TCConnSlice
201   TPolygoneInfo
202   ::GetConnSlice(TInt theElemId) const
203   {
204     return TCConnSlice(*myConn, std::slice((*myIndex)[theElemId] - 1, GetNbConn(theElemId), 1));
205   }
206
207   TConnSlice
208   TPolygoneInfo
209   ::GetConnSlice(TInt theElemId)
210   {
211     return TConnSlice(*myConn, std::slice((*myIndex)[theElemId] - 1, GetNbConn(theElemId), 1));
212   }
213
214   //---------------------------------------------------------------
215   TInt
216   TPolyedreInfo
217   ::GetNbFaces(TInt theElemId) const
218   {
219     return (*myIndex)[theElemId+1] - (*myIndex)[theElemId];
220   }
221
222   TInt
223   TPolyedreInfo
224   ::GetNbNodes(TInt theElemId) const
225   {
226     TInt aNbNodes = 0;
227     TInt aNbFaces = GetNbFaces(theElemId);
228     TInt aStartFaceId = (*myIndex)[theElemId] - 1;
229     for(TInt aFaceId = 0; aFaceId < aNbFaces; aFaceId++, aStartFaceId++){
230       TInt aCurrentId = (*myFaces)[aStartFaceId];
231       TInt aDiff = (*myFaces)[aStartFaceId + 1] - aCurrentId;
232       aNbNodes += aDiff;
233     }
234     return aNbNodes;
235   }
236
237   TCConnSliceArr
238   TPolyedreInfo
239   ::GetConnSliceArr(TInt theElemId) const
240   {
241     TInt aNbFaces = GetNbFaces(theElemId);
242     TCConnSliceArr aConnSliceArr(aNbFaces);
243     TInt aStartFaceId = (*myIndex)[theElemId] - 1;
244     for(TInt aFaceId = 0; aFaceId < aNbFaces; aFaceId++, aStartFaceId++){
245       TInt aCurrentId = (*myFaces)[aStartFaceId];
246       TInt aDiff = (*myFaces)[aStartFaceId + 1] - aCurrentId;
247       aConnSliceArr[aFaceId] =
248         TCConnSlice(*myConn, std::slice(aCurrentId - 1, aDiff, 1));
249     }
250     return aConnSliceArr;
251   }
252
253   TConnSliceArr
254   TPolyedreInfo
255   ::GetConnSliceArr(TInt theElemId)
256   {
257     TInt aNbFaces = GetNbFaces(theElemId);
258     TConnSliceArr aConnSliceArr(aNbFaces);
259     TInt aStartFaceId = (*myIndex)[theElemId] - 1;
260     for(TInt aFaceId = 0; aFaceId < aNbFaces; aFaceId++, aStartFaceId++){
261       TInt aCurrentId = (*myFaces)[aStartFaceId];
262       TInt aDiff = (*myFaces)[aStartFaceId + 1] - aCurrentId;
263       aConnSliceArr[aFaceId] =
264         TConnSlice(*myConn, std::slice(aCurrentId - 1, aDiff, 1));
265     }
266     return aConnSliceArr;
267   }
268
269   //---------------------------------------------------------------
270   TMeshValueBase
271   ::TMeshValueBase():
272     myNbElem(0),
273     myNbComp(0),
274     myNbGauss(0),
275     myStep(0)
276   {}
277
278   void
279   TMeshValueBase
280   ::Allocate(TInt theNbElem,
281              TInt theNbGauss,
282              TInt theNbComp,
283              EModeSwitch theMode)
284   {
285     myModeSwitch = theMode;
286
287     myNbElem = theNbElem;
288     myNbGauss = theNbGauss;
289     myNbComp = theNbComp;
290
291     myStep = theNbComp*theNbGauss;
292   }
293
294   size_t
295   TMeshValueBase
296   ::GetSize() const
297   {
298     return myNbElem * myStep;
299   }
300
301   size_t
302   TMeshValueBase
303   ::GetNbVal() const
304   {
305     return myNbElem * myNbGauss;
306   }
307
308   size_t
309   TMeshValueBase
310   ::GetNbGauss() const
311   {
312     return myNbGauss;
313   }
314
315   size_t
316   TMeshValueBase
317   ::GetStep() const
318   {
319     return myStep;
320   }
321
322   //---------------------------------------------------------------
323   TInt
324   TProfileInfo
325   ::GetElemNum(TInt theId) const
326   {
327     return (*myElemNum)[theId];
328   }
329
330   void
331   TProfileInfo
332   ::SetElemNum(TInt theId,TInt theVal)
333   {
334     (*myElemNum)[theId] = theVal;
335   }
336
337   //---------------------------------------------------------------
338   bool
339   TGaussInfo::TLess
340   ::operator()(const TKey& theLeft, const TKey& theRight) const
341   {
342     EGeometrieElement aLGeom = boost::get<0>(theLeft);
343     EGeometrieElement aRGeom = boost::get<0>(theRight);
344     if(aLGeom != aRGeom)
345       return aLGeom < aRGeom;
346
347     const std::string& aLStr = boost::get<1>(theLeft);
348     const std::string& aRStr = boost::get<1>(theRight);
349     return aLStr < aRStr;
350   }
351
352   bool
353   TGaussInfo::TLess
354   ::operator()(const TGaussInfo& theLeft, const TGaussInfo& theRight) const
355   {
356     if(!&theLeft) // address of reference can be assumed always non-null by compiler - OK
357       return true;
358
359     if(!&theRight) //address of reference can be assumed always non-null by compiler - OK
360       return false;
361
362     if(theLeft.myGeom != theRight.myGeom)
363       return theLeft.myGeom < theRight.myGeom;
364
365     if(theLeft.myRefCoord != theRight.myRefCoord)
366       return theLeft.myRefCoord < theRight.myRefCoord;
367
368     return theLeft.myGaussCoord < theRight.myGaussCoord;
369   }
370
371   TCCoordSlice
372   TGaussInfo
373   ::GetRefCoordSlice(TInt theId) const
374   {
375     if(GetModeSwitch() == eFULL_INTERLACE)
376       return TCCoordSlice(myRefCoord,std::slice(theId*GetDim(),GetDim(),1));
377     else
378       return TCCoordSlice(myRefCoord,std::slice(theId,GetDim(),GetDim()));
379   }
380
381   TCoordSlice
382   TGaussInfo
383   ::GetRefCoordSlice(TInt theId)
384   {
385     if(GetModeSwitch() == eFULL_INTERLACE)
386       return TCoordSlice(myRefCoord,std::slice(theId*GetDim(),GetDim(),1));
387     else
388       return TCoordSlice(myRefCoord,std::slice(theId,GetDim(),GetDim()));
389   }
390
391   TCCoordSlice
392   TGaussInfo
393   ::GetGaussCoordSlice(TInt theId) const
394   {
395     if(GetModeSwitch() == eFULL_INTERLACE)
396       return TCCoordSlice(myGaussCoord,std::slice(theId*GetDim(),GetDim(),1));
397     else
398       return TCCoordSlice(myGaussCoord,std::slice(theId,GetDim(),GetDim()));
399   }
400
401   TCoordSlice
402   TGaussInfo
403   ::GetGaussCoordSlice(TInt theId)
404   {
405     if(GetModeSwitch() == eFULL_INTERLACE)
406       return TCoordSlice(myGaussCoord,std::slice(theId*GetDim(),GetNbGauss(),1));
407     else
408       return TCoordSlice(myGaussCoord,std::slice(theId,GetNbGauss(),GetDim()));
409   }
410
411   //---------------------------------------------------------------
412   TInt
413   TTimeStampInfo
414   ::GetNbGauss(EGeometrieElement theGeom) const
415   {
416     TGeom2NbGauss::const_iterator anIter = myGeom2NbGauss.find(theGeom);
417     if(anIter == myGeom2NbGauss.end())
418       return 1;//EXCEPTION(runtime_error,"TTimeStampInfo::GetNbGauss - myGeom2NbGauss.find(theGeom) fails");
419
420     return anIter->second;
421   }
422
423   //---------------------------------------------------------------
424   // TGrilleInfo structure methods
425   //---------------------------------------------------------------
426   const EGrilleType&
427   TGrilleInfo
428   ::GetGrilleType() const
429   {
430     return myGrilleType;
431   }
432
433   EGrilleType
434   TGrilleInfo
435   ::GetGrilleType()
436   {
437     return myGrilleType;
438   }
439
440   void
441   TGrilleInfo
442   ::SetGrilleType(EGrilleType theGrilleType)
443   {
444     myGrilleType = theGrilleType;
445   }
446
447   const
448   TIndexes&
449   TGrilleInfo
450   ::GetMapOfIndexes() const
451   {
452     return myIndixes;
453   }
454
455   TIndexes&
456   TGrilleInfo
457   ::GetMapOfIndexes()
458   {
459     return myIndixes;
460   }
461
462   const
463   TFloatVector&
464   TGrilleInfo
465   ::GetIndexes(TInt theAxisNumber) const
466   {
467     TIndexes::const_iterator aIter=myIndixes.find(theAxisNumber);
468     if(aIter==myIndixes.end())
469       EXCEPTION(std::runtime_error, "const TGrilleInfo::GetIndexes - myIndixes.find(theAxisNumber); fails");
470     return aIter->second;
471   }
472
473   TFloatVector&
474   TGrilleInfo
475   ::GetIndexes(TInt theAxisNumber)
476   {
477     TIndexes::iterator aIter=myIndixes.find(theAxisNumber);
478     if(aIter==myIndixes.end())
479       EXCEPTION(std::runtime_error, "TGrilleInfo::GetIndexes - myIndixes.find(theAxisNumber="<<theAxisNumber<<"); fails");
480     return aIter->second;
481   }
482
483   TInt
484   TGrilleInfo
485   ::GetNbIndexes(TInt theAxisNumber)
486   {
487     const TFloatVector& aVector=GetIndexes(theAxisNumber);
488     return aVector.size();
489   }
490
491   TInt
492   TGrilleInfo
493   ::GetNbNodes()
494   {
495     TInt nbNodes=0;
496     TInt aDim = myMeshInfo->GetDim();
497     for(int i=0;i<aDim;i++)
498       if(nbNodes == 0)
499         nbNodes = this->GetGrilleStructure()[i];
500       else
501         nbNodes = nbNodes*this->GetGrilleStructure()[i];
502
503     return nbNodes;
504   }
505
506   TInt
507   TGrilleInfo
508   ::GetNbCells()
509   {
510     TInt nbCells=0;
511     TInt aDim = myMeshInfo->GetDim();
512     for(int i=0;i<aDim;i++)
513       if(nbCells == 0)
514         nbCells = this->GetGrilleStructure()[i]-1;
515       else
516         nbCells = nbCells*(this->GetGrilleStructure()[i]-1);
517     return nbCells;
518   }
519
520   TInt
521   TGrilleInfo
522   ::GetNbSubCells()
523   {
524     TInt nb=0;
525     TInt aDim = myMeshInfo->GetDim();
526     switch (aDim) {
527     case 3:
528       nb =
529         (myGrilleStructure[0]  ) * (myGrilleStructure[1]-1) * (myGrilleStructure[2]-1) +
530         (myGrilleStructure[0]-1) * (myGrilleStructure[1]  ) * (myGrilleStructure[2]-1) +
531         (myGrilleStructure[0]-1) * (myGrilleStructure[1]-1) * (myGrilleStructure[2]  );
532       break;
533     case 2:
534       nb =
535         (myGrilleStructure[0]  ) * (myGrilleStructure[1]-1) +
536         (myGrilleStructure[0]-1) * (myGrilleStructure[1]  );
537       break;
538     }
539     return nb;
540   }
541
542   EGeometrieElement
543   TGrilleInfo
544   ::GetGeom()
545   {
546     TInt aDim = myMeshInfo->GetDim();
547     switch(aDim){
548     case 1:
549       return eSEG2;
550     case 2:
551       return eQUAD4;
552     case 3:
553       return eHEXA8;
554     default:
555       return eNONE;
556     }
557   }
558
559   EGeometrieElement
560   TGrilleInfo
561   ::GetSubGeom()
562   {
563     TInt aDim = myMeshInfo->GetDim();
564     switch(aDim){
565     case 2:
566       return eSEG2;
567     case 3:
568       return eQUAD4;
569     }
570     return eNONE;
571   }
572
573   EEntiteMaillage
574   TGrilleInfo
575   ::GetEntity()
576   {
577     return eMAILLE;
578   }
579
580   EEntiteMaillage
581   TGrilleInfo
582   ::GetSubEntity()
583   {
584     TInt aDim = myMeshInfo->GetDim();
585     switch(aDim){
586     case 2:
587       return eARETE;
588     case 3:
589       return eFACE;
590     }
591     return EEntiteMaillage(-1);
592   }
593
594   const
595   TIntVector&
596   TGrilleInfo
597   ::GetGrilleStructure() const
598   {
599     return myGrilleStructure;
600   }
601
602   TIntVector
603   TGrilleInfo
604   ::GetGrilleStructure()
605   {
606     return myGrilleStructure;
607   }
608
609   void
610   TGrilleInfo
611   ::SetGrilleStructure(TInt theAxis,TInt theNb)
612   {
613     if(theAxis >= 0 && theAxis <=2 && theNb >= 0)
614       myGrilleStructure[theAxis]=theNb;
615   }
616
617   const
618   TNodeCoord&
619   TGrilleInfo
620   ::GetNodeCoord() const
621   {
622     return myCoord;
623   }
624
625   TNodeCoord&
626   TGrilleInfo
627   ::GetNodeCoord()
628   {
629     return myCoord;
630   }
631
632   TNodeCoord
633   TGrilleInfo
634   ::GetCoord(TInt theId)
635   {
636     TNodeCoord aCoord;
637     TInt aDim       = myMeshInfo->GetDim();
638     TInt aNbNodes   = this->GetNbNodes();
639     aCoord.resize(aDim);
640
641     if(theId >= aNbNodes)
642       EXCEPTION(std::runtime_error, "TGrilleInfo::GetCoord - theId out of range");
643
644     if(myGrilleType == eGRILLE_STANDARD){
645       switch(aDim){
646       case 3:
647         aCoord[2] = myCoord[aDim*theId+2];
648         // fall through
649       case 2:
650         aCoord[1] = myCoord[aDim*theId+1];
651         // fall through
652       case 1:
653         aCoord[0] = myCoord[aDim*theId];
654         break;
655       }
656     } else {
657
658       TFloatVector aVecX  = this->GetIndexes(0);
659       TInt nbIndxX        = this->GetNbIndexes(0);
660
661       switch(aDim){
662       case 1:{
663         aCoord[0] = aVecX[theId];
664         break;
665       }
666       case 2:{
667         TFloatVector aVecY = this->GetIndexes(1);
668         TInt i,j,k;
669         i = j = k = 0;
670         i = theId % nbIndxX;
671         j = theId / nbIndxX;
672         if(myGrilleType == eGRILLE_CARTESIENNE){
673           aCoord[0] = aVecX[i];
674           aCoord[1] = aVecY[j];
675         } else { // eGRILLE_POLAIRE (cylindrical)
676           aCoord[0] = aVecX[i] * cos(aVecY[j]);
677           aCoord[1] = aVecX[i] * sin(aVecY[j]);
678         }
679         break;
680       }
681       case 3:{
682         TFloatVector aVecY = this->GetIndexes(1);
683         TInt nbIndxY       = this->GetNbIndexes(1);
684         TFloatVector aVecZ = this->GetIndexes(2);
685         TInt i,j,k;
686         i = j = k = 0;
687
688         i = theId % nbIndxX;
689         j = (theId / nbIndxX) % nbIndxY;
690         k = theId / (nbIndxX*nbIndxY);
691
692         if(myGrilleType == eGRILLE_CARTESIENNE){
693           aCoord[0] = aVecX[i];
694           aCoord[1] = aVecY[j];
695           aCoord[2] = aVecZ[k];
696         } else { // eGRILLE_POLAIRE (cylindrical)
697           aCoord[0] = aVecX[i] * cos(aVecY[j]);
698           aCoord[1] = aVecX[i] * sin(aVecY[j]);
699           aCoord[2] = aVecZ[k];
700         }
701
702         break;
703       }
704       }
705     }
706
707     return aCoord;
708   }
709
710   TIntVector
711   TGrilleInfo
712   ::GetConn(TInt theId, const bool isSub)
713   {
714     TIntVector anIndexes;
715     TInt aDim = myMeshInfo->GetDim();
716
717     TInt idx;
718     TInt iMin, jMin, kMin, iMax, jMax, kMax;
719     TInt loc[3];
720
721     loc[0] = loc[1] = loc[2] = 0;
722     iMin = iMax = jMin = jMax = kMin = kMax = 0;
723
724     switch(aDim) {
725     case 3:
726       {
727         TInt nbX = this->GetGrilleStructure()[0];
728         TInt nbY = this->GetGrilleStructure()[1];
729         TInt nbZ = this->GetGrilleStructure()[2];
730         TInt d01 = nbX*nbY, dX = 1, dY = 1, dZ = 1;
731         if ( isSub )
732           {
733             if ( theId < nbX * (nbY-1) * (nbZ-1))
734               { // face is normal to X axis
735                 dX = 0;
736               }
737             else if ( theId < nbX * (nbY-1) * (nbZ-1) + (nbX-1) * nbY * (nbZ-1))
738               {  // face is normal to Y axis
739                 theId -= nbX * (nbY-1) * (nbZ-1);
740                 dY = 0;
741               }
742             else
743               {
744                 theId -= nbX * (nbY-1) * (nbZ-1) + (nbX-1) * nbY * (nbZ-1);
745                 dZ = 0;
746               }
747           }
748         //else
749         {
750           iMin = theId % (nbX - dX);
751           jMin = (theId / (nbX - dX)) % (nbY - dY);
752           kMin = theId / ((nbX - dX) * (nbY - dY));
753           iMax = iMin+dX;
754           jMax = jMin+dY;
755           kMax = kMin+dZ;
756         }
757         for (loc[2]=kMin; loc[2]<=kMax; loc[2]++)
758           for (loc[1]=jMin; loc[1]<=jMax; loc[1]++)
759             for (loc[0]=iMin; loc[0]<=iMax; loc[0]++)
760               {
761                 idx = loc[0] + loc[1]*nbX + loc[2]*d01;
762                 anIndexes.push_back(idx);
763               }
764         break;
765       }
766     case 2:
767       {
768         TInt nbX = this->GetGrilleStructure()[0];
769         TInt nbY = this->GetGrilleStructure()[1];
770         TInt dX = 1, dY = 1;
771         if ( isSub )
772           {
773             if ( theId < nbX * (nbY-1))
774               { // edge is normal to X axis
775                 dX = 0;
776               }
777             else
778               {
779                 theId -= nbX * (nbY-1);
780                 dY = 0;
781               }
782           }
783         iMin = theId % (nbX-dX);
784         jMin = theId / (nbX-dX);
785         iMax = iMin+dX;
786         jMax = jMin+dY;
787         for (loc[1]=jMin; loc[1]<=jMax; loc[1]++)
788           for (loc[0]=iMin; loc[0]<=iMax; loc[0]++)
789             {
790               idx = loc[0] + loc[1]*nbX;
791               anIndexes.push_back(idx);
792             }
793         break;
794       }
795     case 1:
796       {
797         iMin = theId;
798         for (loc[0]=iMin; loc[0]<=iMin+1; loc[0]++)
799           {
800             idx = loc[0];
801             anIndexes.push_back(idx);
802           }
803         break;
804       }
805     }
806
807     return anIndexes;
808   }
809
810   TInt
811   TGrilleInfo
812   ::GetFamNumNode(TInt theId) const
813   {
814     return myFamNumNode[theId];
815   }
816
817   void
818   TGrilleInfo
819   ::SetFamNumNode(TInt theId,TInt theVal)
820   {
821     myFamNumNode[theId] = theVal;
822   }
823
824   TInt
825   TGrilleInfo
826   ::GetFamNum(TInt theId) const
827   {
828     return myFamNum[theId];
829   }
830
831   void
832   TGrilleInfo
833   ::SetFamNum(TInt theId,TInt theVal)
834   {
835     myFamNum[theId] = theVal;
836   }
837
838   TInt
839   TGrilleInfo
840   ::GetFamSubNum(TInt theId) const
841   {
842     return myFamSubNum[theId];
843   }
844
845   void
846   TGrilleInfo
847   ::SetFamSubNum(TInt theId,TInt theVal)
848   {
849     myFamSubNum[theId] = theVal;
850   }
851 }