Salome HOME
294f0e988e0e20b673786b8eea732d591b53825a
[modules/hydro.git] / src / HYDROData / HYDROData_Polyline.cxx
1 #include <HYDROData_Polyline.h>
2 #include <HYDROData_Iterator.h>
3
4 #include <TDataStd_Name.hxx>
5 #include <TDataStd_Integer.hxx>
6 #include <TDataStd_ByteArray.hxx>
7 #include <TDataStd_BooleanArray.hxx>
8 #include <TDataStd_IntegerArray.hxx>
9 #include <TDataStd_RealArray.hxx>
10 #include <TDataStd_ExtStringArray.hxx>
11 #include <TDataStd_UAttribute.hxx>
12 #include <TDF_ListIteratorOfLabelList.hxx>
13
14 #include <QPainterPath>
15
16 // tage of the child of my label that contains information about the operator
17 static const Standard_GUID GUID_MUST_BE_UPDATED("6647e1f7-1971-4c5a-86c7-11ff0291452d");
18
19 #define TAG_POINTS          1
20 #define TAG_SECTIONS_NAME   2
21 #define TAG_SECTIONS_CLOSED 3
22 #define TAG_SECTIONS_SIZE   4
23 #define TAG_SECTIONS_TYPE   5
24
25 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
26 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
27
28 HYDROData_Polyline::HYDROData_Polyline()
29 {
30 }
31
32 HYDROData_Polyline::~HYDROData_Polyline()
33 {
34 }
35
36 /**
37  * Return polyline dimension
38  * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
39  */
40 int HYDROData_Polyline::getDimension() const
41 {
42     Handle(TDataStd_Integer) aDim;
43     if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
44       return 0;
45     return aDim->Get();
46 }
47
48 /**
49  * Set polyline dimension. Should be 2 or 3.
50  * \param theDimension the polyline dimension
51  */
52 void HYDROData_Polyline::setDimension( int theDimension )
53 {
54     removeAll();
55     int aDim=0;
56     if( theDimension == 2 || theDimension == 3){
57         aDim = theDimension;
58     }
59     TDataStd_Integer::Set(myLab, aDim);
60 }
61
62 /**
63  * Replace current polyline data by new sections list
64  * \param theSections the sections list
65  */
66 void HYDROData_Polyline::setPolylineData( const QList<PolylineSection>& theSections )
67 {
68 //Keep dimension
69   int aDim = getDimension();
70   if( aDim == 0 )
71       return;
72   removeAll();
73   setDimension(aDim);
74
75   if( theSections.size() == 0 )
76     return;
77   int aSectionsSize = theSections.size();
78
79   int aPointsCnt = 0;
80
81   TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
82   Handle(TDataStd_ExtStringArray) aSectsNameArray;
83   aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
84
85   TDF_Label aSizeLab = myLab.FindChild(TAG_SECTIONS_SIZE);
86   Handle(TDataStd_IntegerArray) aSizeArray;
87   aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
88
89   TDF_Label aClosedLab = myLab.FindChild(TAG_SECTIONS_CLOSED);
90   Handle(TDataStd_BooleanArray) aClosedArray;
91   aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
92
93   TDF_Label aTypeLab = myLab.FindChild(TAG_SECTIONS_TYPE);
94   Handle(TDataStd_ByteArray) aTypeArray;
95   aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
96
97 //Extract sections parameters and count points
98   for( int i = 0 ; i < theSections.size() ; i++ ){
99     int aSectSize = theSections[i].myCoords.size();
100     aSectsNameArray->SetValue( i, theSections[i].mySectionName );
101     aSizeArray->SetValue( i, aSectSize );
102     aClosedArray->SetValue( i, theSections[i].myIsClosed );
103     char aType = (char)theSections[i].myType;
104     aTypeArray->SetValue( i, aType );
105     aPointsCnt += aSectSize;
106   }
107 //Don't create a points array
108   if( aPointsCnt == 0 )
109     return;
110 //Save coordinates
111   Handle(TDataStd_RealArray) anArray;
112   anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
113   int aPtr = 0;
114   for( int i = 0 ; i < theSections.size() ; i++ ){
115     for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
116       anArray->SetValue(aPtr, theSections[i].myCoords[j]);
117       aPtr++;
118     }
119   }
120 }
121
122 /**
123  * Return polyline data
124  * \return polyline section list
125  */
126 QList<PolylineSection> HYDROData_Polyline::getPolylineData()
127 {
128   int aSectCnt;
129   QList<PolylineSection> aRes;
130 //Get sections size array handle
131   TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
132   Handle(TDataStd_IntegerArray) aSizeArray;
133   if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
134     return aRes; // return empty if no array
135   aSectCnt = aSizeArray->Length();
136   if( aSectCnt == 0 )
137     return aRes;
138 //Get section type array handle
139   aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
140   Handle(TDataStd_ByteArray) aTypeArray;
141   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
142     return aRes;
143   int aLen = aTypeArray->Length();
144   if( aLen != aSectCnt )
145     return aRes;
146 //Get section closed array handle
147   aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
148   Handle(TDataStd_BooleanArray) aClosedArray;
149   if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
150     return aRes;
151   aLen = aClosedArray->Length();
152   if( aLen != aSectCnt )
153     return aRes;
154 //Get sections names
155   TDF_Label aNameLab = myLab.FindChild(TAG_SECTIONS_NAME);
156   Handle(TDataStd_ExtStringArray) aSectNamesArray;
157   if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
158     return aRes;
159   aLen = aSectNamesArray->Length();
160   if( aLen != aSectCnt )
161     return aRes;
162 //Get coordinates array
163   Handle(TDataStd_RealArray) aCoordsArray;
164   myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
165
166   int aCoordPtr = 0;
167   for( int i = 0 ; i < aSectCnt ; i++ ){
168     PolylineSection aSect;
169     aSect.myIsClosed = aClosedArray->Value(i);
170     aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
171     aSect.mySectionName = aSectNamesArray->Value(i);
172     int aSectSize = aSizeArray->Value(i);
173     for( int j = 0 ; j < aSectSize ; j++ ){
174       double aCoord = aCoordsArray->Value(aCoordPtr);
175       aSect.myCoords << aCoord;
176       aCoordPtr++;
177     }
178     aRes << aSect;
179   }
180   return aRes;
181 }
182
183 /**
184  * Remove all polyline attributes except dimension.
185  */
186 void HYDROData_Polyline::removeAll()
187 {
188 //Remove only section data
189   TDF_Label aLab = myLab.FindChild( TAG_SECTIONS_SIZE );
190   aLab.ForgetAllAttributes();
191
192   aLab = myLab.FindChild( TAG_SECTIONS_TYPE );
193   aLab.ForgetAllAttributes();
194
195   aLab = myLab.FindChild( TAG_SECTIONS_CLOSED );
196   aLab.ForgetAllAttributes();
197
198   myLab.ForgetAttribute(TDataStd_RealArray::GetID());
199   return;
200 }
201
202 /**
203  * Return polyline painter path. Current implementation
204  * is ignored section type.
205  * \return polyline painter path.
206  */
207 QPainterPath HYDROData_Polyline::painterPath()
208 {
209   QPainterPath aPath;
210   int aDim = getDimension();
211   if( ( aDim != 2 ) || ( aDim != 3) )
212       return aPath;
213   QList<PolylineSection> aSects = getPolylineData();
214   for( int i = 0 ; aSects.size() ; i++ ){
215     int aPntCnt = aSects[i].myCoords.size()/aDim;
216     if( aPntCnt ){
217       aPath.moveTo(aSects[i].myCoords[0], aSects[i].myCoords[1] );
218     }
219     for( int j = 1 ; j < aPntCnt ; j++ ){
220       int anIndx = j*aDim;
221       aPath.lineTo(aSects[i].myCoords[anIndx], aSects[i].myCoords[anIndx+1]);
222     }
223     if( aSects[i].myIsClosed ){
224       aPath.closeSubpath();
225     }
226   }
227   return aPath;
228 }