#include #include #include #include #include #include #include #include #include #include // ------------------------------------------------------------------------- cpPluginsImageMeshFilters::RasterMeshFilter:: RasterMeshFilter( ) : Superclass( ) { typedef cpPlugins::BaseObjects::DataObject _TDataObject; typedef cpPlugins::DataObjects::Image _TImage; typedef cpPlugins::DataObjects::Mesh _TMesh; this->_ConfigureInput< _TMesh >( "Input", true, false ); this->_ConfigureInput< _TDataObject >( "Template", false, false ); this->_ConfigureOutput< _TImage >( "Output" ); this->m_Parameters.ConfigureAsUint( "InsideValue" ); this->m_Parameters.ConfigureAsUint( "OutsideValue" ); this->m_Parameters.ConfigureAsUint( "MinimumSize" ); this->m_Parameters.SetUint( "InsideValue", 1 ); this->m_Parameters.SetUint( "OutsideValue", 0 ); this->m_Parameters.SetUint( "MinimumSize", 100 ); } // ------------------------------------------------------------------------- cpPluginsImageMeshFilters::RasterMeshFilter:: ~RasterMeshFilter( ) { } // ------------------------------------------------------------------------- void cpPluginsImageMeshFilters::RasterMeshFilter:: _GenerateData( ) { typedef itk::Mesh< float, 3 > _3F; typedef itk::Mesh< double, 3 > _3D; bool is_2d = false; auto pd = this->GetInputData< vtkPolyData >( "Input" ); if( pd != NULL ) { double bounds[ 6 ]; pd->GetBounds( bounds ); is_2d = ( bounds[ 4 ] == bounds[ 5 ] ); } // fi if( !is_2d ) { auto _3f = this->GetInputData< _3F >( "Input" ); auto _3d = this->GetInputData< _3D >( "Input" ); if ( _3f != NULL ) this->_GD0_3D( _3f ); else if( _3d != NULL ) this->_GD0_3D( _3d ); else this->_Error( "No valid input mesh." ); } else this->_GD0_2D( pd ); } // ------------------------------------------------------------------------- template< class _TMesh > void cpPluginsImageMeshFilters::RasterMeshFilter:: _GD0_2D( _TMesh* mesh ) { typedef itk::ImageBase< 2 > _TImageBase; typedef itk::Image< unsigned char, 2 > _TImage; typedef cpPlugins::DataObjects::BoundingBox _TBB; typedef typename _TImage::PointType _TPoint; static const unsigned int PAD = 10; _TImage::Pointer white = this->GetOutputData< _TImage >( "Output" ); if( white.IsNull( ) ) white = _TImage::New( ); // Get configuration values typename _TImage::SpacingType spac; typename _TImage::SizeType size; typename _TImage::PointType origin; typename _TImage::DirectionType direction; typename _TImage::IndexType index; auto in_bb = this->GetInput< _TBB >( "Template" ); auto in_im = this->GetInputData< _TImageBase >( "Template" ); if( in_im != NULL ) { spac = in_im->GetSpacing( ); size = in_im->GetLargestPossibleRegion( ).GetSize( ); origin = in_im->GetOrigin( ); direction = in_im->GetDirection( ); index = in_im->GetLargestPossibleRegion( ).GetIndex( ); } else { _TPoint minBB, maxBB; if( in_bb != NULL ) { minBB = in_bb->GetMinimum< _TPoint >( ); maxBB = in_bb->GetMaximum< _TPoint >( ); } else { double bounds[ 6 ]; mesh->GetBounds( bounds ); minBB[ 0 ] = bounds[ 0 ]; minBB[ 1 ] = bounds[ 1 ]; maxBB[ 0 ] = bounds[ 2 ]; maxBB[ 1 ] = bounds[ 3 ]; } // fi double lx = double( maxBB[ 0 ] - minBB[ 0 ] ); double ly = double( maxBB[ 1 ] - minBB[ 1 ] ); double lm = ( lx < ly )? lx: ly; // Compute spacing spac.Fill( lm / double( this->m_Parameters.GetUint( "MinimumSize" ) ) ); // Compute size size[ 0 ] = ( unsigned long )( std::ceil( lx / spac[ 0 ] ) ); size[ 1 ] = ( unsigned long )( std::ceil( ly / spac[ 1 ] ) ); // ... add some padding pixels size[ 0 ] += PAD; size[ 1 ] += PAD; // Set origin origin = minBB; origin[ 0 ] -= double( PAD >> 1 ) * spac[ 0 ]; origin[ 1 ] -= double( PAD >> 1 ) * spac[ 1 ]; // Remaining values direction.SetIdentity( ); index.Fill( 0 ); } // fi // Configure output image _TImage::RegionType region; region.SetSize( size ); region.SetIndex( index ); white->SetSpacing( spac ); white->SetRegions( region ); white->SetOrigin( origin ); white->SetDirection( direction ); white->Allocate( ); white->FillBuffer( this->m_Parameters.GetUint( "InsideValue" ) ); if( this->m_WhiteImage.IsNull( ) ) this->m_WhiteImage = TImage::New( ); this->m_WhiteImage->SetITK( white ); vtkImageData* white_vtk = this->m_WhiteImage->GetVTK< vtkImageData >( ); // Configure mini-pipeline if( this->m_Stripper.GetPointer( ) == NULL ) this->m_Stripper = vtkSmartPointer< vtkStripper >::New( ); this->m_Stripper->SetInputData( mesh ); this->m_Stripper->Update( ); if( this->m_Extruder.GetPointer( ) == NULL ) this->m_Extruder = vtkSmartPointer< vtkLinearExtrusionFilter >::New( ); this->m_Extruder->SetInputConnection( this->m_Stripper->GetOutputPort( ) ); this->m_Extruder->SetScaleFactor( double( 1 ) ); this->m_Extruder->SetExtrusionTypeToNormalExtrusion( ); this->m_Extruder->SetVector( 0, 0, 1 ); this->m_Extruder->Update( ); if( this->m_PolyDataToStencil.GetPointer( ) == NULL ) this->m_PolyDataToStencil = vtkSmartPointer< vtkPolyDataToImageStencil >::New( ); this->m_PolyDataToStencil->SetTolerance( 0 ); this->m_PolyDataToStencil->SetInputConnection( this->m_Extruder->GetOutputPort( ) ); this->m_PolyDataToStencil->SetOutputOrigin( white_vtk->GetOrigin( ) ); this->m_PolyDataToStencil->SetOutputSpacing( white_vtk->GetSpacing( ) ); this->m_PolyDataToStencil->SetOutputWholeExtent( white_vtk->GetExtent( ) ); this->m_PolyDataToStencil->Update( ); this->m_ImageStencil = this->_CreateVTK< vtkImageStencil >( ); this->m_ImageStencil->SetInputData( white_vtk ); this->m_ImageStencil->SetStencilConnection( this->m_PolyDataToStencil->GetOutputPort( ) ); this->m_ImageStencil->ReverseStencilOff( ); this->m_ImageStencil->SetBackgroundValue( this->m_Parameters.GetUint( "OutsideValue" ) ); this->m_ImageStencil->Update( ); this->GetOutput( "Output" )->SetVTK( this->m_ImageStencil->GetOutput( ) ); } // ------------------------------------------------------------------------- template< class _TMesh > void cpPluginsImageMeshFilters::RasterMeshFilter:: _GD0_3D( _TMesh* mesh ) { typedef unsigned char _TPixel; typedef cpPlugins::DataObjects::BoundingBox _TBB; typedef itk::ImageBase< _TMesh::PointDimension > _TImageBase; typedef itk::Image< _TPixel, _TMesh::PointDimension > _TImage; typedef itk::TriangleMeshToBinaryImageFilter< _TMesh, _TImage > _TFilter; typedef typename _TImage::PointType _TPoint; static const unsigned int PAD = 10; _TFilter* filter = this->_CreateITK< _TFilter >( ); this->m_WhiteImage = NULL; this->m_Stripper = NULL; this->m_Extruder = NULL; this->m_PolyDataToStencil = NULL; this->m_ImageStencil = NULL; // Get configuration values typename _TImage::SpacingType spac; typename _TImage::SizeType size; typename _TImage::PointType origin; typename _TImage::DirectionType direction; typename _TImage::IndexType index; auto in_bb = this->GetInput< _TBB >( "Template" ); auto in_im = this->GetInputData< _TImageBase >( "Template" ); if( in_im != NULL ) { spac = in_im->GetSpacing( ); size = in_im->GetLargestPossibleRegion( ).GetSize( ); origin = in_im->GetOrigin( ); direction = in_im->GetDirection( ); index = in_im->GetLargestPossibleRegion( ).GetIndex( ); } else { _TPoint minBB, maxBB; if( in_bb != NULL ) { minBB = in_bb->GetMinimum< _TPoint >( ); maxBB = in_bb->GetMaximum< _TPoint >( ); } else { auto bb = mesh->GetBoundingBox( ); minBB = bb->GetMinimum( ); maxBB = bb->GetMaximum( ); } // fi double lx = double( maxBB[ 0 ] - minBB[ 0 ] ); double ly = double( maxBB[ 1 ] - minBB[ 1 ] ); double lz = double( maxBB[ 2 ] - minBB[ 2 ] ); double lm = ( lx < ly )? lx: ly; lm = ( lm < lz )? lm: lz; // Compute spacing spac.Fill( lm / double( this->m_Parameters.GetUint( "MinimumSize" ) ) ); // Compute size size[ 0 ] = ( unsigned long )( std::ceil( lx / spac[ 0 ] ) ); size[ 1 ] = ( unsigned long )( std::ceil( ly / spac[ 1 ] ) ); size[ 2 ] = ( unsigned long )( std::ceil( lz / spac[ 2 ] ) ); // ... add some padding pixels size[ 0 ] += PAD; size[ 1 ] += PAD; size[ 2 ] += PAD; // Set origin origin = minBB; origin[ 0 ] -= double( PAD >> 1 ) * spac[ 0 ]; origin[ 1 ] -= double( PAD >> 1 ) * spac[ 1 ]; origin[ 2 ] -= double( PAD >> 1 ) * spac[ 2 ]; // Remaining values direction.SetIdentity( ); index.Fill( 0 ); } // fi // Execute filter->SetInput( mesh ); filter->SetSpacing( spac ); filter->SetSize( size ); filter->SetOrigin( origin ); filter->SetDirection( direction ); filter->SetIndex( index ); filter->SetInsideValue( this->m_Parameters.GetUint( "InsideValue" ) ); filter->SetOutsideValue( this->m_Parameters.GetUint( "OutsideValue" ) ); filter->Update( ); this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) ); } // eof - $RCSfile$