VTK/VTKMatlab: Difference between revisions

From KitwarePublic
< VTK
Jump to navigationJump to search
No edit summary
 
No edit summary
Line 1: Line 1:
Test
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>
***************************************************************************/
 
#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();
 
 
  // 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)

Revision as of 19:28, 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. 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)