X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Image.cxx;h=74c278b4c3328957c03c1145e96e9a075b9f4791;hb=e35b4caf3341d2cece2b7921f349acd17fb89351;hp=41b194c726562e34a73f3ce2eed969bb7ee6f5e9;hpb=9723b0802834ab7ee2b9ac3e18e76e46a27c8dca;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Image.cxx b/src/HYDROData/HYDROData_Image.cxx index 41b194c7..74c278b4 100644 --- a/src/HYDROData/HYDROData_Image.cxx +++ b/src/HYDROData/HYDROData_Image.cxx @@ -1,29 +1,58 @@ -#include -#include - -#include +// Copyright (C) 2014-2015 EDF-R&D +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "HYDROData_Image.h" + +#include "HYDROData_Document.h" +#include "HYDROData_Lambert93.h" +#include "HYDROData_OperationsFactory.h" +#include "HYDROData_Tool.h" #include #include +#include #include #include -#include #include #include -#include + +#ifdef WIN32 + #pragma warning ( disable: 4251 ) +#endif #include +#include #include +#include -static const Standard_GUID GUID_MUST_BE_UPDATED("80f2bb81-3873-4631-8ddd-940d2119f000"); +#ifdef WIN32 + #pragma warning ( default: 4251 ) +#endif -#define PYTHON_IMAGE_ID "1" +static const Standard_GUID GUID_SELF_SPLIT("997995aa-5c19-40bf-9a60-ab4b70ad04d8"); +static const Standard_GUID GUID_HAS_LOCAL_POINTS("FD8841AA-FC44-42fa-B6A7-0F682CCC6F27"); +static const Standard_GUID GUID_HAS_GLOBAL_POINTS("330D0E81-742D-4ea3-92D4-484877CFA7C1"); -IMPLEMENT_STANDARD_HANDLE(HYDROData_Image, HYDROData_Object) -IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Image, HYDROData_Object) +IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Image, HYDROData_Entity) HYDROData_Image::HYDROData_Image() +: HYDROData_Entity( Geom_2d ) { } @@ -31,28 +60,76 @@ HYDROData_Image::~HYDROData_Image() { } -QStringList HYDROData_Image::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const +QStringList HYDROData_Image::DumpToPython( const QString& thePyScriptPath, + MapOfTreatedObjects& theTreatedObjects ) const { - QStringList aResList; - - Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( this ); - if ( aDocument.IsNull() ) - return aResList; - - QString aDocName = aDocument->GetDocPyName(); - QString anImageName = GetName(); - - aResList << QString( "%1 = %2.CreateObject( %3 );" ) - .arg( anImageName ).arg( aDocName ).arg( PYTHON_IMAGE_ID ); - aResList << QString( "%1.SetName( \"%2\" );" ) - .arg( anImageName ).arg( anImageName ); + QStringList aResList = dumpObjectCreation( theTreatedObjects ); + QString anImageName = GetObjPyName(); QString aFilePath = GetFilePath(); if ( !aFilePath.isEmpty() ) { aResList << QString( "" ); - aResList << QString( "%1.LoadImage( \"%2\" );" ) + aResList << QString( "if not(%1.LoadImage( \"%2\" )):" ) .arg( anImageName ).arg( aFilePath ); + aResList << QString( " raise ValueError('problem while loading image')" ); + aResList << QString( "" ); + + // Dump transformation points for image + + bool anIsByTwoPoints = IsByTwoPoints(); + + QPoint aLocalPointA, aLocalPointB, aLocalPointC; + if ( GetLocalPoints( aLocalPointA, aLocalPointB, aLocalPointC ) ) + { + QString aGap = QString().fill( ' ', anImageName.size() + 17 ); + + aResList << QString( "%1.SetLocalPoints( QPoint( %2, %3 )," ) + .arg( anImageName ).arg( aLocalPointA.x() ).arg( aLocalPointA.y() ); + aResList << QString( aGap + "QPoint( %1, %2 )" ) + .arg( aLocalPointB.x() ).arg( aLocalPointB.y() ); + if ( !anIsByTwoPoints ) + { + aResList.last().append( "," ); + aResList << QString( aGap + "QPoint( %1, %2 ) )" ) + .arg( aLocalPointC.x() ).arg( aLocalPointC.y() ); + } + else + { + aResList.last().append( " )" ); + } + aResList << QString( "" ); + } + + HYDROData_Image::TransformationMode aTransformationMode; + QPointF aTrsfPointA, aTrsfPointB, aTrsfPointC; + if ( GetGlobalPoints( aTransformationMode, aTrsfPointA, aTrsfPointB, aTrsfPointC ) ) + { + QString aGap = QString().fill( ' ', anImageName.size() + 18 ); + + aResList << QString( "%1.SetGlobalPoints( %2," ) + .arg( anImageName ).arg( aTransformationMode ); + aResList << QString( aGap + "QPointF( %1, %2 )," ) + .arg( aTrsfPointA.x(), 0, 'f', 3 ).arg( aTrsfPointA.y(), 0, 'f', 3 ); + aResList << QString( aGap + "QPointF( %1, %2 )" ) + .arg( aTrsfPointB.x(), 0, 'f', 3 ).arg( aTrsfPointB.y(), 0, 'f', 3 ); + if ( !anIsByTwoPoints ) + { + aResList.last().append( "," ); + aResList << QString( aGap + "QPointF( %1, %2 ) )" ) + .arg( aTrsfPointC.x(), 0, 'f', 3 ).arg( aTrsfPointC.y(), 0, 'f', 3 ); + } + else + { + aResList.last().append( " )" ); + } + + if ( aTransformationMode == ReferenceImage ) + { + Handle(HYDROData_Image) aRefImg = GetTrsfReferenceImage(); + setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefImg, "SetTrsfReferenceImage" ); + } + } } else { @@ -63,10 +140,11 @@ QStringList HYDROData_Image::DumpToPython( MapOfTreatedObjects& theTreatedObject { aResList << QString( "" ); - aResList << QString( "%1.SetOperatorName( \"%2\" );" ) + aResList << QString( "%1.SetOperatorName( \"%2\" )" ) .arg( anImageName ).arg( anOperatorName ); - ImageComposer_Operator* anImageOp = HYDROOperations_Factory::Factory()->Operator( this ); + ImageComposer_Operator* anImageOp = + HYDROData_OperationsFactory::Factory()->Operator( OperatorName() ); if ( anImageOp ) { // Dump operation arguments @@ -78,7 +156,7 @@ QStringList HYDROData_Image::DumpToPython( MapOfTreatedObjects& theTreatedObject aResList << anOpArgs; aResList << QString( "" ); - aResList << QString( "%1.SetArgs( \"%2\" );" ) + aResList << QString( "%1.SetArgs( %2 )" ) .arg( anImageName ).arg( anOpArgsArrayName ); } } @@ -91,108 +169,149 @@ QStringList HYDROData_Image::DumpToPython( MapOfTreatedObjects& theTreatedObject for ( int i = 0; i < aNbReferences; ++i ) { - Handle(HYDROData_Image) aRefImg = Reference( i ); - if ( aRefImg.IsNull() ) - continue; + Handle(HYDROData_Image) aRefImg = Handle(HYDROData_Image)::DownCast( Reference( i ) ); + setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefImg, "AppendReference" ); + } + } + } - QString aRefImgName = aRefImg->GetName(); + aResList << QString( "" ); + aResList << QString( "%1.Update()" ).arg( anImageName ); - // The definition of reference image must be dumped before this - if ( !theTreatedObjects.contains( aRefImgName ) ) - { - // Write definition of reference image - QStringList aRefImgDump = aRefImg->DumpToPython( theTreatedObjects ); - if ( aRefImgDump.isEmpty() ) - continue; + return aResList; +} - QStringList aTmpList = aResList; - aResList = aRefImgDump; +void HYDROData_Image::Update() +{ + bool anIsToUpdate = IsMustBeUpdated( Geom_2d ); - aResList.append( "" ); - aResList.append( aTmpList ); + HYDROData_Entity::Update(); - theTreatedObjects.insert( aRefImgName, aRefImg ); - } + if ( !anIsToUpdate ) + return; - aResList << QString( "%1.AppendReference( %2 );" ) - .arg( anImageName ).arg( aRefImgName ); - } - } - } + HYDROData_OperationsFactory* aFactory = HYDROData_OperationsFactory::Factory(); - // Dump transformation matrix for image - aResList << QString( "" ); + ImageComposer_Operator* anOp = aFactory->Operator( OperatorName() ); + if ( anOp ) // Update image if there is an operation + { + // Fill by arguments and process the operation + anOp->setBinArgs( Args() ); - QTransform aTrsf = Trsf(); + QVariant anObj1, anObj2; + int aNbReferences = NbReferences(); - aResList << QString( "trsf = QTransform( %2, %3, %4," ) - .arg( aTrsf.m11() ).arg( aTrsf.m12() ).arg( aTrsf.m13() ); - aResList << QString( " %1, %2, %3," ) - .arg( aTrsf.m21() ).arg( aTrsf.m22() ).arg( aTrsf.m23() ); - aResList << QString( " %1, %2, %3 );" ) - .arg( aTrsf.m31() ).arg( aTrsf.m32() ).arg( aTrsf.m33() ); + if ( aNbReferences > 0 ) + { + // First referenced object + Handle(HYDROData_Entity) aRefObj = Reference( 0 ); + if ( !aRefObj.IsNull() ) + { + anObj1 = aRefObj->GetDataVariant(); + if ( !anObj1.isNull() && anObj1.canConvert() ) + { + ImageComposer_Image anImage = anObj1.value(); + QTransform aTransform = anImage.transform(); + SetTrsf( aTransform ); + } + } + } - aResList << QString( "%1.SetTrsf( trsf );" ).arg( anImageName ); + if ( aNbReferences > 1 ) + { + // Second referenced object + Handle(HYDROData_Entity) aRefObj = Reference( 1 ); + if ( !aRefObj.IsNull() ) + anObj2 = aRefObj->GetDataVariant(); + } - // Dump transformation points for image - aResList << QString( "" ); + ImageComposer_Image aResImg = anOp->process( anObj1, anObj2 ); + SetImage( aResImg ); + SetTrsf( aResImg.transform() ); + } + else // Update image if it positioned relatively to other image + { + UpdateTrsf(); + } - QPoint aPointAIn, aPointBIn, aPointCIn; - QPointF aPointAOut, aPointBOut, aPointCOut; - TrsfPoints( aPointAIn, aPointBIn, aPointCIn, - aPointAOut, aPointBOut, aPointCOut ); + ClearChanged(); +} - aResList << QString( "a_in = QPoint( %1, %2 );" ) - .arg( aPointAIn.x() ).arg( aPointAIn.y() ); +bool HYDROData_Image::IsHas2dPrs() const +{ + return true; +} - aResList << QString( "b_in = QPoint( %1, %2 );" ) - .arg( aPointBIn.x() ).arg( aPointBIn.y() ); +QVariant HYDROData_Image::GetDataVariant() +{ + QTransform aTransform = Trsf(); - aResList << QString( "c_in = QPoint( %1, %2 );" ) - .arg( aPointCIn.x() ).arg( aPointCIn.y() ); + ImageComposer_Image anImage = Image(); + anImage.setTransform( aTransform ); - aResList << QString( "a_out = QPointF( %1, %2 );" ) - .arg( aPointAOut.x() ).arg( aPointAOut.y() ); + QVariant aVarData; + aVarData.setValue( anImage ); + + return aVarData; +} - aResList << QString( "b_out = QPointF( %1, %2 );" ) - .arg( aPointBOut.x() ).arg( aPointBOut.y() ); +HYDROData_SequenceOfObjects HYDROData_Image::GetAllReferenceObjects() const +{ + HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects(); - aResList << QString( "c_out = QPointF( %1, %2 );" ) - .arg( aPointCOut.x() ).arg( aPointCOut.y() ); + Handle(HYDROData_Image) aRefImage = GetTrsfReferenceImage(); + if ( !aRefImage.IsNull() ) + aResSeq.Append( aRefImage ); - QString aGap = QString().fill( ' ', anImageName.size() + 16 ); - aResList << QString( "%1.SetTrsfPoints( a_in, b_in, c_in," ).arg( anImageName ); - aResList << QString( aGap + "a_out, b_out, c_out );" ); + HYDROData_SequenceOfObjects aSeqRefObjects = GetReferenceObjects( 0 ); + aResSeq.Append( aSeqRefObjects ); - return aResList; + return aResSeq; } void HYDROData_Image::SetImage(const QImage& theImage) { - if (theImage.isNull()) { + if ( theImage.isNull() ) + { // for empty image remove all previously stored attributes myLab.ForgetAttribute(TDataStd_IntegerArray::GetID()); myLab.ForgetAttribute(TDataStd_ByteArray::GetID()); - return; } - // store width, height, bytes per line and format in integer array - Handle(TDataStd_IntegerArray) aParams; - if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams)) { - aParams = TDataStd_IntegerArray::Set(myLab, 1, 4); + else + { + QImage anImage; + + // convert 8-bits images + if ( theImage.format() == QImage::Format_Indexed8 ) { + anImage = theImage.convertToFormat( QImage::Format_RGB32 ); + } else { + anImage = theImage; + } + + // store width, height, bytes per line and format in integer array + Handle(TDataStd_IntegerArray) aParams; + if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams)) { + aParams = TDataStd_IntegerArray::Set(myLab, 1, 4); + } + aParams->SetValue(1, anImage.width()); + aParams->SetValue(2, anImage.height()); + aParams->SetValue(3, anImage.bytesPerLine()); + aParams->SetValue(4, (int)(anImage.format())); + // store data of image in byte array + const char* aData = (const char*)(anImage.bits()); + SaveByteArray(0, aData, anImage.byteCount()); } - aParams->SetValue(1, theImage.width()); - aParams->SetValue(2, theImage.height()); - aParams->SetValue(3, theImage.bytesPerLine()); - aParams->SetValue(4, (int)(theImage.format())); - // store data of image in byte array - const char* aData = (const char*)(theImage.bits()); - SaveByteArray(0, aData, theImage.byteCount()); + + Changed( Geom_2d ); } -bool HYDROData_Image::LoadImage(const QString& theFilePath) +bool HYDROData_Image::LoadImage( const QString& theFilePath ) { QImage anImage( theFilePath ); SetImage( anImage ); + + SetFilePath( theFilePath ); + return !anImage.isNull(); } @@ -210,19 +329,25 @@ QImage HYDROData_Image::Image() return aResult; } -void HYDROData_Image::SetFilePath(const QString& theFilePath) +void HYDROData_Image::SetFilePath( const QString& theFilePath ) { TCollection_AsciiString anAsciiStr( theFilePath.toStdString().c_str() ); TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), anAsciiStr ); + + Changed( Geom_2d ); } QString HYDROData_Image::GetFilePath() const { QString aRes; - Handle(TDataStd_AsciiString) anAsciiStr; - if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) ) - aRes = QString( anAsciiStr->Get().ToCString() ); + TDF_Label aLabel = myLab.FindChild( DataTag_FilePath, false ); + if ( !aLabel.IsNull() ) + { + Handle(TDataStd_AsciiString) anAsciiStr; + if ( aLabel.FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) ) + aRes = QString( anAsciiStr->Get().ToCString() ); + } return aRes; } @@ -244,6 +369,8 @@ void HYDROData_Image::SetTrsf(const QTransform& theTrsf) anArray->SetValue(7, theTrsf.m31()); anArray->SetValue(8, theTrsf.m32()); anArray->SetValue(9, theTrsf.m33()); + + Changed( Geom_2d ); } QTransform HYDROData_Image::Trsf() const @@ -259,142 +386,483 @@ QTransform HYDROData_Image::Trsf() const return aTrsf; } -void HYDROData_Image::SetTrsfPoints(const QPoint& thePointAIn, - const QPoint& thePointBIn, - const QPoint& thePointCIn, - const QPointF& thePointAOut, - const QPointF& thePointBOut, - const QPointF& thePointCOut) +void HYDROData_Image::UpdateTrsf() +{ + QPoint aPointA, aPointB, aPointC; + if ( !GetLocalPoints( aPointA, aPointB, aPointC ) ) + return; + + TransformationMode aTrsfMode; + QPointF aTrsfPointA, aTrsfPointB, aTrsfPointC; + if ( !GetGlobalPoints( aTrsfMode, aTrsfPointA, aTrsfPointB, aTrsfPointC ) ) + return; + + QTransform aRefTransform; + Handle(HYDROData_Image) aRefImage = GetTrsfReferenceImage(); + + bool anIsRefImage = aTrsfMode == ReferenceImage; + if ( anIsRefImage ) + { + if ( aRefImage.IsNull() ) + return; + + aRefTransform = aRefImage->Trsf(); + } + + bool anIsByTwoPoints = IsByTwoPoints(); + + // Convert lambert coordinates to cartesian + if ( aTrsfMode == ManualGeodesic ) + { + double aXCart = 0, aYCart = 0; + + HYDROData_Lambert93::toXY( aTrsfPointA.y(), aTrsfPointA.x(), aXCart, aYCart ); + aTrsfPointA = QPointF( aXCart, aYCart ); + + HYDROData_Lambert93::toXY( aTrsfPointB.y(), aTrsfPointB.x(), aXCart, aYCart ); + aTrsfPointB = QPointF( aXCart, aYCart ); + + if ( !anIsByTwoPoints ) + { + HYDROData_Lambert93::toXY( aTrsfPointC.y(), aTrsfPointC.x(), aXCart, aYCart ); + aTrsfPointC = QPointF( aXCart, aYCart ); + } + } + + // generate third points if needed + if ( anIsByTwoPoints ) + { + aPointC = generateThirdPoint( aPointA, aPointB, true ).toPoint(); + aTrsfPointC = generateThirdPoint( aTrsfPointA, aTrsfPointB, anIsRefImage ); + } + + int xa = aPointA.x(); + int ya = aPointA.y(); + int xb = aPointB.x(); + int yb = aPointB.y(); + int xc = aPointC.x(); + int yc = aPointC.y(); + + double xta = aTrsfPointA.x(); + double yta = aTrsfPointA.y(); + double xtb = aTrsfPointB.x(); + double ytb = aTrsfPointB.y(); + double xtc = aTrsfPointC.x(); + double ytc = aTrsfPointC.y(); + + // first, check that three input points don't belong to a single line + if( ( yb - ya ) * ( xc - xa ) == ( yc - ya ) * ( xb - xa ) ) + return; + + // the same check for the reference points + if( anIsRefImage && ( ( ytb - yta ) * ( xtc - xta ) == ( ytc - yta ) * ( xtb - xta ) ) ) + return; + + QTransform aTransform1( xa, ya, 1, xb, yb, 1, xc, yc, 1 ); + QTransform aTransform2( xta, yta, 1, xtb, ytb, 1, xtc, ytc, 1 ); + + bool anIsInvertible = false; + QTransform aTransform1Inverted = aTransform1.inverted( &anIsInvertible ); + if( !anIsInvertible ) + return; + + QTransform aResTransform = aTransform1Inverted * aTransform2; + if( anIsRefImage ) + aResTransform *= aRefTransform; + + SetTrsf( aResTransform ); +} + +bool HYDROData_Image::IsByTwoPoints() const +{ + if ( !HasLocalPoints() || !HasGlobalPoints() ) + return false; + + QPoint aPointA, aPointB, aPointC; + GetLocalPoints( aPointA, aPointB, aPointC ); + + return aPointC.x() < 0 && aPointC.y() < 0; +} + +bool HYDROData_Image::HasReferences() const +{ + Handle(HYDROData_Image) aRefImage = GetTrsfReferenceImage(); + int aNbReferences = NbReferences(); + + return !aRefImage.IsNull() || aNbReferences > 0; +} + +void HYDROData_Image::RemoveAllReferences() +{ + if ( !HasReferences() ) + return; + + Handle(HYDROData_Image) aRefImage = GetTrsfReferenceImage(); + if ( !aRefImage.IsNull() ) + { + RemoveTrsfReferenceImage(); + } + else + { + ClearReferences(); + SetOperatorName( "" ); + SetArgs( "" ); + SetIsSelfSplit( false ); + } + + bool anIsByTwoPoints = IsByTwoPoints(); + + QImage anImage = Image(); + if ( anImage.isNull() ) + { + ClearChanged(); + return; + } + + // Set local points to default position + QPoint aLocalPointA = QPoint( 0, 0 ); + QPoint aLocalPointB = QPoint( anImage.width(), 0 ); + QPoint aLocalPointC = anIsByTwoPoints ? QPoint( INT_MIN, INT_MIN ) : QPoint( 0, anImage.height() ); + + SetLocalPoints( aLocalPointA, aLocalPointB, aLocalPointC, false ); + + // Calculate global points + QTransform aTransform = Trsf(); + + QPointF aTrsfPointA = QPointF( aTransform.map( aLocalPointA ) ); + QPointF aTrsfPointB = QPointF( aTransform.map( aLocalPointB ) ); + QPointF aTrsfPointC = anIsByTwoPoints ? QPointF( INT_MIN, INT_MIN ) : + QPointF( aTransform.map( aLocalPointC ) ); + + SetGlobalPoints( ManualCartesian, aTrsfPointA, aTrsfPointB, aTrsfPointC ); + + ClearChanged(); +} + +void HYDROData_Image::SetLocalPoints( const QPoint& thePointA, + const QPoint& thePointB, + const QPoint& thePointC, + const bool theIsUpdate ) +{ + Handle(TDataStd_RealArray) anArray; + if ( !myLab.FindChild( DataTag_TrsfPoints ).FindAttribute( TDataStd_RealArray::GetID(), anArray ) ) + anArray = TDataStd_RealArray::Set( myLab.FindChild( DataTag_TrsfPoints ), 1, 12 ); + + anArray->SetValue( 1, thePointA.x() ); + anArray->SetValue( 2, thePointA.y() ); + anArray->SetValue( 3, thePointB.x() ); + anArray->SetValue( 4, thePointB.y() ); + anArray->SetValue( 5, thePointC.x() ); + anArray->SetValue( 6, thePointC.y() ); + + TDataStd_UAttribute::Set( myLab.FindChild( DataTag_TrsfPoints ), GUID_HAS_LOCAL_POINTS ); + + if ( theIsUpdate ) + UpdateTrsf(); + + Changed( Geom_2d ); +} + +bool HYDROData_Image::GetLocalPoints( QPoint& thePointA, + QPoint& thePointB, + QPoint& thePointC ) const +{ + if ( !HasLocalPoints() ) + return false; + + Handle(TDataStd_RealArray) anArray; + myLab.FindChild( DataTag_TrsfPoints ).FindAttribute( TDataStd_RealArray::GetID(), anArray ); + + thePointA = QPointF( anArray->Value( 1 ), anArray->Value( 2 ) ).toPoint(); + thePointB = QPointF( anArray->Value( 3 ), anArray->Value( 4 ) ).toPoint(); + thePointC = QPointF( anArray->Value( 5 ), anArray->Value( 6 ) ).toPoint(); + + return true; +} + +bool HYDROData_Image::HasLocalPoints() const +{ + TDF_Label aLabel = myLab.FindChild( DataTag_TrsfPoints, false ); + if ( aLabel.IsNull() || !aLabel.IsAttribute( GUID_HAS_LOCAL_POINTS ) ) + return false; + + Handle(TDataStd_RealArray) anArray; + return aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ); +} + + +void HYDROData_Image::SetGlobalPoints( const TransformationMode& theMode, + const QPointF& thePointA, + const QPointF& thePointB, + const QPointF& thePointC, + const bool theIsUpdate ) +{ + Handle(TDataStd_RealArray) anArray; + if ( !myLab.FindChild( DataTag_TrsfPoints ).FindAttribute( TDataStd_RealArray::GetID(), anArray ) ) + anArray = TDataStd_RealArray::Set( myLab.FindChild( DataTag_TrsfPoints ), 1, 12 ); + + anArray->SetValue( 7, thePointA.x() ); + anArray->SetValue( 8, thePointA.y() ); + anArray->SetValue( 9, thePointB.x() ); + anArray->SetValue( 10, thePointB.y() ); + anArray->SetValue( 11, thePointC.x() ); + anArray->SetValue( 12, thePointC.y() ); + + SetTrsfMode( theMode ); + + TDataStd_UAttribute::Set( myLab.FindChild( DataTag_TrsfPoints ), GUID_HAS_GLOBAL_POINTS ); + + if ( theIsUpdate ) + UpdateTrsf(); + + Changed( Geom_2d ); +} + +bool HYDROData_Image::GetGlobalPoints( TransformationMode& theMode, + QPointF& thePointA, + QPointF& thePointB, + QPointF& thePointC ) const { + if ( !HasGlobalPoints() ) + return false; + + theMode = GetTrsfMode(); + Handle(TDataStd_RealArray) anArray; - if (!myLab.FindChild(DataTag_TrsfPoints).FindAttribute(TDataStd_RealArray::GetID(), anArray)) { - anArray = TDataStd_RealArray::Set(myLab.FindChild(DataTag_TrsfPoints), 1, 12); + myLab.FindChild( DataTag_TrsfPoints ).FindAttribute( TDataStd_RealArray::GetID(), anArray ); + + thePointA = QPointF( anArray->Value( 7 ), anArray->Value( 8 ) ); + thePointB = QPointF( anArray->Value( 9 ), anArray->Value( 10 ) ); + thePointC = QPointF( anArray->Value( 11 ), anArray->Value( 12 ) ); + + return true; +} + +bool HYDROData_Image::SetGlobalPointsFromFile( const QString& theFileName ) +{ + bool aRes = false; + + // Try to open the file + QFile aFile( theFileName ); + if ( !aFile.exists() || !aFile.open( QIODevice::ReadOnly ) ) { + return aRes; + } + + QPointF aPointA, aPointB; + double aXmin, anYmin, aXmax, anYmax; + aXmin = anYmin = aXmax = anYmax = -1; + + while ( !aFile.atEnd() && + ( aXmin < 0 || anYmin < 0 || aXmax < 0 || anYmax < 0 ) ) { + // Read line + QString aLine = aFile.readLine().simplified(); + aLine.replace( " ", "" ); + if ( aLine.isEmpty() ) { + continue; + } + + // Try to read double value after ":" + bool isDoubleOk = false; + double aDoubleValue = -1; + QStringList aValues = aLine.split( ":", QString::SkipEmptyParts ); + if ( aValues.count() == 2 ) { + aDoubleValue = aValues.last().toDouble( &isDoubleOk ); + } + + // Check the result + if ( !isDoubleOk || + HYDROData_Tool::IsNan( aDoubleValue ) || + HYDROData_Tool::IsInf( aDoubleValue ) ) { + continue; + } + + // Set the value + if ( aLine.startsWith( "Xminimum" ) ) { + aXmin = aDoubleValue; + } + else if ( aLine.startsWith( "Yminimum" ) ) { + anYmin = aDoubleValue; + } + else if ( aLine.startsWith( "Xmaximum" ) ) { + aXmax = aDoubleValue; + } + else if ( aLine.startsWith( "Ymaximum" ) ) { + anYmax = aDoubleValue; + } } - anArray->SetValue(1, thePointAIn.x()); - anArray->SetValue(2, thePointAIn.y()); - anArray->SetValue(3, thePointBIn.x()); - anArray->SetValue(4, thePointBIn.y()); - anArray->SetValue(5, thePointCIn.x()); - anArray->SetValue(6, thePointCIn.y()); - anArray->SetValue(7, thePointAOut.x()); - anArray->SetValue(8, thePointAOut.y()); - anArray->SetValue(9, thePointBOut.x()); - anArray->SetValue(10, thePointBOut.y()); - anArray->SetValue(11, thePointCOut.x()); - anArray->SetValue(12, thePointCOut.y()); -} - -void HYDROData_Image::TrsfPoints(QPoint& thePointAIn, - QPoint& thePointBIn, - QPoint& thePointCIn, - QPointF& thePointAOut, - QPointF& thePointBOut, - QPointF& thePointCOut) const + + // Close the file + aFile.close(); + + if ( aXmin >= 0 && anYmin >= 0 ) { + aPointA.setX( aXmin ); + aPointA.setY( anYmin ); + } + + if ( aXmax >= 0 && anYmax >= 0 ) { + aPointB.setX( aXmax ); + aPointB.setY( anYmax ); + } + + if ( !aPointA.isNull() && !aPointB.isNull() ) { + SetGlobalPoints( ManualCartesian, aPointA, aPointB ); + aRes = true; + } + + return aRes; +} + +bool HYDROData_Image::HasGlobalPoints() const { + TDF_Label aLabel = myLab.FindChild( DataTag_TrsfPoints, false ); + if ( aLabel.IsNull() || !aLabel.IsAttribute( GUID_HAS_GLOBAL_POINTS ) ) + return false; + Handle(TDataStd_RealArray) anArray; - if (myLab.FindChild(DataTag_TrsfPoints).FindAttribute(TDataStd_RealArray::GetID(), anArray)) { - thePointAIn = QPointF( anArray->Value(1), anArray->Value(2) ).toPoint(); - thePointBIn = QPointF( anArray->Value(3), anArray->Value(4) ).toPoint(); - thePointCIn = QPointF( anArray->Value(5), anArray->Value(6) ).toPoint(); - thePointAOut = QPointF( anArray->Value(7), anArray->Value(8) ); - thePointBOut = QPointF( anArray->Value(9), anArray->Value(10) ); - thePointCOut = QPointF( anArray->Value(11), anArray->Value(12) ); + return aLabel.FindAttribute( TDataStd_RealArray::GetID(), anArray ); +} + +void HYDROData_Image::SetReferencePoints( const Handle(HYDROData_Image)& theRefImage, + const QPointF& thePointA, + const QPointF& thePointB, + const QPointF& thePointC, + const bool theIsUpdate ) +{ + SetTrsfReferenceImage( theRefImage ); + SetGlobalPoints( ReferenceImage, thePointA, thePointB, thePointC, theIsUpdate ); +} + +bool HYDROData_Image::GetReferencePoints( Handle(HYDROData_Image)& theRefImage, + QPointF& thePointA, + QPointF& thePointB, + QPointF& thePointC ) const +{ + if ( !HasReferencePoints() ) + return false; + + theRefImage = GetTrsfReferenceImage(); + + TransformationMode aMode; + GetGlobalPoints( aMode, thePointA, thePointB, thePointC ); + + return true; +} + +bool HYDROData_Image::HasReferencePoints() const +{ + if ( !HasGlobalPoints() ) + return false; + + Handle(HYDROData_Image) aRefImage = GetTrsfReferenceImage(); + if ( aRefImage.IsNull() ) + return false; + + TransformationMode aTrsfMode = GetTrsfMode(); + if ( aTrsfMode != ReferenceImage ) + return false; + + return true; +} + +void HYDROData_Image::SetTrsfMode( const TransformationMode& theMode ) +{ + TDataStd_Integer::Set( myLab.FindChild( DataTag_TrsfMode ), (int)theMode ); + Changed( Geom_2d ); +} + +HYDROData_Image::TransformationMode HYDROData_Image::GetTrsfMode() const +{ + TransformationMode aResMode = ManualGeodesic; + + TDF_Label aLabel = myLab.FindChild( DataTag_TrsfPoints, false ); + if ( !aLabel.IsNull() ) + { + Handle(TDataStd_Integer) aMode; + if ( myLab.FindChild( DataTag_TrsfMode ).FindAttribute( TDataStd_Integer::GetID(), aMode ) ) + aResMode = (TransformationMode)aMode->Get(); } + + return aResMode; } -void HYDROData_Image::AppendReference(Handle(HYDROData_Image) theReferenced) +void HYDROData_Image::SetTrsfReferenceImage( const Handle(HYDROData_Image)& theRefImage ) { - Handle(TDataStd_ReferenceList) aRefs; - if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs)) - aRefs = TDataStd_ReferenceList::Set(myLab); - aRefs->Append(theReferenced->Label()); + SetReferenceObject( theRefImage, DataTag_TrsfImage ); + Changed( Geom_2d ); } -int HYDROData_Image::NbReferences() const +Handle(HYDROData_Image) HYDROData_Image::GetTrsfReferenceImage() const +{ + return Handle(HYDROData_Image)::DownCast( GetReferenceObject( DataTag_TrsfImage ) ); +} + +void HYDROData_Image::RemoveTrsfReferenceImage() +{ + RemoveReferenceObject( DataTag_TrsfImage ); + Changed( Geom_2d ); +} + +void HYDROData_Image::AppendReference( const Handle(HYDROData_Entity)& theReferenced ) { - Handle(TDataStd_ReferenceList) aRefs; - if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs)) - return 0; - return aRefs->Extent(); + AddReferenceObject( theReferenced, 0 ); + Changed( Geom_2d ); } -Handle(HYDROData_Image) HYDROData_Image::Reference(const int theIndex) const +int HYDROData_Image::NbReferences() const { - Handle(TDataStd_ReferenceList) aRefs; - if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs)) - return Handle(HYDROData_Image)(); - if (theIndex < 0 || theIndex >= aRefs->Extent()) - return Handle(HYDROData_Image)(); + return NbReferenceObjects( 0 ); +} - TDF_ListIteratorOfLabelList anIter(aRefs->List()); - for(int anIndex = 0; anIndex != theIndex; anIter.Next(), anIndex++); - const TDF_Label& aRefLab = anIter.Value(); - return Handle(HYDROData_Image)::DownCast(HYDROData_Iterator::Object(aRefLab)); +Handle(HYDROData_Entity) HYDROData_Image::Reference( const int theIndex ) const +{ + return GetReferenceObject( 0, theIndex ); } void HYDROData_Image::ChangeReference( - const int theIndex, Handle(HYDROData_Image) theReferenced) -{ - Handle(TDataStd_ReferenceList) aRefs; - if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs)) - aRefs = TDataStd_ReferenceList::Set(myLab); - if (theIndex >= aRefs->Extent()) { // for too big index append it just to the end - AppendReference(theReferenced); - } else { // remove and insert new - TDF_ListIteratorOfLabelList anIter(aRefs->List()); - int anIndex = 0; - for(; anIndex != theIndex; anIter.Next(), anIndex++); - const TDF_Label& aRemovedLab = anIter.Value(); - anIter.Next(); - aRefs->Remove(aRemovedLab); - if (anIter.More()) - aRefs->InsertBefore(theReferenced->Label(), anIter.Value()); - else - aRefs->Append(theReferenced->Label()); - } + const int theIndex, Handle(HYDROData_Entity) theReferenced) +{ + SetReferenceObject( theReferenced, 0, theIndex ); + Changed( Geom_2d ); } void HYDROData_Image::RemoveReference(const int theIndex) { - Handle(TDataStd_ReferenceList) aRefs; - if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs)) - return; // no references, nothing to remove - if (aRefs->Extent() == 1 && theIndex == 0) { // remove all if only one - ClearReferences(); - return; - } - TDF_ListIteratorOfLabelList anIter(aRefs->List()); - int anIndex = 0; - for(; anIndex != theIndex && anIter.More(); anIter.Next(), anIndex++); - if (anIter.More()) - aRefs->Remove(anIter.Value()); + RemoveReferenceObject( 0, theIndex ); + Changed( Geom_2d ); } void HYDROData_Image::ClearReferences() { - myLab.ForgetAttribute(TDataStd_ReferenceList::GetID()); + ClearReferenceObjects( 0 ); + Changed( Geom_2d ); } -void HYDROData_Image::SetOperatorName(const QString theOpName) +void HYDROData_Image::SetOperatorName( const QString theOpName ) { - TDataStd_Name::Set(myLab.FindChild(DataTag_Operator), - TCollection_ExtendedString(theOpName.toLatin1().constData())); + TCollection_AsciiString anAsciiStr( theOpName.toStdString().c_str() ); + TDataStd_AsciiString::Set( myLab.FindChild( DataTag_Operator ), anAsciiStr ); + Changed( Geom_2d ); } QString HYDROData_Image::OperatorName() const { - Handle(TDataStd_Name) aName; - if (myLab.FindChild(DataTag_Operator). - FindAttribute(TDataStd_Name::GetID(), aName)) { - TCollection_AsciiString aStr(aName->Get()); - return QString(aStr.ToCString()); + QString aRes; + + TDF_Label aLabel = myLab.FindChild( DataTag_Operator, false ); + if ( !aLabel.IsNull() ) + { + Handle(TDataStd_AsciiString) anAsciiStr; + if ( aLabel.FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) ) + aRes = QString( anAsciiStr->Get().ToCString() ); } - return QString(); + + return aRes; } void HYDROData_Image::SetArgs(const QByteArray& theArgs) { SaveByteArray(DataTag_Operator, theArgs.constData(), theArgs.length()); + Changed( Geom_2d ); } QByteArray HYDROData_Image::Args() const @@ -406,16 +874,42 @@ QByteArray HYDROData_Image::Args() const return QByteArray(aData, aLen); } -void HYDROData_Image::MustBeUpdated(bool theFlag) +void HYDROData_Image::SetIsSelfSplit(bool theFlag) { if (theFlag) { - TDataStd_UAttribute::Set(myLab, GUID_MUST_BE_UPDATED); + TDataStd_UAttribute::Set(myLab, GUID_SELF_SPLIT); } else { - myLab.ForgetAttribute(GUID_MUST_BE_UPDATED); + myLab.ForgetAttribute(GUID_SELF_SPLIT); } + Changed( Geom_2d ); } -bool HYDROData_Image::MustBeUpdated() +bool HYDROData_Image::IsSelfSplit() const { - return myLab.IsAttribute(GUID_MUST_BE_UPDATED); + return myLab.IsAttribute(GUID_SELF_SPLIT); } + +QPointF HYDROData_Image::generateThirdPoint( const QPointF& thePointA, + const QPointF& thePointB, + const bool& theIsLocal ) const +{ + // Rotate vector to 90 degrees : clockwise - for local + // counterclockwise - for global + const double aTheta = theIsLocal ? -M_PI_2 : M_PI_2; + + QPointF aResPoint; + + // Move to (0,0) for correct rotation + double x = thePointB.x() - thePointA.x(); + double y = thePointB.y() - thePointA.y(); + + aResPoint.setX( x * cos( aTheta ) - y * sin( aTheta ) ); + aResPoint.setY( x * sin( aTheta ) + y * cos( aTheta ) ); + + // Move back to origin position + aResPoint.setX( aResPoint.x() + thePointA.x() ); + aResPoint.setY( aResPoint.y() + thePointA.y() ); + + return aResPoint; +} +