1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // Authors:
41 // * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
42 //
43 //M*/
44
45 #include "precomp.hpp"
46
47 namespace cv { namespace viz
48 {
49 vtkStandardNewMacro(vtkOBJWriter);
50 }}
51
vtkOBJWriter()52 cv::viz::vtkOBJWriter::vtkOBJWriter()
53 {
54 std::ofstream fout; // only used to extract the default precision
55 this->DecimalPrecision = fout.precision();
56 this->FileName = NULL;
57 }
58
~vtkOBJWriter()59 cv::viz::vtkOBJWriter::~vtkOBJWriter(){}
60
WriteData()61 void cv::viz::vtkOBJWriter::WriteData()
62 {
63 vtkPolyData *input = this->GetInput();
64 if (!input)
65 return;
66
67 if (!this->FileName )
68 {
69 vtkErrorMacro(<< "No FileName specified! Can't write!");
70 this->SetErrorCode(vtkErrorCode::NoFileNameError);
71 return;
72 }
73
74 vtkDebugMacro(<<"Opening vtk file for writing...");
75 ostream *outfilep = new ofstream(this->FileName, ios::out);
76 if (outfilep->fail())
77 {
78 vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
79 this->SetErrorCode(vtkErrorCode::CannotOpenFileError);
80 delete outfilep;
81 return;
82 }
83
84 std::ostream& outfile = *outfilep;
85
86 //write header
87 outfile << "# wavefront obj file written by opencv viz module" << std::endl << std::endl;
88 outfile << "mtllib NONE" << std::endl << std::endl;
89
90 // write out the points
91 for (int i = 0; i < input->GetNumberOfPoints(); i++)
92 {
93 Vec3d p;
94 input->GetPoint(i, p.val);
95 outfile << std::setprecision(this->DecimalPrecision) << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl;
96 }
97
98 const int idStart = 1;
99
100 // write out the point data
101 vtkSmartPointer<vtkDataArray> normals = input->GetPointData()->GetNormals();
102 if(normals)
103 {
104 for (int i = 0; i < normals->GetNumberOfTuples(); i++)
105 {
106 Vec3d p;
107 normals->GetTuple(i, p.val);
108 outfile << std::setprecision(this->DecimalPrecision) << "vn " << p[0] << " " << p[1] << " " << p[2] << std::endl;
109 }
110 }
111
112 vtkSmartPointer<vtkDataArray> tcoords = input->GetPointData()->GetTCoords();
113 if (tcoords)
114 {
115 for (int i = 0; i < tcoords->GetNumberOfTuples(); i++)
116 {
117 Vec2d p;
118 tcoords->GetTuple(i, p.val);
119 outfile << std::setprecision(this->DecimalPrecision) << "vt " << p[0] << " " << p[1] << std::endl;
120 }
121 }
122
123 // write out a group name and material
124 outfile << std::endl << "g grp" << idStart << std::endl;
125 outfile << "usemtl mtlNONE" << std::endl;
126
127 // write out verts if any
128 if (input->GetNumberOfVerts() > 0)
129 {
130 vtkIdType npts = 0, *index = 0;
131 vtkCellArray *cells = input->GetVerts();
132 for (cells->InitTraversal(); cells->GetNextCell(npts, index); )
133 {
134 outfile << "p ";
135 for (int i = 0; i < npts; i++)
136 outfile << index[i] + idStart << " ";
137 outfile << std::endl;
138 }
139 }
140
141 // write out lines if any
142 if (input->GetNumberOfLines() > 0)
143 {
144 vtkIdType npts = 0, *index = 0;
145 vtkCellArray *cells = input->GetLines();
146 for (cells->InitTraversal(); cells->GetNextCell(npts, index); )
147 {
148 outfile << "l ";
149 if (tcoords)
150 {
151 for (int i = 0; i < npts; i++)
152 outfile << index[i] + idStart << "/" << index[i] + idStart << " ";
153 }
154 else
155 for (int i = 0; i < npts; i++)
156 outfile << index[i] + idStart << " ";
157
158 outfile << std::endl;
159 }
160 }
161
162 // write out polys if any
163 if (input->GetNumberOfPolys() > 0)
164 {
165 vtkIdType npts = 0, *index = 0;
166 vtkCellArray *cells = input->GetPolys();
167 for (cells->InitTraversal(); cells->GetNextCell(npts, index); )
168 {
169 outfile << "f ";
170 for (int i = 0; i < npts; i++)
171 {
172 if (normals)
173 {
174 if (tcoords)
175 outfile << index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << " ";
176 else
177 outfile << index[i] + idStart << "//" << index[i] + idStart << " ";
178 }
179 else
180 {
181 if (tcoords)
182 outfile << index[i] + idStart << " " << index[i] + idStart << " ";
183 else
184 outfile << index[i] + idStart << " ";
185 }
186 }
187 outfile << std::endl;
188 }
189 }
190
191 // write out tstrips if any
192 if (input->GetNumberOfStrips() > 0)
193 {
194 vtkIdType npts = 0, *index = 0;
195 vtkCellArray *cells = input->GetStrips();
196 for (cells->InitTraversal(); cells->GetNextCell(npts, index); )
197 {
198 for (int i = 2, i1, i2; i < npts; ++i)
199 {
200 if (i % 2)
201 {
202 i1 = i - 1;
203 i2 = i - 2;
204 }
205 else
206 {
207 i1 = i - 1;
208 i2 = i - 2;
209 }
210
211 if(normals)
212 {
213 if (tcoords)
214 {
215 outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << "/" << index[i1] + idStart << " "
216 << index[i2]+ idStart << "/" << index[i2] + idStart << "/" << index[i2] + idStart << " "
217 << index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << std::endl;
218 }
219 else
220 {
221 outfile << "f " << index[i1] + idStart << "//" << index[i1] + idStart << " " << index[i2] + idStart
222 << "//" << index[i2] + idStart << " " << index[i] + idStart << "//" << index[i] + idStart << std::endl;
223 }
224 }
225 else
226 {
227 if (tcoords)
228 {
229 outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << " " << index[i2] + idStart
230 << "/" << index[i2] + idStart << " " << index[i] + idStart << "/" << index[i] + idStart << std::endl;
231 }
232 else
233 outfile << "f " << index[i1] + idStart << " " << index[i2] + idStart << " " << index[i] + idStart << std::endl;
234 }
235 } /* for (int i = 2; i < npts; ++i) */
236 }
237 } /* if (input->GetNumberOfStrips() > 0) */
238
239 vtkDebugMacro(<<"Closing vtk file\n");
240 delete outfilep;
241
242 // Delete the file if an error occurred
243 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
244 {
245 vtkErrorMacro("Ran out of disk space; deleting file: " << this->FileName);
246 unlink(this->FileName);
247 }
248 }
249
PrintSelf(ostream & os,vtkIndent indent)250 void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent)
251 {
252 Superclass::PrintSelf(os, indent);
253 os << indent << "DecimalPrecision: " << DecimalPrecision << "\n";
254 }
255
FillInputPortInformation(int,vtkInformation * info)256 int cv::viz::vtkOBJWriter::FillInputPortInformation(int, vtkInformation *info)
257 {
258 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
259 return 1;
260 }
261
GetInput()262 vtkPolyData* cv::viz::vtkOBJWriter::GetInput()
263 {
264 return vtkPolyData::SafeDownCast(this->Superclass::GetInput());
265 }
266
GetInput(int port)267 vtkPolyData* cv::viz::vtkOBJWriter::GetInput(int port)
268 {
269 return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port));
270 }
271