Tom, <br><br>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. <br>
<br>This next bit is a little off topic, but applies to vtkMatlabMexAdapter:<br><br>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 <a href="http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess.html">http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess.html</a> specifically Shared Memory <a href="http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory.shared_memory_a_simple_example">http://www.boost.org/doc/libs/1_43_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory.shared_memory_a_simple_example</a>. 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?<br>
<br><br>/*<br> * volume_render.cpp<br> *<br> * Created on: May 12, 2010<br> * Author: bdavis<br> */<br><br>#include "vtkPolyDataMapper.h"<br>#include "vtkActor.h"<br>#include "vtkRenderWindow.h"<br>
#include "vtkRenderer.h"<br>#include "vtkRenderWindowInteractor.h"<br>#include "vtkDICOMImageReader.h"<br>#include "vtkVolume.h"<br>#include "vtkVolumeMapper.h"<br>#include <vtkVolumeTextureMapper3D.h><br>
#include <vtkConeSource.h><br>#include "vtkImageActor.h"<br>#include <vtkImageCast.h><br>//#include <vtkVolumeRayCastMapper.h><br>#include "vtkVolumeRayCastMIPFunction.h"<br>#include <vtkFixedPointVolumeRayCastMapper.h><br>
#include <vtkFixedPointVolumeRayCastMIPHelper.h><br>#include "vtkFiniteDifferenceGradientEstimator.h"<br>#include "vtkPiecewiseFunction.h"<br>#include "vtkColorTransferFunction.h"<br>#include <vtkVolumeProperty.h><br>
<br>#include <vtkKWEGPUInfo.h><br>#include <vtkKWEGPUInfoList.h><br>#include <vtkIndent.h><br><br>// bjd - includes for VTKEdge<br>#include <vtkKWEGPUVolumeRayCastMapper.h><br>#include <vtkSmartPointer.h><br>
//#include <vtkDataArray.h><br>//#include <vtkDenseArray.h><br>#include <vtkDoubleArray.h><br>#include <vtkImageData.h><br>#include <vtkMatlabMexAdapter.h><br>#include <vtkPointData.h> <br>
#include <vtkDataArray.h><br><br>#include <volume_render.h><br><br><br>// Boost includes<br>#include <boost/numeric/conversion/cast.hpp> <br><br><br>#include <matrix.h><br><br><br>#define USE_GPU_RENDER_DEMO_COLORMAP<br>
#define GPU_RENDER_VOLUME<br>#define USE_VTKMATLABMEXADAPTER<br><br>using boost::numeric_cast;<br><br>using boost::numeric::bad_numeric_cast;<br>using boost::numeric::positive_overflow;<br>using boost::numeric::negative_overflow;<br>
<br><br>void DllImportExport volume_render::renderVolumeData( int nrhs, const mxArray *prhs[] )<br>{<br> #ifndef USE_VTKMATLABMEXADAPTER<br> double *volumeData;<br> #else<br> vtkSmartPointer<vtkDataArray> volumeData;<br>
<br> #endif<br> size_t y_dim;<br> size_t x_dim;<br> size_t z_dim;<br><br> if( nrhs > 1 )<br> {<br> mexErrMsgTxt("Render volume can only accept one 3D array to render");<br> return;<br>
}<br><br><br><br> for (int i = 0; i < nrhs; i++)<br> {<br><br> if( mxGetNumberOfDimensions( prhs[i] ) != 3 )<br> {<br> mexErrMsgTxt("Render volume can only accept matrix of 3 dimensions");<br>
return;<br> }<br><br> // Get the dimensions<br> const mwSize* matDimensions = mxGetDimensions( prhs[i] );<br><br> y_dim = matDimensions[0];<br> x_dim = matDimensions[1];<br> z_dim = matDimensions[2];<br>
<br> mexPrintf( "y_dim = %d, x_dim = %d, z_dim = %d \n", y_dim, x_dim, z_dim );<br><br> // Get the data <br> #ifndef USE_VTKMATLABMEXADAPTER<br> volumeData = mxGetPr(prhs[i]);<br> #else<br>
<br> vtkSmartPointer<vtkMatlabMexAdapter> matlabMexAdapter = vtkMatlabMexAdapter::New();<br> volumeData =<br> (vtkDataArray*) matlabMexAdapter->mxArrayTovtkDataArray(prhs[i]);<br> #endif<br>
}<br><br><br><br><br><br> // Create a transfer function mapping scalar value to opacity<br> vtkPiecewiseFunction *oTFun = vtkPiecewiseFunction::New();<br> oTFun->AddSegment(10, 0.0, 255, 0.3);<br><br> vtkPiecewiseFunction *oTFun2 = vtkPiecewiseFunction::New();<br>
oTFun2->AddSegment( 0, 0.0, 128, 1.0);<br> oTFun2->AddSegment(128, 1.0, 255, 0.0);<br><br> // Create a transfer function mapping scalar value to color (grey)<br> vtkPiecewiseFunction *gTFun = vtkPiecewiseFunction::New();<br>
#ifndef USE_GPU_RENDER_DEMO_COLORMAP<br> gTFun->AddSegment(0, 1.0, 255, 1.0);<br> #endif<br><br> // Create a transfer function mapping scalar value to color (color)<br> vtkColorTransferFunction *cTFun = vtkColorTransferFunction::New();<br>
#ifndef USE_GPU_RENDER_DEMO_COLORMAP<br> cTFun->AddRGBPoint( 0, 1.0, 0.0, 0.0 );<br> cTFun->AddRGBPoint( 64, 1.0, 1.0, 0.0 );<br> cTFun->AddRGBPoint( 128, 0.0, 1.0, 0.0 );<br> cTFun->AddRGBPoint( 192, 0.0, 1.0, 1.0 );<br>
cTFun->AddRGBPoint( 255, 0.0, 0.0, 1.0 );<br> #endif<br> // Create a transfer function mapping magnitude of gradient to opacity<br> vtkPiecewiseFunction *goTFun = vtkPiecewiseFunction::New();<br> #ifndef USE_GPU_RENDER_DEMO_COLORMAP<br>
goTFun->AddPoint( 0, 0.0 );<br> goTFun->AddPoint( 30, 0.0 );<br> goTFun->AddPoint( 40, 1.0 );<br> goTFun->AddPoint( 255, 1.0 );<br> #endif<br><br> #ifdef USE_GPU_RENDER_DEMO_COLORMAP<br>
double opacityWindow = 4096;<br> double opacityLevel = 2048;<br> cTFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0 );<br> goTFun->AddSegment( opacityLevel - 0.5*opacityWindow, 0.0,<br> opacityLevel + 0.5*opacityWindow, 1.0 );<br>
<br> #endif<br> vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New();<br> volumeProperty->SetColor( cTFun );<br> volumeProperty->SetColor( gTFun );<br> // volumeProperty->SetShade(k);<br>
volumeProperty->SetAmbient(0.3);<br> volumeProperty->SetDiffuse(1.0);<br> volumeProperty->SetSpecular(0.2);<br> volumeProperty->SetSpecularPower(50.0);<br> volumeProperty->SetScalarOpacity(oTFun);<br>
<br> vtkConeSource *cone = vtkConeSource::New();<br> cone->SetHeight( 3.0 );<br> cone->SetRadius( 1.0 );<br> cone->SetResolution( 10 );<br> vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();<br>
coneMapper->SetInputConnection( cone->GetOutputPort() );<br> vtkActor *coneActor = vtkActor::New();<br> coneActor->SetMapper( coneMapper );<br><br><br> // a renderer and render window<br> vtkRenderer *ren1 = vtkRenderer::New();<br>
vtkRenderWindow *renWin = vtkRenderWindow::New();<br><br> // Add the cone.<br> ren1->AddActor( coneActor );<br><br><br> // an interactor<br> vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();<br>
iren->SetRenderWindow(renWin);<br><br> vtkVolume *volume = vtkVolume::New();<br> volume->SetProperty(volumeProperty);<br><br> #ifndef GPU_RENDER_VOLUME<br> vtkFixedPointVolumeRayCastMapper * volumeMapper = vtkFixedPointVolumeRayCastMapper::New();<br>
<br> vtkFixedPointVolumeRayCastMIPHelper * fixedPointVolumeRayCastMIPHelper = volumeMapper->GetMIPHelper();<br> #endif<br><br><br> #ifndef GPU_RENDER_VOLUME<br><br> // Create mip ray functions<br> vtkVolumeRayCastMIPFunction *MIPFunction1 = vtkVolumeRayCastMIPFunction::New();<br>
<br> MIPFunction1->SetMaximizeMethodToOpacity();<br><br><br> vtkFiniteDifferenceGradientEstimator *gradest =<br> vtkFiniteDifferenceGradientEstimator::New();<br><br><br> vtkVolumeRayCastMIPFunction *MIPFunction2 =<br>
vtkVolumeRayCastMIPFunction::New();<br> MIPFunction2->SetMaximizeMethodToOpacity();<br> #else<br> std::cout << "performing GPU Rendering" << std::endl;<br> // Create and initialize the mapper<br>
vtkKWEGPUVolumeRayCastMapper *volumeMapper = vtkKWEGPUVolumeRayCastMapper::New();<br><br> #endif<br><br> #ifdef USE_GPU_RENDER_DEMO_COLORMAP<br> volumeMapper->SetBlendModeToMaximumIntensity();<br> #endif<br>
<br> vtkActor * volumeActor = vtkActor::New();<br>/*<br> std::string fileName = "C:\\data\\343_512recon\\volume\\343_.XA.NEURO_VARIABLE.2.6.2009.10.06.15.19.19.62500.5825682.IMA";<br> // Create a dicom reader object.<br>
// vtkDICOMImageReader* vtk_dicom_reader = vtkDICOMImageReader::New();<br> vtkDICOMImageReader * vtk_dicom_reader = vtkDICOMImageReader::New();<br><br> if( vtk_dicom_reader->CanReadFile( fileName.c_str() ) )<br>
{<br> printf( "VTK is able to open file: %s\n", fileName.c_str() );<br> }<br> else<br> {<br> printf( "VTK unable to read file %s\n", fileName.c_str() );<br> }<br><br><br> vtk_dicom_reader->SetDirectoryName( "C:\\data\\343\\reconstructed 256x256");<br>
<br><br> printf( "Setting volume mapper input connection\n" );<br> // Set the volume mapper to read from the DICOM reader.<br> volumeMapper->SetInputConnection( vtk_dicom_reader->GetOutputPort() );<br>
*/<br><br><br><br> // vtkDenseArray<double>* vtkArray = vtkDenseArray<double>::New();<br> // vtkSmartPointer<vtkDenseArray<double>> vtkArray = vtkSmartPointer<vtkDenseArray<double>>::New)();<br>
<br>// vtkSmartPointer<vtkDoubleArray> dataArray = vtkSmartPointer<vtkDoubleArray>::New();<br><br> #ifndef USE_VTKMATLABMEXADAPTER<br> vtkDoubleArray* dataArray = vtkDoubleArray::New();<br><br> // Set the array to point to data<br>
<br> dataArray->SetVoidArray( (void *) volumeData, y_dim*x_dim*z_dim , 1);<br><br><br> #else<br><br> #endif<br> <br>// vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New(); <br>
vtkImageData* image = vtkImageData::New();<br><br> image->SetDimensions( numeric_cast<int>(y_dim) , numeric_cast<int>(x_dim), numeric_cast<int>(z_dim) );<br>// image->SetSpacing(1.0, 1.0, 1.0);<br>
image->SetOrigin(0.0, 0.0, 0.0);<br><br><br>// vtkSmartPointer<vtkDataArray> dataArray = vtkSmartPointer<vtkDataArray>::New();<br>// vtkDataArray* dataArray = vtkDataArray::New();<br><br>// dataArray->DeepCopy( vtkArray );<br>
#ifndef USE_VTKMATLABMEXADAPTER<br> image->GetPointData()->SetScalars(dataArray);<br> #else<br> image->GetPointData()->SetScalars(volumeData);<br> #endif<br>// image->GetPointData()->SetScalars(dataArray);<br>
<br><br><br> volumeMapper->SetInput( image );<br><br> // set the volume mapper.<br> volume->SetMapper( volumeMapper );<br><br> #ifdef GPU_RENDER_VOLUME<br><br> volumeMapper->SetBlendModeToComposite();<br>
<br>// volume->SetMapper(volumeMapper);<br><br> #endif<br><br><br> printf( "Adding volume to render\n" );<br> // Add the volume to be rendered.<br> ren1->AddVolume(volume);<br><br> renWin->SetSize( 1024, 1024 );<br>
// render an image (lights and cameras are created automatically)<br> renWin->Render();<br><br> renWin->AddRenderer(ren1);<br><br> // begin mouse interaction<br> iren->Start();<br><br><br> // Clean up<br>
// vtk_dicom_reader->Delete();<br> volumeActor->Delete();<br> #ifndef GPU_RENDER_VOLUME<br> MIPFunction1->Delete();<br> gradest->Delete();<br> MIPFunction2->Delete();<br> #endif<br> volumeMapper->Delete();<br>
volume->Delete();<br> image->Delete();<br> #ifndef USE_VTKMATLABMEXADAPTER<br> dataArray->Delete();<br> #endif<br> iren->Delete();<br> renWin->Delete();<br> ren1->Delete();<br> coneActor->Delete();<br>
coneMapper->Delete();<br> cone->Delete();<br> volumeProperty->Delete();<br> cTFun->Delete();<br> gTFun->Delete();<br> oTFun2->Delete();<br> oTFun->Delete();<br><br><br>}<br><br><br>
<br><br><br>