New visualization system for octave (using VTK)

Dragan Tubic <[email protected]>
Newsgroups gmane.comp.gnu.octave.graphics
Message-ID <[email protected]>
Hello all,

I made a new visualization system for octave based on the VTK library. The 
system is an automatic wrapper for VTK classes which brings most of the VTK 
in octave (670 classes to be exact). The octave wrapper is actually a hacked 
TCL wrapper which comes with VTK.

The wrapper crates an .oct file for each VTK class. Each .oct file defines a 
single function whose name is the same as the name of the VTK class as well 
as the name of the .oct file. For example vtkRenderer class is wrapped in 
vtkRenderer.oct file that defines vtkRenderer function. To use a VTK class in 
octave (a method defined in the class), the function bearing the name of the 
class should be called as follows:

vtkClassName( vtkObject, "VTKClassMethod", parameter1, parameter2, ... );

where vtkObject denotes an instance of the object vtkClassName.

C++ equivalent of the above command is:
vtkObject->VTKClassMethod(parameter1, parameter2, ... );

Instances of the vtk objects are created using a similar syntax:

vtkObjectInstance = vtkClassName("New");

In octave, vtk objects are represented as a new octave type called vtk_object 
that holds a pointer to the real instances of vtk classes. The vtk_object 
type is defined in vtk_init.oct which should be called before any other vtk 
commands. 

Finally, here is a classic VTK example converted into an octave script with 
the original C++ code commented on the right side:

	vtk_init;	
  
	x   = [ 0,0,0; 1,0,0; 1,1,0; 0,1,0; 0,0,1; 1,0,1; 1,1,1; 0,1,1 ];
  pts = [ 0,1,2,3; 4,5,6,7; 0,1,5,4; 1,2,6,5; 2,3,7,6; 3,0,4,7 ];
  
	cube    = vtkPolyData("New");								% vtkPolyData *cube = 
vtkPolyData::New();
  points  = vtkPoints("New");									% vtkPoints *points = vtkPoints::New();
  polys   = vtkCellArray("New");							% vtkCellArray *polys = 
vtkCellArray::New();
  scalars = vtkFloatArray("New");							% vtkFloatArray *scalars = 
vtkFloatArray::New();
  
	for i=1:8																		% for (i=0; i<8; i++) points->InsertPoint(i,x[i]);
		vtkPoints(points,"InsertPoint",i-1,x(i,1),x(i,2),x(i,3));
	end
  
	for i=1:6																		% for (i=0; i<6; i++) 
polys->InsertNextCell(4,pts[i]);
		vtkCellArray( polys, "InsertNextCell", 4 );
		vtkCellArray( polys, "InsertCellPoint", pts(i,1) );
		vtkCellArray( polys, "InsertCellPoint", pts(i,2) );
		vtkCellArray( polys, "InsertCellPoint", pts(i,3) );
		vtkCellArray( polys, "InsertCellPoint", pts(i,4) );
	end
  
	for i=1:8																		% for (i=0; i<8; i++) scalars->InsertValue(i,i);	
		vtkFloatArray(scalars,"InsertValue",i-1,i-1);
	end

  vtkPointSet(cube,"SetPoints",points);				  % cube->SetPoints(points);
  vtkPolyData(cube,"SetPolys",polys);					  % cube->SetPolys(polys);
  pointData = vtkDataSet(cube,"GetPointData" ); %
cube->GetPointData()->SetScalars(scalars);
	  vtkDataSetAttributes(pointData,"SetScalars",scalars);

  cubeMapper = vtkPolyDataMapper("New");				%vtkPolyDataMapper *cubeMapper = 
vtkPolyDataMapper::New();
      vtkPolyDataMapper(cubeMapper,"SetInput",cube);	% 
cubeMapper->SetInput(cube);
      vtkMapper(cubeMapper,"SetScalarRange",0,7);			% 
cubeMapper->SetScalarRange(0,7);	
  
  cubeActor = vtkActor("New");												% vtkActor *cubeActor = 
vtkActor::New();
      vtkActor(cubeActor,"SetMapper",cubeMapper);			% 
cubeActor->SetMapper(cubeMapper);

 	renderer = vtkRenderer("New");											% vtkRenderer *renderer = 
vtkRenderer::New();
	renWin = vtkRenderWindow("New");										% vtkRenderWindow *renWin = 
vtkRenderWindow::New();															
		vtkRenderWindow(renWin,"AddRenderer",renderer);		% 
renWin->AddRenderer(renderer);

  
	iren = vtkRenderWindowInteractor("New");						% vtkRenderWindowInteractor 
*iren = vtkRenderWindowInteractor::New();
		vtkRenderWindowInteractor(iren,"SetRenderWindow",renWin); % 
iren->SetRenderWindow(renWin);

  vtkRenderer(renderer,"AddActor",cubeActor);					% 
renderer->AddActor(cubeActor);
	vtkRenderWindow(renWin,"Render");										% renWin->Render();
	vtkRenderWindowInteractor(iren,"Start");						% iren->Start();


There is still a lot of stuff missing, for example when the user interaction 
is activated, octave is halted (press e to exit). Also, the wrapper does not 
analyze super classes so some (inherited) methods are missing. I intend to 
resolve those issues in near future and to properly integrate the project in 
octave and vtk (might need some help though). Before I go any further I would 
really like to have some feedback from octave developers.

Sources and two screenshots are here: http://vision.gel.ulaval.ca/~tdragan/
octaviz.html. To build the wrappers you'll need octave 2.1.52 and vtk 4.2. 
Unpack the sources in a directory, change VTK_INCLUDE and VTK_LIB at the 
beginning of the Makefile and do "make all" (there is no real makefiles and 
configuration scripts). Couple of hours later, start octave in the same 
directory and try the two demos: demo.m and somb.m (which will allow you to 
see the famous sombrero from a different point of view). Please note that 
this version of the software is a proof of concept and a demo. It really 
should not be used for anything else.

Regards,

Dragan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.