VTK/VTKMatlab: Difference between revisions
No edit summary |
No edit summary |
||
Line 161: | Line 161: | ||
</pre> | </pre> | ||
Under linux this is normal compiling stuff, provide includes and linking directives, see GNU GCC documentation. Under Windows this is more trouble. First off, you need a C++ compiler. I couldnt get the Matlab C compiler to work so I used the well known MinGW (http://www.mingw.org/). Install, learn how to use it. Download CMake and VTK sources and compile VTK yourself (version 5.0.0 compiled silently). Then you need something to compile our VTK mex example - the Matlab C compiler didnt work out. I used gnumex (http://gnumex.sourceforge.net/) - a way to use Mingw with Matlab. Install and follow documentation therein. I eventually had to change the mexopts to use g++ instead of gcc, otherwise the C++ standard stuff (eg. cout etc.) was not available. Also, beware of spaces in filenames everywhere. Avoid wherever possible, otherwise use 'quotes'. Under Windows I compiled VTK with static libs and could find no way of using -L/-l directives. If you find out let me know. I ended up doing it explicitely: | Under linux this is normal compiling stuff, provide includes and linking directives, see GNU GCC documentation. Under Windows this is more trouble. First off, you need a C++ compiler. I couldnt get the Matlab C compiler to work so I used the well known MinGW (http://www.mingw.org/). Install, learn how to use it. Download CMake and VTK sources and compile VTK yourself (version 5.0.0 compiled silently). The linux way I am used to (i.e. cmake src_dir called from a build_dir) failed rather violently, with Microsoft apologizing for inconvenience. You have to do something like: | ||
/c/Program\ Files/CMake\ 2.4/bin/CMakeSetup | |||
and configure everything from in there. | |||
Then you need something to compile our VTK mex example - the Matlab C compiler didnt work out. I used gnumex (http://gnumex.sourceforge.net/) - a way to use Mingw with Matlab. Install and follow documentation therein. I eventually had to change the mexopts to use g++ instead of gcc, otherwise the C++ standard stuff (eg. cout etc.) was not available. Also, beware of spaces in filenames everywhere. Avoid wherever possible, otherwise use 'quotes'. Under Windows I compiled VTK with static libs and could find no way of using -L/-l directives. If you find out let me know. I ended up doing it explicitely: | |||
Revision as of 20:07, 6 July 2006
It is possible (and highly desirable) to provide VTK bindings for Matlab. For that to happen one has to write a C++ file to be compiled with mex compiler right from under Matlab. Worked example:
/**************************************************** (C) 2005 Dominik Szczerba <domi at vision ee ethz ch> *****************************************************/ #include <cstdlib> #include <cmath> /* MEX HEADERS */ #include <mex.h> /* VTK HEADERS */ #include <vtkPolyData.h> #include <vtkPoints.h> #include <vtkCellArray.h> #include <vtkDoubleArray.h> #include <vtkPolyData.h> #include <vtkCell.h> #include <vtkCellData.h> #include <vtkDataSet.h> #include <vtkDataSetAttributes.h> #include <vtkProperty.h> #include <vtkDataSetMapper.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleTrackballCamera.h> /* MAIN FUNCTION */ void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]){ double *v; // Vertices double *f; // Faces unsigned int nV, nF, nC=0, i, j; if(nrhs<2) mexErrMsgTxt("2+ input args required"); double* dcolors = 0; vtkDoubleArray* dcolarr = 0; nV = mxGetM(prhs[0]); nF = mxGetM(prhs[1]); v = mxGetPr(prhs[0]); f = (double*)mxGetPr(prhs[1]); if(nrhs>=3){ //mexPrintf("found color information\n"); nC = mxGetM(prhs[2]); if(nC!=nF) mexErrMsgTxt("dimension mismatch"); dcolors = mxGetPr(prhs[2]); dcolarr = vtkDoubleArray::New(); dcolarr->SetName("aCellScalar"); dcolarr->SetArray(dcolors,nF,0); } mexPrintf("got %d nodes, %d faces and %d colors\n",nV,nF,nC); // Initialize vtk variables vtkPolyData *surf = vtkPolyData::New(); vtkPoints *sverts = vtkPoints::New(); vtkCellArray *sfaces = vtkCellArray::New(); // for (i=0; i<nV; i++) mexPrintf("%d %f %f %f\n",i,v[i],v[nV+i],v[2*nV+i]); // for (i=0; i<nF; i++){ // for(j=0;j<3;j++) // mexPrintf("%d ",f[j*nF+i]); // mexPrintf("\n"); // } // Load the point, cell, and data attributes. //indexes in VTK are 0-based, in Matlab 1-based const int offset = -1; for(i=0; i<nV; i++) sverts->InsertPoint(i,v[i],v[nV+i],v[2*nV+i]); for(i=0; i<nF; i++){ sfaces->InsertNextCell(3); for(j=0;j<3;j++){ int idx = (unsigned int)f[j*nF+i]+offset; if(idx<0 || idx>=nV) //mexPrintf("Warning : wrong index\n"); mexErrMsgTxt("wrong index"); sfaces->InsertCellPoint(vtkIdType(idx)); } } // assign the pieces to the vtkPolyData. surf->SetPoints(sverts); surf->SetPolys(sfaces); sverts->Delete(); sfaces->Delete(); if(nC>0){ surf->GetCellData()->SetScalars(dcolarr); } // now render vtkDataSetMapper::SetResolveCoincidentTopologyToPolygonOffset(); vtkPolyDataMapper *surfMapper = vtkPolyDataMapper::New(); vtkActor *surfActor = vtkActor::New(); vtkRenderer *aRenderer = vtkRenderer::New(); vtkRenderWindow *renWin = vtkRenderWindow::New(); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); surfMapper->SetInput(surf); //surfMapper->ScalarVisibilityOff(); if(nC>0){ surfMapper->ScalarVisibilityOn(); surfMapper->SetScalarRange(0,1); } surfActor->SetMapper(surfMapper); surfActor->GetProperty()->SetAmbient(0.1); surfActor->GetProperty()->SetDiffuse(0.3); surfActor->GetProperty()->SetSpecular(1.0); surfActor->GetProperty()->SetSpecularPower(30.0); aRenderer->AddActor(surfActor); aRenderer->SetBackground(0.2,0.2,0.2); //needed after camera moves //aRenderer->ResetCameraClippingRange (); iren->SetRenderWindow(renWin); renWin->AddRenderer(aRenderer); renWin->SetSize(500,500); renWin->Render(); vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New(); iren->SetInteractorStyle(style); // Start interactive rendering iren->Start(); // clean up surfMapper->Delete(); surfActor->Delete(); surf->Delete(); aRenderer->Delete(); renWin->Delete(); iren->Delete(); style->Delete(); }
Compile it under matlab with:
> mex -I<includesToVtkHeaders> fileToCompile.cpp -L<libDir> -lvtkLibStuff
Under linux this is normal compiling stuff, provide includes and linking directives, see GNU GCC documentation. Under Windows this is more trouble. First off, you need a C++ compiler. I couldnt get the Matlab C compiler to work so I used the well known MinGW (http://www.mingw.org/). Install, learn how to use it. Download CMake and VTK sources and compile VTK yourself (version 5.0.0 compiled silently). The linux way I am used to (i.e. cmake src_dir called from a build_dir) failed rather violently, with Microsoft apologizing for inconvenience. You have to do something like:
/c/Program\ Files/CMake\ 2.4/bin/CMakeSetup
and configure everything from in there.
Then you need something to compile our VTK mex example - the Matlab C compiler didnt work out. I used gnumex (http://gnumex.sourceforge.net/) - a way to use Mingw with Matlab. Install and follow documentation therein. I eventually had to change the mexopts to use g++ instead of gcc, otherwise the C++ standard stuff (eg. cout etc.) was not available. Also, beware of spaces in filenames everywhere. Avoid wherever possible, otherwise use 'quotes'. Under Windows I compiled VTK with static libs and could find no way of using -L/-l directives. If you find out let me know. I ended up doing it explicitely:
>> mex -ID:\MyProjects\VTK-5.0\include\vtk-5.0 vtkPolyDataRenderer.cxx D:\MyProjects\VTK-5.0\lib\libvtkRendering.a D:\MyProjects\VTK-5.0\lib\libvtkIO.a D:\MyProjects\VTK-5.0\lib\libvtkGraphics.a D:\MyProjects\VTK-5.0\lib\libvtkImaging.a D:\MyProjects\VTK-5.0\lib\libvtkftgl.a D:\MyProjects\VTK-5.0\lib\libvtkfreetype.a C:\mingw\lib\libopengl32.a D:\MyProjects\VTK-5.0\lib\libvtkFiltering.a D:\MyProjects\VTK-5.0\lib\libvtkCommon.a D:\MyProjects\VTK-5.0\lib\libvtksys.a D:\MyProjects\VTK-5.0\lib\libvtkDICOMParser.a D:\MyProjects\VTK-5.0\lib\libvtkpng.a D:\MyProjects\VTK-5.0\lib\libvtktiff.a D:\MyProjects\VTK-5.0\lib\libvtkzlib.a D:\MyProjects\VTK-5.0\lib\libvtkjpeg.a D:\MyProjects\VTK-5.0\lib\libvtkexpat.a C:\mingw\lib\libvfw32.a D:\MyProjects\VTK-5.0\lib\libvtkMPEG2Encode.a C:\mingw\lib\libgdi32.a
Change paths where appropriate, think of smarter syntax (get -L -l stuff to work or modify your mexopts.bat) Refer to mex documentation for more information.
Problems
[x y z v] = flow; q = z./x.*y.^3; mesh=isosurface(x, y, z, q, -.08, v); [N,M]=size(mesh.faces); scalars=[0:1:N-1]'/(N-1); vtkPolyDataRenderer(mesh.vertices,mesh.faces,scalars);