1 #include <HYDROData_Image.h>
2 #include <HYDROData_Iterator.h>
4 #include <HYDROOperations_Factory.h>
6 #include <TDataStd_RealArray.hxx>
7 #include <TDataStd_ByteArray.hxx>
8 #include <TDataStd_IntegerArray.hxx>
9 #include <TDataStd_ReferenceList.hxx>
10 #include <TDataStd_Name.hxx>
11 #include <TDataStd_UAttribute.hxx>
12 #include <TDataStd_AsciiString.hxx>
13 #include <TDF_ListIteratorOfLabelList.hxx>
15 #include <ImageComposer_Operator.h>
17 #include <QStringList>
19 static const Standard_GUID GUID_MUST_BE_UPDATED("80f2bb81-3873-4631-8ddd-940d2119f000");
21 #define PYTHON_IMAGE_ID "1"
23 IMPLEMENT_STANDARD_HANDLE(HYDROData_Image, HYDROData_Object)
24 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Image, HYDROData_Object)
26 HYDROData_Image::HYDROData_Image()
30 HYDROData_Image::~HYDROData_Image()
34 QStringList HYDROData_Image::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
38 Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( this );
39 if ( aDocument.IsNull() )
42 QString aDocName = aDocument->GetDocPyName();
43 QString anImageName = GetName();
45 aResList << QString( "%1 = %2.CreateObject( %3 );" )
46 .arg( anImageName ).arg( aDocName ).arg( PYTHON_IMAGE_ID );
47 aResList << QString( "%1.SetName( \"%2\" );" )
48 .arg( anImageName ).arg( anImageName );
50 QString aFilePath = GetFilePath();
51 if ( !aFilePath.isEmpty() )
53 aResList << QString( "" );
54 aResList << QString( "%1.LoadImage( \"%2\" );" )
55 .arg( anImageName ).arg( aFilePath );
59 // Image is composed from other image(s)
61 QString anOperatorName = OperatorName();
62 if ( !anOperatorName.isEmpty() )
64 aResList << QString( "" );
66 aResList << QString( "%1.SetOperatorName( \"%2\" );" )
67 .arg( anImageName ).arg( anOperatorName );
69 ImageComposer_Operator* anImageOp = HYDROOperations_Factory::Factory()->Operator( this );
72 // Dump operation arguments
73 QString anOpArgsArrayName;
74 QStringList anOpArgs = anImageOp->dumpArgsToPython( anOpArgsArrayName );
75 if ( !anOpArgs.isEmpty() )
77 aResList << QString( "" );
80 aResList << QString( "" );
81 aResList << QString( "%1.SetArgs( %2 );" )
82 .arg( anImageName ).arg( anOpArgsArrayName );
87 int aNbReferences = NbReferences();
88 if ( aNbReferences > 0 )
90 aResList << QString( "" );
92 for ( int i = 0; i < aNbReferences; ++i )
94 Handle(HYDROData_Image) aRefImg = Reference( i );
95 if ( aRefImg.IsNull() )
98 QString aRefImgName = aRefImg->GetName();
100 // The definition of reference image must be dumped before this
101 if ( !theTreatedObjects.contains( aRefImgName ) )
103 // Write definition of reference image
104 QStringList aRefImgDump = aRefImg->DumpToPython( theTreatedObjects );
105 if ( aRefImgDump.isEmpty() )
108 QStringList aTmpList = aResList;
109 aResList = aRefImgDump;
111 aResList.append( "" );
112 aResList.append( aTmpList );
114 theTreatedObjects.insert( aRefImgName, aRefImg );
117 aResList << QString( "%1.AppendReference( %2 );" )
118 .arg( anImageName ).arg( aRefImgName );
123 // Dump transformation matrix for image
124 aResList << QString( "" );
126 QTransform aTrsf = Trsf();
128 aResList << QString( "trsf = QTransform( %2, %3, %4," )
129 .arg( aTrsf.m11() ).arg( aTrsf.m12() ).arg( aTrsf.m13() );
130 aResList << QString( " %1, %2, %3," )
131 .arg( aTrsf.m21() ).arg( aTrsf.m22() ).arg( aTrsf.m23() );
132 aResList << QString( " %1, %2, %3 );" )
133 .arg( aTrsf.m31() ).arg( aTrsf.m32() ).arg( aTrsf.m33() );
135 aResList << QString( "%1.SetTrsf( trsf );" ).arg( anImageName );
137 // Dump transformation points for image
138 aResList << QString( "" );
140 QPoint aPointAIn, aPointBIn, aPointCIn;
141 QPointF aPointAOut, aPointBOut, aPointCOut;
142 TrsfPoints( aPointAIn, aPointBIn, aPointCIn,
143 aPointAOut, aPointBOut, aPointCOut );
145 aResList << QString( "a_in = QPoint( %1, %2 );" )
146 .arg( aPointAIn.x() ).arg( aPointAIn.y() );
148 aResList << QString( "b_in = QPoint( %1, %2 );" )
149 .arg( aPointBIn.x() ).arg( aPointBIn.y() );
151 aResList << QString( "c_in = QPoint( %1, %2 );" )
152 .arg( aPointCIn.x() ).arg( aPointCIn.y() );
154 aResList << QString( "a_out = QPointF( %1, %2 );" )
155 .arg( aPointAOut.x() ).arg( aPointAOut.y() );
157 aResList << QString( "b_out = QPointF( %1, %2 );" )
158 .arg( aPointBOut.x() ).arg( aPointBOut.y() );
160 aResList << QString( "c_out = QPointF( %1, %2 );" )
161 .arg( aPointCOut.x() ).arg( aPointCOut.y() );
163 QString aGap = QString().fill( ' ', anImageName.size() + 16 );
164 aResList << QString( "%1.SetTrsfPoints( a_in, b_in, c_in," ).arg( anImageName );
165 aResList << QString( aGap + "a_out, b_out, c_out );" );
170 void HYDROData_Image::SetImage(const QImage& theImage)
172 if (theImage.isNull()) {
173 // for empty image remove all previously stored attributes
174 myLab.ForgetAttribute(TDataStd_IntegerArray::GetID());
175 myLab.ForgetAttribute(TDataStd_ByteArray::GetID());
178 // store width, height, bytes per line and format in integer array
179 Handle(TDataStd_IntegerArray) aParams;
180 if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams)) {
181 aParams = TDataStd_IntegerArray::Set(myLab, 1, 4);
183 aParams->SetValue(1, theImage.width());
184 aParams->SetValue(2, theImage.height());
185 aParams->SetValue(3, theImage.bytesPerLine());
186 aParams->SetValue(4, (int)(theImage.format()));
187 // store data of image in byte array
188 const char* aData = (const char*)(theImage.bits());
189 SaveByteArray(0, aData, theImage.byteCount());
192 bool HYDROData_Image::LoadImage(const QString& theFilePath)
194 QImage anImage( theFilePath );
196 return !anImage.isNull();
199 QImage HYDROData_Image::Image()
201 Handle(TDataStd_IntegerArray) aParams;
202 if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams))
203 return QImage(); // return empty image if there is no array
205 uchar* anArray = (uchar*)ByteArray(0, aLen);
207 return QImage(); // return empty image if there is no array
208 QImage aResult(anArray, aParams->Value(1), aParams->Value(2),
209 aParams->Value(3), QImage::Format(aParams->Value(4)));
213 void HYDROData_Image::SetFilePath(const QString& theFilePath)
215 TCollection_AsciiString anAsciiStr( theFilePath.toStdString().c_str() );
216 TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), anAsciiStr );
219 QString HYDROData_Image::GetFilePath() const
223 Handle(TDataStd_AsciiString) anAsciiStr;
224 if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
225 aRes = QString( anAsciiStr->Get().ToCString() );
230 void HYDROData_Image::SetTrsf(const QTransform& theTrsf)
232 // locate 9 coeffs of matrix into the real array
233 Handle(TDataStd_RealArray) anArray;
234 if (!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray)) {
235 if (theTrsf.isIdentity()) return; // no need to store identity transformation
236 anArray = TDataStd_RealArray::Set(myLab, 1, 9);
238 anArray->SetValue(1, theTrsf.m11());
239 anArray->SetValue(2, theTrsf.m12());
240 anArray->SetValue(3, theTrsf.m13());
241 anArray->SetValue(4, theTrsf.m21());
242 anArray->SetValue(5, theTrsf.m22());
243 anArray->SetValue(6, theTrsf.m23());
244 anArray->SetValue(7, theTrsf.m31());
245 anArray->SetValue(8, theTrsf.m32());
246 anArray->SetValue(9, theTrsf.m33());
249 QTransform HYDROData_Image::Trsf() const
251 // get 9 coeffs of matrix from the real array
252 Handle(TDataStd_RealArray) anArray;
253 if (!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray))
254 return QTransform(); // return identity if there is no array
256 anArray->Value(1), anArray->Value(2), anArray->Value(3),
257 anArray->Value(4), anArray->Value(5), anArray->Value(6),
258 anArray->Value(7), anArray->Value(8), anArray->Value(9));
262 void HYDROData_Image::SetTrsfPoints(const QPoint& thePointAIn,
263 const QPoint& thePointBIn,
264 const QPoint& thePointCIn,
265 const QPointF& thePointAOut,
266 const QPointF& thePointBOut,
267 const QPointF& thePointCOut)
269 Handle(TDataStd_RealArray) anArray;
270 if (!myLab.FindChild(DataTag_TrsfPoints).FindAttribute(TDataStd_RealArray::GetID(), anArray)) {
271 anArray = TDataStd_RealArray::Set(myLab.FindChild(DataTag_TrsfPoints), 1, 12);
273 anArray->SetValue(1, thePointAIn.x());
274 anArray->SetValue(2, thePointAIn.y());
275 anArray->SetValue(3, thePointBIn.x());
276 anArray->SetValue(4, thePointBIn.y());
277 anArray->SetValue(5, thePointCIn.x());
278 anArray->SetValue(6, thePointCIn.y());
279 anArray->SetValue(7, thePointAOut.x());
280 anArray->SetValue(8, thePointAOut.y());
281 anArray->SetValue(9, thePointBOut.x());
282 anArray->SetValue(10, thePointBOut.y());
283 anArray->SetValue(11, thePointCOut.x());
284 anArray->SetValue(12, thePointCOut.y());
287 void HYDROData_Image::TrsfPoints(QPoint& thePointAIn,
290 QPointF& thePointAOut,
291 QPointF& thePointBOut,
292 QPointF& thePointCOut) const
294 Handle(TDataStd_RealArray) anArray;
295 if (myLab.FindChild(DataTag_TrsfPoints).FindAttribute(TDataStd_RealArray::GetID(), anArray)) {
296 thePointAIn = QPointF( anArray->Value(1), anArray->Value(2) ).toPoint();
297 thePointBIn = QPointF( anArray->Value(3), anArray->Value(4) ).toPoint();
298 thePointCIn = QPointF( anArray->Value(5), anArray->Value(6) ).toPoint();
299 thePointAOut = QPointF( anArray->Value(7), anArray->Value(8) );
300 thePointBOut = QPointF( anArray->Value(9), anArray->Value(10) );
301 thePointCOut = QPointF( anArray->Value(11), anArray->Value(12) );
305 void HYDROData_Image::AppendReference(Handle(HYDROData_Image) theReferenced)
307 Handle(TDataStd_ReferenceList) aRefs;
308 if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
309 aRefs = TDataStd_ReferenceList::Set(myLab);
310 aRefs->Append(theReferenced->Label());
313 int HYDROData_Image::NbReferences() const
315 Handle(TDataStd_ReferenceList) aRefs;
316 if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
318 return aRefs->Extent();
321 Handle(HYDROData_Image) HYDROData_Image::Reference(const int theIndex) const
323 Handle(TDataStd_ReferenceList) aRefs;
324 if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
325 return Handle(HYDROData_Image)();
326 if (theIndex < 0 || theIndex >= aRefs->Extent())
327 return Handle(HYDROData_Image)();
329 TDF_ListIteratorOfLabelList anIter(aRefs->List());
330 for(int anIndex = 0; anIndex != theIndex; anIter.Next(), anIndex++);
331 const TDF_Label& aRefLab = anIter.Value();
332 return Handle(HYDROData_Image)::DownCast(HYDROData_Iterator::Object(aRefLab));
335 void HYDROData_Image::ChangeReference(
336 const int theIndex, Handle(HYDROData_Image) theReferenced)
338 Handle(TDataStd_ReferenceList) aRefs;
339 if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
340 aRefs = TDataStd_ReferenceList::Set(myLab);
341 if (theIndex >= aRefs->Extent()) { // for too big index append it just to the end
342 AppendReference(theReferenced);
343 } else { // remove and insert new
344 TDF_ListIteratorOfLabelList anIter(aRefs->List());
346 for(; anIndex != theIndex; anIter.Next(), anIndex++);
347 const TDF_Label& aRemovedLab = anIter.Value();
349 aRefs->Remove(aRemovedLab);
351 aRefs->InsertBefore(theReferenced->Label(), anIter.Value());
353 aRefs->Append(theReferenced->Label());
357 void HYDROData_Image::RemoveReference(const int theIndex)
359 Handle(TDataStd_ReferenceList) aRefs;
360 if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
361 return; // no references, nothing to remove
362 if (aRefs->Extent() == 1 && theIndex == 0) { // remove all if only one
366 TDF_ListIteratorOfLabelList anIter(aRefs->List());
368 for(; anIndex != theIndex && anIter.More(); anIter.Next(), anIndex++);
370 aRefs->Remove(anIter.Value());
373 void HYDROData_Image::ClearReferences()
375 myLab.ForgetAttribute(TDataStd_ReferenceList::GetID());
378 void HYDROData_Image::SetOperatorName(const QString theOpName)
380 TDataStd_Name::Set(myLab.FindChild(DataTag_Operator),
381 TCollection_ExtendedString(theOpName.toLatin1().constData()));
384 QString HYDROData_Image::OperatorName() const
386 Handle(TDataStd_Name) aName;
387 if (myLab.FindChild(DataTag_Operator).
388 FindAttribute(TDataStd_Name::GetID(), aName)) {
389 TCollection_AsciiString aStr(aName->Get());
390 return QString(aStr.ToCString());
395 void HYDROData_Image::SetArgs(const QByteArray& theArgs)
397 SaveByteArray(DataTag_Operator, theArgs.constData(), theArgs.length());
400 QByteArray HYDROData_Image::Args() const
403 const char* aData = ByteArray(DataTag_Operator, aLen);
406 return QByteArray(aData, aLen);
409 void HYDROData_Image::MustBeUpdated(bool theFlag)
412 TDataStd_UAttribute::Set(myLab, GUID_MUST_BE_UPDATED);
414 myLab.ForgetAttribute(GUID_MUST_BE_UPDATED);
418 bool HYDROData_Image::MustBeUpdated()
420 return myLab.IsAttribute(GUID_MUST_BE_UPDATED);