mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2025-01-13 02:00:35 +05:00
GEOM_Displayer - Loading textures with non-ansi paths.
- Loading textures using Qt tools. - Image caching.
This commit is contained in:
parent
8e102c8ec4
commit
8bbd6e250f
@ -106,6 +106,8 @@
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
|
||||
#include <Prs3d_ShadingAspect.hxx>
|
||||
|
||||
@ -136,6 +138,127 @@
|
||||
// Hard-coded value of shape deflection coefficient for VTK viewer
|
||||
const double VTK_MIN_DEFLECTION = 0.001;
|
||||
|
||||
// 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 : 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 = new Image_PixMap();
|
||||
aPixmap->InitTrash( Image_PixMap::ImgBGRA, anImage.width(), anImage.height() );
|
||||
aPixmap->SetTopDown( Standard_True );
|
||||
|
||||
const uchar* aImageBytes = anImage.bits();
|
||||
|
||||
for ( int aLine = anImage.height() - 1; aLine >= 0; --aLine ) {
|
||||
Image_ColorBGRA* aPixmapBytes = aPixmap->EditData<Image_ColorBGRA>().ChangeRow(aLine);
|
||||
|
||||
// convert pixels from ARGB to renderer-compatible RGBA
|
||||
for ( int aByte = 0; aByte < anImage.width(); ++aByte ) {
|
||||
aPixmapBytes->b() = (Standard_Byte) *aImageBytes++;
|
||||
aPixmapBytes->g() = (Standard_Byte) *aImageBytes++;
|
||||
aPixmapBytes->r() = (Standard_Byte) *aImageBytes++;
|
||||
aPixmapBytes->a() = (Standard_Byte) *aImageBytes++;
|
||||
aPixmapBytes++;
|
||||
}
|
||||
}
|
||||
|
||||
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(Image_PixMap)& aPixmap = aAISShape->TexturePixMap();
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Function : getActiveStudy
|
||||
// Purpose : Get active study, returns 0 if no open study frame
|
||||
@ -729,10 +852,10 @@ void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShap
|
||||
AISShape->SetOwnDeviationCoefficient( qMax( propMap.value( GEOM::propertyName( GEOM::Deflection ) ).toDouble(), GEOM::minDeflection() ) );
|
||||
|
||||
// set texture
|
||||
bool textureAdded = false;
|
||||
QString aImagePath;
|
||||
if ( HasTexture() ) {
|
||||
// predefined display texture, manually set to displayer via GEOM_Displayer::SetTexture() function
|
||||
AISShape->SetTextureFileName( TCollection_AsciiString( GetTexture().c_str() ) );
|
||||
aImagePath = GetTexture().c_str();
|
||||
if ( ! entry.isEmpty() ) {
|
||||
// check that study is active
|
||||
SalomeApp_Study* study = getActiveStudy();
|
||||
@ -745,21 +868,23 @@ void GEOM_Displayer::updateShapeProperties( const Handle(GEOM_AISShape)& AISShap
|
||||
propMap = getObjectProperties( study, entry, myViewFrame );
|
||||
}
|
||||
}
|
||||
textureAdded = true;
|
||||
}
|
||||
else {
|
||||
// Texture from properties
|
||||
QString aTexture = propMap.value( GEOM::propertyName( GEOM::Texture ) ).toString();
|
||||
if ( !aTexture.isEmpty() ) {
|
||||
AISShape->SetTextureFileName( TCollection_AsciiString( aTexture.toUtf8().constData() ) );
|
||||
textureAdded = true;
|
||||
}
|
||||
aImagePath = propMap.value( GEOM::propertyName( GEOM::Texture ) ).toString();
|
||||
}
|
||||
|
||||
if ( textureAdded ){
|
||||
|
||||
Handle(Image_PixMap) aPixmap;
|
||||
if ( !aImagePath.isEmpty() )
|
||||
aPixmap = cacheTextureFor( aImagePath, AISShape );
|
||||
|
||||
// apply image to shape
|
||||
if ( !aPixmap.IsNull() ) {
|
||||
AISShape->SetTexturePixMap( aPixmap );
|
||||
AISShape->SetTextureMapOn();
|
||||
AISShape->DisableTextureModulate();
|
||||
}
|
||||
else
|
||||
AISShape->SetTextureMapOff();
|
||||
|
||||
// set line width
|
||||
AISShape->SetWidth( HasWidth() ?
|
||||
@ -1823,6 +1948,12 @@ void GEOM_Displayer::AfterDisplay( SALOME_View* v, const SALOME_OCCPrs* p )
|
||||
UpdateColorScale(false,false);
|
||||
}
|
||||
|
||||
void GEOM_Displayer::BeforeErase( SALOME_View* v, const SALOME_OCCPrs* p )
|
||||
{
|
||||
LightApp_Displayer::BeforeErase( v, p );
|
||||
releaseTextures( p );
|
||||
}
|
||||
|
||||
void GEOM_Displayer::AfterErase( SALOME_View* v, const SALOME_OCCPrs* p )
|
||||
{
|
||||
LightApp_Displayer::AfterErase( v, p );
|
||||
|
@ -175,6 +175,7 @@ public:
|
||||
virtual void Update( SALOME_VTKPrs* );
|
||||
virtual void BeforeDisplay( SALOME_View*, const SALOME_OCCPrs* );
|
||||
virtual void AfterDisplay ( SALOME_View*, const SALOME_OCCPrs* );
|
||||
virtual void BeforeErase ( SALOME_View*, const SALOME_OCCPrs* );
|
||||
virtual void AfterErase ( SALOME_View*, const SALOME_OCCPrs* );
|
||||
|
||||
/* This methos is used for activisation/deactivisation of objects to be displayed*/
|
||||
|
Loading…
Reference in New Issue
Block a user