1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkIVExporter.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 #include "vtkIVExporter.h"
16 
17 #include "vtkAssemblyNode.h"
18 #include "vtkAssemblyPath.h"
19 #include "vtkCamera.h"
20 #include "vtkCellArray.h"
21 #include "vtkGeometryFilter.h"
22 #include "vtkImageData.h"
23 #include "vtkLight.h"
24 #include "vtkLightCollection.h"
25 #include "vtkMath.h"
26 #include "vtkObjectFactory.h"
27 #include "vtkPointData.h"
28 #include "vtkPolyData.h"
29 #include "vtkPolyDataMapper.h"
30 #include "vtkProperty.h"
31 #include "vtkRenderWindow.h"
32 #include "vtkRendererCollection.h"
33 #include "vtkTexture.h"
34 #include "vtkTransform.h"
35 #include "vtkUnsignedCharArray.h"
36 #include <vtksys/SystemTools.hxx>
37 
38 vtkStandardNewMacro(vtkIVExporter);
39 
vtkIVExporter()40 vtkIVExporter::vtkIVExporter()
41 {
42   this->FileName = nullptr;
43 }
44 
~vtkIVExporter()45 vtkIVExporter::~vtkIVExporter()
46 {
47   delete[] this->FileName;
48 }
49 
50 static char indent[256];
51 static int indent_now = 0;
52 #define VTK_INDENT_MORE                                                                            \
53   {                                                                                                \
54     indent[indent_now] = ' ';                                                                      \
55     indent_now += 4;                                                                               \
56     indent[indent_now] = 0;                                                                        \
57   }
58 #define VTK_INDENT_LESS                                                                            \
59   {                                                                                                \
60     indent[indent_now] = ' ';                                                                      \
61     indent_now -= 4;                                                                               \
62     indent[indent_now] = 0;                                                                        \
63   }
64 
WriteData()65 void vtkIVExporter::WriteData()
66 {
67   FILE* fp;
68   vtkActorCollection* ac;
69   vtkActor *anActor, *aPart;
70   vtkLightCollection* lc;
71   vtkLight* aLight;
72   vtkCamera* cam;
73   double* tempd;
74 
75   for (int i = 0; i < 256; i++)
76   {
77     indent[i] = ' ';
78   }
79   indent[indent_now] = 0;
80 
81   // make sure the user specified a filename
82   if (this->FileName == nullptr)
83   {
84     vtkErrorMacro(<< "Please specify FileName to use");
85     return;
86   }
87 
88   // get the renderer
89   vtkRenderer* ren = this->ActiveRenderer;
90   if (!ren)
91   {
92     ren = this->RenderWindow->GetRenderers()->GetFirstRenderer();
93   }
94 
95   // make sure it has at least one actor
96   if (ren->GetActors()->GetNumberOfItems() < 1)
97   {
98     vtkErrorMacro(<< "no actors found for writing OpenInventor file.");
99     return;
100   }
101 
102   // try opening the files
103   fp = vtksys::SystemTools::Fopen(this->FileName, "w");
104   if (!fp)
105   {
106     vtkErrorMacro(<< "unable to open OpenInventor file " << this->FileName);
107     return;
108   }
109 
110   //
111   //  Write header
112   //
113   vtkDebugMacro("Writing OpenInventor file");
114   fprintf(fp, "#Inventor V2.0 ascii\n");
115   fprintf(fp, "# OpenInventor file written by the visualization toolkit\n\n");
116 
117   fprintf(fp, "Separator {\n");
118   VTK_INDENT_MORE;
119 
120   // do the camera
121   cam = ren->GetActiveCamera();
122   if (cam->GetParallelProjection())
123   {
124     fprintf(fp, "%sOrthographicCamera\n%s{\n", indent, indent);
125   }
126   else
127   {
128     // this assumes the aspect ratio is 1
129     fprintf(fp, "%sPerspectiveCamera\n%s{\n%s    heightAngle %f\n", indent, indent, indent,
130       cam->GetViewAngle() * vtkMath::Pi() / 180.0);
131   }
132   VTK_INDENT_MORE;
133   fprintf(fp, "%snearDistance %f\n", indent, cam->GetClippingRange()[0]);
134   fprintf(fp, "%sfarDistance %f\n", indent, cam->GetClippingRange()[1]);
135   fprintf(fp, "%sfocalDistance %f\n", indent, cam->GetDistance());
136   fprintf(fp, "%sposition %f %f %f\n", indent, cam->GetPosition()[0], cam->GetPosition()[1],
137     cam->GetPosition()[2]);
138   tempd = cam->GetOrientationWXYZ();
139   fprintf(fp, "%sorientation %g %g %g %g\n%s}\n", indent, tempd[1], tempd[2], tempd[3],
140     tempd[0] * vtkMath::Pi() / 180.0, indent);
141   VTK_INDENT_LESS;
142 
143   // do the lights first the ambient then the others
144   fprintf(fp, "# The following environment information is disabled\n");
145   fprintf(fp, "# because a popular viewer (Template Graphics Software SceneViewer) has\n");
146   fprintf(fp, "# trouble (access violations under Windows NT) with it.\n");
147   fprintf(fp, "#%sEnvironment {\n", indent);
148   // couldn't figure out a way to do headlight -- seems to be a property of the
149   // viewer not the model
150   VTK_INDENT_MORE;
151   fprintf(fp, "#%sambientIntensity 1.0 # ambient light\n", indent);
152   fprintf(fp, "#%sambientColor %f %f %f }\n\n", indent, ren->GetAmbient()[0], ren->GetAmbient()[1],
153     ren->GetAmbient()[2]);
154   VTK_INDENT_LESS;
155 
156   // make sure we have a default light
157   // if we don't then use a headlight
158   lc = ren->GetLights();
159   vtkCollectionSimpleIterator lsit;
160   for (lc->InitTraversal(lsit); (aLight = lc->GetNextLight(lsit));)
161   {
162     this->WriteALight(aLight, fp);
163   }
164 
165   // do the actors now
166   ac = ren->GetActors();
167   vtkAssemblyPath* apath;
168   vtkCollectionSimpleIterator ait;
169   for (ac->InitTraversal(ait); (anActor = ac->GetNextActor(ait));)
170   {
171     for (anActor->InitPathTraversal(); (apath = anActor->GetNextPath());)
172     {
173       aPart = static_cast<vtkActor*>(apath->GetLastNode()->GetViewProp());
174       this->WriteAnActor(aPart, fp);
175     }
176   }
177 
178   VTK_INDENT_LESS;
179   fprintf(fp, "}\n"); // close Separator
180 
181   fclose(fp);
182 }
183 
WriteALight(vtkLight * aLight,FILE * fp)184 void vtkIVExporter::WriteALight(vtkLight* aLight, FILE* fp)
185 {
186   double *pos, *focus, *color;
187   float dir[3];
188 
189   pos = aLight->GetPosition();
190   focus = aLight->GetFocalPoint();
191   color = aLight->GetDiffuseColor();
192 
193   dir[0] = focus[0] - pos[0];
194   dir[1] = focus[1] - pos[1];
195   dir[2] = focus[2] - pos[2];
196   vtkMath::Normalize(dir);
197 
198   if (aLight->GetPositional())
199   {
200     double* attn;
201 
202     if (aLight->GetConeAngle() >= 90.0)
203     {
204       fprintf(fp, "%sPointLight {\n", indent);
205       VTK_INDENT_MORE;
206     }
207     else
208     {
209       fprintf(fp, "%sSpotLight {\n", indent);
210       VTK_INDENT_MORE;
211       fprintf(fp, "%sdirection %f %f %f\n", indent, dir[0], dir[1], dir[2]);
212       fprintf(fp, "%scutOffAngle %f\n", indent, aLight->GetConeAngle());
213       // the following ignores linear and quadratic attenuation values
214       attn = aLight->GetAttenuationValues();
215       fprintf(fp, "%sdropOffRate %f\n", indent, attn[0]);
216     }
217     fprintf(fp, "%slocation %f %f %f\n", indent, pos[0], pos[1], pos[2]);
218   }
219   else
220   {
221     fprintf(fp, "%sDirectionalLight {\n", indent);
222     VTK_INDENT_MORE;
223     fprintf(fp, "%sdirection %f %f %f\n", indent, dir[0], dir[1], dir[2]);
224   }
225 
226   fprintf(fp, "%scolor %f %f %f\n", indent, color[0], color[1], color[2]);
227   fprintf(fp, "%sintensity %f\n", indent, aLight->GetIntensity());
228   if (aLight->GetSwitch())
229   {
230     fprintf(fp, "%son TRUE\n%s}\n", indent, indent);
231   }
232   else
233   {
234     fprintf(fp, "%son FALSE\n%s}\n", indent, indent);
235   }
236   VTK_INDENT_LESS;
237 }
238 
WriteAnActor(vtkActor * anActor,FILE * fp)239 void vtkIVExporter::WriteAnActor(vtkActor* anActor, FILE* fp)
240 {
241   vtkDataSet* ds;
242   vtkPolyData* pd;
243   vtkGeometryFilter* gf = nullptr;
244   vtkPointData* pntData;
245   vtkPoints* points;
246   vtkDataArray* normals = nullptr;
247   vtkDataArray* tcoords = nullptr;
248   int i;
249   vtkProperty* prop;
250   double* tempd;
251   vtkCellArray* cells;
252   vtkIdType npts = 0;
253   const vtkIdType* indx = nullptr;
254   float tempf2;
255   vtkPolyDataMapper* pm;
256   vtkUnsignedCharArray* colors;
257   double* p;
258   unsigned char* c;
259   vtkTransform* trans;
260 
261   // see if the actor has a mapper. it could be an assembly
262   if (anActor->GetMapper() == nullptr)
263   {
264     return;
265   }
266 
267   fprintf(fp, "%sSeparator {\n", indent);
268   VTK_INDENT_MORE;
269 
270   // first stuff out the transform
271   trans = vtkTransform::New();
272   trans->SetMatrix(anActor->vtkProp3D::GetMatrix());
273 
274   fprintf(fp, "%sTransform {\n", indent);
275   VTK_INDENT_MORE;
276   tempd = trans->GetPosition();
277   fprintf(fp, "%stranslation %g %g %g\n", indent, tempd[0], tempd[1], tempd[2]);
278   tempd = trans->GetOrientationWXYZ();
279   fprintf(fp, "%srotation %g %g %g %g\n", indent, tempd[1], tempd[2], tempd[3],
280     tempd[0] * vtkMath::Pi() / 180.0);
281   tempd = trans->GetScale();
282   fprintf(fp, "%sscaleFactor %g %g %g\n", indent, tempd[0], tempd[1], tempd[2]);
283   fprintf(fp, "%s}\n", indent);
284   VTK_INDENT_LESS;
285   trans->Delete();
286 
287   // get the mappers input and matrix
288   ds = anActor->GetMapper()->GetInput();
289 
290   vtkAlgorithmOutput* pdProducer = nullptr;
291   // we really want polydata
292   if (ds->GetDataObjectType() != VTK_POLY_DATA)
293   {
294     gf = vtkGeometryFilter::New();
295     gf->SetInputConnection(anActor->GetMapper()->GetInputConnection(0, 0));
296     gf->Update();
297     pd = gf->GetOutput();
298     pdProducer = gf->GetOutputPort();
299   }
300   else
301   {
302     anActor->GetMapper()->GetInputAlgorithm()->Update();
303     pd = static_cast<vtkPolyData*>(ds);
304     pdProducer = anActor->GetMapper()->GetInputConnection(0, 0);
305   }
306 
307   pm = vtkPolyDataMapper::New();
308   pm->SetInputConnection(pdProducer);
309   pm->SetScalarRange(anActor->GetMapper()->GetScalarRange());
310   pm->SetScalarVisibility(anActor->GetMapper()->GetScalarVisibility());
311   pm->SetLookupTable(anActor->GetMapper()->GetLookupTable());
312 
313   points = pd->GetPoints();
314   pntData = pd->GetPointData();
315   normals = pntData->GetNormals();
316   tcoords = pntData->GetTCoords();
317   colors = pm->MapScalars(1.0);
318 
319   fprintf(fp, "%sMaterial {\n", indent);
320   VTK_INDENT_MORE;
321 
322   // write out the material properties to the mat file
323   prop = anActor->GetProperty();
324   // the following is based on a guess about how VTK's GetAmbient
325   // property corresponds to SoMaterial's ambientColor
326   tempf2 = prop->GetAmbient();
327   tempd = prop->GetAmbientColor();
328   fprintf(fp, "%sambientColor %g %g %g\n", indent, tempd[0] * tempf2, tempd[1] * tempf2,
329     tempd[2] * tempf2);
330   tempf2 = prop->GetDiffuse();
331   tempd = prop->GetDiffuseColor();
332   fprintf(fp, "%sdiffuseColor %g %g %g\n", indent, tempd[0] * tempf2, tempd[1] * tempf2,
333     tempd[2] * tempf2);
334   tempf2 = prop->GetSpecular();
335   tempd = prop->GetSpecularColor();
336   fprintf(fp, "%sspecularColor %g %g %g\n", indent, tempd[0] * tempf2, tempd[1] * tempf2,
337     tempd[2] * tempf2);
338   fprintf(fp, "%sshininess %g\n", indent, prop->GetSpecularPower() / 128.0);
339   fprintf(fp, "%stransparency %g\n", indent, 1.0 - prop->GetOpacity());
340   fprintf(fp, "%s}\n", indent); // close matrial
341   VTK_INDENT_LESS;
342 
343   // is there a texture map
344   if (anActor->GetTexture())
345   {
346     vtkTexture* aTexture = anActor->GetTexture();
347     int *size, xsize, ysize, bpp;
348     vtkDataArray* scalars;
349     vtkUnsignedCharArray* mappedScalars;
350     unsigned char* txtrData;
351     int totalValues;
352 
353     // make sure it is updated and then get some info
354     if (aTexture->GetInput() == nullptr)
355     {
356       vtkErrorMacro(<< "texture has no input!\n");
357       return;
358     }
359     aTexture->GetInputAlgorithm()->Update();
360     size = aTexture->GetInput()->GetDimensions();
361     scalars = aTexture->GetInput()->GetPointData()->GetScalars();
362 
363     // make sure scalars are non null
364     if (!scalars)
365     {
366       vtkErrorMacro(<< "No scalar values found for texture input!\n");
367       return;
368     }
369 
370     // make sure using unsigned char data of color scalars type
371     if (aTexture->GetColorMode() == VTK_COLOR_MODE_MAP_SCALARS ||
372       (scalars->GetDataType() != VTK_UNSIGNED_CHAR))
373     {
374       mappedScalars = aTexture->GetMappedScalars();
375     }
376     else
377     {
378       mappedScalars = static_cast<vtkUnsignedCharArray*>(scalars);
379     }
380 
381     // we only support 2d texture maps right now
382     // so one of the three sizes must be 1, but it
383     // could be any of them, so lets find it
384     if (size[0] == 1)
385     {
386       xsize = size[1];
387       ysize = size[2];
388     }
389     else
390     {
391       xsize = size[0];
392       if (size[1] == 1)
393       {
394         ysize = size[2];
395       }
396       else
397       {
398         ysize = size[1];
399         if (size[2] != 1)
400         {
401           vtkErrorMacro(<< "3D texture maps currently are not supported!\n");
402           return;
403         }
404       }
405     }
406 
407     fprintf(fp, "%sTexture2 {\n", indent);
408     VTK_INDENT_MORE;
409     bpp = mappedScalars->GetNumberOfComponents();
410     fprintf(fp, "%simage %d %d %d\n", indent, xsize, ysize, bpp);
411     VTK_INDENT_MORE;
412     txtrData = static_cast<vtkUnsignedCharArray*>(mappedScalars)->GetPointer(0);
413     totalValues = xsize * ysize;
414     fprintf(fp, "%s", indent);
415     for (i = 0; i < totalValues; i++)
416     {
417       fprintf(fp, "%.2x", *txtrData);
418       txtrData++;
419       if (bpp > 1)
420       {
421         fprintf(fp, "%.2x", *txtrData);
422         txtrData++;
423       }
424       if (bpp > 2)
425       {
426         fprintf(fp, "%.2x", *txtrData);
427         txtrData++;
428       }
429       if (bpp > 3)
430       {
431         fprintf(fp, "%.2x", *txtrData);
432         txtrData++;
433       }
434       if (i % 8 == 0)
435       {
436         fprintf(fp, "\n%s    ", indent);
437       }
438       else
439       {
440         fprintf(fp, " ");
441       }
442     }
443     VTK_INDENT_LESS;
444     fprintf(fp, "%s}\n", indent);
445     VTK_INDENT_LESS;
446   }
447 
448   // write out point data if any
449   this->WritePointData(points, normals, tcoords, colors, fp);
450 
451   // write out polys if any
452   if (pd->GetNumberOfPolys() > 0)
453   {
454     fprintf(fp, "%sIndexedFaceSet {\n", indent);
455     VTK_INDENT_MORE;
456     fprintf(fp, "%scoordIndex  [\n", indent);
457     VTK_INDENT_MORE;
458 
459     cells = pd->GetPolys();
460     for (cells->InitTraversal(); cells->GetNextCell(npts, indx);)
461     {
462       fprintf(fp, "%s", indent);
463       for (i = 0; i < npts; i++)
464       {
465         // treating vtkIdType as int
466         fprintf(fp, "%i, ", static_cast<int>(indx[i]));
467         if (((i + 1) % 10) == 0)
468         {
469           fprintf(fp, "\n%s    ", indent);
470         }
471       }
472       fprintf(fp, "-1,\n");
473     }
474     fprintf(fp, "%s]\n", indent);
475     VTK_INDENT_LESS;
476     fprintf(fp, "%s}\n", indent);
477     VTK_INDENT_LESS;
478   }
479 
480   // write out tstrips if any
481   if (pd->GetNumberOfStrips() > 0)
482   {
483     fprintf(fp, "%sIndexedTriangleStripSet {\n", indent);
484     VTK_INDENT_MORE;
485     fprintf(fp, "%scoordIndex  [\n", indent);
486     VTK_INDENT_MORE;
487     cells = pd->GetStrips();
488     for (cells->InitTraversal(); cells->GetNextCell(npts, indx);)
489     {
490       fprintf(fp, "%s", indent);
491       for (i = 0; i < npts; i++)
492       {
493         // treating vtkIdType as int
494         fprintf(fp, "%i, ", static_cast<int>(indx[i]));
495         if (((i + 1) % 10) == 0)
496         {
497           fprintf(fp, "\n%s    ", indent);
498         }
499       }
500       fprintf(fp, "-1,\n");
501     }
502     fprintf(fp, "%s]\n", indent);
503     VTK_INDENT_LESS;
504     fprintf(fp, "%s}\n", indent);
505     VTK_INDENT_LESS;
506   }
507 
508   // write out lines if any
509   if (pd->GetNumberOfLines() > 0)
510   {
511     fprintf(fp, "%sIndexedLineSet {\n", indent);
512     VTK_INDENT_MORE;
513     fprintf(fp, "%scoordIndex  [\n", indent);
514     VTK_INDENT_MORE;
515     cells = pd->GetLines();
516     for (cells->InitTraversal(); cells->GetNextCell(npts, indx);)
517     {
518       fprintf(fp, "%s", indent);
519       for (i = 0; i < npts; i++)
520       {
521         // treating vtkIdType as int
522         fprintf(fp, "%i, ", static_cast<int>(indx[i]));
523         if (((i + 1) % 10) == 0)
524         {
525           fprintf(fp, "\n%s    ", indent);
526         }
527       }
528       fprintf(fp, "-1,\n");
529     }
530     fprintf(fp, "%s]\n", indent);
531     VTK_INDENT_LESS;
532     fprintf(fp, "%s}\n", indent);
533     VTK_INDENT_LESS;
534   }
535 
536   // write out verts if any
537   // (more complex because there is no IndexedPointSet)
538   if (pd->GetNumberOfVerts() > 0)
539   {
540     fprintf(fp, "%sSeparator {\n", indent);
541     VTK_INDENT_MORE;
542     fprintf(fp, "%sCoordinate3 {\n", indent);
543     VTK_INDENT_MORE;
544     fprintf(fp, "%spoint [", indent);
545     VTK_INDENT_MORE;
546     cells = pd->GetVerts();
547     for (cells->InitTraversal(); cells->GetNextCell(npts, indx);)
548     {
549       for (i = 0; i < npts; i++)
550       {
551         p = points->GetPoint(indx[i]);
552         fprintf(fp, "%s%g %g %g,\n", indent, p[0], p[1], p[2]);
553       }
554     }
555     fprintf(fp, "%s]\n", indent);
556     VTK_INDENT_LESS;
557     fprintf(fp, "%s}\n", indent);
558     VTK_INDENT_LESS;
559     if (colors)
560     {
561       fprintf(fp, "%sPackedColor {", indent);
562       VTK_INDENT_MORE;
563       fprintf(fp, "%srgba [\n", indent);
564       VTK_INDENT_MORE;
565       for (cells->InitTraversal(); cells->GetNextCell(npts, indx);)
566       {
567         fprintf(fp, "%s", indent);
568         for (i = 0; i < npts; i++)
569         {
570           c = colors->GetPointer(4 * indx[i]);
571           fprintf(fp, "%#lx, ",
572             (static_cast<unsigned long>(c[3]) << 24) | (static_cast<unsigned long>(c[2]) << 16) |
573               (static_cast<unsigned long>(c[1]) << 8) | static_cast<unsigned long>(c[0]));
574 
575           if (((i + 1) % 5) == 0)
576           {
577             fprintf(fp, "\n%s", indent);
578           }
579         }
580       }
581       fprintf(fp, "\n%s]\n", indent);
582       VTK_INDENT_LESS;
583       fprintf(fp, "%s}\n", indent);
584       VTK_INDENT_LESS;
585       fprintf(fp, "%sMaterialBinding { value PER_VERTEX_INDEXED }\n", indent);
586     }
587 
588     fprintf(fp, "%sPointSet {\n", indent);
589     VTK_INDENT_MORE;
590     // treating vtkIdType as int
591     fprintf(fp, "%snumPoints %d\n", indent, static_cast<int>(npts));
592     VTK_INDENT_MORE;
593     fprintf(fp, "%s}\n", indent);
594     VTK_INDENT_LESS;
595     fprintf(fp, "%s}\n", indent); // close the Separator
596     VTK_INDENT_LESS;
597   }
598   fprintf(fp, "%s}\n", indent);
599   VTK_INDENT_LESS;
600   if (gf)
601   {
602     gf->Delete();
603   }
604   pm->Delete();
605 }
606 
WritePointData(vtkPoints * points,vtkDataArray * normals,vtkDataArray * tcoords,vtkUnsignedCharArray * colors,FILE * fp)607 void vtkIVExporter::WritePointData(vtkPoints* points, vtkDataArray* normals, vtkDataArray* tcoords,
608   vtkUnsignedCharArray* colors, FILE* fp)
609 {
610   double* p;
611   int i;
612   unsigned char* c;
613 
614   // write out the points
615   fprintf(fp, "%sCoordinate3 {\n", indent);
616   VTK_INDENT_MORE;
617   fprintf(fp, "%spoint [\n", indent);
618   VTK_INDENT_MORE;
619   for (i = 0; i < points->GetNumberOfPoints(); i++)
620   {
621     p = points->GetPoint(i);
622     fprintf(fp, "%s%g %g %g,\n", indent, p[0], p[1], p[2]);
623   }
624   fprintf(fp, "%s]\n", indent);
625   VTK_INDENT_LESS;
626   fprintf(fp, "%s}\n", indent);
627   VTK_INDENT_LESS;
628 
629   // write out the point data
630   if (normals)
631   {
632     fprintf(fp, "%sNormal {\n", indent);
633     VTK_INDENT_MORE;
634     fprintf(fp, "%svector [\n", indent);
635     VTK_INDENT_MORE;
636     for (i = 0; i < normals->GetNumberOfTuples(); i++)
637     {
638       p = normals->GetTuple(i);
639       fprintf(fp, "%s%g %g %g,\n", indent, p[0], p[1], p[2]);
640     }
641     fprintf(fp, "%s]\n", indent);
642     VTK_INDENT_LESS;
643     fprintf(fp, "%s}\n", indent);
644     VTK_INDENT_LESS;
645   }
646 
647   // write out the point data
648   if (tcoords)
649   {
650     fprintf(fp, "%sTextureCoordinateBinding  {\n", indent);
651     VTK_INDENT_MORE;
652     fprintf(fp, "%svalue PER_VERTEX_INDEXED\n", indent);
653     VTK_INDENT_LESS;
654     fprintf(fp, "%s}\n", indent);
655     fprintf(fp, "%sTextureCoordinate2 {\n", indent);
656     VTK_INDENT_MORE;
657     fprintf(fp, "%spoint [\n", indent);
658     VTK_INDENT_MORE;
659     for (i = 0; i < tcoords->GetNumberOfTuples(); i++)
660     {
661       p = tcoords->GetTuple(i);
662       fprintf(fp, "%s%g %g,\n", indent, p[0], p[1]);
663     }
664     fprintf(fp, "%s]\n", indent);
665     VTK_INDENT_LESS;
666     fprintf(fp, "%s}\n", indent);
667     VTK_INDENT_LESS;
668   }
669 
670   // write out the point data
671   if (colors)
672   {
673     fprintf(fp, "%sPackedColor {\n", indent);
674     VTK_INDENT_MORE;
675     fprintf(fp, "%srgba [\n", indent);
676     VTK_INDENT_MORE;
677     fprintf(fp, "%s", indent);
678     for (i = 0; i < colors->GetNumberOfTuples(); i++)
679     {
680       c = colors->GetPointer(4 * i);
681       fprintf(fp, "%#lx, ",
682         (static_cast<unsigned long>(c[3]) << 24) | (static_cast<unsigned long>(c[2]) << 16) |
683           (static_cast<unsigned long>(c[1]) << 8) | static_cast<unsigned long>(c[0]));
684 
685       if (((i + 1) % 5) == 0)
686       {
687         fprintf(fp, "\n%s", indent);
688       }
689     }
690     fprintf(fp, "\n%s]\n", indent);
691     VTK_INDENT_LESS;
692     fprintf(fp, "%s}\n", indent);
693     VTK_INDENT_LESS;
694     fprintf(fp, "%sMaterialBinding { value PER_VERTEX_INDEXED }\n", indent);
695   }
696 }
697 
PrintSelf(ostream & os,vtkIndent ind)698 void vtkIVExporter::PrintSelf(ostream& os, vtkIndent ind)
699 {
700   this->Superclass::PrintSelf(os, ind);
701 
702   if (this->FileName)
703   {
704     os << ind << "FileName: " << this->FileName << "\n";
705   }
706   else
707   {
708     os << ind << "FileName: (null)\n";
709   }
710 }
711