[vtkusers] Voxel Data from MATLAB to VTK

Brian Davis bitminer at gmail.com
Fri May 21 14:12:19 EDT 2010


Tom,

Yea sorry for the confusion.  I was eliding the #ifdefs sections and showing
what was working to condense the code.  Here's was latest hack attack as of
Friday minus commented out / unused code.  I wil not have a chance to look
at this until Monday and there is no need to respond back until then.  I am
sure mxArrayTovtkArray will work and I will try that first chance I get.  I
did check for this this function but obviously did not have enough coffee in
the afternoon and overlooked it.  Thanks for the insight.   When I get it
working I will post again the modified working code.

This next bit is a little off topic, but applies to vtkMatlabMexAdapter:

There is however the next part I want to accomplish and that is to take the
mex or vtk data and put it in shared memory using Boost.Process
http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess.html specifically
Shared Memory
http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory.shared_memory_a_simple_example.
This way I can send the data to another process which stays running so that
the visualization is still available after the mex function exits.  What I
am also after is not having gobs of copies of data sure I have 16GB of
memory on the dev machine, but I would like to be as efficient as possible
so I can still develop on my 8GB laptop.  Is there a way to use
vtkMatlabMexAdapter and send data through shared memory without a large
number of duplicate copies?  Maybe there is a way to put it in the
vtkPipeline and utilize shared memory?


/*
 * volume_render.cpp
 *
 *  Created on: May 12, 2010
 *      Author: bdavis
 */

#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkDICOMImageReader.h"
#include "vtkVolume.h"
#include "vtkVolumeMapper.h"
#include <vtkVolumeTextureMapper3D.h>
#include <vtkConeSource.h>
#include "vtkImageActor.h"
#include <vtkImageCast.h>
//#include <vtkVolumeRayCastMapper.h>
#include "vtkVolumeRayCastMIPFunction.h"
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkFixedPointVolumeRayCastMIPHelper.h>
#include "vtkFiniteDifferenceGradientEstimator.h"
#include "vtkPiecewiseFunction.h"
#include "vtkColorTransferFunction.h"
#include <vtkVolumeProperty.h>

#include <vtkKWEGPUInfo.h>
#include <vtkKWEGPUInfoList.h>
#include <vtkIndent.h>

// bjd - includes for VTKEdge
#include <vtkKWEGPUVolumeRayCastMapper.h>
#include <vtkSmartPointer.h>
//#include <vtkDataArray.h>
//#include <vtkDenseArray.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkMatlabMexAdapter.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>

#include <volume_render.h>


// Boost includes
#include <boost/numeric/conversion/cast.hpp>


#include <matrix.h>


#define USE_GPU_RENDER_DEMO_COLORMAP
#define GPU_RENDER_VOLUME
#define USE_VTKMATLABMEXADAPTER

using boost::numeric_cast;

using boost::numeric::bad_numeric_cast;
using boost::numeric::positive_overflow;
using boost::numeric::negative_overflow;


void DllImportExport volume_render::renderVolumeData( int nrhs, const
mxArray *prhs[] )
{
    #ifndef USE_VTKMATLABMEXADAPTER
    double *volumeData;
    #else
    vtkSmartPointer<vtkDataArray> volumeData;

    #endif
    size_t y_dim;
    size_t x_dim;
    size_t z_dim;

    if( nrhs > 1 )
    {
        mexErrMsgTxt("Render volume can only accept one 3D array to
render");
        return;
    }



    for (int i = 0; i < nrhs; i++)
    {

        if( mxGetNumberOfDimensions( prhs[i] ) != 3 )
        {
            mexErrMsgTxt("Render volume can only accept matrix of 3
dimensions");
            return;
        }

        // Get the dimensions
        const mwSize* matDimensions = mxGetDimensions( prhs[i] );

        y_dim = matDimensions[0];
        x_dim = matDimensions[1];
        z_dim = matDimensions[2];

        mexPrintf( "y_dim = %d, x_dim = %d, z_dim = %d \n", y_dim, x_dim,
z_dim );

        // Get the data
        #ifndef USE_VTKMATLABMEXADAPTER
        volumeData = mxGetPr(prhs[i]);
        #else

        vtkSmartPointer<vtkMatlabMexAdapter> matlabMexAdapter =
vtkMatlabMexAdapter::New();
        volumeData =
            (vtkDataArray*)
matlabMexAdapter->mxArrayTovtkDataArray(prhs[i]);
        #endif
    }





    // Create a transfer function mapping scalar value to opacity
    vtkPiecewiseFunction *oTFun = vtkPiecewiseFunction::New();
    oTFun->AddSegment(10, 0.0, 255, 0.3);

    vtkPiecewiseFunction *oTFun2 = vtkPiecewiseFunction::New();
    oTFun2->AddSegment(  0, 0.0, 128, 1.0);
    oTFun2->AddSegment(128, 1.0, 255, 0.0);

    // Create a transfer function mapping scalar value to color (grey)
    vtkPiecewiseFunction *gTFun = vtkPiecewiseFunction::New();
    #ifndef USE_GPU_RENDER_DEMO_COLORMAP
    gTFun->AddSegment(0, 1.0, 255, 1.0);
    #endif

    // Create a transfer function mapping scalar value to color (color)
    vtkColorTransferFunction *cTFun = vtkColorTransferFunction::New();
    #ifndef USE_GPU_RENDER_DEMO_COLORMAP
    cTFun->AddRGBPoint(   0, 1.0, 0.0, 0.0 );
    cTFun->AddRGBPoint(  64, 1.0, 1.0, 0.0 );
    cTFun->AddRGBPoint( 128, 0.0, 1.0, 0.0 );
    cTFun->AddRGBPoint( 192, 0.0, 1.0, 1.0 );
    cTFun->AddRGBPoint( 255, 0.0, 0.0, 1.0 );
    #endif
    // Create a transfer function mapping magnitude of gradient to opacity
    vtkPiecewiseFunction *goTFun = vtkPiecewiseFunction::New();
    #ifndef USE_GPU_RENDER_DEMO_COLORMAP
    goTFun->AddPoint(   0, 0.0 );
    goTFun->AddPoint(  30, 0.0 );
    goTFun->AddPoint(  40, 1.0 );
    goTFun->AddPoint( 255, 1.0 );
    #endif

    #ifdef USE_GPU_RENDER_DEMO_COLORMAP
    double opacityWindow = 4096;
    double opacityLevel = 2048;
    cTFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0 );
    goTFun->AddSegment( opacityLevel - 0.5*opacityWindow, 0.0,
                            opacityLevel + 0.5*opacityWindow, 1.0 );

    #endif
    vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New();
    volumeProperty->SetColor( cTFun );
    volumeProperty->SetColor( gTFun );
    //    volumeProperty->SetShade(k);
    volumeProperty->SetAmbient(0.3);
    volumeProperty->SetDiffuse(1.0);
    volumeProperty->SetSpecular(0.2);
    volumeProperty->SetSpecularPower(50.0);
    volumeProperty->SetScalarOpacity(oTFun);

    vtkConeSource *cone = vtkConeSource::New();
    cone->SetHeight( 3.0 );
    cone->SetRadius( 1.0 );
    cone->SetResolution( 10 );
    vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
    coneMapper->SetInputConnection( cone->GetOutputPort() );
    vtkActor *coneActor = vtkActor::New();
    coneActor->SetMapper( coneMapper );


    // a renderer and render window
    vtkRenderer *ren1 = vtkRenderer::New();
    vtkRenderWindow *renWin = vtkRenderWindow::New();

    // Add the cone.
    ren1->AddActor( coneActor );


    // an interactor
    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);

    vtkVolume *volume = vtkVolume::New();
    volume->SetProperty(volumeProperty);

    #ifndef GPU_RENDER_VOLUME
    vtkFixedPointVolumeRayCastMapper * volumeMapper  =
vtkFixedPointVolumeRayCastMapper::New();

    vtkFixedPointVolumeRayCastMIPHelper * fixedPointVolumeRayCastMIPHelper =
volumeMapper->GetMIPHelper();
    #endif


    #ifndef GPU_RENDER_VOLUME

    // Create mip ray functions
    vtkVolumeRayCastMIPFunction *MIPFunction1 =
vtkVolumeRayCastMIPFunction::New();

    MIPFunction1->SetMaximizeMethodToOpacity();


    vtkFiniteDifferenceGradientEstimator *gradest =
        vtkFiniteDifferenceGradientEstimator::New();


    vtkVolumeRayCastMIPFunction *MIPFunction2 =
            vtkVolumeRayCastMIPFunction::New();
    MIPFunction2->SetMaximizeMethodToOpacity();
    #else
    std::cout << "performing GPU Rendering" << std::endl;
    // Create and initialize the mapper
    vtkKWEGPUVolumeRayCastMapper *volumeMapper =
vtkKWEGPUVolumeRayCastMapper::New();

    #endif

    #ifdef USE_GPU_RENDER_DEMO_COLORMAP
    volumeMapper->SetBlendModeToMaximumIntensity();
    #endif

    vtkActor * volumeActor = vtkActor::New();
/*
    std::string fileName =
"C:\\data\\343_512recon\\volume\\343_.XA.NEURO_VARIABLE.2.6.2009.10.06.15.19.19.62500.5825682.IMA";
    // Create a dicom reader object.
    //          vtkDICOMImageReader* vtk_dicom_reader =
vtkDICOMImageReader::New();
    vtkDICOMImageReader * vtk_dicom_reader = vtkDICOMImageReader::New();

    if( vtk_dicom_reader->CanReadFile( fileName.c_str() ) )
    {
        printf( "VTK is able to open file: %s\n", fileName.c_str() );
    }
    else
    {
        printf( "VTK unable to read file %s\n", fileName.c_str() );
    }


    vtk_dicom_reader->SetDirectoryName( "C:\\data\\343\\reconstructed
256x256");


    printf( "Setting volume mapper input connection\n" );
    // Set the volume mapper to read from the DICOM reader.
    volumeMapper->SetInputConnection( vtk_dicom_reader->GetOutputPort() );
*/



    // vtkDenseArray<double>* vtkArray = vtkDenseArray<double>::New();
    // vtkSmartPointer<vtkDenseArray<double>> vtkArray =
vtkSmartPointer<vtkDenseArray<double>>::New)();

//    vtkSmartPointer<vtkDoubleArray> dataArray =
vtkSmartPointer<vtkDoubleArray>::New();

    #ifndef USE_VTKMATLABMEXADAPTER
    vtkDoubleArray* dataArray = vtkDoubleArray::New();

    // Set the array to point to data

    dataArray->SetVoidArray( (void *) volumeData, y_dim*x_dim*z_dim , 1);


    #else

    #endif

//    vtkSmartPointer<vtkImageData> image =
vtkSmartPointer<vtkImageData>::New();
    vtkImageData* image = vtkImageData::New();

    image->SetDimensions( numeric_cast<int>(y_dim) ,
numeric_cast<int>(x_dim), numeric_cast<int>(z_dim) );
//    image->SetSpacing(1.0, 1.0, 1.0);
    image->SetOrigin(0.0, 0.0, 0.0);


//    vtkSmartPointer<vtkDataArray> dataArray =
vtkSmartPointer<vtkDataArray>::New();
//    vtkDataArray* dataArray = vtkDataArray::New();

//    dataArray->DeepCopy( vtkArray );
    #ifndef USE_VTKMATLABMEXADAPTER
    image->GetPointData()->SetScalars(dataArray);
    #else
    image->GetPointData()->SetScalars(volumeData);
    #endif
//    image->GetPointData()->SetScalars(dataArray);



    volumeMapper->SetInput( image );

    // set the volume mapper.
    volume->SetMapper( volumeMapper );

    #ifdef GPU_RENDER_VOLUME

    volumeMapper->SetBlendModeToComposite();

//    volume->SetMapper(volumeMapper);

    #endif


    printf( "Adding volume to render\n" );
    // Add the volume to be rendered.
    ren1->AddVolume(volume);

    renWin->SetSize( 1024, 1024 );
    // render an image (lights and cameras are created automatically)
    renWin->Render();

    renWin->AddRenderer(ren1);

    // begin mouse interaction
    iren->Start();


    // Clean up
//    vtk_dicom_reader->Delete();
    volumeActor->Delete();
    #ifndef GPU_RENDER_VOLUME
    MIPFunction1->Delete();
    gradest->Delete();
    MIPFunction2->Delete();
    #endif
    volumeMapper->Delete();
    volume->Delete();
    image->Delete();
    #ifndef USE_VTKMATLABMEXADAPTER
    dataArray->Delete();
    #endif
    iren->Delete();
    renWin->Delete();
    ren1->Delete();
    coneActor->Delete();
    coneMapper->Delete();
    cone->Delete();
    volumeProperty->Delete();
    cTFun->Delete();
    gTFun->Delete();
    oTFun2->Delete();
    oTFun->Delete();


}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100521/c4c96c87/attachment.htm>


More information about the vtkusers mailing list