Browse Source

Added matplot_vtk to build.

enhancement_3
Trevor Irons 9 years ago
parent
commit
d93ff67056

+ 34
- 3
CMakeLists.txt View File

@@ -1,12 +1,27 @@
1 1
 cmake_minimum_required (VERSION 2.8.7)
2 2
 
3
-project (Lemma)
3
+project (Lemma CXX)
4
+
5
+
6
+# required external programs (for runtime of nix, not buildtime)
7
+FIND_PROGRAM(HAVEGIT git
8
+  PATHS /usr/bin/ /bin ENV PATH NO_DEFAULT_PATH
9
+)
10
+if(NOT HAVEGIT)
11
+  message(FATAL_ERROR "Lemma requires that git is installed and in the path of your machine")
12
+endif(NOT HAVEGIT)
13
+
14
+# FIND_PROGRAM(HAVEHG hg
15
+#   PATHS /usr/bin/ /bin ENV PATH NO_DEFAULT_PATH
16
+# )
17
+# if(NOT HAVEHG)
18
+#   message(STATUS "Mercurial (hg) was not found.")
19
+# endif(NOT HAVEHG)
4 20
 
5 21
 ###################
6 22
 # External Projects
7 23
 ###################
8 24
 include(ExternalProject)
9
-
10 25
 # Eigen, this header-library is used extensively for linear algebra, matrices, and arrays
11 26
 # Mercurial (hg) repo pull, Would it be better to just download latest stable?
12 27
 #ExternalProject_Add(EIGEN
@@ -76,9 +91,25 @@ if (VTK_SUPPORT)
76 91
 	find_package(VTK 6 REQUIRED NO_MODULE)
77 92
 	include(${VTK_USE_FILE})
78 93
 	add_compile_options(-DLEMMAUSEVTK) 
94
+
95
+	# Compile Matplot_vtk if VTK is present
96
+	add_subdirectory(Matplot_vtk)	
97
+	include_directories ("${PROJECT_SOURCE_DIR}/Matplot_vtk")
98
+
79 99
 endif()
80 100
 
81
-add_compile_options(-std=c++11) 
101
+# Add the c++11 flag 
102
+include(CheckCXXCompilerFlag)
103
+CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11)
104
+CHECK_CXX_COMPILER_FLAG(-std=c++0x COMPILER_SUPPORTS_CXX0X)
105
+if(COMPILER_SUPPORTS_CXX11)
106
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
107
+elseif(COMPILER_SUPPORTS_CXX0X)
108
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
109
+else()
110
+  message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
111
+endif()
112
+#add_compile_options(-std=c++11) 
82 113
 
83 114
 set(LEMMA_VERSION_MAJOR "0")
84 115
 set(LEMMA_VERSION_MINOR "0")

+ 5
- 1
LemmaCore/CMakeLists.txt View File

@@ -14,7 +14,11 @@ if (MATIO_SUPPORT)
14 14
 endif()
15 15
 if (VTK_SUPPORT) 
16 16
 	target_link_libraries(lemmacore ${VTK_LIBRARIES})
17
+	target_link_libraries(lemmacore "matplot")
17 18
 endif()
18 19
 target_link_libraries(lemmacore "yaml-cpp")
19 20
 
20
-add_subdirectory(examples)
21
+option( BUILDEXAMPLES "Compile example Lemma applications" OFF )
22
+if (BUILDEXAMPLES)
23
+	add_subdirectory(examples)
24
+endif()

+ 1
- 1
LemmaCore/examples/CMakeLists.txt View File

@@ -1,4 +1,4 @@
1
-FILE(GLOB  examples  "*.cpp")
1
+#FILE(GLOB  examples  "*.cpp")
2 2
 
3 3
 add_executable( datatem datatem.cpp )
4 4
 target_link_libraries(datatem "lemmacore")

+ 2
- 0
Matplot_vtk/CMakeLists.txt View File

@@ -0,0 +1,2 @@
1
+add_library( matplot matplot.cpp )
2
+target_link_libraries(matplot ${VTK_LIBRARIES})

+ 700
- 0
Matplot_vtk/matplot.cpp View File

@@ -0,0 +1,700 @@
1
+#ifdef LEMMAUSEVTK
2
+
3
+#include "matplot.h"
4
+
5
+#include "vtkActor.h"
6
+#include "vtkAxesActor.h"
7
+#include "vtkCamera.h"
8
+#include "vtkCaptionActor2D.h"
9
+#include "vtkContourFilter.h"
10
+#include "vtkDataSetMapper.h"
11
+#include "vtkGlyph3D.h"
12
+#include "vtkGlyphSource2D.h"
13
+#include "vtkOutlineFilter.h"
14
+#include "vtkPolyData.h"
15
+#include "vtkPolyDataMapper.h"
16
+#include "vtkPNGWriter.h"
17
+#include "vtkProperty.h"
18
+#include "vtkProperty2D.h"
19
+#include "vtkRectilinearGridGeometryFilter.h"
20
+#include "vtkRenderWindow.h"
21
+#include "vtkRenderWindowInteractor.h"
22
+#include "vtkStructuredGridGeometryFilter.h"
23
+#include "vtkScalarBarActor.h"
24
+#include "vtkTextProperty.h"
25
+#include "vtkTubeFilter.h"
26
+#include "vtkWarpScalar.h"
27
+#include "vtkWindowToImageFilter.h"
28
+#include "vtkRenderLargeImage.h"
29
+
30
+#include "vtkTextActor.h"
31
+#include "vtkVectorText.h"
32
+#include "vtkTransformPolyDataFilter.h"
33
+#include "vtkTransform.h"
34
+#include "vtkFollower.h"
35
+
36
+#include "vtkAxisActor2D.h"
37
+//#include "vtkCubeAxesActor.h"
38
+#include "vtkCubeAxesActor2D.h"
39
+
40
+using namespace matplot;
41
+
42
+/// Default constructor
43
+Plot2D_VTK::Plot2D_VTK(std::string x_label, std::string y_label,
44
+		       int xpix, int ypix, bool semilogX)
45
+{
46
+    semilogx = semilogX;
47
+    xPix = xpix;
48
+    yPix = ypix;
49
+
50
+    plot_no = 0;
51
+
52
+    // set up the renderer
53
+    rend = vtkRenderer::New();
54
+    rend->SetBackground(1., 1., 1.);
55
+
56
+    // set up the xy plot
57
+    xyplot = vtkXYPlotActor::New();
58
+
59
+    xyplot->GetProperty()->SetColor(0.0, 0.0, 0.0);
60
+
61
+    xyplot->SetBorder(10);
62
+    xyplot->GetPositionCoordinate()->SetValue(0.0, 0.0, 0);
63
+    xyplot->GetPosition2Coordinate()->SetValue(1.0, 1.0, 0);
64
+
65
+    xyplot->GetProperty()->SetLineWidth(1);
66
+    xyplot->GetProperty()->SetPointSize(5);
67
+
68
+    xyplot->PlotPointsOff();
69
+    xyplot->PlotLinesOff();
70
+    xyplot->PlotCurvePointsOn();
71
+    xyplot->PlotCurveLinesOn();
72
+
73
+    xyplot->SetXValuesToArcLength();
74
+
75
+    xyplot->SetLabelFormat("%2.1f");
76
+    xyplot->SetTitle("");
77
+    xyplot->SetXTitle(x_label.c_str());
78
+    xyplot->SetYTitle(y_label.c_str());
79
+
80
+    if (semilogx) {
81
+        xyplot->LogxOn();
82
+    }
83
+
84
+    vtkTextProperty* text_prop = xyplot->GetTitleTextProperty();
85
+    text_prop->SetColor(0.0, 0.0, 0.0);
86
+    text_prop->SetFontFamilyToArial();
87
+    xyplot->SetAxisTitleTextProperty(text_prop);
88
+    xyplot->SetAxisLabelTextProperty(text_prop);
89
+    xyplot->SetTitleTextProperty(text_prop);
90
+}
91
+
92
+/// Destructor
93
+Plot2D_VTK::~Plot2D_VTK()
94
+{
95
+    xyplot->Delete();
96
+    rend->Delete();
97
+}
98
+
99
+/// Render current figure to screen
100
+void Plot2D_VTK::show()
101
+{
102
+    rend->AddActor(xyplot);
103
+    render_interactive(rend,xPix,yPix);
104
+}
105
+
106
+/// Render current figure to file
107
+void Plot2D_VTK::draw_to_png(std::string filename)
108
+{
109
+    rend->AddActor(xyplot);
110
+    render_to_png(rend,xPix,yPix,filename);
111
+}
112
+//==============================================================================
113
+
114
+Surf_VTK::Surf_VTK(int px, int py)
115
+{
116
+    has_data = false;
117
+    Lxy = -1;
118
+    Lz = -1;
119
+    xPix = px;
120
+    yPix = py;
121
+
122
+    gridfunc = vtkStructuredGrid::New();
123
+    rend = vtkRenderer::New();
124
+}
125
+
126
+/// Destructor
127
+Surf_VTK::~Surf_VTK()
128
+{
129
+    gridfunc->Delete();
130
+    rend->Delete();
131
+}
132
+
133
+/// Clear plot data before reuse
134
+void Surf_VTK::purge()
135
+{
136
+    assert(has_data);
137
+    gridfunc->Delete();
138
+    rend->Delete();
139
+    gridfunc = vtkStructuredGrid::New();
140
+    rend = vtkRenderer::New();
141
+    has_data = false;
142
+    Lxy = -1;
143
+    Lz = -1;
144
+}
145
+
146
+void Surf_VTK::renderer(bool draw_axes, bool draw_colorbar, bool draw_box,
147
+			bool do_warp)
148
+{
149
+    assert(has_data);
150
+
151
+    // filter to geometry primitive
152
+    vtkStructuredGridGeometryFilter *geometry =
153
+	vtkStructuredGridGeometryFilter::New();
154
+    geometry->SetInputData(gridfunc);
155
+
156
+    // warp to fit in box
157
+    vtkWarpScalar *warp = vtkWarpScalar::New();
158
+    if (do_warp)
159
+    {
160
+	double scale = Lxy/Lz;
161
+	warp->SetInputConnection(geometry->GetOutputPort());
162
+	warp->XYPlaneOn();
163
+	warp->SetScaleFactor(scale);
164
+    }
165
+
166
+    // map gridfunction
167
+    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
168
+    if (do_warp)
169
+	mapper->SetInputConnection(warp->GetOutputPort());
170
+    else
171
+	mapper->SetInputConnection(geometry->GetOutputPort());
172
+
173
+    double tmp[2];
174
+    gridfunc->GetScalarRange(tmp);
175
+    mapper->SetScalarRange(tmp[0], tmp[1]);
176
+
177
+    // create plot surface actor
178
+    vtkActor *surfplot = vtkActor::New();
179
+    surfplot->SetMapper(mapper);
180
+
181
+    // create outline
182
+    vtkOutlineFilter *outlinefilter = vtkOutlineFilter::New();
183
+    if (do_warp)
184
+	outlinefilter->SetInputConnection(warp->GetOutputPort());
185
+    else
186
+	outlinefilter->SetInputConnection(geometry->GetOutputPort());
187
+    vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
188
+    outlineMapper->SetInputConnection(outlinefilter->GetOutputPort());
189
+    vtkActor *outline = vtkActor::New();
190
+    outline->SetMapper(outlineMapper);
191
+    outline->GetProperty()->SetColor(0, 0, 0);
192
+
193
+    // create axes
194
+    vtkAxesActor* axes = vtkAxesActor::New();
195
+    axes->SetShaftTypeToCylinder();
196
+    axes->SetNormalizedShaftLength( 0.85, 0.85, 0.85);
197
+    axes->SetNormalizedTipLength( 0.15, 0.15, 0.15);
198
+    axes->SetCylinderRadius( 0.500 * axes->GetCylinderRadius() );
199
+    axes->SetConeRadius( 1.025 * axes->GetConeRadius() );
200
+    axes->SetSphereRadius( 1.500 * axes->GetSphereRadius() );
201
+    vtkTextProperty* text_prop_ax = axes->GetXAxisCaptionActor2D()->
202
+	GetCaptionTextProperty();
203
+    text_prop_ax->SetColor(0.0, 0.0, 0.0);
204
+    text_prop_ax->SetFontFamilyToArial();
205
+    text_prop_ax->SetFontSize(8);
206
+    axes->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->
207
+	ShallowCopy(text_prop_ax);
208
+    axes->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->
209
+	ShallowCopy(text_prop_ax);
210
+
211
+    // create colorbar
212
+    vtkScalarBarActor *colorbar = vtkScalarBarActor::New();
213
+    colorbar->SetLookupTable(mapper->GetLookupTable());
214
+    colorbar->SetWidth(0.085);
215
+    colorbar->SetHeight(0.9);
216
+    colorbar->SetPosition(0.9, 0.1);
217
+    vtkTextProperty* text_prop_cb = colorbar->GetLabelTextProperty();
218
+    text_prop_cb->SetColor(1.0, 1.0, 1.0);
219
+    colorbar->SetLabelTextProperty(text_prop_cb);
220
+
221
+    // renderer
222
+    rend->AddActor(surfplot);
223
+    if (draw_box)
224
+	rend->AddActor(outline);
225
+    if (draw_axes)
226
+	rend->AddActor(axes);
227
+    if (draw_colorbar)
228
+	    rend->AddActor(colorbar);
229
+
230
+    rend->SetBackground(0.25, 0.25, 0.25);
231
+
232
+    // renderer is now set up!
233
+
234
+    // clean up
235
+    colorbar->Delete();
236
+    warp->Delete();
237
+    axes->Delete();
238
+    outline->Delete();
239
+    outlinefilter->Delete();
240
+    outlineMapper->Delete();
241
+    surfplot->Delete();
242
+    mapper->Delete();
243
+    geometry->Delete();
244
+}
245
+//==============================================================================
246
+
247
+/// Default constructor
248
+Contour_VTK::Contour_VTK(int px, int py)
249
+{
250
+	XScale = LINEAR;
251
+	YScale = LINEAR;
252
+
253
+    has_data = false;
254
+    xPix = px;
255
+    yPix = py;
256
+
257
+    gridfunc = vtkRectilinearGrid::New();
258
+    rend = vtkRenderer::New();
259
+}
260
+
261
+/// Default constructor
262
+Contour_VTK::Contour_VTK(int px, int py, SCALE xsc, SCALE ysc)
263
+{
264
+	XScale = xsc;
265
+	YScale = ysc;
266
+
267
+	xlabel  = "x";
268
+	ylabel  = "y";
269
+
270
+    has_data = false;
271
+    xPix = px;
272
+    yPix = py;
273
+
274
+    gridfunc = vtkRectilinearGrid::New();
275
+    rend = vtkRenderer::New();
276
+}
277
+
278
+/// Destructor
279
+Contour_VTK::~Contour_VTK()
280
+{
281
+    gridfunc->Delete();
282
+    rend->Delete();
283
+}
284
+
285
+/// Clear plot data before reuse
286
+void Contour_VTK::purge()
287
+{
288
+    assert(has_data);
289
+    gridfunc->Delete();
290
+    rend->Delete();
291
+    gridfunc = vtkRectilinearGrid::New();
292
+    rend = vtkRenderer::New();
293
+    has_data = false;
294
+}
295
+
296
+/// Set labels for contour plots
297
+void Contour_VTK::SetXLabel(const std::string &xlab) {
298
+	xlabel = xlab;
299
+}
300
+
301
+void Contour_VTK::SetYLabel(const std::string &ylab ) {
302
+	ylabel = ylab;
303
+}
304
+
305
+void Contour_VTK::renderer(bool draw_colorbar, bool draw_surf, int lines)
306
+{
307
+    assert(has_data);
308
+
309
+    // filter to geometry primitive
310
+    vtkRectilinearGridGeometryFilter *geometry =
311
+	vtkRectilinearGridGeometryFilter::New();
312
+    geometry->SetInputData(gridfunc);
313
+
314
+    // map gridfunction
315
+    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
316
+    mapper->SetInputConnection(geometry->GetOutputPort());
317
+
318
+    double tmp[2];
319
+    gridfunc->GetScalarRange(tmp);
320
+    mapper->SetScalarRange(tmp[0], tmp[1]);
321
+
322
+    // create plot surface actor
323
+    vtkActor *surfplot = vtkActor::New();
324
+    surfplot->SetMapper(mapper);
325
+
326
+    // create contour lines (10 lines)
327
+    vtkContourFilter *contlines = vtkContourFilter::New();
328
+    contlines->SetInputConnection(geometry->GetOutputPort());
329
+    double tempdiff = (tmp[1]-tmp[0])/(10*lines);
330
+    contlines->GenerateValues(lines, tmp[0]+tempdiff, tmp[1]-tempdiff);
331
+    vtkPolyDataMapper *contourMapper = vtkPolyDataMapper::New();
332
+    contourMapper->SetInputConnection(contlines->GetOutputPort());
333
+    if (draw_surf)
334
+	contourMapper->ScalarVisibilityOff();
335
+    else
336
+	contourMapper->SetScalarRange(tmp[0], tmp[1]);
337
+    vtkActor *contours = vtkActor::New();
338
+    contours->SetMapper(contourMapper);
339
+	contours->GetProperty()->SetOpacity(.25);
340
+	contours->GetProperty()->SetColor(0.5,0.5,0.5);
341
+
342
+    // create outline
343
+    vtkOutlineFilter *outlinefilter = vtkOutlineFilter::New();
344
+    outlinefilter->SetInputConnection(geometry->GetOutputPort());
345
+    vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
346
+    outlineMapper->SetInputConnection(outlinefilter->GetOutputPort());
347
+    vtkActor *outline = vtkActor::New();
348
+    outline->SetMapper(outlineMapper);
349
+    outline->GetProperty()->SetColor(0, 0, 0);
350
+
351
+    // create colorbar
352
+    vtkScalarBarActor *colorbar = vtkScalarBarActor::New();
353
+    if (draw_surf)
354
+	colorbar->SetLookupTable(mapper->GetLookupTable());
355
+    else
356
+	colorbar->SetLookupTable(contourMapper->GetLookupTable());
357
+//
358
+    colorbar->SetWidth(0.085);
359
+    colorbar->SetHeight(0.9);
360
+    colorbar->SetPosition(0.9, 0.1);
361
+    vtkTextProperty* text_prop_cb = colorbar->GetLabelTextProperty();
362
+    text_prop_cb->SetColor(1.0, 1.0, 1.0);
363
+    colorbar->SetLabelTextProperty(text_prop_cb);
364
+
365
+	double xrange[2];
366
+ 	double yrange[2];
367
+ 	gridfunc->GetXCoordinates()->GetRange(xrange);
368
+ 	gridfunc->GetYCoordinates()->GetRange(yrange);
369
+ 	vtkCubeAxesActor2D  *caxis = vtkCubeAxesActor2D::New();
370
+
371
+	caxis->ZAxisVisibilityOff();
372
+	caxis->SetXLabel(xlabel.c_str());
373
+	caxis->SetYLabel(ylabel.c_str());
374
+
375
+	vtkCamera* mycam = rend->MakeCamera(); // vtkCamera::New();
376
+	//rend->SetActiveCamera(mycam);
377
+  	caxis->SetBounds( xrange[0], xrange[1], yrange[0], yrange[1], 0, 0);
378
+  	caxis->SetRanges( xrange[0], xrange[1], ymin, ymax, 0, 0);
379
+	caxis->SetUseRanges(1);
380
+
381
+  	caxis->SetCamera( mycam );
382
+	caxis->SetNumberOfLabels(6);
383
+	// doesn't work, rotate y label 90 degrees
384
+	caxis->GetYAxisActor2D()->GetTitleTextProperty()->SetOrientation(90.);
385
+   	rend->AddActor(caxis);
386
+
387
+	mycam->Delete();
388
+	caxis->Delete();
389
+
390
+	// handdrwan label
391
+// 	// X label
392
+// 	vtkVectorText                     *xlabel = vtkVectorText::New();
393
+// 	vtkTransformPolyDataFilter  *transxlabel  = vtkTransformPolyDataFilter::New();
394
+// 	vtkTransform                      *trans  = vtkTransform::New();
395
+// 	vtkPolyDataMapper               *xlabmap  = vtkPolyDataMapper::New();
396
+// 	vtkFollower                     *xlabact  = vtkFollower::New();
397
+	// locate and rotate as needed
398
+ 	//double yranget = std::abs(yrange[1]-yrange[0]);
399
+	//double xranget = std::abs(xrange[1]-xrange[0]);
400
+// 	trans->Identity();
401
+// 	trans->Scale(5,5,5);  // TODO, is 5 always OK???
402
+// 	transxlabel->SetTransform(trans);
403
+// 	transxlabel->SetInputConnection(xlabel->GetOutputPort());
404
+// 	// TODO input name
405
+// 	xlabel->SetText("Frequency [Hz]");
406
+// 	transxlabel->SetInputConnection(xlabel->GetOutputPort());
407
+// 	xlabmap->SetInputConnection(transxlabel->GetOutputPort());
408
+// 	xlabact->SetMapper(xlabmap);
409
+// 	// centre between axis
410
+// 	xlabact->SetPosition( (xrange[0]+xrange[1])/2 - xlabact->GetCenter()[0],
411
+// 					       yrange[0]-.2*yranget, 0 );
412
+// 	//rend->AddActor(xlabact);
413
+// 	// Y label
414
+// 	vtkVectorText                     *ylabel = vtkVectorText::New();
415
+// 	vtkTransformPolyDataFilter  *transylabel  = vtkTransformPolyDataFilter::New();
416
+// 	vtkTransform                     *ytrans  = vtkTransform::New();
417
+// 	vtkPolyDataMapper               *ylabmap  = vtkPolyDataMapper::New();
418
+// 	vtkFollower                     *ylabact  = vtkFollower::New();
419
+// 	// locate and rotate as needed
420
+// 	ytrans->Identity();
421
+// 	ytrans->Scale(5,5,5); // TODO don't hard code, calc from window size maybe??
422
+// 	ytrans->RotateZ(90);
423
+// 	transylabel->SetTransform(ytrans);
424
+// 	transylabel->SetInputConnection(ylabel->GetOutputPort());
425
+//
426
+// 	ylabel->SetText("Pulse moment [A sec]");
427
+// 	transylabel->SetInputConnection(ylabel->GetOutputPort());
428
+// 	ylabmap->SetInputConnection(transylabel->GetOutputPort());
429
+// 	ylabact->SetMapper(ylabmap);
430
+// 	ylabact->SetPosition( xrange[0]-.2*xranget,
431
+// 					      (yrange[0]+yrange[1])/2 - ylabact->GetCenter()[1],
432
+// 						  0 );
433
+// 	//rend->AddActor(ylabact);
434
+
435
+    if (draw_surf)
436
+ 	rend->AddActor(surfplot);
437
+
438
+	rend->AddActor(contours);
439
+	rend->AddActor(outline);
440
+	if (draw_colorbar) {
441
+		rend->AddActor(colorbar);
442
+ 	}
443
+
444
+	rend->SetBackground(0.25, 0.25, 0.25);
445
+
446
+// 	double xrange[2];
447
+// 	double yrange[2];
448
+// 	gridfunc->GetXCoordinates()->GetRange(xrange);
449
+// 	gridfunc->GetYCoordinates()->GetRange(yrange);
450
+// 	vtkCubeAxesActor	 *caxis = vtkCubeAxesActor::New();
451
+// 	caxis->ZAxisVisibilityOff();
452
+// 	caxis->SetCamera(rend->GetActiveCamera());
453
+// 	caxis->SetBounds( xrange[0], xrange[1], yrange[0], yrange[1], 0, 1 );
454
+//  	rend->AddActor(caxis);
455
+
456
+ 	//rend->AddActor(yaxis);
457
+//     // clean up
458
+// 	xlabel->Delete();
459
+// 	transxlabel->Delete();
460
+// 	trans->Delete();
461
+// 	xlabmap->Delete();
462
+// 	xlabact->Delete();
463
+//
464
+// 	ylabel->Delete();
465
+// 	transylabel->Delete();
466
+// 	ytrans->Delete();
467
+// 	ylabmap->Delete();
468
+// 	ylabact->Delete();
469
+
470
+	// renderer is now set up!
471
+	//caxis->Delete();
472
+	//yaxis->Delete();
473
+
474
+    contours->Delete();
475
+    contlines->Delete();
476
+    contourMapper->Delete();
477
+    outline->Delete();
478
+    outlinefilter->Delete();
479
+    outlineMapper->Delete();
480
+    colorbar->Delete();
481
+    surfplot->Delete();
482
+    mapper->Delete();
483
+    geometry->Delete();
484
+
485
+}
486
+//==============================================================================
487
+
488
+/// Default constructor
489
+Quiver_VTK::Quiver_VTK(int px, int py)
490
+{
491
+    has_data = false;
492
+    xPix = px;
493
+    yPix = py;
494
+
495
+    gridfunc = vtkRectilinearGrid::New();
496
+    rend = vtkRenderer::New();
497
+}
498
+
499
+/// Destructor
500
+Quiver_VTK::~Quiver_VTK()
501
+{
502
+    gridfunc->Delete();
503
+    rend->Delete();
504
+}
505
+
506
+/// Clear plot data before reuse
507
+void Quiver_VTK::purge()
508
+{
509
+    assert(has_data);
510
+    gridfunc->Delete();
511
+    rend->Delete();
512
+    gridfunc = vtkRectilinearGrid::New();
513
+    rend = vtkRenderer::New();
514
+    has_data = false;
515
+}
516
+
517
+void Quiver_VTK::renderer(double s)
518
+{
519
+    assert(has_data);
520
+
521
+    // filter to geometry primitive
522
+    vtkRectilinearGridGeometryFilter *geometry =
523
+	vtkRectilinearGridGeometryFilter::New();
524
+    geometry->SetInputData(gridfunc);
525
+
526
+    // make a vector glyph
527
+    vtkGlyphSource2D* vec = vtkGlyphSource2D::New();
528
+    vec->SetGlyphTypeToArrow();
529
+    vec->SetScale(s);
530
+    vec->FilledOff();
531
+
532
+    vtkGlyph3D* glyph = vtkGlyph3D::New();
533
+    glyph->SetInputConnection(geometry->GetOutputPort());
534
+    glyph->SetSourceConnection(vec->GetOutputPort());
535
+    glyph->SetColorModeToColorByScalar();
536
+
537
+    // map gridfunction
538
+    vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
539
+    mapper->SetInputConnection(glyph->GetOutputPort());
540
+
541
+    double tmp[2];
542
+    gridfunc->GetScalarRange(tmp);
543
+    mapper->SetScalarRange(tmp[0], tmp[1]);
544
+
545
+    // create plot quiver actor
546
+    vtkActor *quiver_actor = vtkActor::New();
547
+    quiver_actor->SetMapper(mapper);
548
+
549
+    // create colorbar
550
+    vtkScalarBarActor *colorbar = vtkScalarBarActor::New();
551
+    colorbar->SetLookupTable(mapper->GetLookupTable());
552
+    colorbar->SetWidth(0.085);
553
+    colorbar->SetHeight(0.9);
554
+    colorbar->SetPosition(0.9, 0.1);
555
+    vtkTextProperty* text_prop_cb = colorbar->GetLabelTextProperty();
556
+    text_prop_cb->SetColor(1.0, 1.0, 1.0);
557
+    colorbar->SetLabelTextProperty(text_prop_cb);
558
+
559
+    // create outline
560
+    vtkOutlineFilter *outlinefilter = vtkOutlineFilter::New();
561
+    outlinefilter->SetInputConnection(geometry->GetOutputPort());
562
+    vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
563
+    outlineMapper->SetInputConnection(outlinefilter->GetOutputPort());
564
+    vtkActor *outline = vtkActor::New();
565
+    outline->SetMapper(outlineMapper);
566
+    outline->GetProperty()->SetColor(0, 0, 0);
567
+
568
+    // add actors to renderer
569
+    rend->AddActor(quiver_actor);
570
+    rend->AddActor(colorbar);
571
+    rend->AddActor(outline);
572
+    rend->SetBackground(0.25, 0.25, 0.25);
573
+
574
+    // renderer is now set up!
575
+
576
+    // clean up
577
+    outline->Delete();
578
+    outlinefilter->Delete();
579
+    outlineMapper->Delete();
580
+    vec->Delete();
581
+    glyph->Delete();
582
+    colorbar->Delete();
583
+    quiver_actor->Delete();
584
+    mapper->Delete();
585
+
586
+}
587
+
588
+//==============================================================================
589
+
590
+/** Start interactive rendereing (default camera).
591
+ * Sets resolution to (xPix,yPix)
592
+ */
593
+void matplot::render_interactive(vtkRenderer *rend, int xPix, int yPix)
594
+{
595
+	vtkRenderWindow *renWin = vtkRenderWindow::New();
596
+    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
597
+    renWin->AddRenderer(rend);
598
+    iren->SetRenderWindow(renWin);
599
+    renWin->SetSize(xPix, yPix);
600
+
601
+	// makes first frame look reasonable interactive
602
+	renWin->Render();
603
+	renWin->Start();
604
+
605
+    // Start interactive rendering
606
+    iren->Initialize();
607
+    iren->Start();
608
+    iren->Disable();
609
+	iren->Delete();
610
+    renWin->Delete();
611
+}
612
+
613
+/** Start interactive rendereing (manual camera placement).
614
+ * Sets resolution to (xPix,yPix)
615
+ */
616
+void matplot::render_interactive_cam(vtkRenderer *rend, int xPix, int yPix,
617
+				     double cam[3], double focal[3])
618
+{
619
+    rend->GetActiveCamera()->SetViewUp(0, 0, 1);
620
+    rend->GetActiveCamera()->SetPosition(cam);
621
+    rend->GetActiveCamera()->SetFocalPoint(focal);
622
+
623
+    vtkRenderWindow *renWin = vtkRenderWindow::New();
624
+    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
625
+    renWin->AddRenderer(rend);
626
+    iren->SetRenderWindow(renWin);
627
+    renWin->SetSize(xPix, yPix);
628
+
629
+    // Start interactive rendering
630
+    iren->Initialize();
631
+    iren->Start();
632
+
633
+    iren->Delete();
634
+    renWin->Delete();
635
+}
636
+
637
+/// Renders scene to PNG (default camera)
638
+void matplot::render_to_png(vtkRenderer *rend, int xPix, int yPix,
639
+			    std::string fname)
640
+{
641
+    vtkRenderWindow *renWin = vtkRenderWindow::New();
642
+    renWin->AddRenderer(rend);
643
+    renWin->SetSize(xPix, yPix);
644
+    renWin->Render();
645
+    rend->Render();
646
+
647
+    vtkRenderLargeImage* renderLarge = vtkRenderLargeImage::New();
648
+        renderLarge->SetInput(rend);
649
+        renderLarge->SetMagnification(1);
650
+
651
+    vtkPNGWriter *pngfile = vtkPNGWriter::New();
652
+        pngfile->SetFileName(fname.c_str());
653
+        pngfile->SetInputConnection(renderLarge->GetOutputPort());
654
+        pngfile->Update();
655
+        pngfile->Update();
656
+
657
+    pngfile->Update();
658
+    pngfile->Write();
659
+
660
+    renderLarge->Delete();
661
+    pngfile->Delete();
662
+    renWin->Delete();
663
+}
664
+
665
+/// Renders scene to PNG (manual camera placement)
666
+void matplot::render_to_png_cam(vtkRenderer *rend, int xPix, int yPix,
667
+				std::string fname, double cam[3],
668
+				double focal[3])
669
+{
670
+    rend->GetActiveCamera()->SetViewUp(0, 0, 1);
671
+    rend->GetActiveCamera()->SetPosition(cam);
672
+    rend->GetActiveCamera()->SetFocalPoint(focal);
673
+
674
+    vtkRenderWindow *renWin = vtkRenderWindow::New();
675
+    renWin->AddRenderer(rend);
676
+    renWin->SetSize(xPix, yPix);
677
+
678
+    vtkRenderLargeImage* renderLarge = vtkRenderLargeImage::New();
679
+        renderLarge->SetInput(rend);
680
+        renderLarge->SetMagnification(1);
681
+
682
+    //vtkWindowToImageFilter *w2i = vtkWindowToImageFilter::New();
683
+    vtkPNGWriter *pngfile = vtkPNGWriter::New();
684
+        //pngfile->SetInputConnection(w2i->GetOutputPort());
685
+        pngfile->SetInputConnection(renderLarge->GetOutputPort());
686
+    pngfile->SetFileName(fname.c_str());
687
+
688
+    //w2i->SetInput(renWin);
689
+    //w2i->Update();
690
+
691
+    renWin->Render();
692
+    pngfile->Write();
693
+
694
+    //w2i->Delete();
695
+    renderLarge->Delete();
696
+    pngfile->Delete();
697
+    renWin->Delete();
698
+}
699
+
700
+#endif

+ 634
- 0
Matplot_vtk/matplot.h View File

@@ -0,0 +1,634 @@
1
+#ifndef __MATPLOT_VTK
2
+#define __MATPLOT_VTK
3
+
4
+/*
5
+ * MatPlot_VTK
6
+ *
7
+ * Simple plotting of vectors and matrices based on
8
+ * the VTK libraries.
9
+ *
10
+ * Four classes:
11
+ * Plot2D_VTK  - 2d plotting akin to plot(x,y)
12
+ * Surf_VTK    - Surface plotting akin to surf(x,y,z)
13
+ * Contour_VTK - Contour plotting
14
+ * Quiver_VTK  - Vector field plot
15
+ *
16
+ * See examples.cpp for usage instructions.
17
+ *
18
+ * These classes are released "as is", without any implied
19
+ * warranty or fitness for any particular purpose.
20
+ *
21
+ * Dag Lindbo, dag@csc.kth.se, 2007-12-09
22
+ */
23
+
24
+// matrix size functions
25
+// #include "ublas_dims.h"
26
+//#include "mtl4_dims.h"
27
+
28
+// system includes
29
+#include <assert.h>
30
+#include <string>
31
+#include <cmath>
32
+
33
+// vtk includes used by templates
34
+#include "vtkFloatArray.h"
35
+#include "vtkPointData.h"
36
+#include "vtkPoints.h"
37
+#include "vtkRectilinearGrid.h"
38
+#include "vtkRenderer.h"
39
+#include "vtkStructuredGrid.h"
40
+#include "vtkXYPlotActor.h"
41
+
42
+namespace matplot {
43
+
44
+	enum SCALE {LINEAR, LOG10};
45
+
46
+    void render_interactive(vtkRenderer *rend, int xPix, int yPix);
47
+
48
+	void render_interactive_camera(vtkRenderer *rend, int xPix, int yPix,
49
+					vtkCamera* mycam);
50
+
51
+    void render_interactive_cam(vtkRenderer *rend, int xPix, int yPix,
52
+				double cam[3], double focal[3]);
53
+
54
+    void render_to_png(vtkRenderer *rend, int xPix, int yPix,std::string fname);
55
+
56
+    void render_to_png_cam(vtkRenderer *rend, int xPix, int yPix,
57
+			   std::string fname, double cam[3], double focal[3]);
58
+
59
+    /** Plot vectors x versus y.
60
+     * Inspired by "plot" in Matlab.
61
+     *
62
+     * Notes:
63
+     *
64
+     * Call plot(x,y,<...>) multiple times before show() to
65
+     * get multiple curves in one figure.
66
+     *
67
+     * \author Dag Lindbo
68
+     */
69
+    class Plot2D_VTK {
70
+
71
+		public:
72
+
73
+			Plot2D_VTK(std::string x_label="x", std::string y_label="y",
74
+			   int xpix = 800, int ypix = 600, bool semilogx=false );
75
+			~Plot2D_VTK();
76
+
77
+			/** Insert curve x vs.\ y into plot.
78
+			 * - Default color is blue, {0 , 0, 1}.
79
+			 * - Default line style is solid line, "-".
80
+			 */
81
+			template<typename Vec_t>
82
+			void plot(const Vec_t &x, const Vec_t &y) {
83
+		    	double color[3] = { 0, 0, 1.0 };
84
+		    	plot(x, y, color, "-");
85
+			}
86
+
87
+			/** Insert curve x vs.\ y into plot (specify color and line style).
88
+			 * Color specification:
89
+			 * 		- RGB (normalized decimal), {0.32, 0.1, 0.0}
90
+			 *
91
+			 * Line style specification:
92
+			 * 		-	"-" 			solid line
93
+			 * 		-	"." 			dotted line
94
+			 * 		-	".-" or "-." 	solid line with dots
95
+			 */
96
+			template<typename Vec_t>
97
+			void plot(const Vec_t &x, const Vec_t &y, const double col[3],
98
+			  const std::string linespec) {
99
+
100
+				int i, N = x.size(), plot_points = 0, plot_lines = 0;
101
+
102
+			    vtkRectilinearGrid *curve;
103
+			    vtkFloatArray *yVal;
104
+			    vtkFloatArray *xVal;
105
+
106
+			    // determine line style
107
+			    if (linespec == "-")
108
+					plot_lines = 1;
109
+			    else if (linespec == ".")
110
+					plot_points = 1;
111
+			    else if (linespec == ".-" || linespec == "-.") {
112
+					plot_points = 1;
113
+					plot_lines = 1;
114
+			    }
115
+
116
+			    // put (x,y) into VTK FloatArrays
117
+			    xVal = vtkFloatArray::New();
118
+			    yVal = vtkFloatArray::New();
119
+
120
+			    for (i=0; i<N; i++) {
121
+					xVal->InsertNextTuple1(x[i]);
122
+					yVal->InsertNextTuple1(y[i]);
123
+			    }
124
+
125
+			    // Make a VTK Rectlinear grid from arrays
126
+			    curve = vtkRectilinearGrid::New();
127
+			    curve->SetDimensions(N, 1, 1);
128
+			    curve->SetXCoordinates(xVal);
129
+			    curve->GetPointData()->SetScalars(yVal);
130
+
131
+			    // attach gridfunction to plot
132
+			    xyplot->AddDataSetInput(curve);
133
+
134
+                if (semilogx) {
135
+                    xyplot->LogxOn();
136
+                }
137
+                // VTK doesn't have this? :(
138
+                //xyplot->LogyOn();
139
+
140
+			    // how to read data
141
+			    xyplot->SetXValuesToValue();
142
+
143
+			    // set attributes
144
+			    xyplot->SetPlotColor(plot_no, col[0], col[1], col[2]);
145
+			    xyplot->SetPlotLines(plot_no, plot_lines);
146
+			    xyplot->SetPlotPoints(plot_no, plot_points);
147
+
148
+			    plot_no++;
149
+
150
+			    xVal->Delete();
151
+			    yVal->Delete();
152
+			    curve->Delete();
153
+			}
154
+
155
+			void show();
156
+			void draw_to_png(std::string filename);
157
+
158
+    	private:
159
+
160
+			int xPix;
161
+			int yPix;
162
+            bool semilogx;
163
+			int plot_no;
164
+
165
+
166
+			vtkRenderer* rend;
167
+			vtkXYPlotActor* xyplot;
168
+    };
169
+
170
+    /** Plot z = f(x,y) surface.
171
+     * Inspired by "surf" in Matlab
172
+     *
173
+     * \author Dag Lindbo
174
+     */
175
+    class Surf_VTK
176
+    {
177
+    public:
178
+
179
+	Surf_VTK(int px = 800, int py = 600);
180
+	~Surf_VTK();
181
+
182
+	/** Create surface plot.
183
+	 * Matrix z, with respect to vectors x and y.
184
+	 */
185
+	template<typename Vec_t, typename Mat_t>
186
+	void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z)
187
+	{
188
+	    geometry(x, y, z);
189
+	    renderer(false, true, true, false);
190
+	    render_interactive(rend, xPix, yPix);
191
+	}
192
+
193
+	/** Create surface plot.
194
+	 * Matrix z, with respect to vectors x and y.
195
+	 *
196
+	 * Warp z-axis to produce better fit:
197
+	 * - do_warp = true
198
+	 */
199
+	template<typename Vec_t, typename Mat_t>
200
+	void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z, bool do_warp)
201
+	{
202
+	    geometry(x, y, z);
203
+	    renderer(false, true, true, do_warp);
204
+	    render_interactive(rend, xPix, yPix);
205
+	}
206
+
207
+	/** Create surface plot.
208
+	 * Matrix z, with respect to vectors x and y.
209
+	 *
210
+	 * Warp z-axis to produce better fit:
211
+	 * - do_warp = true
212
+	 *
213
+	 * Camera control:
214
+	 * - specify camera position: cam = { -15.0, 10.0, 12.0 }
215
+	 * - specify focal point: focal = { 0, 0, 0 }
216
+	 */
217
+	template<typename Vec_t, typename Mat_t>
218
+	void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z, bool do_warp,
219
+		  double observer[3], double focal[3])
220
+	{
221
+	    geometry(x, y, z);
222
+	    renderer(false, true, true, do_warp);
223
+	    render_interactive_cam(rend, xPix, yPix, observer, focal);
224
+	}
225
+
226
+	/** Create surface plot and render to file
227
+	 * Matrix z, with respect to vectors x and y.
228
+	 *
229
+	 * Warp z-axis to produce better fit:
230
+	 * - do_warp = true
231
+	 *
232
+	 * Camera control:
233
+	 * - specify camera position: cam = { -15.0, 10.0, 12.0 }
234
+	 * - specify focal point: focal = { 0, 0, 0 }
235
+	 */
236
+	template<typename Vec_t, typename Mat_t>
237
+	void surf_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &z,
238
+			  bool do_warp, std::string fname, double observer[3],
239
+			  double focal[3])
240
+	{
241
+	    geometry(x, y, z);
242
+	    renderer(false, true, true, do_warp);
243
+	    render_to_png_cam(rend, xPix, yPix, fname, observer, focal);
244
+	}
245
+
246
+	void purge();
247
+
248
+    private:
249
+	vtkStructuredGrid *gridfunc;
250
+	vtkRenderer *rend;
251
+
252
+	double Lxy, Lz;
253
+	bool has_data;
254
+
255
+	int xPix, yPix;
256
+
257
+	template<typename Vec_t, typename Mat_t>
258
+	void geometry(const Vec_t &x, const Vec_t &y, const Mat_t &z)
259
+	{
260
+	    const unsigned int Nx = x.size(); //vec_dim(x);
261
+	    const unsigned int Ny = y.size(); //vec_dim(y);
262
+	    unsigned int i, j, k;
263
+
264
+	    // make sure the input is ok and that this surfaceplot is free
265
+	    assert(Nx == z.rows() );
266
+	    assert(Ny == z.cols() );
267
+	    assert(!has_data);
268
+
269
+	    // determine x-y range of data
270
+	    if (x(Nx-1)-x(0) > y(Ny-1)-y(0))
271
+		Lxy = x(Nx-1)-x(0);
272
+	    else
273
+		Lxy = y(Ny-1)-y(0);
274
+	    double z_low = 10000, z_upp = -10000;
275
+
276
+	    // put data, z, into a 2D structured grid
277
+	    gridfunc->SetDimensions(Nx, Ny, 1);
278
+
279
+	    vtkPoints *points = vtkPoints::New();
280
+	    for (j = 0; j < Ny; j++)
281
+	    {
282
+		for (i = 0; i < Nx; i++)
283
+		{
284
+		    points->InsertNextPoint(x(i), y(j), z(i, j));
285
+
286
+		    if (z(i, j)< z_low)
287
+			z_low = z(i, j);
288
+		    if (z(i, j)> z_upp)
289
+			z_upp = z(i, j);
290
+		}
291
+	    }
292
+	    gridfunc->SetPoints(points);
293
+
294
+	    // get scalar field from z-values
295
+	    vtkFloatArray *colors = vtkFloatArray::New();
296
+	    colors->SetNumberOfComponents(1);
297
+	    colors->SetNumberOfTuples(Nx*Ny);
298
+	    k = 0;
299
+	    for (j = 0; j < Ny; j++)
300
+		for (i = 0; i < Nx; i++)
301
+		{
302
+		    colors->InsertComponent(k, 0, z(i, j));
303
+		    k++;
304
+		}
305
+
306
+	    gridfunc->GetPointData()->SetScalars(colors);
307
+
308
+	    points->Delete();
309
+	    colors->Delete();
310
+
311
+	    has_data = true;
312
+	    Lz = z_upp-z_low;
313
+	}
314
+
315
+	void renderer(bool, bool, bool, bool);
316
+
317
+    };
318
+
319
+    /** Plot contour lines for a function in the plane.
320
+     * Inspired by "contour" in Matlab
321
+     *
322
+     * \author Dag Lindbo
323
+     */
324
+
325
+	class Contour_VTK {
326
+
327
+		public:
328
+
329
+			Contour_VTK(int px = 800, int py = 600);
330
+
331
+			// specify linear or log on bars
332
+			Contour_VTK(int px = 800, int py = 600, SCALE xscale=LINEAR, SCALE
333
+							yscale=LINEAR);
334
+
335
+			~Contour_VTK();
336
+
337
+			/** Create contour plot.
338
+			 * Matrix z vs. vectors x and y.
339
+			 * Produces a default number of contour lines (10) and
340
+			 * colors the lines instead of the underlying surface.
341
+			 */
342
+			template<typename Vec_t, typename Mat_t>
343
+			void contour(const Vec_t &x, const Vec_t &y, const Mat_t &z) {
344
+				geometry(x, y, z);
345
+				renderer(true, false, 10);
346
+				render_interactive(rend, xPix, yPix);
347
+			}
348
+
349
+			/**Create contour plot.
350
+			 * Matrix z vs. vectors x and y.
351
+			 *
352
+			 * Number of contour lines:
353
+			 * - num_lines
354
+			 *
355
+			 * Coloring:
356
+			 * - draw_surf = false: color contour lines and omits underlying surface
357
+			 * - draw_surf = true:  draw contour lines white and color the
358
+			 *                      underlying surface
359
+			 */
360
+			template<typename Vec_t, typename Mat_t>
361
+			void contour(const Vec_t &x, const Vec_t &y, const Mat_t &z,
362
+				     bool draw_surf, int num_lines) {
363
+			    geometry(x, y, z);
364
+			    renderer(true, draw_surf, num_lines);
365
+			    render_interactive(rend, xPix, yPix);
366
+			}
367
+
368
+			/**Create contour plot and render to file.
369
+			 * Matrix z vs. vectors x and y.
370
+			 *
371
+			 * Number of contour lines:
372
+			 * - num_lines
373
+			 *
374
+			 * Coloring:
375
+			 * - draw_surf = false: color contour lines and omits underlying surface
376
+			 * - draw_surf = true:  draw contour lines white and color the
377
+			 *                      underlying surface
378
+			 */
379
+
380
+			template<typename Vec_t, typename Mat_t>
381
+			void contour_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &z,
382
+				     bool draw_surf, int num_lines, std::string fname)
383
+			{
384
+			    geometry(x, y, z);
385
+			    renderer(true, draw_surf, num_lines);
386
+			    render_to_png(rend, xPix, yPix, fname);
387
+			}
388
+
389
+			void purge();
390
+
391
+			void SetXLabel(const std::string &xlab);
392
+			void SetYLabel(const std::string &ylab);
393
+
394
+		private:
395
+
396
+			SCALE XScale;
397
+			SCALE YScale;
398
+
399
+			vtkRectilinearGrid *gridfunc;
400
+			vtkRenderer *rend;
401
+
402
+			bool has_data;
403
+
404
+			int xPix, yPix;
405
+			double axscale;
406
+			double ymin;
407
+			double ymax;
408
+			std::string xlabel;
409
+			std::string ylabel;
410
+
411
+			template<typename Vec_t, typename Mat_t>
412
+
413
+			void geometry(const Vec_t &x, const Vec_t &y, const Mat_t &z) {
414
+
415
+		    	const unsigned int Nx = x.size();
416
+			    const unsigned int Ny = y.size();
417
+			    unsigned int i, j, k;
418
+
419
+			    // make sure the input is ok and that this contourplot is free
420
+	    		assert(Nx == z.rows() );
421
+	  	 	 	assert(Ny == z.cols() );
422
+	    		assert(!has_data);
423
+
424
+			    // x and y vectors go into vtkFloatArray
425
+			    vtkFloatArray *xcoord = vtkFloatArray::New();
426
+			    xcoord->SetNumberOfComponents(1);
427
+			    xcoord->SetNumberOfTuples(Nx);
428
+			    vtkFloatArray *ycoord = vtkFloatArray::New();
429
+			    ycoord->SetNumberOfComponents(1);
430
+			    ycoord->SetNumberOfTuples(Ny);
431
+
432
+				// We want the two axis to be equal, not squashed
433
+				// normalize axis ratio
434
+				axscale = 1.;
435
+				ymin = y.minCoeff();
436
+				ymax = y.maxCoeff();
437
+
438
+				if (YScale == LINEAR && XScale == LINEAR)
439
+					axscale =  (x.maxCoeff() - x.minCoeff()) /
440
+					           (y.maxCoeff() - y.minCoeff()) ;
441
+
442
+				if (YScale == LOG10 && XScale == LINEAR)
443
+					axscale = (           x.maxCoeff() -             x.minCoeff() ) /
444
+						      (std::log10(y.maxCoeff()) - std::log10(y.minCoeff())) ;
445
+
446
+				if (YScale == LOG10 && XScale == LOG10)
447
+					axscale =   ( (std::log10(x.maxCoeff()) - std::log10(x.minCoeff())) /
448
+						          (std::log10(y.maxCoeff()) - std::log10(y.minCoeff())) );
449
+
450
+				if (YScale == LINEAR && XScale == LOG10)
451
+					axscale =     (std::log10(x.maxCoeff()) - std::log10(x.minCoeff())) /
452
+						     (                y.maxCoeff()  -            y.minCoeff() ) ;
453
+
454
+				if (XScale == LINEAR) {
455
+			    	for (i=0; i<Nx; i++)
456
+						xcoord->InsertComponent(i, 0, x(i));
457
+				} else {
458
+			    	for (i=0; i<Nx; i++)
459
+						xcoord->InsertComponent(i, 0, std::log10(x(i)));
460
+				}
461
+
462
+				if (YScale == LINEAR) {
463
+			    	for (i=0; i<Ny; i++)
464
+						ycoord->InsertComponent(i, 0, axscale*y(i));
465
+				} else {
466
+			    	for (i=0; i<Ny; i++)
467
+						ycoord->InsertComponent(i, 0, axscale*std::log10(y(i)));
468
+				}
469
+
470
+
471
+			    // Create rectilinear grid
472
+			    gridfunc->SetDimensions(Nx, Ny, 1);
473
+			    gridfunc->SetXCoordinates(xcoord);
474
+			    gridfunc->SetYCoordinates(ycoord);
475
+
476
+			    // add z-values as scalars to grid
477
+			    vtkFloatArray *colors = vtkFloatArray::New();
478
+			    colors->SetNumberOfComponents(1);
479
+			    colors->SetNumberOfTuples(Nx*Ny);
480
+			    k = 0;
481
+			    for (j = 0; j < Ny; j++)
482
+				for (i = 0; i < Nx; i++) {
483
+			    	colors->InsertComponent(k, 0, z(i, j));
484
+			    	k++;
485
+				}
486
+
487
+		    	gridfunc->GetPointData()->SetScalars(colors);
488
+
489
+		    	colors->Delete();
490
+			    xcoord->Delete();
491
+			    ycoord->Delete();
492
+
493
+			    has_data = true;
494
+			}
495
+
496
+			void renderer(bool, bool, int);
497
+    };
498
+
499
+    /** Plot vector-valued function in the plane.
500
+     * Inspired by "quiver" in Matlab
501
+     *
502
+     * \author Dag Lindbo
503
+     */
504
+    class Quiver_VTK
505
+    {
506
+    public:
507
+
508
+	Quiver_VTK(int px = 800, int py = 600);
509
+	~Quiver_VTK();
510
+
511
+	/** Create vector arrow plot (quiver).
512
+	 * Pointwise vecotrs in matrices u and v, at grid
513
+	 * points given by vectors x and y. Color by magnitude.
514
+	 * Defaults to no scaling of arrow lengths.
515
+	 */
516
+	template<typename Vec_t, typename Mat_t>
517
+	void quiver(const Vec_t &x, const Vec_t &y, const Mat_t &u,
518
+		    const Mat_t &v)
519
+	{
520
+	    geometry(x, y, u, v);
521
+	    renderer(1.0);
522
+	    render_interactive(rend, xPix, yPix);
523
+	}
524
+
525
+	/** Create vector arrow plot (quiver).
526
+	 * Pointwise vectors in matrices u and v, at grid
527
+	 * points given by vectors x and y. Color by magnitude.
528
+	 *
529
+	 * Scales arrows by a factor s.
530
+	 */
531
+	template<typename Vec_t, typename Mat_t>
532
+	void quiver(const Vec_t &x, const Vec_t &y, const Mat_t &u,
533
+		    const Mat_t &v, double s)
534
+	{
535
+	    geometry(x, y, u, v);
536
+	    renderer(s);
537
+	    render_interactive(rend, xPix, yPix);
538
+	}
539
+
540
+	/** Create vector arrow plot (quiver) and render to file.
541
+	 * Pointwise vectors in matrices u and v, at grid
542
+	 * points given by vectors x and y. Color by magnitude
543
+	 *
544
+	 * Scales arrows by a factor s.
545
+	 */
546
+	template<typename Vec_t, typename Mat_t>
547
+	void quiver_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &u,
548
+			    const Mat_t &v, double s, std::string filename)
549
+	{
550
+	    geometry(x, y, u, v);
551
+	    renderer(s);
552
+	    render_to_png(rend, xPix, yPix, filename);
553
+	}
554
+
555
+	void purge();
556
+
557
+    private:
558
+	vtkRectilinearGrid *gridfunc;
559
+	vtkRenderer *rend;
560
+
561
+	bool has_data;
562
+
563
+	int xPix, yPix;
564
+
565
+	template<typename Vec_t, typename Mat_t>
566
+	void geometry(const Vec_t& x, const Vec_t& y, const Mat_t& u,
567
+		      const Mat_t& v)
568
+	{
569
+	    const unsigned int Nx = x.size(); //vec_dim(x);
570
+	    const unsigned int Ny = y.size(); //vec_dim(y);
571
+	    unsigned int i, j, k;
572
+
573
+	    // make sure the input is ok and that this contourplot is free
574
+	    assert(Nx == u.rows());
575
+	    assert(Ny == u.cols());
576
+	    assert(Nx == v.rows());
577
+	    assert(Ny == v.cols());
578
+	    assert(!has_data);
579
+
580
+	    // x and y vectors go into vtkFloatArray
581
+	    vtkFloatArray *xcoord = vtkFloatArray::New();
582
+	    xcoord->SetNumberOfComponents(1);
583
+	    xcoord->SetNumberOfTuples(Nx);
584
+	    vtkFloatArray *ycoord = vtkFloatArray::New();
585
+	    ycoord->SetNumberOfComponents(1);
586
+	    ycoord->SetNumberOfTuples(Ny);
587
+
588
+	    for (i=0; i<Nx; i++)
589
+		xcoord->InsertComponent(i, 0, x(i));
590
+	    for (i=0; i<Ny; i++)
591
+		ycoord->InsertComponent(i, 0, y(i));
592
+
593
+	    // Create rectilinear grid
594
+	    gridfunc->SetDimensions(Nx, Ny, 1);
595
+	    gridfunc->SetXCoordinates(xcoord);
596
+	    gridfunc->SetYCoordinates(ycoord);
597
+
598
+	    // add magnitude of (u,v) as scalars to grid
599
+	    vtkFloatArray *colors = vtkFloatArray::New();
600
+	    colors->SetNumberOfComponents(1);
601
+	    colors->SetNumberOfTuples(Nx*Ny);
602
+
603
+	    // add vector (u,v) to grid
604
+	    vtkFloatArray *vectors = vtkFloatArray::New();
605
+	    vectors->SetNumberOfComponents(3);
606
+	    vectors->SetNumberOfTuples(Nx*Ny);
607
+
608
+	    k = 0;
609
+	    for (j = 0; j < Ny; j++)
610
+		for (i = 0; i < Nx; i++)
611
+		{
612
+		    colors->InsertTuple1(k,sqrt(u(i,j)*u(i,j)+v(i,j)*v(i,j)));
613
+		    vectors->InsertTuple3(k, u(i, j), v(i, j), 0.0);
614
+		    k++;
615
+		}
616
+
617
+	    gridfunc->GetPointData()->SetScalars(colors);
618
+	    gridfunc->GetPointData()->SetVectors(vectors);
619
+
620
+	    vectors->Delete();
621
+	    colors->Delete();
622
+	    xcoord->Delete();
623
+	    ycoord->Delete();
624
+
625
+	    has_data = true;
626
+	}
627
+
628
+	void renderer(double);
629
+
630
+    };
631
+
632
+}
633
+
634
+#endif

Loading…
Cancel
Save