+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 )