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