1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: TestOSPRayRenderMesh.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 // This test verifies that we can do simple mesh rendering with ospray
16 // and that VTK's many standard rendering modes (points, lines, surface, with
17 // a variety of color controls (actor, point, cell, texture) etc work as
18 // they should.
19 //
20 // The command line arguments are:
21 // -I => run in interactive mode; unless this is used, the program will
22 // not allow interaction and exit.
23 // In interactive mode it responds to the keys listed
24 // vtkOSPRayTestInteractor.h
25 // -GL => users OpenGL instead of OSPRay to render
26 // -type N => where N is one of 0,1,2, or 3 makes meshes consisting of
27 // points, wireframes, triangles (=the default) or triangle strips
28 // -rep N => where N is one of 0,1 or 2 draws the meshes as points, lines
29 // or surfaces
30
31 #include "vtkActor.h"
32 #include "vtkActorCollection.h"
33 #include "vtkCamera.h"
34 #include "vtkCellData.h"
35 #include "vtkDoubleArray.h"
36 #include "vtkExtractEdges.h"
37 #include "vtkImageData.h"
38 #include "vtkInformation.h"
39 #include "vtkLight.h"
40 #include "vtkLightCollection.h"
41 #include "vtkOpenGLRenderer.h"
42 #include "vtkOSPRayActorNode.h"
43 #include "vtkOSPRayPass.h"
44 #include "vtkPiecewiseFunction.h"
45 #include "vtkPointData.h"
46 #include "vtkPolyData.h"
47 #include "vtkPolyDataMapper.h"
48 #include "vtkPolyDataNormals.h"
49 #include "vtkProperty.h"
50 #include "vtkRenderer.h"
51 #include "vtkRenderWindow.h"
52 #include "vtkRenderWindowInteractor.h"
53 #include "vtkSmartPointer.h"
54 #include "vtkSphereSource.h"
55 #include "vtkStripper.h"
56 #include "vtkTexture.h"
57 #include "vtkTextureMapToSphere.h"
58 #include "vtkTransformTextureCoords.h"
59 #include "vtkUnsignedCharArray.h"
60 #include "vtkVertexGlyphFilter.h"
61
62 #include <vector>
63 #include <string>
64
65 #include "vtkOSPRayTestInteractor.h"
66
67 class renderable
68 {
69 public:
70 vtkSphereSource *s;
71 vtkPolyDataMapper *m;
72 vtkActor *a;
~renderable()73 ~renderable()
74 {
75 s->Delete();
76 m->Delete();
77 a->Delete();
78 }
79 };
80
MakeSphereAt(double x,double y,double z,int res,int type,int rep,const char * name)81 renderable *MakeSphereAt(double x, double y, double z, int res,
82 int type, int rep, const char *name)
83 {
84 vtkOSPRayTestInteractor::AddName(name);
85 renderable *ret = new renderable;
86 ret->s = vtkSphereSource::New();
87 ret->s->SetEndTheta(180); //half spheres better show variation and f and back
88 ret->s->SetStartPhi(30);
89 ret->s->SetEndPhi(150);
90 ret->s->SetPhiResolution(res);
91 ret->s->SetThetaResolution(res);
92 ret->s->SetCenter(x,y,z);
93 //make texture coordinate
94 vtkSmartPointer<vtkTextureMapToSphere> tc =
95 vtkSmartPointer<vtkTextureMapToSphere>::New();
96 tc->SetCenter(x,y,z);
97 tc->PreventSeamOn();
98 tc->AutomaticSphereGenerationOff();
99 tc->SetInputConnection(ret->s->GetOutputPort());
100 vtkSmartPointer<vtkTransformTextureCoords> tt =
101 vtkSmartPointer<vtkTransformTextureCoords>::New();
102 tt->SetInputConnection(tc->GetOutputPort());
103 //tt->SetScale(1,0.5,1);
104 //make normals
105 vtkSmartPointer<vtkPolyDataNormals> nl =
106 vtkSmartPointer<vtkPolyDataNormals>::New();
107 nl->SetInputConnection(tt->GetOutputPort());
108 nl->Update();
109 //make more attribute arrays
110 vtkPolyData *pd = nl->GetOutput();
111 //point aligned
112 vtkSmartPointer<vtkDoubleArray> da = vtkSmartPointer<vtkDoubleArray>::New();
113 da->SetName("testarray1");
114 da->SetNumberOfComponents(1);
115 pd->GetPointData()->AddArray(da);
116 int np = pd->GetNumberOfPoints();
117 int nc = pd->GetNumberOfCells();
118 for (int i = 0; i < np; i++)
119 {
120 da->InsertNextValue((double)i/(double)np);
121 }
122 da = vtkSmartPointer<vtkDoubleArray>::New();
123 da->SetName("testarray2");
124 da->SetNumberOfComponents(3);
125 pd->GetPointData()->AddArray(da);
126 for (int i = 0; i < np; i++)
127 {
128 double vals[3] = {(double)i/(double)np, (double)(i*4)/(double)np-2.0, 42.0};
129 da->InsertNextTuple3(vals[0],vals[1],vals[2]);
130 }
131
132 vtkSmartPointer<vtkUnsignedCharArray> pac =
133 vtkSmartPointer<vtkUnsignedCharArray>::New();
134 pac->SetName("testarrayc1");
135 pac->SetNumberOfComponents(3);
136 pd->GetPointData()->AddArray(pac);
137 for (int i = 0; i < np; i++)
138 {
139 unsigned char vals[3] =
140 {static_cast<unsigned char>(255*((double)i/(double)np)),
141 static_cast<unsigned char>(255*((double)(i*4)/(double)np-2.0)),
142 42};
143 pac->InsertNextTuple3(vals[0],vals[1],vals[2]);
144 }
145
146 vtkSmartPointer<vtkUnsignedCharArray> ca =
147 vtkSmartPointer<vtkUnsignedCharArray>::New();
148 ca->SetName("testarray3");
149 ca->SetNumberOfComponents(3);
150 pd->GetPointData()->AddArray(ca);
151 for (int i = 0; i < np; i++)
152 {
153 unsigned char vals[3] =
154 {static_cast<unsigned char>((double)i/(double)np*255),
155 static_cast<unsigned char>((double)(1-i)/(double)np),
156 42};
157 ca->InsertNextTuple3(vals[0],vals[1],vals[2]);
158 }
159 //cell aligned
160 da = vtkSmartPointer<vtkDoubleArray>::New();
161 da->SetName("testarray4");
162 da->SetNumberOfComponents(1);
163 pd->GetCellData()->AddArray(da);
164 for (int i = 0; i < pd->GetNumberOfCells(); i++)
165 {
166 da->InsertNextValue((double)i/(double)pd->GetNumberOfCells());
167 }
168 da = vtkSmartPointer<vtkDoubleArray>::New();
169 da->SetName("testarray5");
170 da->SetNumberOfComponents(3);
171 pd->GetCellData()->AddArray(da);
172 for (int i = 0; i < nc; i++)
173 {
174 double vals[3] = {(double)i/(double)nc, (double)(i*2)/(double)nc, 42.0};
175 da->InsertNextTuple3(vals[0],vals[1],vals[2]);
176 }
177 ca = vtkSmartPointer<vtkUnsignedCharArray>::New();
178 ca->SetName("testarray6");
179 ca->SetNumberOfComponents(3);
180 pd->GetCellData()->AddArray(ca);
181 for (int i = 0; i < nc; i++)
182 {
183 unsigned char vals[3] =
184 {static_cast<unsigned char>((double)i/(double)np*255),
185 static_cast<unsigned char>((double)(1-i)/(double)np),
186 42};
187 ca->InsertNextTuple3(vals[0],vals[1],vals[2]);
188 }
189 ret->m = vtkPolyDataMapper::New();
190 ret->m->SetInputData(pd);
191
192 switch (type)
193 {
194 case 0: //points
195 {
196 vtkSmartPointer<vtkVertexGlyphFilter> filter =
197 vtkSmartPointer<vtkVertexGlyphFilter>::New();
198 filter->SetInputData(pd);
199 filter->Update();
200 ret->m->SetInputData(filter->GetOutput());
201 break;
202 }
203 case 1: //lines
204 {
205 vtkSmartPointer<vtkExtractEdges> filter =
206 vtkSmartPointer<vtkExtractEdges>::New();
207 filter->SetInputData(pd);
208 filter->Update();
209 ret->m->SetInputData(filter->GetOutput());
210 break;
211 }
212 case 2: //polys
213 break;
214 case 3: //strips
215 {
216 vtkSmartPointer<vtkStripper> filter =
217 vtkSmartPointer<vtkStripper>::New();
218 filter->SetInputData(pd);
219 filter->Update();
220 ret->m->SetInputData(filter->GetOutput());
221 break;
222 }
223 }
224 ret->a=vtkActor::New();
225 ret->a->SetMapper(ret->m);
226 ret->a->GetProperty()->SetPointSize(20);
227 ret->a->GetProperty()->SetLineWidth(10);
228 if (rep != -1)
229 {
230 ret->a->GetProperty()->SetRepresentation(rep);
231 }
232 return ret;
233 }
234
TestOSPRayRenderMesh(int argc,char * argv[])235 int TestOSPRayRenderMesh(int argc, char* argv[])
236 {
237 bool useGL = false;
238 int type = 2;
239 int rep = -1;
240 for (int i = 0; i < argc; i++)
241 {
242 if (!strcmp(argv[i], "-GL"))
243 {
244 useGL = true;
245 }
246 if (!strcmp(argv[i], "-type"))
247 {
248 type = atoi(argv[i+1]);
249 }
250 if (!strcmp(argv[i], "-rep"))
251 {
252 rep = atoi(argv[i+1]);
253 }
254 }
255
256 vtkSmartPointer<vtkRenderWindowInteractor> iren =
257 vtkSmartPointer<vtkRenderWindowInteractor>::New();
258 vtkSmartPointer<vtkRenderWindow> renWin =
259 vtkSmartPointer<vtkRenderWindow>::New();
260 iren->SetRenderWindow(renWin);
261 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
262 renWin->AddRenderer(renderer);
263 renderer->AutomaticLightCreationOn();
264 renderer->SetBackground(0.75,0.75,0.75);
265 renWin->SetSize(600,550);
266 vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
267 camera->SetPosition(2.5,11,-3);
268 camera->SetFocalPoint(2.5,0,-3);
269 camera->SetViewUp(0,0,1);
270 renderer->SetActiveCamera(camera);
271 renWin->Render();
272
273 vtkSmartPointer<vtkOSPRayPass> ospray = vtkSmartPointer<vtkOSPRayPass>::New();
274 if (!useGL)
275 {
276 renderer->SetPass(ospray);
277 }
278 //Now, vary most of the many parameters that rendering can vary by.
279
280 //representations points, wireframe, surface
281 renderable *ren = MakeSphereAt(5,0,-5, 10, type, rep, "points");
282 ren->a->GetProperty()->SetRepresentationToPoints();
283 renderer->AddActor(ren->a);
284 delete(ren);
285
286 ren = MakeSphereAt(5,0,-4, 10, type, rep, "wireframe");
287 ren->a->GetProperty()->SetRepresentationToWireframe();
288 renderer->AddActor(ren->a);
289 delete(ren);
290
291 ren = MakeSphereAt(5,0,-3, 10, type, rep, "surface");
292 ren->a->GetProperty()->SetRepresentationToSurface();
293 renderer->AddActor(ren->a);
294 delete(ren);
295
296 //actor color
297 ren = MakeSphereAt(4,0,-5, 10, type, rep, "actor_color");
298 ren->a->GetProperty()->SetColor(0,1,0);
299 renderer->AddActor(ren->a);
300 delete(ren);
301
302 //ambient, diffuse, and specular components
303 ren = MakeSphereAt(4,0,-4, 7, type, rep, "amb/diff/spec");
304 ren->a->GetProperty()->SetAmbient(0.5);
305 ren->a->GetProperty()->SetAmbientColor(0.1,0.1,0.3);
306 ren->a->GetProperty()->SetDiffuse(0.4);
307 ren->a->GetProperty()->SetDiffuseColor(0.5,0.1,0.1);
308 ren->a->GetProperty()->SetSpecular(0.2);
309 ren->a->GetProperty()->SetSpecularColor(1,1,1);
310 ren->a->GetProperty()->SetSpecularPower(100);
311 ren->a->GetProperty()->SetInterpolationToPhong();
312 renderer->AddActor(ren->a);
313 delete(ren);
314
315 //opacity
316 ren = MakeSphereAt(4,0,-3, 10, type, rep, "opacity");
317 ren->a->GetProperty()->SetOpacity(0.2);
318 renderer->AddActor(ren->a);
319 delete(ren);
320
321 //color map cell values
322 ren = MakeSphereAt(3,0,-5, 10, type, rep, "cell_value");
323 ren->m->SetScalarModeToUseCellFieldData();
324 ren->m->SelectColorArray(0);
325 renderer->AddActor(ren->a);
326 delete(ren);
327
328 //default color component
329 ren = MakeSphereAt(3,0,-4, 10, type, rep, "cell_default_comp");
330 ren->m->SetScalarModeToUseCellFieldData();
331 ren->m->SelectColorArray(1);
332 renderer->AddActor(ren->a);
333 delete(ren);
334
335 //choose color component
336 ren = MakeSphereAt(3,0,-3, 10, type, rep, "cell_comp_1");
337 ren->m->SetScalarModeToUseCellFieldData();
338 ren->m->SelectColorArray(1);
339 ren->m->ColorByArrayComponent(1,1); //todo, use lut since this is deprecated
340 renderer->AddActor(ren->a);
341 delete(ren);
342
343 //RGB direct
344 ren = MakeSphereAt(3,0,-2, 10, type, rep, "cell_rgb");
345 ren->m->SetScalarModeToUseCellFieldData();
346 ren->m->SelectColorArray(2);
347 renderer->AddActor(ren->a);
348 delete(ren);
349
350 //RGB through LUT
351 ren = MakeSphereAt(3,0,-1, 10, type, rep, "cell_rgb_through_LUT");
352 ren->m->SetScalarModeToUseCellFieldData();
353 ren->m->SelectColorArray(2);
354 ren->m->SetColorModeToMapScalars();
355 renderer->AddActor(ren->a);
356 delete(ren);
357
358 //color map point values
359 ren = MakeSphereAt(2,0,-5,6, type, rep, "point_value");
360 ren->m->SetScalarModeToUsePointFieldData();
361 ren->m->SelectColorArray("testarray1");
362 renderer->AddActor(ren->a);
363 delete(ren);
364
365 //interpolate scalars before mapping
366 ren = MakeSphereAt(2,0,-4,6, type, rep, "point_interp");
367 ren->m->SetScalarModeToUsePointFieldData();
368 ren->m->SelectColorArray("testarray1");
369 ren->m->InterpolateScalarsBeforeMappingOn();
370 renderer->AddActor(ren->a);
371 delete(ren);
372
373 //RGB direct
374 ren = MakeSphereAt(2,0,-3, 10, type, rep, "point_rgb");
375 ren->m->SetScalarModeToUsePointFieldData();
376 ren->m->SetColorModeToDefault();
377 ren->m->SelectColorArray("testarrayc1");
378 renderer->AddActor(ren->a);
379 delete(ren);
380
381 //RGB mapped
382 ren = MakeSphereAt(2,0,-2, 10, type, rep, "point_rgb_through_LUT");
383 ren->m->SetScalarModeToUsePointFieldData();
384 ren->m->SetColorModeToMapScalars();
385 ren->m->SelectColorArray("testarrayc1");
386 renderer->AddActor(ren->a);
387 delete(ren);
388
389 //unlit, flat, and gouraud lighting
390 ren = MakeSphereAt(1,0,-5,7, type, rep, "not_lit");
391 ren->a->GetProperty()->LightingOff();
392 renderer->AddActor(ren->a);
393 delete(ren);
394
395 ren = MakeSphereAt(1,0,-4,7, type, rep, "flat");
396 ren->a->GetProperty()->SetInterpolationToFlat();
397 renderer->AddActor(ren->a);
398 delete(ren);
399
400 ren = MakeSphereAt(1,0,-3,7, type, rep, "gouraud");
401 ren->a->GetProperty()->SetInterpolationToGouraud();
402 renderer->AddActor(ren->a);
403 delete(ren);
404
405 //texture
406 int maxi = 100;
407 int maxj = 100;
408 vtkSmartPointer<vtkImageData> texin = vtkSmartPointer<vtkImageData>::New();
409 texin->SetExtent(0,maxi,0,maxj,0,0);
410 texin->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
411 vtkUnsignedCharArray *aa =
412 vtkArrayDownCast<vtkUnsignedCharArray>(texin->GetPointData()->GetScalars());
413 int idx = 0;
414 for (int i = 0; i<=maxi; i++)
415 {
416 for (int j = 0; j<=maxj; j++)
417 {
418 bool ival = (i/10)%2==1;
419 bool jval = (j/10)%2==1;
420 unsigned char val = (ival^jval) ? 255 : 0;
421 aa->SetTuple3(idx, val, val, val);
422 if (j <= 3 || j >= maxj-3)
423 {
424 aa->SetTuple3(idx, 255, 255, 0);
425 }
426 if (i <= 20 || i >= maxi-20)
427 {
428 aa->SetTuple3(idx, 255, 0, 0);
429 }
430 idx = idx + 1;
431 }
432 }
433 ren = MakeSphereAt(0,0,-5,20,type, rep, "texture");
434 renderer->AddActor(ren->a);
435 vtkSmartPointer<vtkTexture> texture =
436 vtkSmartPointer<vtkTexture>::New();
437 texture->SetInputData(texin);
438 ren->a->SetTexture(texture);
439 delete(ren);
440
441 //imagespace positional transformations
442 ren = MakeSphereAt(0,0,-4,10, type, rep, "transform");
443 ren->a->SetScale(1.2,1.0,0.87);
444 renderer->AddActor(ren->a);
445 delete(ren);
446
447 //TODO: lut manipulation and range effects
448 //TODO: NaN colors
449 //TODO: mapper clipping planes
450 //TODO: hierarchical actors
451
452 renWin->Render();
453
454 vtkLight *light =
455 vtkLight::SafeDownCast(renderer->GetLights()->GetItemAsObject(0));
456 double lColor[3];
457 light->GetDiffuseColor(lColor);
458 light->SetPosition(2,15,-2);
459 light->SetFocalPoint(2,0,-2);
460 light->PositionalOff();
461
462 vtkSmartPointer<vtkOSPRayTestInteractor> style =
463 vtkSmartPointer<vtkOSPRayTestInteractor>::New();
464 style->
465 SetPipelineControlPoints(renderer, ospray, nullptr);
466 iren->SetInteractorStyle(style);
467 style->SetCurrentRenderer(renderer);
468
469 iren->Start();
470
471 return 0;
472 }
473