Salome HOME
Dump Polyline data to python script (Feature #13).
[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 #include <QStringList>
16
17 // tage of the child of my label that contains information about the operator
18 static const Standard_GUID GUID_MUST_BE_UPDATED("6647e1f7-1971-4c5a-86c7-11ff0291452d");
19
20 #define PYTHON_POLYLINE_ID "2"
21
22 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline, HYDROData_Object)
23 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline, HYDROData_Object)
24
25 HYDROData_Polyline::HYDROData_Polyline()
26 {
27 }
28
29 HYDROData_Polyline::~HYDROData_Polyline()
30 {
31 }
32
33 /**
34  * Dump object to Python script representation.
35  */
36 QStringList HYDROData_Polyline::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
37 {
38   QStringList aResList;
39
40   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( this );
41   if ( aDocument.IsNull() )
42     return aResList;
43                              
44   QString aDocName = aDocument->GetDocPyName();
45   QString aPolylineName = GetName();
46
47   aResList << QString( "%1 = %2.CreateObject( %3 );" )
48               .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
49   aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
50
51   // Set polilyne dimension
52
53   aResList << QString( "" );
54
55   int aDim = getDimension();
56   aResList << QString( "%1.setDimension( %2 );" )
57               .arg( aPolylineName ).arg( aDim );
58
59   // Set polilyne data
60
61   PolylineData aPolylineData = getPolylineData();
62   if ( !aPolylineData.isEmpty() )
63   {
64     QString aPolylineDataName = "polyline_data";
65
66     aResList << QString( "" );
67     aResList << QString( "%1 = [];" ).arg( aPolylineDataName );
68
69     PolylineData::const_iterator aDataIt = aPolylineData.constBegin();
70     for ( ; aDataIt != aPolylineData.constEnd(); ++aDataIt )
71     {
72       const PolylineSection& aSection = *aDataIt;
73
74       QString aPolylineSectName = "polyline_section";
75
76       aResList << QString( "" );
77       aResList << QString( "%1 = PolylineSection();" ).arg( aPolylineSectName );
78
79       QString aCoordsStr;
80       foreach( const double& aCoordVal, aSection.myCoords )
81         aCoordsStr += QString::number( aCoordVal ) + ", ";
82       aCoordsStr.remove( aCoordsStr.length() - 2, 2 );
83
84       aResList << QString( "" );
85
86       aResList << QString( "%1.mySectionName = \"%2\";" )
87                   .arg( aPolylineSectName )
88                   .arg( TCollection_AsciiString( aSection.mySectionName ).ToCString() );
89       aResList << QString( "%1.myType = %2;" )
90                   .arg( aPolylineSectName ).arg( aSection.myType );
91       aResList << QString( "%1.myIsClosed = %2;" )
92                   .arg( aPolylineSectName ).arg( aSection.myIsClosed );
93       aResList << QString( "%1.myCoords = [ %2 ];" )
94                   .arg( aPolylineSectName ).arg( aCoordsStr );
95
96       aResList << QString( "%1.append( %2 );" )
97                   .arg( aPolylineDataName ).arg( aPolylineSectName );
98     }
99
100     aResList << QString( "%1.setPolylineData( %2 );" )
101                   .arg( aPolylineName ).arg( aPolylineDataName );
102   }
103
104   return aResList;
105 }
106
107 /**
108  * Return polyline dimension
109  * \return polyline dimension. 2 or 3 is valid. 0 is invalid.
110  */
111 int HYDROData_Polyline::getDimension() const
112 {
113     Handle(TDataStd_Integer) aDim;
114     if(!myLab.FindAttribute(TDataStd_Integer::GetID(), aDim))
115       return 0;
116     return aDim->Get();
117 }
118
119 /**
120  * Set polyline dimension. Should be 2 or 3.
121  * \param theDimension the polyline dimension
122  */
123 void HYDROData_Polyline::setDimension( int theDimension )
124 {
125     removeAll();
126     int aDim=0;
127     if( theDimension == 2 || theDimension == 3){
128         aDim = theDimension;
129     }
130     TDataStd_Integer::Set(myLab, aDim);
131 }
132
133 /**
134  * Replace current polyline data by new sections list
135  * \param theSections the sections list
136  */
137 void HYDROData_Polyline::setPolylineData( const PolylineData& theSections )
138 {
139 //Keep dimension
140   int aDim = getDimension();
141   if( aDim == 0 )
142       return;
143   removeAll();
144   setDimension(aDim);
145
146   if( theSections.size() == 0 )
147     return;
148   int aSectionsSize = theSections.size();
149
150   int aPointsCnt = 0;
151
152   TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
153   Handle(TDataStd_ExtStringArray) aSectsNameArray;
154   aSectsNameArray = TDataStd_ExtStringArray::Set(aNameLab, 0, aSectionsSize-1, false );
155
156   TDF_Label aSizeLab = myLab.FindChild(DataTag_SectionsSize);
157   Handle(TDataStd_IntegerArray) aSizeArray;
158   aSizeArray = TDataStd_IntegerArray::Set(aSizeLab, 0, aSectionsSize-1, false );
159
160   TDF_Label aClosedLab = myLab.FindChild(DataTag_SectionsClosed);
161   Handle(TDataStd_BooleanArray) aClosedArray;
162   aClosedArray = TDataStd_BooleanArray::Set(aClosedLab, 0, aSectionsSize-1 );
163
164   TDF_Label aTypeLab = myLab.FindChild(DataTag_SectionsType);
165   Handle(TDataStd_ByteArray) aTypeArray;
166   aTypeArray = TDataStd_ByteArray::Set(aTypeLab, 0, aSectionsSize-1, false );
167
168 //Extract sections parameters and count points
169   for( int i = 0 ; i < theSections.size() ; i++ ){
170     int aSectSize = theSections[i].myCoords.size();
171     aSectsNameArray->SetValue( i, theSections[i].mySectionName );
172     aSizeArray->SetValue( i, aSectSize );
173     aClosedArray->SetValue( i, theSections[i].myIsClosed );
174     char aType = (char)theSections[i].myType;
175     aTypeArray->SetValue( i, aType );
176     aPointsCnt += aSectSize;
177   }
178 //Don't create a points array
179   if( aPointsCnt == 0 )
180     return;
181 //Save coordinates
182   Handle(TDataStd_RealArray) anArray;
183   anArray = TDataStd_RealArray::Set( myLab, 0, aPointsCnt*aDim - 1 );
184   int aPtr = 0;
185   for( int i = 0 ; i < theSections.size() ; i++ ){
186     for( int j = 0 ; j < theSections[i].myCoords.size() ; j++ ){
187       anArray->SetValue(aPtr, theSections[i].myCoords[j]);
188       aPtr++;
189     }
190   }
191 }
192
193 /**
194  * Return polyline data
195  * \return polyline section list
196  */
197 HYDROData_Polyline::PolylineData HYDROData_Polyline::getPolylineData() const
198 {
199   int aSectCnt;
200   PolylineData aRes;
201 //Get sections size array handle
202   TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
203   Handle(TDataStd_IntegerArray) aSizeArray;
204   if (!aLab.FindAttribute(TDataStd_IntegerArray::GetID(), aSizeArray))
205     return aRes; // return empty if no array
206   aSectCnt = aSizeArray->Length();
207   if( aSectCnt == 0 )
208     return aRes;
209 //Get section type array handle
210   aLab = myLab.FindChild( DataTag_SectionsType );
211   Handle(TDataStd_ByteArray) aTypeArray;
212   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aTypeArray))
213     return aRes;
214   int aLen = aTypeArray->Length();
215   if( aLen != aSectCnt )
216     return aRes;
217 //Get section closed array handle
218   aLab = myLab.FindChild( DataTag_SectionsClosed );
219   Handle(TDataStd_BooleanArray) aClosedArray;
220   if (!aLab.FindAttribute(TDataStd_BooleanArray::GetID(), aClosedArray))
221     return aRes;
222   aLen = aClosedArray->Length();
223   if( aLen != aSectCnt )
224     return aRes;
225 //Get sections names
226   TDF_Label aNameLab = myLab.FindChild(DataTag_SectionsName);
227   Handle(TDataStd_ExtStringArray) aSectNamesArray;
228   if(!aNameLab.FindAttribute(TDataStd_ExtStringArray::GetID(), aSectNamesArray))
229     return aRes;
230   aLen = aSectNamesArray->Length();
231   if( aLen != aSectCnt )
232     return aRes;
233 //Get coordinates array
234   Handle(TDataStd_RealArray) aCoordsArray;
235   myLab.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray);
236
237   int aCoordPtr = 0;
238   for( int i = 0 ; i < aSectCnt ; i++ ){
239     PolylineSection aSect;
240     aSect.myIsClosed = aClosedArray->Value(i);
241     aSect.myType = (PolylineSection::SectionType)aTypeArray->Value(i);
242     aSect.mySectionName = aSectNamesArray->Value(i);
243     int aSectSize = aSizeArray->Value(i);
244     for( int j = 0 ; j < aSectSize ; j++ ){
245       double aCoord = aCoordsArray->Value(aCoordPtr);
246       aSect.myCoords << aCoord;
247       aCoordPtr++;
248     }
249     aRes << aSect;
250   }
251   return aRes;
252 }
253
254 /**
255  * Remove all polyline attributes except dimension.
256  */
257 void HYDROData_Polyline::removeAll()
258 {
259 //Remove only section data
260   TDF_Label aLab = myLab.FindChild( DataTag_SectionsSize );
261   aLab.ForgetAllAttributes();
262
263   aLab = myLab.FindChild( DataTag_SectionsType );
264   aLab.ForgetAllAttributes();
265
266   aLab = myLab.FindChild( DataTag_SectionsClosed );
267   aLab.ForgetAllAttributes();
268
269   myLab.ForgetAttribute(TDataStd_RealArray::GetID());
270   return;
271 }
272
273 /**
274  * Return polyline painter path. Current implementation
275  * is ignored section type.
276  * \return polyline painter path.
277  */
278 QPainterPath HYDROData_Polyline::painterPath()
279 {
280   QPainterPath aPath;
281   int aDim = getDimension();
282   if( ( aDim != 2 ) && ( aDim != 3) )
283       return aPath;
284   PolylineData aSects = getPolylineData();
285   for( int i = 0 ; i < aSects.size() ; i++ ){
286     int aPntCnt = aSects[i].myCoords.size()/aDim;
287     if( aPntCnt ){
288       aPath.moveTo(aSects[i].myCoords[0], aSects[i].myCoords[1] );
289     }
290     for( int j = 1 ; j < aPntCnt ; j++ ){
291       int anIndx = j*aDim;
292       aPath.lineTo(aSects[i].myCoords[anIndx], aSects[i].myCoords[anIndx+1]);
293     }
294     if( aSects[i].myIsClosed ){
295       aPath.closeSubpath();
296     }
297   }
298   return aPath;
299 }