VTK/VTKMatlab

From KitwarePublic
< VTK
Revision as of 19:28, 6 July 2006 by Domel (talk | contribs)
Jump to navigationJump to search

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. Example:

/************************************************************************** Copyright (C) 2005 Dominik Szczerba <domi at vision ee ethz ch>

                                                                                                                                                      • /
  1. include <cstdlib>
  2. include <cmath>

/* MEX HEADERS */

  1. include <mex.h>

/* VTK HEADERS */

  1. include <vtkPolyData.h>
  2. include <vtkPoints.h>
  3. include <vtkCellArray.h>
  4. include <vtkDoubleArray.h>
  5. include <vtkPolyData.h>
  1. include <vtkCell.h>
  2. include <vtkCellData.h>
  3. include <vtkDataSet.h>
  4. include <vtkDataSetAttributes.h>
  5. include <vtkProperty.h>
  1. include <vtkDataSetMapper.h>
  2. include <vtkPolyDataMapper.h>
  3. include <vtkActor.h>
  4. include <vtkRenderer.h>
  5. include <vtkRenderWindow.h>
  6. include <vtkRenderWindowInteractor.h>
  7. 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();


 // 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 *skinMapper = vtkPolyDataMapper::New();
 vtkActor *skin = vtkActor::New();
 vtkRenderer *aRenderer = vtkRenderer::New();
 vtkRenderWindow *renWin = vtkRenderWindow::New();
 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
 
 skinMapper->SetInput(surf);
 //skinMapper->ScalarVisibilityOff();
 if(nC>0){

skinMapper->ScalarVisibilityOn(); skinMapper->SetScalarRange(0,1);

 }
 skin->SetMapper(skinMapper);
 skin->GetProperty()->SetAmbient(0.1);
 skin->GetProperty()->SetDiffuse(0.3);
 skin->GetProperty()->SetSpecular(1.0);
 skin->GetProperty()->SetSpecularPower(30.0);
 
 aRenderer->AddActor(skin);
 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
 surf->Delete();
 skinMapper->Delete();
 skin->Delete();
 aRenderer->Delete();
 renWin->Delete();
 style->Delete();
 iren->Delete();

}



[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)