+// If the next macro is defined, the deflection coefficient for VTK presentation
+// is limited by VTK_MIN_DEFLECTION
+//#define LIMIT_DEFLECTION_FOR_VTK
+
+// Pixmap caching support
+namespace
+{
+ typedef NCollection_Map<Handle(GEOM_AISShape)> SetOfAISShapes;
+ typedef NCollection_DataMap<Handle(Image_PixMap), SetOfAISShapes> PixmapUsageMap;
+ typedef QMap<QString, Handle(Image_PixMap)> PixmapCacheMap;
+
+ static inline PixmapUsageMap& getPixmapUsageMap()
+ {
+ static PixmapUsageMap aMap;
+ return aMap;
+ }
+
+ static inline PixmapCacheMap& getPixmapCacheMap()
+ {
+ static PixmapCacheMap aMap;
+ return aMap;
+ }
+
+ //===========================================================================
+ // Function : getDefaultTexture
+ // Purpose : Get default texture
+ //===========================================================================
+ static inline Handle(Image_PixMap) getDefaultTexture()
+ {
+ static Handle(Image_PixMap) aPixmap;
+ if ( aPixmap.IsNull() ) {
+ QPixmap px(":images/default_texture.png");
+ if ( !px.isNull() )
+ aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage() );
+ }
+ return aPixmap;
+ }
+
+ //===========================================================================
+ // Function : cacheTextureFor
+ // Purpose : Load and cache image for the specified presentation.
+ //===========================================================================
+ static inline Handle(Image_PixMap) cacheTextureFor( const QString& thePath,
+ const Handle(GEOM_AISShape)& theShape )
+ {
+ if ( thePath.isEmpty() )
+ return NULL;
+
+ PixmapUsageMap& aPixmapUsersMap = getPixmapUsageMap();
+ PixmapCacheMap& aPixmapCacheMap = getPixmapCacheMap();
+
+ Handle(Image_PixMap) aPixmap = aPixmapCacheMap.value( thePath, NULL );
+ if ( !aPixmap.IsNull() ) {
+ // point that the texture is used by the presentation
+ if ( !aPixmapUsersMap.IsBound( aPixmap ) )
+ aPixmapUsersMap.Bind( aPixmap, SetOfAISShapes() );
+
+ aPixmapUsersMap.ChangeFind( aPixmap ).Add( theShape );
+
+ return aPixmap;
+ }
+
+ // convert texture to compatible image format
+ QImage anImage = QImage( thePath ).convertToFormat( QImage::Format_ARGB32 );
+ if ( anImage.isNull() )
+ return NULL;
+
+ aPixmap = OCCViewer_Utilities::imageToPixmap( anImage );
+
+ aPixmapCacheMap.insert( thePath, aPixmap );
+
+ if ( !aPixmapUsersMap.IsBound( aPixmap ) )
+ aPixmapUsersMap.Bind( aPixmap, SetOfAISShapes() );
+
+ aPixmapUsersMap.ChangeFind( aPixmap ).Add( theShape );
+
+ return aPixmap;
+ }
+
+ //===========================================================================
+ // Function : releaseTextures
+ // Purpose : Releases cached textures found for the specified presentation.
+ //===========================================================================
+ static inline void releaseTextures( const SALOME_OCCPrs* thePrs )
+ {
+ const SOCC_Prs* anOccPrs = dynamic_cast<const SOCC_Prs*>( thePrs );
+
+ AIS_ListOfInteractive aListOfIO;
+
+ anOccPrs->GetObjects( aListOfIO );
+
+ AIS_ListIteratorOfListOfInteractive aIterateIO( aListOfIO );
+
+ PixmapUsageMap& aPixmapUsersMap = getPixmapUsageMap();
+ PixmapCacheMap& aPixmapCacheMap = getPixmapCacheMap();
+
+ for ( ; aIterateIO.More(); aIterateIO.Next() )
+ {
+ Handle(GEOM_AISShape) aAISShape =
+ Handle(GEOM_AISShape)::DownCast( aIterateIO.Value() );
+
+ if ( aAISShape.IsNull() )
+ continue;
+
+ const Handle(Graphic3d_TextureMap)& aTexture = aAISShape->Attributes()->ShadingAspect()->Aspect()->TextureMap();
+ if ( aTexture.IsNull() )
+ continue;
+
+ const Handle(Image_PixMap)& aPixmap = aTexture->GetImage();
+ if ( aPixmap.IsNull() )
+ continue;
+
+ if ( !aPixmapUsersMap.IsBound( aPixmap ) )
+ continue;
+
+ SetOfAISShapes& aUsersShapes = aPixmapUsersMap.ChangeFind( aPixmap );
+
+ aUsersShapes.Remove( aAISShape );
+
+ if ( aUsersShapes.IsEmpty() ) {
+ aPixmapUsersMap.UnBind( aPixmap );
+ aPixmapCacheMap.remove( aPixmapCacheMap.key( aPixmap ) );
+ }
+ }
+ }
+
+ uint randomize( uint size )
+ {
+ static bool initialized = false;
+ if ( !initialized ) {
+ qsrand( QDateTime::currentDateTime().toTime_t() );
+ initialized = true;
+ }
+ uint v = qrand();
+ v = uint( (double)( v ) / RAND_MAX * size );
+ v = qMax( uint(0), qMin ( v, size-1 ) );
+ return v;
+ }
+} // namespace