1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkMCubesWriter.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 "vtkMCubesWriter.h"
16 
17 #include "vtkByteSwap.h"
18 #include "vtkCellArray.h"
19 #include "vtkInformation.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPointData.h"
22 #include "vtkPolyData.h"
23 
24 vtkStandardNewMacro(vtkMCubesWriter);
25 
26 // Create object.
vtkMCubesWriter()27 vtkMCubesWriter::vtkMCubesWriter()
28 {
29   this->FileName = nullptr;
30   this->LimitsFileName = nullptr;
31 }
32 
~vtkMCubesWriter()33 vtkMCubesWriter::~vtkMCubesWriter()
34 {
35   delete[] this->FileName;
36   delete [] this->LimitsFileName;
37 }
38 
39 // Write out data in MOVIE.BYU format.
WriteData()40 void vtkMCubesWriter::WriteData()
41 {
42   vtkPoints *pts;
43   vtkDataArray *normals;
44   vtkCellArray *polys;
45   vtkPolyData *input=this->GetInput();
46 
47   polys = input->GetPolys();
48   pts = input->GetPoints();
49   if (pts == nullptr || polys == nullptr )
50   {
51     vtkErrorMacro(<<"No data to write!");
52     return;
53   }
54 
55   normals = input->GetPointData()->GetNormals();
56   if (normals == nullptr )
57   {
58     vtkErrorMacro(<<"No normals to write!: use vtkPolyDataNormals to generate them");
59     return;
60   }
61 
62   if ( this->FileName == nullptr)
63   {
64     vtkErrorMacro(<< "Please specify FileName to write");
65     return;
66   }
67 
68   vtkDebugMacro("Writing MCubes tri file");
69   FILE *fp;
70   if ((fp = fopen(this->FileName, "w")) == nullptr)
71   {
72     vtkErrorMacro(<< "Couldn't open file: " << this->FileName);
73     return;
74   }
75   this->WriteMCubes(fp, pts, normals, polys);
76   fclose (fp);
77 
78   if (this->LimitsFileName)
79   {
80     vtkDebugMacro("Writing MCubes limits file");
81     if ((fp = fopen(this->LimitsFileName, "w")) == nullptr)
82     {
83       vtkErrorMacro(<< "Couldn't open file: " << this->LimitsFileName);
84       return;
85     }
86     this->WriteLimits(fp, input->GetBounds ());
87     fclose (fp);
88   }
89 }
90 
WriteMCubes(FILE * fp,vtkPoints * pts,vtkDataArray * normals,vtkCellArray * polys)91 void vtkMCubesWriter::WriteMCubes(FILE *fp, vtkPoints *pts,
92                                   vtkDataArray *normals,
93                                   vtkCellArray *polys)
94 {
95   typedef struct {float x[3], n[3];} pointType;
96   pointType point;
97   int i;
98   vtkIdType npts;
99   vtkIdType *indx = nullptr;
100 
101   //  Write out triangle polygons.  In not a triangle polygon, create
102   //  triangles.
103   //
104   double p[3], n[3];
105   bool status=true;
106   for (polys->InitTraversal(); polys->GetNextCell(npts,indx) && status; )
107   {
108     for (i=0; i < 3 && status; i++)
109     {
110       pts->GetPoint(indx[i],p);
111       normals->GetTuple(indx[i],n);
112       point.x[0] = static_cast<float>(p[0]);
113       point.x[1] = static_cast<float>(p[1]);
114       point.x[2] = static_cast<float>(p[2]);
115       point.n[0] = static_cast<float>(n[0]);
116       point.n[1] = static_cast<float>(n[1]);
117       point.n[2] = static_cast<float>(n[2]);
118       status=vtkByteSwap::SwapWrite4BERange(reinterpret_cast<float *>(&point),
119                                             6,fp);
120       if(!status)
121       {
122         vtkErrorMacro(<< "SwapWrite failed.");
123       }
124     }
125   }
126 }
WriteLimits(FILE * fp,double * bounds)127 void vtkMCubesWriter::WriteLimits(FILE *fp, double *bounds)
128 {
129   float fbounds[6];
130   fbounds[0] = static_cast<float>(bounds[0]);
131   fbounds[1] = static_cast<float>(bounds[1]);
132   fbounds[2] = static_cast<float>(bounds[2]);
133   fbounds[3] = static_cast<float>(bounds[3]);
134   fbounds[4] = static_cast<float>(bounds[4]);
135   fbounds[5] = static_cast<float>(bounds[5]);
136   bool status=vtkByteSwap::SwapWrite4BERange(fbounds,6,fp);
137   if(!status)
138   {
139     vtkErrorMacro(<< "SwapWrite failed.");
140   }
141   else
142   {
143     status=vtkByteSwap::SwapWrite4BERange(fbounds,6,fp);
144     if(!status)
145     {
146       vtkErrorMacro(<< "SwapWrite failed.");
147     }
148   }
149 }
150 
PrintSelf(ostream & os,vtkIndent indent)151 void vtkMCubesWriter::PrintSelf(ostream& os, vtkIndent indent)
152 {
153   this->Superclass::PrintSelf(os,indent);
154 
155   os << indent << "Limits File Name: "
156      << (this->LimitsFileName ? this->LimitsFileName : "(none)") << "\n";
157 }
158 
GetInput()159 vtkPolyData* vtkMCubesWriter::GetInput()
160 {
161   return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
162 }
163 
GetInput(int port)164 vtkPolyData* vtkMCubesWriter::GetInput(int port)
165 {
166   return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
167 }
168 
FillInputPortInformation(int,vtkInformation * info)169 int vtkMCubesWriter::FillInputPortInformation(int, vtkInformation *info)
170 {
171   info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
172   return 1;
173 }
174