INCLUDE(cmake/cpPlugins_KitwareTools.cmake)
INCLUDE(cmake/cpPlugins_Qt4Tools.cmake)
-## ===================================
-## == Libraries to dynamically load ==
-## ===================================
-
-SET(cpPlugins_DynLibs)
-FOREACH(i ${VTK_LIBRARIES})
- GET_TARGET_PROPERTY(lib_${i} ${i} LOCATION)
- LIST(APPEND cpPlugins_DynLibs ${lib_${i}})
-ENDFOREACH(i)
-FOREACH(i ${ITK_LIBRARIES})
- GET_TARGET_PROPERTY(lib_${i} ${i} LOCATION)
- LIST(APPEND cpPlugins_DynLibs ${lib_${i}})
-ENDFOREACH(i)
-
## =========================
## == Include directories ==
## =========================
#include "PipelineEditor.h"
#include "ui_PipelineEditor.h"
+#include <cstdlib>
+
+#include <QFileInfo>
#include <QMessageBox>
#include <cpPlugins/Image.h>
: Superclass( argc, argv, app, parent ),
m_UI( new Ui::PipelineEditor )
{
+ // Load environment configuration
+ char* p = std::getenv( cpPlugins_PATHS );
+ std::string sp = "";
+ if( p != NULL )
+ sp = std::string( p ) + std::string( cpPlugins_SEPARATOR );
+ QFileInfo info( argv[ 0 ] );
+ if( info.exists( ) )
+ sp += info.canonicalPath( ).toStdString( );
+ setenv( cpPlugins_PATHS, sp.c_str( ), 0 );
+
// Basic configuration
this->m_UI->setupUi( this );
this->_Configure(
int main( int argc, char* argv[] )
{
// Load interface
- cpPlugins::Interface interface;
- interface.GuessAccesiblePlugins( );
+ cpPlugins::Interface* interface = NULL;
+ try
+ {
+ interface = new cpPlugins::Interface( );
+ interface->GuessAccesiblePlugins( );
+ }
+ catch( std::exception& err )
+ {
+ if( interface != NULL )
+ delete interface;
+ std::cerr
+ << "Error caught: "
+ << err.what( )
+ << std::endl;
+ return( 1 );
+
+ } // yrt
// Show loaded plugins
- auto plugins = interface.GetPlugins( );
+ auto plugins = interface->GetPlugins( );
for( auto pIt = plugins.begin( ); pIt != plugins.end( ); ++pIt )
std::cout << "Plugin: " << *pIt << std::endl;
std::cout << std::endl;
// Show loaded filters
- auto filters = interface.GetFilters( );
+ auto filters = interface->GetFilters( );
for( auto cIt = filters.begin( ); cIt != filters.end( ); ++cIt )
{
std::cout << "Category: " << cIt->first << std::endl;
<< std::endl;
} // rof
+
+ // Free all and finish
+ delete interface;
return( 0 );
}
{
if( actor != NULL )
{
- std::cout << name << " " << actor << std::endl;
-
this->m_Renderers[ 3 ]->AddViewProp( actor );
this->m_VTK[ 3 ]->GetRenderWindow( )->Render( );
this->m_NamedActors[ name ].insert( actor );
- std::cout << "Size: " << this->m_NamedActors.size( ) << " " << this->m_NamedActors[ name ].size( ) << std::endl;
-
+ if( this->m_Renderers[ 3 ]->GetViewProps( )->GetNumberOfItems( ) == 1 )
+ {
+ this->m_Renderers[ 3 ]->ResetCamera( );
+ this->m_VTK[ 3 ]->GetRenderWindow( )->Render( );
- double bounds[ 6 ];
- this->m_Renderers[ 3 ]->ComputeVisiblePropBounds( bounds );
- std::cout
- << bounds[ 0 ] << " " << bounds[ 1 ] << " "
- << bounds[ 2 ] << " " << bounds[ 3 ] << " "
- << bounds[ 4 ] << " " << bounds[ 5 ] << std::endl;
+ } // fi
} // fi
}
: Superclass( parent ),
m_Application( app ),
m_PluginsPath( "." ),
+ m_Interface( NULL ),
+ m_Workspace( NULL ),
m_TreeWidget( NULL ),
m_Editor( NULL ),
m_MPR( NULL )
{
- this->m_Interface.GuessAccesiblePlugins( );
-
- // Try to load plugins from executable dir
+ this->m_ApplicationPath = ".";
QFileInfo info( argv[ 0 ] );
if( info.exists( ) )
- this->_LoadPluginsFromPath( info.canonicalPath( ).toStdString( ) );
-
- // Prepare workspace
- this->m_Workspace.SetInterface( &( this->m_Interface ) );
+ this->m_ApplicationPath = info.canonicalPath( ).toStdString( );
}
// -------------------------------------------------------------------------
cpPipelineEditor::BaseQtMainWindow::
~BaseQtMainWindow( )
{
- this->m_Interface.UnloadAll( );
+ if( this->m_Workspace != NULL )
+ delete this->m_Workspace;
+ delete this->m_Interface;
}
// -------------------------------------------------------------------------
cpPipelineEditor::Editor* editor
)
{
+ if( this->m_Interface != NULL )
+ {
+ delete this->m_Interface;
+ this->m_Interface = NULL;
+
+ } // fi
+
+ try
+ {
+ this->m_Interface = new cpPlugins::Interface( );
+ this->m_Interface->GuessAccesiblePlugins( );
+ }
+ catch( std::exception& err )
+ {
+ if( this->m_Interface != NULL )
+ delete this->m_Interface;
+ this->m_Interface = NULL;
+ QMessageBox::critical(
+ this,
+ "Error creating plugins interface",
+ err.what( )
+ );
+ std::exit( 1 );
+
+ } // yrt
+
+ // Try to load plugins from executable dir
+ this->_LoadPluginsFromPath( this->m_ApplicationPath );
+
+ // Finish configuration
this->m_TreeWidget = tree;
if( this->m_TreeWidget != NULL )
this->_UpdateLoadedPlugins( );
this->m_Editor = editor;
- if( this->m_Editor != NULL )
- this->m_Editor->setWorkspace( &( this->m_Workspace ) );
- if( mpr != NULL )
- this->m_Workspace.SetMPRViewer( mpr );
this->m_MPR = mpr;
+ this->_CreateWorkspace( );
+}
+
+// -------------------------------------------------------------------------
+void cpPipelineEditor::BaseQtMainWindow::
+_CreateWorkspace( )
+{
+ if( this->m_Workspace != NULL )
+ delete this->m_Workspace;
+ this->m_Workspace = new cpPlugins::Workspace( );
+ this->m_Workspace->SetInterface( this->m_Interface );
+ if( this->m_Editor != NULL )
+ this->m_Editor->setWorkspace( this->m_Workspace );
+ if( this->m_MPR != NULL )
+ this->m_Workspace->SetMPRViewer( this->m_MPR );
}
// -------------------------------------------------------------------------
{
try
{
- this->m_Interface.LoadPluginFile( filename );
+ this->m_Interface->LoadPluginFile( filename );
this->_UpdateLoadedPlugins( );
}
catch( std::exception& err )
{
try
{
- this->m_Interface.LoadPluginDir( path );
+ this->m_Interface->LoadPluginDir( path );
this->_UpdateLoadedPlugins( );
}
catch( std::exception& err )
_UpdateLoadedPlugins( )
{
this->_Block( );
- auto filters = this->m_Interface.GetFilters( );
+ auto filters = this->m_Interface->GetFilters( );
if( filters.size( ) == 0 )
{
this->_UnBlock( );
void cpPipelineEditor::BaseQtMainWindow::
_LoadWorkspace( const std::string& filename )
{
- std::string err = this->m_Workspace.LoadWorkspace( filename );
+ this->_CreateWorkspace( );
+ std::string err = this->m_Workspace->LoadWorkspace( filename );
if( err != "" )
{
QMessageBox::critical(
else
{
if( this->m_Editor != NULL )
- this->m_Editor->setWorkspace( &( this->m_Workspace ) );
+ this->m_Editor->setWorkspace( this->m_Workspace );
} // fi
}
void cpPipelineEditor::BaseQtMainWindow::
_SaveWorkspace( const std::string& filename )
{
- std::string err = this->m_Workspace.SaveWorkspace( filename );
- if( err != "" )
- QMessageBox::critical(
- this,
- QMessageBox::tr( "Error saving workspace" ),
- QMessageBox::tr( err.c_str( ) )
- );
+ if( this->m_Workspace != NULL )
+ {
+ std::string err = this->m_Workspace->SaveWorkspace( filename );
+ if( err != "" )
+ QMessageBox::critical(
+ this,
+ QMessageBox::tr( "Error saving workspace" ),
+ QMessageBox::tr( err.c_str( ) )
+ );
+
+ } // fi
}
// -------------------------------------------------------------------------
void cpPipelineEditor::BaseQtMainWindow::
_ShowData( const std::string& filter_name, const std::string& output_name )
{
- if( this->m_MPR == NULL )
+ if( this->m_MPR == NULL || this->m_Workspace == NULL )
return;
- auto output = this->m_Workspace.GetOutput( filter_name, output_name );
+
+ auto output = this->m_Workspace->GetOutput( filter_name, output_name );
if( output != NULL )
{
this->_Block( );
void cpPipelineEditor::BaseQtMainWindow::
_HideData( const std::string& filter, const std::string& output )
{
+ std::cout << "BaseQtMainWindow::HideData" << std::endl;
+ /* TODO
+ */
}
// -------------------------------------------------------------------------
const std::string& filter_name, const std::string& output_name
)
{
- if( this->m_MPR == NULL )
+ if( this->m_MPR == NULL || this->m_Workspace == NULL )
return;
- auto output = this->m_Workspace.GetOutput( filter_name, output_name );
+
+ auto output = this->m_Workspace->GetOutput( filter_name, output_name );
if( output != NULL )
{
this->_Block( );
void cpPipelineEditor::BaseQtMainWindow::
_BackgroundProperties( unsigned int i )
{
+ if( this->m_MPR == NULL )
+ return;
+
QColor color =
QColorDialog::getColor(
QColor( 0, 0, 0 ),
dlg.setFileMode( QFileDialog::ExistingFiles );
dlg.setDirectory( this->m_PluginsPath.c_str( ) );
- std::stringstream name_filter;
+ std::stringstream filter;
std::string suffix = std::string( cpPlugins_LIB_EXT );
- name_filter
- << "Plugins file (*." << cpPlugins_LIB_EXT << ");;All files (*)";
- dlg.setNameFilter( name_filter.str( ).c_str( ) );
+ filter << "Plugins file (*." << cpPlugins_LIB_EXT << ");;All files (*)";
+ dlg.setNameFilter( filter.str( ).c_str( ) );
dlg.setDefaultSuffix( suffix.c_str( ) );
if( !( dlg.exec( ) ) )
return;
-
QStringList names = dlg.selectedFiles( );
for( auto qIt = names.begin( ); qIt != names.end( ); ++qIt )
this->_LoadPlugins( qIt->toStdString( ) );
void cpPipelineEditor::BaseQtMainWindow::
_InteractiveLoadPluginsFromPath( )
{
- QFileDialog dlg( this );
- dlg.setFileMode( QFileDialog::DirectoryOnly );
- dlg.setDirectory( this->m_PluginsPath.c_str( ) );
- if( !( dlg.exec( ) ) )
+ QFileDialog d( this );
+ d.setFileMode( QFileDialog::DirectoryOnly );
+ d.setDirectory( this->m_PluginsPath.c_str( ) );
+ if( !( d.exec( ) ) )
return;
- this->_LoadPluginsFromPath( dlg.selectedFiles( ).begin( )->toStdString( ) );
+ this->_LoadPluginsFromPath( d.selectedFiles( ).begin( )->toStdString( ) );
}
// -------------------------------------------------------------------------
void cpPipelineEditor::BaseQtMainWindow::
_InteractiveSaveWorkspace( )
{
- QFileDialog dlg( this );
- dlg.setFileMode( QFileDialog::AnyFile );
- dlg.setDirectory( "." );
- dlg.setAcceptMode( QFileDialog::AcceptSave );
- dlg.setNameFilter(
- QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
- );
- dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
- if( !( dlg.exec( ) ) )
- return;
- this->_SaveWorkspace( dlg.selectedFiles( ).begin( )->toStdString( ) );
+ if( this->m_Workspace != NULL )
+ {
+ QFileDialog dlg( this );
+ dlg.setFileMode( QFileDialog::AnyFile );
+ dlg.setDirectory( "." );
+ dlg.setAcceptMode( QFileDialog::AcceptSave );
+ dlg.setNameFilter(
+ QFileDialog::tr( "Workspace file (*.wxml);;All files (*)" )
+ );
+ dlg.setDefaultSuffix( QFileDialog::tr( "wxml" ) );
+ if( !( dlg.exec( ) ) )
+ return;
+ this->_SaveWorkspace( dlg.selectedFiles( ).begin( )->toStdString( ) );
+
+ } // fi
}
// -------------------------------------------------------------------------
void cpPipelineEditor::BaseQtMainWindow::
_ExecFilter( const std::string& filter_name )
{
+ if( this->m_Workspace == NULL )
+ return;
+
this->_Block( );
try
{
- this->m_Workspace.Execute( filter_name );
+ this->m_Workspace->Execute( filter_name );
this->_UnBlock( );
}
catch( itk::ExceptionObject& err1 )
cpExtensions::QT::SimpleMPRWidget* mpr,
cpPipelineEditor::Editor* editor
);
+ void _CreateWorkspace( );
void _LoadPlugins( const std::string& filename );
void _LoadPluginsFromPath( const std::string& path );
void _UpdateLoadedPlugins( );
void _ExecFilter( const std::string& filter_name );
protected:
- QApplication* m_Application;
- _TBlocker m_Blocker;
- cpPlugins::Workspace m_Workspace;
- cpPlugins::Interface m_Interface;
- std::string m_PluginsPath;
+ QApplication* m_Application;
+ _TBlocker m_Blocker;
+ std::string m_PluginsPath;
+ std::string m_ApplicationPath;
+
+ cpPlugins::Interface* m_Interface;
+ cpPlugins::Workspace* m_Workspace;
QTreeWidget* m_TreeWidget;
Editor* m_Editor;
${PROJECT_BINARY_DIR}/lib/${lib_DIR}/Config.h
@ONLY
)
-CONFIGURE_FILE(
- cpPlugins_DynLibs.h.in
- ${PROJECT_BINARY_DIR}/lib/${lib_DIR}/cpPlugins_DynLibs.h
- @ONLY
- )
## ===============
## = Source code =
VERSION "${prj_VER}"
SOVERSION "${prj_sVER}"
)
+ADD_DEPENDENCIES(${lib_NAME} ${cpPlugins_LIBRARIES})
GENERATE_EXPORT_HEADER(
${lib_NAME}
BASE_NAME ${lib_NAME}
# include <dlfcn.h>
#endif // cpPlugins_SYS_WINDOWS
#include <cpPlugins_dirent.h>
-#include <cpPlugins/cpPlugins_DynLibs.h>
+#include <cpPlugins_Instances/cpPlugins_DynLibs.h>
#include <algorithm>
// -------------------------------------------------------------------------
// Explicitly load all ITK and VTK
if( Self::InterfacesCount == 0 )
{
+ // Base libraries
std::vector< std::string > libs;
cpPlugins::TokenizeString( libs, cpPlugins_DynLibs, ";" );
- this->_AddInstancesLib( libs, cpPlugins_CompilationDir );
- this->_AddInstancesLib( libs, cpPlugins_InstallationDir );
+
+ // Local instances
+ for( auto p = this->m_Paths.begin( ); p != this->m_Paths.end( ); ++p )
+ {
+ DIR* dir;
+ struct dirent* ent;
+ if( ( dir = opendir( p->c_str( ) ) ) != NULL )
+ {
+ while( ( ent = readdir( dir ) ) != NULL )
+ {
+ std::string fname = *p + std::string( "/" ) + ent->d_name;
+ if( fname.find( "_Instances" ) != std::string::npos )
+ libs.push_back( fname );
+
+ } // elihw
+ closedir( dir );
+
+ } // fi
+
+ } // rof
for( auto l = libs.begin( ); l != libs.end( ); ++l )
{
return( res );
}
-// -------------------------------------------------------------------------
-template< class _TList >
-void cpPlugins::Interface::
-_AddInstancesLib( _TList& libs, const std::string& path )
-{
- DIR* dir;
- struct dirent* ent;
- if( ( dir = opendir( path.c_str( ) ) ) != NULL )
- {
- while( ( ent = readdir( dir ) ) != NULL )
- {
- std::string fname = path + std::string( "/" ) + ent->d_name;
- if( fname.find( "cpPlugins_Instances_" ) != std::string::npos )
- libs.push_back( fname );
-
- } // elihw
- closedir( dir );
-
- } // fi
-}
-
// -------------------------------------------------------------------------
void* cpPlugins::Interface::
_DLOpen( const std::string& fname, std::string& error )
std::set< std::string > GetPlugins( ) const;
protected:
- template< class _TList >
- inline void _AddInstancesLib( _TList& libs, const std::string& path );
static void* _DLOpen( const std::string& fname, std::string& error );
static const char* _DLGetName( void* hnd );
static TFilters _DLGetFilters( void* hnd );
void cpPlugins::OrthoNormalBase::
SetITK( itk::LightObject* o )
{
- // Do nothing since itk::Matrix does not belong to LightObject hierarchy.
+ // WARNING: Do nothing since itk::Matrix does not belong to the
+ // itk::LightObject hierarchy.
}
// -------------------------------------------------------------------------
OrthoNormalBase( )
: Superclass( )
{
+ this->m_BaseActor = vtkSmartPointer< vtkAxesActor >::New( );
}
// -------------------------------------------------------------------------
const_cast< vtkMatrix4x4* >( this->GetVTK< vtkMatrix4x4 >( ) );
if( matrix != NULL )
{
- this->m_BaseActor.SetBase( matrix );
- this->m_Actor = this->m_BaseActor.Actor.GetPointer( );
- /* TODO
- double o[ 3 ], x[ 3 ], y[ 3 ], z[ 3 ];
-
- o[ 0 ] = matrix->GetElement( 0, 3 );
- o[ 1 ] = matrix->GetElement( 1, 3 );
- o[ 2 ] = matrix->GetElement( 2, 3 );
-
- x[ 0 ] = matrix->GetElement( 0, 0 ) + o[ 0 ];
- x[ 1 ] = matrix->GetElement( 1, 0 ) + o[ 1 ];
- x[ 2 ] = matrix->GetElement( 2, 0 ) + o[ 2 ];
-
- y[ 0 ] = matrix->GetElement( 0, 1 ) + o[ 0 ];
- y[ 1 ] = matrix->GetElement( 1, 1 ) + o[ 1 ];
- y[ 2 ] = matrix->GetElement( 2, 1 ) + o[ 2 ];
-
- z[ 0 ] = matrix->GetElement( 0, 2 ) + o[ 0 ];
- z[ 1 ] = matrix->GetElement( 1, 2 ) + o[ 1 ];
- z[ 2 ] = matrix->GetElement( 2, 2 ) + o[ 2 ];
-
- static vtkPoints* points = vtkPoints::New( );
- points->InsertNextPoint( o );
- points->InsertNextPoint( x );
- points->InsertNextPoint( y );
- points->InsertNextPoint( z );
-
- static vtkCellArray* lines = vtkCellArray::New( );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 1 );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 2 );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 3 );
-
- static vtkPolyData* base = vtkPolyData::New( );
- base->SetPoints( points );
- base->SetLines( lines );
-
- static vtkPolyDataMapper* mapper = vtkPolyDataMapper::New( );
- mapper->SetInputData( base );
-
- static vtkActor* actor = vtkActor::New( );
- actor->SetMapper( mapper );
- this->m_Actor = actor;
- */
- /*
- this->m_AxesActor = vtkSmartPointer< vtkAxesActor >::New( );
- this->m_AxesActor->SetUserMatrix( matrix );
- this->m_Actor = this->m_AxesActor.GetPointer( );
- */
+ this->m_BaseActor->SetUserMatrix( matrix );
+ this->m_Actor = this->m_BaseActor.GetPointer( );
} // fi
}
#define __CPPLUGINS__ORTHONORMALBASE__H__
#include <cpPlugins/DataObject.h>
-#include <vtkActor.h>
-#include <vtkAxes.h>
-#include <vtkPolyDataMapper.h>
-#include <vtkActor.h>
-#include <vtkCellArray.h>
-#include <vtkPoints.h>
-#include <vtkPolyData.h>
-#include <vtkPolyDataMapper.h>
+#include <vtkAxesActor.h>
#include <vtkSmartPointer.h>
namespace cpPlugins
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer< const Self > ConstPointer;
- struct BaseActor
- {
- vtkSmartPointer< vtkPolyData > Axes;
- vtkSmartPointer< vtkPolyDataMapper > Mapper;
- vtkSmartPointer< vtkActor > Actor;
-
- void SetBase( vtkMatrix4x4* matrix )
- {
- this->Axes = vtkSmartPointer< vtkPolyData >::New( );
- this->Mapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
- this->Actor = vtkSmartPointer< vtkActor >::New( );
-
- vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New( );
- points->InsertNextPoint( 0, 0, 0 );
- points->InsertNextPoint( 1, 0, 0 );
- points->InsertNextPoint( 0, 1, 0 );
- points->InsertNextPoint( 0, 0, 1 );
- vtkSmartPointer< vtkCellArray > lines = vtkSmartPointer< vtkCellArray >::New( );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 1 );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 2 );
- lines->InsertNextCell( 2 ); lines->InsertCellPoint( 0 ); lines->InsertCellPoint( 3 );
- this->Axes->SetPoints( points );
- this->Axes->SetLines( lines );
-
- this->Mapper->SetInputData( this->Axes );
- this->Actor->SetMapper( this->Mapper );
- }
- };
-
public:
itkNewMacro( Self );
itkTypeMacro( OrthoNormalBase, DataObject );
Self& operator=( const Self& );
protected:
- mutable BaseActor m_BaseActor;
+ mutable vtkSmartPointer< vtkAxesActor > m_BaseActor;
};
} // ecapseman
+++ /dev/null
-
-#define cpPlugins_CompilationDir "@PROJECT_BINARY_DIR@"
-#define cpPlugins_InstallationDir "@CMAKE_INSTALL_PREFIX@/lib"
-#define cpPlugins_DynLibs "@cpPlugins_DynLibs@"
-
-// eof - $RCSfile$
CACHE INTERNAL "All valid instances." FORCE
)
+## ===================================
+## == Libraries to dynamically load ==
+## ===================================
+
+SET(cpPlugins_DynLibs)
+FOREACH(i ${VTK_LIBRARIES})
+ GET_TARGET_PROPERTY(lib_${i} ${i} LOCATION)
+ GET_FILENAME_COMPONENT(lib_name_${i} ${lib_${i}} NAME)
+ LIST(APPEND cpPlugins_DynLibs ${lib_name_${i}})
+ENDFOREACH(i)
+FOREACH(i ${ITK_LIBRARIES})
+ GET_TARGET_PROPERTY(lib_${i} ${i} LOCATION)
+ GET_FILENAME_COMPONENT(lib_name_${i} ${lib_${i}} NAME)
+ LIST(APPEND cpPlugins_DynLibs ${lib_name_${i}})
+ENDFOREACH(i)
+CONFIGURE_FILE(
+ cpPlugins_DynLibs.h.in
+ ${PROJECT_BINARY_DIR}/lib/cpPlugins_Instances/cpPlugins_DynLibs.h
+ @ONLY
+ )
+
## eof - $RCSfile$
--- /dev/null
+#ifndef __CPPLUGINS_INSTANCES__DYNLIBS__H__
+#define __CPPLUGINS_INSTANCES__DYNLIBS__H__
+
+#define cpPlugins_DynLibs "@cpPlugins_DynLibs@"
+
+#endif // __CPPLUGINS_INSTANCES__DYNLIBS__H__
+
+// eof - $RCSfile$