001/*
002 * Copyright 2010, 2011 Institut Pasteur.
003 * 
004 * This file is part of ICY.
005 * 
006 * ICY is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * ICY is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with ICY. If not, see <http://www.gnu.org/licenses/>.
018 */
019package plugins.tutorial.vtk;
020
021import icy.painter.Overlay;
022import icy.painter.VtkPainter;
023import icy.util.Random;
024import vtk.vtkActor;
025import vtk.vtkCardinalSpline;
026import vtk.vtkCellArray;
027import vtk.vtkGlyph3D;
028import vtk.vtkPoints;
029import vtk.vtkPolyData;
030import vtk.vtkPolyDataMapper;
031import vtk.vtkProp;
032import vtk.vtkSphereSource;
033import vtk.vtkTubeFilter;
034
035/**
036 * @author stephane
037 */
038public class VtkComplexeSplinePainter extends Overlay implements VtkPainter
039{
040    // vtk object
041    private vtkActor glyph;
042    private vtkActor profile;
043
044    public VtkComplexeSplinePainter()
045    {
046        super("VTK spline");
047
048        init();
049    }
050
051    // init vtk objects
052    private void init()
053    {
054        // This will be used later to get random numbers.
055        // Total number of points.
056        final int numberOfInputPoints = 20;
057
058        // One spline for each direction.
059        final vtkCardinalSpline aSplineX = new vtkCardinalSpline();
060        final vtkCardinalSpline aSplineY = new vtkCardinalSpline();
061        final vtkCardinalSpline aSplineZ = new vtkCardinalSpline();
062
063        // Generate random (pivot); points and add the corresponding
064        // coordinates to the splines.
065        // aSplineX will interpolate the x values of the points
066        // aSplineY will interpolate the y values of the points
067        // aSplineZ will interpolate the z values of the points
068        final vtkPoints inputPoints = new vtkPoints();
069        for (int i = 0; i < numberOfInputPoints; i++)
070        {
071            final double x = 200 * Random.nextDouble();
072            final double y = 100 * Random.nextDouble();
073            final double z = 50 * Random.nextDouble();
074            aSplineX.AddPoint(i, x);
075            aSplineY.AddPoint(i, y);
076            aSplineZ.AddPoint(i, z);
077            inputPoints.InsertPoint(i, x, y, z);
078        }
079
080        // The following section will create glyphs for the pivot points
081        // in order to make the effect of the spline more clear.
082
083        // Create a polydata to be glyphed.
084        final vtkPolyData inputData = new vtkPolyData();
085        inputData.SetPoints(inputPoints);
086
087        // Use sphere as glyph source.
088        final vtkSphereSource balls = new vtkSphereSource();
089        // balls.SetRadius(.02);
090        balls.SetRadius(5);
091        balls.SetPhiResolution(10);
092        balls.SetThetaResolution(10);
093
094        final vtkGlyph3D glyphPoints = new vtkGlyph3D();
095        glyphPoints.SetInputData(inputData);
096        glyphPoints.SetSourceConnection(balls.GetOutputPort());
097
098        final vtkPolyDataMapper glyphMapper = new vtkPolyDataMapper();
099        glyphMapper.SetInputConnection(glyphPoints.GetOutputPort());
100
101        glyph = new vtkActor();
102        glyph.SetMapper(glyphMapper);
103        glyph.GetProperty().SetDiffuseColor(1, 1, 0);
104        glyph.GetProperty().SetSpecular(.3);
105        glyph.GetProperty().SetSpecularPower(30);
106
107        // Generate the polyline for the spline.
108        final vtkPoints points = new vtkPoints();
109        final vtkPolyData profileData = new vtkPolyData();
110
111        // Number of points on the spline
112        final int numberOfOutputPoints = 4000;
113
114        // Interpolate x, y and z by using the three spline filters and
115        // create new points
116        for (int i = 0; i < numberOfOutputPoints; i++)
117        {
118            final double t = (numberOfInputPoints - 1.0) / (numberOfOutputPoints - 1.0) * i;
119            points.InsertPoint(i, aSplineX.Evaluate(t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t));
120        }
121
122        // Create the polyline.
123        final vtkCellArray lines = new vtkCellArray();
124        lines.InsertNextCell(numberOfOutputPoints);
125        for (int i = 0; i < numberOfOutputPoints; i++)
126            lines.InsertCellPoint(i);
127
128        profileData.SetPoints(points);
129        profileData.SetLines(lines);
130
131        // Add thickness to the resulting line.
132        final vtkTubeFilter profileTubes = new vtkTubeFilter();
133        profileTubes.SetNumberOfSides(8);
134        profileTubes.SetInputData(profileData);
135        // profileTubes.SetRadius(.01);
136        profileTubes.SetRadius(1);
137
138        final vtkPolyDataMapper profileMapper = new vtkPolyDataMapper();
139        profileMapper.SetInputConnection(profileTubes.GetOutputPort());
140
141        profile = new vtkActor();
142        profile.SetMapper(profileMapper);
143
144        profile.GetProperty().SetOpacity(1);
145        profile.GetProperty().SetDiffuseColor(1, 0, 1);
146        profile.GetProperty().SetSpecular(.3);
147        profile.GetProperty().SetSpecularPower(30);
148    }
149
150    @Override
151    public vtkProp[] getProps()
152    {
153//        return new vtkProp[] {glyph};
154        return new vtkProp[] {glyph, profile};
155    }
156
157}