1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPOVExporter.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 /*=========================================================================
16
17 Program: VTK/ParaView Los Alamos National Laboratory Modules (PVLANL)
18 Module: vtkPOVExporter.cxx
19
20 Copyright (c) 2007, Los Alamos National Security, LLC
21
22 All rights reserved.
23
24 Copyright 2007. Los Alamos National Security, LLC.
25 This software was produced under U.S. Government contract DE-AC52-06NA25396
26 for Los Alamos National Laboratory (LANL), which is operated by
27 Los Alamos National Security, LLC for the U.S. Department of Energy.
28 The U.S. Government has rights to use, reproduce, and distribute this software.
29 NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY,
30 EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.
31 If software is modified to produce derivative works, such modified software
32 should be clearly marked, so as not to confuse it with the version available
33 from LANL.
34
35 Additionally, redistribution and use in source and binary forms, with or
36 without modification, are permitted provided that the following conditions
37 are met:
38 - Redistributions of source code must retain the above copyright notice,
39 this list of conditions and the following disclaimer.
40 - Redistributions in binary form must reproduce the above copyright notice,
41 this list of conditions and the following disclaimer in the documentation
42 and/or other materials provided with the distribution.
43 - Neither the name of Los Alamos National Security, LLC, Los Alamos National
44 Laboratory, LANL, the U.S. Government, nor the names of its contributors
45 may be used to endorse or promote products derived from this software
46 without specific prior written permission.
47
48 THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
49 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
50 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
52 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
55 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
56 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
57 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
58 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59
60 =========================================================================*/
61
62 #include "vtkPOVExporter.h"
63
64 #include "vtkAssemblyPath.h"
65 #include "vtkCamera.h"
66 #include "vtkCellArray.h"
67 #include "vtkCompositeDataGeometryFilter.h"
68 #include "vtkCompositeDataSet.h"
69 #include "vtkFloatArray.h"
70 #include "vtkGeometryFilter.h"
71 #include "vtkLightCollection.h"
72 #include "vtkLight.h"
73 #include "vtkMapper.h"
74 #include "vtkMatrix4x4.h"
75 #include "vtkPointData.h"
76 #include "vtkPolyData.h"
77 #include "vtkProperty.h"
78 #include "vtkRendererCollection.h"
79 #include "vtkRenderer.h"
80 #include "vtkRenderWindow.h"
81 #include "vtkSmartPointer.h"
82 #include "vtkTexture.h"
83 #include "vtkTypeTraits.h"
84 #include "vtkUnsignedCharArray.h"
85
86 #include <vtksys/ios/sstream>
87
88 #include "vtkObjectFactory.h"
89
90 vtkStandardNewMacro(vtkPOVExporter);
91
92 //Can't use printf("%d", a_vtkIdType) because vtkIdType is not always int.
93 //This internal class holds format strings vtkPOVExporter can use instead.
94 class vtkPOVInternals
95 {
96 public:
vtkPOVInternals()97 vtkPOVInternals()
98 {
99 this->CountFormat = new char[100]; //"\t\t%d,\n"
100 strcpy(this->CountFormat, "\t\t");
101 strcat(this->CountFormat, vtkTypeTraits<vtkIdType>::ParseFormat());
102 strcat(this->CountFormat, ",\n");
103
104 char *triFormat = new char[100]; //"%d, %d, %d"
105 strcpy(triFormat, vtkTypeTraits<vtkIdType>::ParseFormat());
106 strcat(triFormat, ", ");
107 strcat(triFormat, vtkTypeTraits<vtkIdType>::ParseFormat());
108 strcat(triFormat, ", ");
109 strcat(triFormat, vtkTypeTraits<vtkIdType>::ParseFormat());
110
111 this->TriangleFormat1 = new char[100]; //"\t\t<%d, %d, %d>,"
112 strcpy(this->TriangleFormat1, "\t\t<");
113 strcat(this->TriangleFormat1, triFormat);
114 strcat(this->TriangleFormat1, ">,");
115
116 this->TriangleFormat2 = new char[100]; //" %d, %d, %d,\n"
117 strcpy(this->TriangleFormat2, " ");
118 strcat(this->TriangleFormat2, triFormat);
119 strcat(this->TriangleFormat2, ",\n");
120
121 delete[] triFormat;
122 }
123
~vtkPOVInternals()124 ~vtkPOVInternals()
125 {
126 delete[] this->CountFormat;
127 delete[] this->TriangleFormat1;
128 delete[] this->TriangleFormat2;
129 }
130
131 char *CountFormat;
132 char *TriangleFormat1;
133 char *TriangleFormat2;
134 };
135
136 #define VTKPOV_CNTFMT this->Internals->CountFormat
137 #define VTKPOV_TRIFMT1 this->Internals->TriangleFormat1
138 #define VTKPOV_TRIFMT2 this->Internals->TriangleFormat2
139
140 //============================================================================
vtkPOVExporter()141 vtkPOVExporter::vtkPOVExporter()
142 {
143 this->FileName = NULL;
144 this->FilePtr = NULL;
145 this->Internals = new vtkPOVInternals;
146 }
147
~vtkPOVExporter()148 vtkPOVExporter::~vtkPOVExporter()
149 {
150 delete[] this->FileName;
151 delete this->Internals;
152 }
153
WriteData()154 void vtkPOVExporter::WriteData()
155 {
156 // make sure user specified a filename
157 if (this->FileName == NULL)
158 {
159 vtkErrorMacro(<< "Please specify file name to create");
160 return;
161 }
162
163 //get the renderer
164 vtkRenderer *renderer =
165 this->RenderWindow->GetRenderers()->GetFirstRenderer();
166 // make sure it has at least one actor
167 if (renderer->GetActors()->GetNumberOfItems() < 1)
168 {
169 vtkErrorMacro(<< "no actors found for writing .pov file.");
170 return;
171 }
172
173 // try opening the file
174 this->FilePtr = fopen(this->FileName, "w");
175 if (this->FilePtr == NULL)
176 {
177 vtkErrorMacro (<< "Cannot open " << this->FileName);
178 return;
179 }
180
181
182 // write header
183 this->WriteHeader(renderer);
184
185 // write camera
186 this->WriteCamera(renderer->GetActiveCamera());
187
188 // write lights
189 vtkLightCollection *lc = renderer->GetLights();
190 vtkCollectionSimpleIterator sit;
191 lc->InitTraversal(sit);
192 if (lc->GetNextLight(sit) == NULL)
193 {
194 vtkWarningMacro(<< "No light defined, creating one at camera position");
195 renderer->CreateLight();
196 }
197 vtkLight *light;
198 for (lc->InitTraversal(sit); (light = lc->GetNextLight(sit));)
199 {
200 if (light->GetSwitch())
201 {
202 this->WriteLight(light);
203 }
204 }
205
206 // write actors
207 vtkActorCollection *ac = renderer->GetActors();
208 vtkAssemblyPath *apath;
209 vtkCollectionSimpleIterator ait;
210 vtkActor *anActor, *aPart;
211 for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait)); )
212 {
213 for (anActor->InitPathTraversal(); (apath = anActor->GetNextPath()); )
214 {
215 aPart = static_cast<vtkActor *>(apath->GetLastNode()->GetViewProp());
216 this->WriteActor(aPart);
217 }
218 }
219
220 fclose(this->FilePtr);
221 }
222
WriteHeader(vtkRenderer * renderer)223 void vtkPOVExporter::WriteHeader(vtkRenderer *renderer)
224 {
225 fprintf(this->FilePtr, "// POVRay file exported by vtkPOVExporter\n");
226 fprintf(this->FilePtr, "//\n");
227
228 // width and height of output image,
229 //and other default command line args to POVRay
230 int *size = renderer->GetSize();
231 fprintf(this->FilePtr, "// +W%d +H%d\n\n", size[0], size[1]);
232
233 // global settings
234 fprintf(this->FilePtr, "global_settings {\n");
235 fprintf(this->FilePtr, "\tambient_light color rgb <1.0, 1.0, 1.0>\n");
236 fprintf(this->FilePtr, "\tassumed_gamma 2\n");
237 fprintf(this->FilePtr, "}\n\n");
238
239 // background
240 double *color = renderer->GetBackground();
241 fprintf(this->FilePtr, "background { color rgb <%f, %f, %f>}\n\n",
242 color[0], color[1], color[2]);
243 }
244
WriteCamera(vtkCamera * camera)245 void vtkPOVExporter::WriteCamera(vtkCamera *camera)
246 {
247 fprintf(this->FilePtr, "camera {\n");
248 if (camera->GetParallelProjection())
249 {
250 fprintf(this->FilePtr, "\torthographic\n");
251 }
252 else
253 {
254 fprintf(this->FilePtr, "\tperspective\n");
255 }
256
257 double *position = camera->GetPosition();
258 fprintf(this->FilePtr, "\tlocation <%f, %f, %f>\n",
259 position[0], position[1], position[2]);
260
261 double *up = camera->GetViewUp();
262 // the camera up vector is called "sky" in POVRay
263 fprintf(this->FilePtr, "\tsky <%f, %f, %f>\n", up[0], up[1], up[2]);
264
265 // make POVRay to use left handed system to right handed
266 // TODO: aspect ratio
267 fprintf(this->FilePtr, "\tright <-1, 0, 0>\n");
268 //fprintf(this->FilePtr, "\tup <-1, 0, 0>\n");
269
270 fprintf(this->FilePtr, "\tangle %f\n", camera->GetViewAngle());
271
272 double *focal = camera->GetFocalPoint();
273 fprintf(this->FilePtr, "\tlook_at <%f, %f, %f>\n",
274 focal[0], focal[1], focal[2]);
275
276 fprintf(this->FilePtr, "}\n\n");
277 }
278
WriteLight(vtkLight * light)279 void vtkPOVExporter::WriteLight(vtkLight *light)
280 {
281 fprintf(this->FilePtr, "light_source {\n");
282
283 double *position = light->GetPosition();
284 fprintf(this->FilePtr, "\t<%f, %f, %f>\n",
285 position[0], position[1], position[2]);
286
287 double *color = light->GetDiffuseColor();
288 fprintf(this->FilePtr, "\tcolor <%f, %f, %f>*%f\n",
289 color[0], color[1], color[2],
290 light->GetIntensity());
291
292 if (light->GetPositional())
293 {
294 fprintf(this->FilePtr, "\tspotlight\n");
295 fprintf(this->FilePtr, "\tradius %f\n", light->GetConeAngle());
296 fprintf(this->FilePtr, "\tfalloff %f\n", light->GetExponent());
297 }
298 else
299 {
300 fprintf(this->FilePtr, "\tparallel\n");
301 }
302 double *focal = light->GetFocalPoint();
303 fprintf(this->FilePtr, "\tpoint_at <%f, %f, %f>\n",
304 focal[0], focal[1], focal[2]);
305
306 fprintf(this->FilePtr, "}\n\n");
307 }
308
WriteActor(vtkActor * actor)309 void vtkPOVExporter::WriteActor(vtkActor *actor)
310 {
311 if (actor->GetMapper() == NULL)
312 {
313 return;
314 }
315
316 // write geometry, first ask the pipeline to update data
317 vtkDataSet *dataset = NULL;
318 vtkSmartPointer<vtkDataSet> tempDS;
319
320 vtkDataObject* dObj = actor->GetMapper()->GetInputDataObject(0, 0);
321 vtkCompositeDataSet* cd = vtkCompositeDataSet::SafeDownCast(dObj);
322 if (cd)
323 {
324 vtkCompositeDataGeometryFilter* gf = vtkCompositeDataGeometryFilter::New();
325 gf->SetInputConnection(actor->GetMapper()->GetInputConnection(0, 0));
326 gf->Update();
327 tempDS = gf->GetOutput();
328 gf->Delete();
329
330 dataset = tempDS;
331 }
332 else
333 {
334 dataset = actor->GetMapper()->GetInput();
335 }
336
337 if (dataset == NULL)
338 {
339 return;
340 }
341 actor->GetMapper()->GetInputAlgorithm()->Update();
342
343 // convert non polygon data to polygon data if needed
344 vtkGeometryFilter *geometryFilter = NULL;
345 vtkPolyData *polys = NULL;;
346 if (dataset->GetDataObjectType() != VTK_POLY_DATA)
347 {
348 geometryFilter = vtkGeometryFilter::New();
349 geometryFilter->SetInputConnection(
350 actor->GetMapper()->GetInputConnection(0, 0));
351 geometryFilter->Update();
352 polys = geometryFilter->GetOutput();
353 }
354 else
355 {
356 polys = static_cast<vtkPolyData *>(dataset);
357 }
358
359 // we only export Polygons and Triangle Strips
360 if ((polys->GetNumberOfPolys() == 0) && (polys->GetNumberOfStrips() == 0))
361 {
362 return;
363 }
364
365 // write point coordinates
366 vtkPoints *points = polys->GetPoints();
367
368 // we use mesh2 since it maps better to how VTK stores
369 // polygons/triangle strips
370 fprintf(this->FilePtr, "mesh2 {\n");
371
372 fprintf(this->FilePtr, "\tvertex_vectors {\n");
373 fprintf(this->FilePtr, VTKPOV_CNTFMT, points->GetNumberOfPoints());
374 for (vtkIdType i = 0; i < points->GetNumberOfPoints(); i++)
375 {
376 double *pos = points->GetPoint(i);
377 fprintf(this->FilePtr, "\t\t<%f, %f, %f>,\n", pos[0], pos[1], pos[2]);
378 }
379 fprintf(this->FilePtr, "\t}\n");
380
381 // write vertex normal
382 vtkPointData *pointData = polys->GetPointData();
383 if (pointData->GetNormals())
384 {
385 vtkDataArray *normals = pointData->GetNormals();
386 fprintf(this->FilePtr, "\tnormal_vectors {\n");
387 fprintf(this->FilePtr, VTKPOV_CNTFMT, normals->GetNumberOfTuples());
388 for (vtkIdType i = 0; i < normals->GetNumberOfTuples(); i++)
389 {
390 double *normal = normals->GetTuple(i);
391 fprintf(this->FilePtr, "\t\t<%f, %f, %f>,\n",
392 normal[0], normal[1], normal[2]);
393 }
394 fprintf(this->FilePtr, "\t}\n");
395 }
396
397 // TODO: write texture coordinates (uv vectors)
398
399 // write vertex texture, ask mapper to generate color for each vertex if
400 // the scalar data visibility is on
401 bool scalar_visible = false;
402 if (actor->GetMapper()->GetScalarVisibility())
403 {
404 vtkUnsignedCharArray *color_array = actor->GetMapper()->MapScalars(1.0);
405 if (color_array != NULL)
406 {
407 scalar_visible = true;
408 fprintf(this->FilePtr, "\ttexture_list {\n");
409 fprintf(this->FilePtr, VTKPOV_CNTFMT, color_array->GetNumberOfTuples());
410 for (vtkIdType i = 0; i < color_array->GetNumberOfTuples(); i++) {
411 unsigned char *color = color_array->GetPointer(4*i);
412 fprintf(this->FilePtr,
413 "\t\ttexture { pigment {color rgbf <%f, %f, %f, %f> } },\n",
414 color[0]/255.0,
415 color[1]/255.0,
416 color[2]/255.0,
417 1.0 - color[3]/255.0);
418 }
419 fprintf(this->FilePtr, "\t}\n");
420 }
421 }
422
423 // write polygons
424 if (polys->GetNumberOfPolys() > 0)
425 {
426 this->WritePolygons(polys, scalar_visible);
427 }
428
429 // write triangle strips
430 if (polys->GetNumberOfStrips() > 0)
431 {
432 this->WriteTriangleStrips(polys, scalar_visible);
433 }
434
435 // write transformation for the actor, it is column major and looks like transposed
436 vtkMatrix4x4 *matrix = actor->GetMatrix();
437 fprintf(this->FilePtr, "\tmatrix < %f, %f, %f,\n",
438 matrix->GetElement(0, 0),
439 matrix->GetElement(1, 0),
440 matrix->GetElement(2, 0));
441 fprintf(this->FilePtr, "\t\t %f, %f, %f,\n",
442 matrix->GetElement(0, 1),
443 matrix->GetElement(1, 1),
444 matrix->GetElement(2, 1));
445 fprintf(this->FilePtr, "\t\t %f, %f, %f,\n",
446 matrix->GetElement(0, 2),
447 matrix->GetElement(1, 2),
448 matrix->GetElement(2, 2));
449 fprintf(this->FilePtr, "\t\t %f, %f, %f >\n",
450 matrix->GetElement(0, 3),
451 matrix->GetElement(1, 3),
452 matrix->GetElement(2, 3));
453
454 // write property
455 this->WriteProperty(actor->GetProperty());
456
457 // done with this actor
458 fprintf(this->FilePtr, "}\n\n");
459
460 if (geometryFilter)
461 {
462 geometryFilter->Delete();
463 }
464 }
465
WritePolygons(vtkPolyData * polys,bool scalar_visible)466 void vtkPOVExporter::WritePolygons(vtkPolyData *polys, bool scalar_visible)
467 {
468 // write polygons with on the fly triangulation,
469 // assuming polygon are simple and can be triangulated into "fans"
470 vtkIdType numtriangles = 0;
471 vtkCellArray *cells = polys->GetPolys();
472 vtkIdType npts = 0, *pts = 0;
473
474 // first pass,
475 // calculate how many triangles there will be after triangulation
476 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
477 {
478 // the number of triangles for each polygon will be # of vertex - 2
479 numtriangles += (npts - 2);
480 }
481
482 // second pass, triangulate and write face indices
483 fprintf(this->FilePtr, "\tface_indices {\n");
484 fprintf(this->FilePtr, VTKPOV_CNTFMT, numtriangles);
485 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
486 {
487 vtkIdType triangle[3];
488 // the first triangle
489 triangle[0] = pts[0];
490 triangle[1] = pts[1];
491 triangle[2] = pts[2];
492
493 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
494 triangle[0], triangle[1], triangle[2]);
495 if (scalar_visible)
496 {
497 fprintf(this->FilePtr, VTKPOV_TRIFMT2,
498 triangle[0], triangle[1], triangle[2]);
499 }
500 else
501 {
502 fprintf(this->FilePtr, "\n");
503 }
504
505 // the rest of triangles
506 for (vtkIdType i = 3; i < npts; i++)
507 {
508 triangle[1] = triangle[2];
509 triangle[2] = pts[i];
510 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
511 triangle[0], triangle[1], triangle[2]);
512 if (scalar_visible)
513 {
514 fprintf(this->FilePtr, VTKPOV_TRIFMT2,
515 triangle[0], triangle[1], triangle[2]);
516 }
517 else
518 {
519 fprintf(this->FilePtr, "\n");
520 }
521 }
522 }
523 fprintf(this->FilePtr, "\t}\n");
524
525 // third pass, the same thing as 2nd pass but for normal_indices
526 if (polys->GetPointData()->GetNormals())
527 {
528 fprintf(this->FilePtr, "\tnormal_indices {\n");
529 fprintf(this->FilePtr, VTKPOV_CNTFMT, numtriangles);
530 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
531 {
532 vtkIdType triangle[3];
533 // the first triangle
534 triangle[0] = pts[0];
535 triangle[1] = pts[1];
536 triangle[2] = pts[2];
537
538 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
539 triangle[0], triangle[1], triangle[2]);
540 fprintf(this->FilePtr, "\n");
541
542 // the rest of triangles
543 for (vtkIdType i = 3; i < npts; i++)
544 {
545 triangle[1] = triangle[2];
546 triangle[2] = pts[i];
547 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
548 triangle[0], triangle[1], triangle[2]);
549 fprintf(this->FilePtr, "\n");
550 }
551 }
552 fprintf(this->FilePtr, "\t}\n");
553 }
554
555 // TODO: 4th pass, texture indices
556
557 }
558
WriteTriangleStrips(vtkPolyData * polys,bool scalar_visible)559 void vtkPOVExporter::WriteTriangleStrips(
560 vtkPolyData *polys, bool scalar_visible)
561 {
562 // convert triangle strips into triangles
563 vtkIdType numtriangles = 0;
564 vtkCellArray *cells = polys->GetStrips();
565 vtkIdType npts = 0, *pts = 0;
566
567 // first pass, calculate how many triangles there will be after conversion
568 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
569 {
570 // the number of triangles for each polygon will be # of vertex - 2
571 numtriangles += (npts - 2);
572 }
573
574 // second pass, convert to triangles and write face indices
575 fprintf(this->FilePtr, "\tface_indices {\n");
576 fprintf(this->FilePtr, VTKPOV_CNTFMT, numtriangles);
577 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
578 {
579 vtkIdType triangle[3];
580 // the first triangle
581 triangle[0] = pts[0];
582 triangle[1] = pts[1];
583 triangle[2] = pts[2];
584
585 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
586 triangle[0], triangle[1], triangle[2]);
587 if (scalar_visible)
588 {
589 fprintf(this->FilePtr, VTKPOV_TRIFMT2,
590 triangle[0], triangle[1], triangle[2]);
591 }
592 else
593 {
594 fprintf(this->FilePtr, "\n");
595 }
596
597 // the rest of triangles
598 for (vtkIdType i = 3; i < npts; i++)
599 {
600 triangle[0] = triangle[1];
601 triangle[1] = triangle[2];
602 triangle[2] = pts[i];
603 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
604 triangle[0], triangle[1], triangle[2]);
605 if (scalar_visible)
606 {
607 fprintf(this->FilePtr, VTKPOV_TRIFMT2,
608 triangle[0], triangle[1], triangle[2]);
609 }
610 else
611 {
612 fprintf(this->FilePtr, "\n");
613 }
614 }
615 }
616 fprintf(this->FilePtr, "\t}\n");
617
618 // third pass, the same thing as 2nd pass but for normal_indices
619 if (polys->GetPointData()->GetNormals())
620 {
621 fprintf(this->FilePtr, "\tnormal_indices {\n");
622 fprintf(this->FilePtr, VTKPOV_CNTFMT, numtriangles);
623 for (cells->InitTraversal(); cells->GetNextCell(npts, pts);)
624 {
625 vtkIdType triangle[3];
626 // the first triangle
627 triangle[0] = pts[0];
628 triangle[1] = pts[1];
629 triangle[2] = pts[2];
630
631 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
632 triangle[0], triangle[1], triangle[2]);
633 fprintf(this->FilePtr, "\n");
634
635 // the rest of triangles
636 for (vtkIdType i = 3; i < npts; i++)
637 {
638 triangle[0] = triangle[1];
639 triangle[1] = triangle[2];
640 triangle[2] = pts[i];
641 fprintf(this->FilePtr, VTKPOV_TRIFMT1,
642 triangle[0], triangle[1], triangle[2]);
643 fprintf(this->FilePtr, "\n");
644 }
645 }
646 fprintf(this->FilePtr, "\t}\n");
647 }
648
649 // TODO: 4th pass, texture indices
650 }
651
WriteProperty(vtkProperty * property)652 void vtkPOVExporter::WriteProperty(vtkProperty *property)
653 {
654 fprintf(this->FilePtr, "\ttexture {\n");
655
656 /* write color */
657 fprintf(this->FilePtr, "\t\tpigment {\n");
658 double *color = property->GetColor();
659 fprintf(this->FilePtr, "\t\t\tcolor rgbf <%f, %f, %f %f>\n",
660 color[0], color[1], color[2], 1.0 - property->GetOpacity());
661 fprintf(this->FilePtr, "\t\t}\n");
662
663 /* write ambient, diffuse and specular coefficients */
664 fprintf(this->FilePtr, "\t\tfinish {\n\t\t\t");
665 fprintf(this->FilePtr, "ambient %f ", property->GetAmbient());
666 fprintf(this->FilePtr, "diffuse %f ", property->GetDiffuse());
667 fprintf(this->FilePtr, "phong %f ", property->GetSpecular());
668 fprintf(this->FilePtr, "phong_size %f ", property->GetSpecularPower());
669 fprintf(this->FilePtr, "\n\t\t}\n");
670
671 fprintf(this->FilePtr, "\t}\n");
672 }
673
PrintSelf(ostream & os,vtkIndent indent)674 void vtkPOVExporter::PrintSelf(ostream& os, vtkIndent indent)
675 {
676 this->Superclass::PrintSelf(os, indent);
677 if (this->FileName)
678 {
679 os << indent << "FileName: " << this->FileName << "\n";
680 }
681 else
682 {
683 os << indent << "FileName: (null)\n";
684 }
685 }
686