1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <HYDROGUI_ShapeImage.h>
24 #include <HYDROGUI_DataObject.h>
25 #include <HYDROGUI_Tool.h>
26 #include <HYDROData_Document.h>
27 #include <HYDROData_Image.h>
29 #include <AIS_TexturedShape.hxx>
30 #include <BRepBuilderAPI_MakeEdge.hxx>
31 #include <BRepBuilderAPI_MakeWire.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Wire.hxx>
36 #include <SUIT_MessageBox.h>
39 HYDROGUI_ShapeImage::HYDROGUI_ShapeImage( const Handle(AIS_InteractiveContext)& theContext,
40 const Handle_HYDROData_Image& theImage,
42 : HYDROGUI_Shape( theContext, theImage, theZLayer )
46 HYDROGUI_ShapeImage::~HYDROGUI_ShapeImage()
51 void HYDROGUI_ShapeImage::update( bool theIsUpdateViewer, bool isDeactivateSelection )
53 setIsToUpdate( false );
55 // Try to retrieve information from object
56 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( getObject() );
58 if( !anImageObj.IsNull() )
62 QString aTextureFileName = generateTextureFileName( anImageObj );
64 QImage anImage = anImageObj->Image();
65 QString aFilePath = anImageObj->GetFilePath();
66 QTransform aTrsf = anImageObj->Trsf();
68 int aWidth = anImage.width();
69 int aHeight = anImage.height();
71 QString anImageError = "";
73 QTransform anInversion = QTransform::fromScale( -1, -1 );
74 anImage = anImage.transformed( anInversion * aTrsf, Qt::SmoothTransformation );
76 if ( anImage.isNull() )
77 anImageError = QObject::tr( "IMAGE_TRANSFORMATION_CAN_NOT_BE_APPLYED" );
80 // Workaround: Scale the texture image to the nearest width multiple 4 due to the CASCADE bug 23813
81 int aTrsfWidth = anImage.width();
82 int aDelta = aTrsfWidth % 4;
85 aTrsfWidth += ( 4 - aDelta );
87 anImage = anImage.scaledToWidth( aTrsfWidth );
89 // temporary optimization, to reduce the saved image size (and the texture quality)
90 QImage anImageToSave = anImage; //RKV:reduceTexture( anImage, 500 );
92 bool isSaved = anImageToSave.save( aTextureFileName );
94 anImageError = QObject::tr( "FILE_CAN_NOT_BE_CREATED" ).arg( aTextureFileName );
96 QFile::setPermissions( aTextureFileName, (QFile::Permissions)0x4FFFF );
99 if ( !anImageError.isEmpty() )
101 SUIT_MessageBox::warning( 0, QObject::tr( "SHAPE_IMAGE_ERROR" ),
102 QObject::tr( "IMAGE_CAN_NOT_BE_CREATED" ) + anImageError );
105 QPointF aPoint1( 0, 0 ); // 1: top left
106 QPointF aPoint2( aWidth, 0 ); // 2: top right
107 QPointF aPoint3( aWidth, aHeight ); // 3: bottom right
108 QPointF aPoint4( 0, aHeight ); // 4: bottom left
110 aPoint1 = aTrsf.map( aPoint1 );
111 aPoint2 = aTrsf.map( aPoint2 );
112 aPoint3 = aTrsf.map( aPoint3 );
113 aPoint4 = aTrsf.map( aPoint4 );
115 QPolygonF aPolygon = QPolygonF() << aPoint1 << aPoint2 << aPoint3 << aPoint4;
116 QRectF aRect = aPolygon.boundingRect();
118 gp_Pnt aPnt1( aRect.topLeft().x(), aRect.topLeft().y(), 0 );
119 gp_Pnt aPnt2( aRect.topRight().x(), aRect.topRight().y(), 0 );
120 gp_Pnt aPnt3( aRect.bottomRight().x(), aRect.bottomRight().y(), 0 );
121 gp_Pnt aPnt4( aRect.bottomLeft().x(), aRect.bottomLeft().y(), 0 );
123 Handle_HYDROData_Document aDoc = HYDROData_Document::Document( anImageObj->Label() );
124 aDoc->Transform( aPnt1, true );
125 aDoc->Transform( aPnt2, true );
126 aDoc->Transform( aPnt3, true );
127 aDoc->Transform( aPnt4, true );
129 TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge( aPnt1, aPnt2 ).Edge();
130 TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge( aPnt2, aPnt3 ).Edge();
131 TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge( aPnt3, aPnt4 ).Edge();
132 TopoDS_Edge anEdge4 = BRepBuilderAPI_MakeEdge( aPnt4, aPnt1 ).Edge();
134 TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge1, anEdge2, anEdge3, anEdge4 ).Wire();
135 aWire.Closed( true );
137 setTextureFileName( aTextureFileName, false, false );
138 setFace( aWire, false, false, aTextureFileName );
139 isDeactivateSelection = true;
142 HYDROGUI_Shape::update( theIsUpdateViewer, isDeactivateSelection );
145 void HYDROGUI_ShapeImage::setTextureFileName( const QString& theFileName,
146 const bool theToDisplay,
147 const bool theIsUpdateViewer )
149 myTextureFileName = theFileName;
150 updateShape( theToDisplay, theIsUpdateViewer );
153 QString HYDROGUI_ShapeImage::getTextureFileName() const
155 return myTextureFileName;
158 QString HYDROGUI_ShapeImage::generateTextureFileName( const Handle(HYDROData_Entity)& theImageObj )
161 if( !theImageObj.IsNull() )
163 QString aTempDir = HYDROGUI_Tool::GetTempDir( true );
165 int aStudyId = HYDROGUI_Tool::GetActiveStudyId();
166 QString aPrefix = QString( "image_%1" ).arg( aStudyId );
168 QString anEntry = HYDROGUI_DataObject::dataObjectEntry( theImageObj, false );
169 anEntry.replace( ':', '_' );
171 QString anExtension = "bmp";
173 aResult = QString( "%1/%2_%3.%4" ).arg( aTempDir, aPrefix, anEntry, anExtension );
178 void HYDROGUI_ShapeImage::removeTextureFile() const
180 QFile aFile( getTextureFileName() );
185 QImage HYDROGUI_ShapeImage::reduceTexture( const QImage& theImage, const int theSizeLimit )
187 double aSizeLimit = (double)theSizeLimit;
188 double aWidth = (double)theImage.width();
189 double aHeight = (double)theImage.height();
190 if( aWidth > aSizeLimit || aHeight > aSizeLimit )
192 if( aWidth > aHeight )
194 aHeight /= ( aWidth / aSizeLimit );
199 aWidth /= ( aHeight / aSizeLimit );
200 aHeight = aSizeLimit;
203 return theImage.scaled( aWidth, aHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation );
206 Handle_AIS_InteractiveObject HYDROGUI_ShapeImage::createShape() const
208 QString aTextureFileName = getTextureFileName();
209 bool anIsTexture = !aTextureFileName.isEmpty();
212 Handle_AIS_TexturedShape aTexturedShape = new AIS_TexturedShape( getTopoShape() );
214 aTexturedShape->SetTextureFileName( HYDROGUI_Tool::ToAsciiString( aTextureFileName ) );
215 aTexturedShape->SetTextureMapOn();
216 // Just use the texture image as is
217 aTexturedShape->DisableTextureModulate();
218 aTexturedShape->SetTextureRepeat( false ); // don't repeat the texture image on the face
220 return aTexturedShape;
223 return Handle_AIS_InteractiveObject();