VTK Java项目构建和运行

date: 2019-04-02 10:24:00

VTK Java项目构建和运行

准备工作

本文的运行环境是Ubuntu。在自己建立的VTK build的文件夹(这里名称为VTK-bin,见前文),找到vtk.jar,这里在VTK-bin/lib下。

新建工程

使用JetBrains的IDEA新建一个工程,将样例代码(见附录A)添加到工程中的src中,

添加vtk.jar

make之后生成的VTK-bin/lib路径下的vtk.jar路径添加到Project Structure->Modules->Dependencies中。

添加库

Ubuntu中.so文件相当于windows下的.dll动态链接库文件,

make之后生成的VTK-bin/lib路径加入到环境变量中,

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/[你自己的路径]/VTK-bin/lib

在IDEA中,File->Project Structure->Libraries(或者Ctrl+Shift+Alt+s),

编译运行

正常的结果如下:
Result

若出现类似vtkxxxx not loaded,如下图所示,原因在于make之后的库文件没有配置正确,导致程序无法调用。若vtk.jar文件配置错误,则程序本身语法上会报错(本文中没有出现这种情况)。

Error

程序不报错,但是一些vtk开头的库无法加载,

java.lang.UnsatisfiedLinkError: no vtkFiltersPointsJava in java.library.path

提示有类似上面的错误,

怀疑是java.library.path中缺少链接库。Ubuntu中.so文件相当于windows下的.dll动态链接库文件,将make之后生成的VTK-bin/lib路径加入到环境变量中,

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/xxxx/VTK-bin/lib

在IDEA中,File->Project Structure->Libraries(或者Ctrl+Shift+Alt+s),将上面的路径添加进来,重新编译,成功运行。

注意

  • 在添加Library路径之前已经将vtk.jar路径添加到Project Structure->Modules->Dependencies中。
  • 有Windows下的文章说讲生成的.dll文件复制到JAVA_HOME/bin下[3],在Ubuntu下尝试类似做法,行不通。
  • IDEA中使用File->Create->Project from Existing Files,创建工程不生成src文件夹,按照相同的配置可能出错。

参考

[1] VTK Java Wrappinghttps://vtk.org/Wiki/VTK/Java_Wrapping#Linux

[2] Java加载dll或so库文件的路径 java.library.path.https://blog.csdn.net/daylight_1/article/details/70199452

[3] vtk-8.01的java版本环境配置.https://blog.csdn.net/sinat_23619409/article/details/85106858

参考

[1] https://www.particleincell.com/2011/vtk-java-visualization/

附录

附录A. 一个vtk java样例程序

来源

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JToggleButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import vtk.vtkNativeLibrary;
import vtk.vtkPanel;
import vtk.vtkActor;
import vtk.vtkSphere;
import vtk.vtkSphereSource;
import vtk.vtkSampleFunction;
import vtk.vtkContourFilter;
import vtk.vtkPlane;
import vtk.vtkCutter;
import vtk.vtkLookupTable;
import vtk.vtkPolyDataMapper;

/* ************************************************************
 * Demo applications showcasing how to use VTK with Java
 * 
 * Based on SimpleVTK.java example distributed with VTK
 * 
 * For more information see:
 * http://www.particleincell.com/2011/vtk-java-visualization
 * 
 * Information about VTK can be found at:
 * http://vtk.org/
 * 
 * ***********************************************************/

public class DemoJavaVTK extends JPanel implements ActionListener 
{
    private static final long serialVersionUID = 1L;
    private vtkPanel renWin;
    private vtkActor cutActor;
    private vtkActor isoActor;
	
    private JPanel buttons;
    private JToggleButton slicesButton;
    private JToggleButton isoButton;
    private JButton exitButton;

    /* Load VTK shared librarires (.dll) on startup, print message if not found */
    static 
    {				
        if (!vtkNativeLibrary.LoadAllNativeLibraries()) 
	{
	       for (vtkNativeLibrary lib : vtkNativeLibrary.values()) 
		{
                	if (!lib.IsLoaded()) 
				System.out.println(lib.GetLibraryName() + " not loaded");    
		}
			
		System.out.println("Make sure the search path is correct: ");
		System.out.println(System.getProperty("java.library.path"));
        }
        vtkNativeLibrary.DisableOutputWindow(null);
    }

    /* Constructor - generates visualization pipeline and adds actors*/
    public DemoJavaVTK() 
    {
        super(new BorderLayout()); /* large center and small border areas*/
		
        double radius = 0.8;		/*sphere radius*/
		
	/**** 1) INPUT DATA: Sphere Implicit Function ****/
	vtkSphere sphere = new vtkSphere();
	sphere.SetRadius(radius);
		
	vtkSampleFunction sample = new vtkSampleFunction();
	sample.SetSampleDimensions(50,50,50);
	sample.SetImplicitFunction(sphere);
		
	/**** 2) PIPELINE 1: Isosurface Actor ****/
		
	/* contour filter - will generate isosurfaces from 3D data*/
	vtkContourFilter contour = new vtkContourFilter();
	contour.SetInputConnection(sample.GetOutputPort());
	contour.GenerateValues(3,0,1);
		
	/* mapper, translates polygonal representation to graphics primitives */
	vtkPolyDataMapper isoMapper = new vtkPolyDataMapper();
        isoMapper.SetInputConnection(contour.GetOutputPort());
		
	/*isosurface actor*/
        isoActor = new vtkActor();
        isoActor.SetMapper(isoMapper);
	
	/**** 3) PIPELINE 2: Cutting Plane Actor ****/
		
	/* define a plane in x-y plane and passing through the origin*/
	vtkPlane plane = new vtkPlane();
	plane.SetOrigin(0,0,0);
	plane.SetNormal(0,0,1);
		
	/* cutter, basically interpolates source data onto the plane */
	vtkCutter planeCut = new vtkCutter();
	planeCut.SetInputConnection(sample.GetOutputPort());
	planeCut.SetCutFunction(plane);
	/*this will actually create 3 planes at the subspace where the implicit
	 * function evaluates to -0.7, 0, 0.7 (0 would be original plane). In 
	 * our case this will create three x-y planes passing through 
	 * z=-0.7, z=0, and z=+0.7*/
	planeCut.GenerateValues(3,-0.7,0.7);
		
	/* look up table, we want to reduce number of values to get discrete bands */
	vtkLookupTable lut = new vtkLookupTable();
	lut.SetNumberOfTableValues(5);
		
	/* mapper, using our custom LUT */
	vtkPolyDataMapper cutMapper = new vtkPolyDataMapper();
        cutMapper.SetInputConnection(planeCut.GetOutputPort());
	cutMapper.SetLookupTable(lut);
		
	/* cutting plane actor, looks much better with flat shading */
	cutActor = new vtkActor();
        cutActor.SetMapper(cutMapper);
	cutActor.GetProperty().SetInterpolationToFlat();
		
	/**** 4) PIPELINE 3: Surface Geometry Actor ****/
		
	/* create polygonal representation of a sphere */
	vtkSphereSource surf = new vtkSphereSource();
	surf.SetRadius(radius);
		
	/* another mapper*/
	vtkPolyDataMapper surfMapper = new vtkPolyDataMapper();
	surfMapper.SetInputConnection(surf.GetOutputPort());
		
	/* surface geometry actor, turn on edges and apply flat shading*/
	vtkActor surfActor = new vtkActor();
	surfActor.SetMapper(surfMapper);
	surfActor.GetProperty().EdgeVisibilityOn();
	surfActor.GetProperty().SetEdgeColor(0.2,0.2,0.2);
	surfActor.GetProperty().SetInterpolationToFlat();

	/**** 5) RENDER WINDOW ****/
		
	/* vtkPanel - this is the interface between Java and VTK */
	renWin = new vtkPanel();
		
	/* add the surface geometry plus the isosurface */
	renWin.GetRenderer().AddActor(surfActor);
	renWin.GetRenderer().AddActor(isoActor);
		
	/* the default zoom is whacky, zoom out to see the whole domain */
        renWin.GetRenderer().GetActiveCamera().Dolly(0.2); 
	renWin.GetRenderer().SetBackground(1, 1, 1);
		
	/**** 6) CREATE PANEL FOR BUTTONS ****/
	buttons  = new JPanel();
	buttons.setLayout(new GridLayout(1,0));
		
        /* isosurface button, clicked by default */
	isoButton = new JToggleButton("Isosurfaces",true);
        isoButton.addActionListener(this);
		
	/* cutting planes button */
        slicesButton = new JToggleButton("Slices");
        slicesButton.addActionListener(this);
		
	/* exit button */
	exitButton = new JButton("Exit");
        exitButton.addActionListener(this);
		
	/* add buttons to the panel */
	buttons.add(isoButton); 
	buttons.add(slicesButton);
	buttons.add(exitButton); 

	/**** 7) POPULATE MAIN PANEL ****/
        add(renWin, BorderLayout.CENTER);
        add(buttons, BorderLayout.SOUTH);	
    }

    /* ActionListener that responds to button clicks
     * Toggling iso/slices buttons results in addition or removal
     * of the corresponding actor */
    public void actionPerformed(ActionEvent e) 
    {
	/*cutting planes button, add or remove cutActor */
	if (e.getSource().equals(slicesButton))
	{
		if (slicesButton.isSelected())
			renWin.GetRenderer().AddActor(cutActor);
		else
			renWin.GetRenderer().RemoveActor(cutActor);
			
		renWin.Render();
	}
	/*isosurface button, add or remove isoActor */
	else if (e.getSource().equals(isoButton))
	{
		if (isoButton.isSelected())
			renWin.GetRenderer().AddActor(isoActor);
		else
			renWin.GetRenderer().RemoveActor(isoActor);
		renWin.Render();
	}
	/*exit button, end application */
	else if (e.getSource().equals(exitButton)) 
	{
            System.exit(0);
        }
    }

    /* main, creates a new JFrame and populates it with the DemoJavaVTK panel */
    public static void main(String s[]) 
    {
        SwingUtilities.invokeLater(new Runnable() 
	{
            @Override
            public void run() 
	    {
                JFrame frame = new JFrame("Java and VTK Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new BorderLayout());
                frame.getContentPane().add(new DemoJavaVTK(), BorderLayout.CENTER);
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值