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 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 59 cv::viz::vtkOBJWriter::~vtkOBJWriter(){} 60 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 250 void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent) 251 { 252 Superclass::PrintSelf(os, indent); 253 os << indent << "DecimalPrecision: " << DecimalPrecision << "\n"; 254 } 255 256 int cv::viz::vtkOBJWriter::FillInputPortInformation(int, vtkInformation *info) 257 { 258 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData"); 259 return 1; 260 } 261 262 vtkPolyData* cv::viz::vtkOBJWriter::GetInput() 263 { 264 return vtkPolyData::SafeDownCast(this->Superclass::GetInput()); 265 } 266 267 vtkPolyData* cv::viz::vtkOBJWriter::GetInput(int port) 268 { 269 return vtkPolyData::SafeDownCast(this->Superclass::GetInput(port)); 270 } 271