First checkin for OpenMesh 2.0
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
17
Core/IO/writer/ACGMakefile
Normal file
17
Core/IO/writer/ACGMakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Config
|
||||
#==============================================================================
|
||||
|
||||
|
||||
SUBDIRS = $(call find-subdirs)
|
||||
|
||||
PACKAGES :=
|
||||
|
||||
PROJ_LIBS :=
|
||||
|
||||
MODULES := cxxlib
|
||||
|
||||
|
||||
#== SYSTEM PART -- DON'T TOUCH ==============================================
|
||||
include $(ACGMAKE)/Rules
|
||||
#==============================================================================
|
||||
88
Core/IO/writer/BaseWriter.cc
Normal file
88
Core/IO/writer/BaseWriter.cc
Normal file
@@ -0,0 +1,88 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#if defined(OM_CC_MIPS)
|
||||
# include <ctype.h>
|
||||
#else
|
||||
# include <cctype>
|
||||
#endif
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
|
||||
static inline char tolower(char c)
|
||||
{
|
||||
using namespace std;
|
||||
return ::tolower(c);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
BaseWriter::
|
||||
can_u_write(const std::string& _filename) const
|
||||
{
|
||||
// get file extension
|
||||
std::string extension;
|
||||
std::string::size_type pos(_filename.rfind("."));
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
extension = _filename.substr(pos+1, _filename.length()-pos-1);
|
||||
|
||||
std::transform( extension.begin(), extension.end(),
|
||||
extension.begin(), tolower );
|
||||
}
|
||||
|
||||
// locate extension in extension string
|
||||
return (get_extensions().find(extension) != std::string::npos);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
108
Core/IO/writer/BaseWriter.hh
Normal file
108
Core/IO/writer/BaseWriter.hh
Normal file
@@ -0,0 +1,108 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements the baseclass for IOManager writer modules
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __BASEWRITER_HH__
|
||||
#define __BASEWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
// STD C++
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// OpenMesh
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/IO/Options.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
Base class for all writer modules. The module should register itself at
|
||||
the IOManager by calling the register_module function.
|
||||
*/
|
||||
class BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
typedef unsigned int Option;
|
||||
|
||||
/// Return short description of the supported file format.
|
||||
virtual std::string get_description() const = 0;
|
||||
|
||||
/// Return file format's extension.
|
||||
virtual std::string get_extensions() const = 0;
|
||||
|
||||
/// Returns true if writer can parse _filename (checks extension)
|
||||
virtual bool can_u_write(const std::string& _filename) const;
|
||||
|
||||
/// Write to file _filename. Data source specified by BaseExporter _be.
|
||||
virtual bool write(const std::string& _filename,
|
||||
BaseExporter& _be,
|
||||
Options _opt) const = 0;
|
||||
|
||||
/// Returns expected size of file if binary format is supported else 0.
|
||||
virtual size_t binary_size(BaseExporter&, Options) const { return 0; }
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool check(BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals())
|
||||
&& (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords())
|
||||
&& (_opt.check(Options::VertexColor) <= _be.has_vertex_colors())
|
||||
&& (_opt.check(Options::FaceNormal) <= _be.has_face_normals())
|
||||
&& (_opt.check(Options::FaceColor) <= _be.has_face_colors());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
303
Core/IO/writer/OBJWriter.cc
Normal file
303
Core/IO/writer/OBJWriter.cc
Normal file
@@ -0,0 +1,303 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
//STL
|
||||
#include <fstream>
|
||||
|
||||
// OpenMesh
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/IO/writer/OBJWriter.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Utils/color_cast.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== INSTANCIATE =============================================================
|
||||
|
||||
|
||||
// register the OBJLoader singleton with MeshLoader
|
||||
_OBJWriter_ __OBJWriterinstance;
|
||||
_OBJWriter_& OBJWriter() { return __OBJWriterinstance; }
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
_OBJWriter_::_OBJWriter_() { IOManager().register_module(this); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_OBJWriter_::
|
||||
write(const std::string& _filename, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
std::fstream out(_filename.c_str(), std::ios_base::out );
|
||||
|
||||
if (!out)
|
||||
{
|
||||
omerr() << "[OBJWriter] : cannot open file "
|
||||
<< _filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
#if defined(WIN32)
|
||||
std::string::size_type dot = _filename.find_last_of("\\/");
|
||||
#else
|
||||
std::string::size_type dot = _filename.rfind("/");
|
||||
#endif
|
||||
|
||||
if (dot == std::string::npos){
|
||||
path_ = "./";
|
||||
objName_ = _filename;
|
||||
}else{
|
||||
path_ = _filename.substr(0,dot+1);
|
||||
objName_ = _filename.substr(dot+1);
|
||||
}
|
||||
|
||||
//remove the file extension
|
||||
dot = _filename.find_last_of(".");
|
||||
|
||||
if(dot != std::string::npos)
|
||||
objName_ = objName_.substr(0,dot-1);
|
||||
}
|
||||
|
||||
bool result = write(out, _be, _opt);
|
||||
|
||||
out.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int _OBJWriter_::getMaterial(OpenMesh::Vec3f _color) const
|
||||
{
|
||||
for (uint i=0; i < material_.size(); i++)
|
||||
if(material_[i] == _color)
|
||||
return i;
|
||||
|
||||
//not found add new material
|
||||
material_.push_back( _color );
|
||||
return material_.size()-1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int _OBJWriter_::getMaterial(OpenMesh::Vec4f _color) const
|
||||
{
|
||||
for (uint i=0; i < materialA_.size(); i++)
|
||||
if(materialA_[i] == _color)
|
||||
return i;
|
||||
|
||||
//not found add new material
|
||||
materialA_.push_back( _color );
|
||||
return materialA_.size()-1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
_OBJWriter_::
|
||||
writeMaterial(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
OpenMesh::Vec3f c;
|
||||
OpenMesh::Vec4f cA;
|
||||
|
||||
material_.clear();
|
||||
materialA_.clear();
|
||||
|
||||
//iterate over faces
|
||||
for (int i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
//color with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = color_cast<OpenMesh::Vec4f> (_be.colorA( FaceHandle(i) ));
|
||||
getMaterial(cA);
|
||||
}else{
|
||||
//and without alpha
|
||||
c = color_cast<OpenMesh::Vec3f> (_be.color( FaceHandle(i) ));
|
||||
getMaterial(c);
|
||||
}
|
||||
}
|
||||
|
||||
//write the materials
|
||||
if ( _opt.color_has_alpha() )
|
||||
for (uint i=0; i < materialA_.size(); i++){
|
||||
_out << "newmtl " << "mat" << i << std::endl;
|
||||
_out << "Ka 0.5000 0.5000 0.5000" << std::endl;
|
||||
_out << "Kd " << materialA_[i][0] << materialA_[i][1] << materialA_[i][2] << std::endl;;
|
||||
_out << "Tr " << materialA_[i][3] << std::endl;
|
||||
_out << "illum 1" << std::endl;
|
||||
}
|
||||
else
|
||||
for (uint i=0; i < material_.size(); i++){
|
||||
_out << "newmtl " << "mat" << i << std::endl;
|
||||
_out << "Ka 0.5000 0.5000 0.5000" << std::endl;
|
||||
_out << "Kd " << material_[i][0] << material_[i][1] << material_[i][2] << std::endl;;
|
||||
_out << "illum 1" << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_OBJWriter_::
|
||||
write(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
unsigned int i, j, nV, nF, idx;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
VertexHandle vh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
bool useMatrial = false;
|
||||
OpenMesh::Vec3f c;
|
||||
OpenMesh::Vec4f cA;
|
||||
|
||||
omlog() << "[OBJWriter] : write file\n";
|
||||
|
||||
|
||||
// check exporter features
|
||||
if (!check( _be, _opt))
|
||||
return false;
|
||||
|
||||
|
||||
// check writer features
|
||||
if ( _opt.check(Options::Binary) || // not supported by format
|
||||
_opt.check(Options::FaceNormal) ||
|
||||
_opt.check(Options::FaceColor))
|
||||
return false;
|
||||
|
||||
|
||||
//create material file if needed
|
||||
if ( _opt.check(Options::FaceColor) ){
|
||||
|
||||
std::string matFile = path_ + objName_ + ".mat";
|
||||
|
||||
std::fstream matStream(matFile.c_str(), std::ios_base::out );
|
||||
|
||||
if (!_out)
|
||||
{
|
||||
omerr() << "[OBJWriter] : cannot write material file " << matFile << std::endl;
|
||||
|
||||
}else{
|
||||
useMatrial = writeMaterial(matStream, _be, _opt);
|
||||
|
||||
matStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
// header
|
||||
_out << "# " << _be.n_vertices() << " vertices, ";
|
||||
_out << _be.n_faces() << " faces" << std::endl;
|
||||
|
||||
// material file
|
||||
if (useMatrial && _opt.check(Options::FaceColor) )
|
||||
_out << "mtllib " << objName_ << ".mat" << std::endl;
|
||||
|
||||
// vertex data (point, normals, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(i);
|
||||
v = _be.point(vh);
|
||||
n = _be.normal(vh);
|
||||
t = _be.texcoord(vh);
|
||||
|
||||
_out << "v " << v[0] <<" "<< v[1] <<" "<< v[2] << std::endl;
|
||||
|
||||
if (_opt.check(Options::VertexNormal))
|
||||
_out << "n " << n[0] <<" "<< n[1] <<" "<< n[2] << std::endl;
|
||||
|
||||
if (_opt.check(Options::VertexTexCoord))
|
||||
_out << "vt " << t[0] <<" "<< t[1] << std::endl;
|
||||
}
|
||||
|
||||
int lastMat = -1;
|
||||
|
||||
// faces (indices starting at 1 not 0)
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
|
||||
if (useMatrial && _opt.check(Options::FaceColor) ){
|
||||
int i;
|
||||
//color with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = color_cast<OpenMesh::Vec4f> (_be.colorA( FaceHandle(i) ));
|
||||
i = getMaterial(cA);
|
||||
}else{
|
||||
//and without alpha
|
||||
c = color_cast<OpenMesh::Vec3f> (_be.color( FaceHandle(i) ));
|
||||
i = getMaterial(c);
|
||||
}
|
||||
|
||||
if(lastMat != i)
|
||||
_out << "usemtl mat" << i << std::endl;
|
||||
}
|
||||
|
||||
_out << "f";
|
||||
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
|
||||
for (j=0; j< vhandles.size(); ++j)
|
||||
{
|
||||
idx = vhandles[j].idx() + 1;
|
||||
_out << " " << idx;
|
||||
|
||||
if (_opt.check(Options::VertexTexCoord))
|
||||
_out << "/" << idx;
|
||||
|
||||
if ( _opt.check(Options::VertexNormal) )
|
||||
_out << "/" << idx;
|
||||
}
|
||||
|
||||
_out << std::endl;
|
||||
}
|
||||
|
||||
material_.clear();
|
||||
materialA_.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
108
Core/IO/writer/OBJWriter.hh
Normal file
108
Core/IO/writer/OBJWriter.hh
Normal file
@@ -0,0 +1,108 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements an IOManager writer module for OBJ files
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __OBJWRITER_HH__
|
||||
#define __OBJWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
This class defines the OBJ writer. This class is further singleton'ed
|
||||
by SingletonT to OBJWriter.
|
||||
*/
|
||||
class _OBJWriter_ : public BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
_OBJWriter_();
|
||||
|
||||
std::string get_description() const { return "Alias/Wavefront"; }
|
||||
std::string get_extensions() const { return "obj"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
size_t binary_size(BaseExporter&, Options) const { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
mutable std::string path_;
|
||||
mutable std::string objName_;
|
||||
|
||||
mutable std::vector< OpenMesh::Vec3f > material_;
|
||||
mutable std::vector< OpenMesh::Vec4f > materialA_;
|
||||
|
||||
int getMaterial(OpenMesh::Vec3f _color) const;
|
||||
|
||||
int getMaterial(OpenMesh::Vec4f _color) const;
|
||||
|
||||
bool writeMaterial(std::fstream& _out, BaseExporter&, Options) const;
|
||||
|
||||
bool write(std::fstream& _out, BaseExporter&, Options) const;
|
||||
};
|
||||
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
|
||||
/// Declare the single entity of the OBJ writer
|
||||
extern _OBJWriter_ __OBJWriterinstance;
|
||||
_OBJWriter_& OBJWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
432
Core/IO/writer/OFFWriter.cc
Normal file
432
Core/IO/writer/OFFWriter.cc
Normal file
@@ -0,0 +1,432 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/IO/writer/OFFWriter.hh>
|
||||
|
||||
#include <OpenMesh/Core/IO/SR_store.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== INSTANCIATE =============================================================
|
||||
|
||||
|
||||
// register the OFFLoader singleton with MeshLoader
|
||||
_OFFWriter_ __OFFWriterInstance;
|
||||
_OFFWriter_& OFFWriter() { return __OFFWriterInstance; }
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
_OFFWriter_::_OFFWriter_() { IOManager().register_module(this); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_OFFWriter_::
|
||||
write(const std::string& _filename, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
// check exporter features
|
||||
if ( !check( _be, _opt ) )
|
||||
return false;
|
||||
|
||||
|
||||
// check writer features
|
||||
if ( _opt.check(Options::FaceNormal) ) // not supported by format
|
||||
return false;
|
||||
|
||||
// open file
|
||||
std::fstream out(_filename.c_str(), (_opt.check(Options::Binary) ? std::ios_base::binary | std::ios_base::out
|
||||
: std::ios_base::out) );
|
||||
if (!out)
|
||||
{
|
||||
omerr() << "[OFFWriter] : cannot open file "
|
||||
<< _filename
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// write header line
|
||||
if (_opt.check(Options::VertexTexCoord)) out << "ST";
|
||||
if (_opt.check(Options::VertexColor) || _opt.check(Options::FaceColor)) out << "C";
|
||||
if (_opt.check(Options::VertexNormal)) out << "N";
|
||||
out << "OFF";
|
||||
if (_opt.check(Options::Binary)) out << " BINARY";
|
||||
out << "\n";
|
||||
|
||||
|
||||
// write to file
|
||||
bool result = (_opt.check(Options::Binary) ?
|
||||
write_binary(out, _be, _opt) :
|
||||
write_ascii(out, _be, _opt));
|
||||
|
||||
|
||||
// return result
|
||||
out.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_OFFWriter_::
|
||||
write_ascii(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
omlog() << "[OFFWriter] : write ascii file\n";
|
||||
|
||||
|
||||
unsigned int i, j, nV, nF;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
OpenMesh::Vec3i c;
|
||||
OpenMesh::Vec4i cA;
|
||||
VertexHandle vh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
|
||||
// #vertices, #faces
|
||||
_out << _be.n_vertices() << " ";
|
||||
_out << _be.n_faces() << " ";
|
||||
_out << 0 << "\n";
|
||||
|
||||
|
||||
// vertex data (point, normals, colors, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(i);
|
||||
v = _be.point(vh);
|
||||
|
||||
//Vertex
|
||||
_out << v[0] << " " << v[1] << " " << v[2];
|
||||
|
||||
// VertexNormal
|
||||
if ( _opt.vertex_has_normal() ) {
|
||||
n = _be.normal(vh);
|
||||
_out << " " << n[0] << " " << n[1] << " " << n[2];
|
||||
}
|
||||
|
||||
// VertexColor
|
||||
if ( _opt.vertex_has_color() ) {
|
||||
//with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = _be.colorA(vh);
|
||||
_out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
}else{
|
||||
//without alpha
|
||||
c = _be.color(vh);
|
||||
_out << " " << c[0] << " " << c[1] << " " << c[2];
|
||||
}
|
||||
}
|
||||
|
||||
// TexCoord
|
||||
if (_opt.vertex_has_texcoord() ) {
|
||||
t = _be.texcoord(vh);
|
||||
_out << " " << t[0] << " " << t[1];
|
||||
}
|
||||
|
||||
_out << "\n";
|
||||
|
||||
}
|
||||
|
||||
// faces (indices starting at 0)
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
_out << 3 << " ";
|
||||
_out << vhandles[0].idx() << " ";
|
||||
_out << vhandles[1].idx() << " ";
|
||||
_out << vhandles[2].idx();
|
||||
|
||||
//face color
|
||||
if ( _opt.face_has_color() ){
|
||||
//with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = _be.colorA( FaceHandle(i) );
|
||||
_out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
}else{
|
||||
//without alpha
|
||||
c = _be.color( FaceHandle(i) );
|
||||
_out << " " << c[0] << " " << c[1] << " " << c[2];
|
||||
}
|
||||
}
|
||||
_out << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
_out << nV << " ";
|
||||
for (j=0; j<vhandles.size(); ++j)
|
||||
_out << vhandles[j].idx() << " ";
|
||||
|
||||
//face color
|
||||
if ( _opt.face_has_color() ){
|
||||
//with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = _be.colorA( FaceHandle(i) );
|
||||
_out << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
}else{
|
||||
//without alpha
|
||||
c = _be.color( FaceHandle(i) );
|
||||
_out << c[0] << " " << c[1] << " " << c[2];
|
||||
}
|
||||
}
|
||||
|
||||
_out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void _OFFWriter_::writeValue(std::fstream& _out, int value) const {
|
||||
|
||||
uint32_t tmp = value;
|
||||
store(_out, tmp, false);
|
||||
}
|
||||
|
||||
void _OFFWriter_::writeValue(std::fstream& _out, unsigned int value) const {
|
||||
|
||||
uint32_t tmp = value;
|
||||
store(_out, tmp, false);
|
||||
}
|
||||
|
||||
void _OFFWriter_::writeValue(std::fstream& _out, float value) const {
|
||||
|
||||
float32_t tmp = value;
|
||||
store(_out, tmp, false);
|
||||
}
|
||||
|
||||
bool
|
||||
_OFFWriter_::
|
||||
write_binary(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
omlog() << "[OFFWriter] : write ascii file\n";
|
||||
|
||||
|
||||
unsigned int i, j, nV, nF;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
OpenMesh::Vec4i c;
|
||||
VertexHandle vh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
|
||||
// #vertices, #faces
|
||||
writeValue(_out, (uint)_be.n_vertices() );
|
||||
writeValue(_out, (uint) _be.n_faces() );
|
||||
writeValue(_out, 0 );
|
||||
|
||||
|
||||
// vertex data (point, normals, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(i);
|
||||
v = _be.point(vh);
|
||||
|
||||
//vertex
|
||||
writeValue(_out, v[0]);
|
||||
writeValue(_out, v[1]);
|
||||
writeValue(_out, v[2]);
|
||||
|
||||
// vertex normal
|
||||
if ( _opt.vertex_has_normal() ) {
|
||||
n = _be.normal(vh);
|
||||
writeValue(_out, n[0]);
|
||||
writeValue(_out, n[1]);
|
||||
writeValue(_out, n[2]);
|
||||
}
|
||||
// vertex color
|
||||
if ( _opt.vertex_has_color() ) {
|
||||
c = _be.colorA(vh);
|
||||
writeValue(_out, c[0]);
|
||||
writeValue(_out, c[1]);
|
||||
writeValue(_out, c[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(_out, c[3]);
|
||||
}
|
||||
// texCoords
|
||||
if (_opt.vertex_has_texcoord() ) {
|
||||
t = _be.texcoord(vh);
|
||||
writeValue(_out, t[0]);
|
||||
writeValue(_out, t[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// faces (indices starting at 0)
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
//face
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
writeValue(_out, 3);
|
||||
writeValue(_out, vhandles[0].idx());
|
||||
writeValue(_out, vhandles[1].idx());
|
||||
writeValue(_out, vhandles[2].idx());
|
||||
|
||||
//face color
|
||||
if ( _opt.face_has_color() ){
|
||||
c = _be.colorA( FaceHandle(i) );
|
||||
writeValue(_out, c[0]);
|
||||
writeValue(_out, c[1]);
|
||||
writeValue(_out, c[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(_out, c[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
//face
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
writeValue(_out, nV);
|
||||
for (j=0; j<vhandles.size(); ++j)
|
||||
writeValue(_out, vhandles[j].idx() );
|
||||
|
||||
//face color
|
||||
if ( _opt.face_has_color() ){
|
||||
c = _be.colorA( FaceHandle(i) );
|
||||
writeValue(_out, c[0]);
|
||||
writeValue(_out, c[1]);
|
||||
writeValue(_out, c[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(_out, c[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
size_t
|
||||
_OFFWriter_::
|
||||
binary_size(BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
size_t header(0);
|
||||
size_t data(0);
|
||||
size_t _3longs(3*sizeof(long));
|
||||
size_t _3floats(3*sizeof(float));
|
||||
size_t _3ui(3*sizeof(unsigned int));
|
||||
size_t _4ui(4*sizeof(unsigned int));
|
||||
|
||||
if ( !_opt.is_binary() )
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
header += 11; // 'OFF BINARY\n'
|
||||
header += _3longs; // #V #F #E
|
||||
data += _be.n_vertices() * _3floats; // vertex data
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_normal() && _be.has_vertex_normals() )
|
||||
{
|
||||
header += 1; // N
|
||||
data += _be.n_vertices() * _3floats;
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_color() && _be.has_vertex_colors() )
|
||||
{
|
||||
header += 1; // C
|
||||
data += _be.n_vertices() * _3floats;
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_texcoord() && _be.has_vertex_texcoords() )
|
||||
{
|
||||
size_t _2floats(2*sizeof(float));
|
||||
header += 2; // ST
|
||||
data += _be.n_vertices() * _2floats;
|
||||
}
|
||||
|
||||
// topology
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
data += _be.n_faces() * _4ui;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i, nV, nF;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
data += nV * sizeof(unsigned int);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// face colors
|
||||
if ( _opt.face_has_color() && _be.has_face_colors() ){
|
||||
if ( _opt.color_has_alpha() )
|
||||
data += _be.n_faces() * _4ui;
|
||||
else
|
||||
data += _be.n_faces() * _3ui;
|
||||
}
|
||||
|
||||
return header+data;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
113
Core/IO/writer/OFFWriter.hh
Normal file
113
Core/IO/writer/OFFWriter.hh
Normal file
@@ -0,0 +1,113 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements a writer module for OFF files
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __OFFWRITER_HH__
|
||||
#define __OFFWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
Implementation of the OFF format writer. This class is singleton'ed by
|
||||
SingletonT to OFFWriter.
|
||||
|
||||
By passing Options to the write function you can manipulate the writing behavoir.
|
||||
The following options can be set:
|
||||
|
||||
Binary
|
||||
VertexNormal
|
||||
VertexColor
|
||||
VertexTexCoord
|
||||
FaceColor
|
||||
ColorAlpha
|
||||
|
||||
*/
|
||||
class _OFFWriter_ : public BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
_OFFWriter_();
|
||||
|
||||
std::string get_description() const { return "no description"; }
|
||||
std::string get_extensions() const { return "off"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
|
||||
|
||||
protected:
|
||||
void writeValue(std::fstream& _out, int value) const;
|
||||
void writeValue(std::fstream& _out, unsigned int value) const;
|
||||
void writeValue(std::fstream& _out, float value) const;
|
||||
|
||||
bool write_ascii(std::fstream& _in, BaseExporter&, Options) const;
|
||||
bool write_binary(std::fstream& _in, BaseExporter&, Options) const;
|
||||
};
|
||||
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
|
||||
/// Declare the single entity of the OFF writer.
|
||||
extern _OFFWriter_ __OFFWriterInstance;
|
||||
_OFFWriter_& OFFWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
504
Core/IO/writer/OMWriter.cc
Normal file
504
Core/IO/writer/OMWriter.cc
Normal file
@@ -0,0 +1,504 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
// -------------------- STL
|
||||
#if defined( OM_CC_MIPS )
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <ctime>
|
||||
# include <cstring>
|
||||
#endif
|
||||
#include <fstream>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/OMFormat.hh>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/OMWriter.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== INSTANCIATE =============================================================
|
||||
|
||||
|
||||
// register the OMLoader singleton with MeshLoader
|
||||
_OMWriter_ __OMWriterInstance;
|
||||
_OMWriter_& OMWriter() { return __OMWriterInstance; }
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
const OMFormat::uchar _OMWriter_::magic_[3] = "OM";
|
||||
const OMFormat::uint8 _OMWriter_::version_ = OMFormat::mk_version(1,2);
|
||||
|
||||
|
||||
_OMWriter_::
|
||||
_OMWriter_()
|
||||
{
|
||||
IOManager().register_module(this);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_OMWriter_::write(const std::string& _filename, BaseExporter& _be,
|
||||
Options _opt) const
|
||||
{
|
||||
// check whether exporter can give us an OpenMesh BaseKernel
|
||||
if (!_be.kernel()) return false;
|
||||
|
||||
|
||||
// check for om extension in filename, we can only handle OM
|
||||
if (_filename.rfind(".om") == std::string::npos)
|
||||
return false;
|
||||
|
||||
_opt += Options::Binary; // only binary format supported
|
||||
|
||||
std::ofstream ofs(_filename.c_str(), std::ios::binary);
|
||||
|
||||
// check if file is open
|
||||
if (!ofs.is_open())
|
||||
{
|
||||
omerr() << "[OMWriter] : cannot open file " << _filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// call stream save method
|
||||
bool rc = write(ofs, _be, _opt);
|
||||
|
||||
// close filestream
|
||||
ofs.close();
|
||||
|
||||
// return success/failure notice
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
_OMWriter_::write(std::ostream& _os, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
// std::clog << "[OMWriter]::write( stream )\n";
|
||||
|
||||
// check exporter features
|
||||
if ( !check( _be, _opt ) )
|
||||
{
|
||||
omerr() << "[OMWriter]: exporter does not support wanted feature!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Maybe an ascii version will be implemented in the future.
|
||||
// For now, support only a binary format
|
||||
if ( !_opt.check( Options::Binary ) )
|
||||
_opt += Options::Binary;
|
||||
|
||||
// Ignore LSB/MSB bit. Always store in LSB (little endian)
|
||||
_opt += Options::LSB;
|
||||
_opt -= Options::MSB;
|
||||
|
||||
// if ( _opt.check(Options::Binary) )
|
||||
// {
|
||||
return write_binary(_os, _be, _opt);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return write_ascii(_os, _be, _opt);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// bool _OMWriter_::write_ascii(std::ostream& _os, BaseExporter& _be,
|
||||
// Options _opt) const
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
template <typename T> struct Enabler
|
||||
{
|
||||
Enabler( T& obj ) : obj_(obj)
|
||||
{}
|
||||
|
||||
~Enabler() { obj_.enable(); }
|
||||
|
||||
T& obj_;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
Options _opt) const
|
||||
{
|
||||
Enabler<mostream> enabler(omlog());
|
||||
|
||||
omlog() << "[OMWriter] : write binary file\n";
|
||||
|
||||
size_t bytes = 0;
|
||||
|
||||
bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);
|
||||
|
||||
unsigned int i, nV, nF;
|
||||
Vec3f v;
|
||||
Vec2f t;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
|
||||
// -------------------- write header
|
||||
OMFormat::Header header;
|
||||
|
||||
header.magic_[0] = 'O';
|
||||
header.magic_[1] = 'M';
|
||||
header.mesh_ = _be.is_triangle_mesh() ? 'T' : 'P';
|
||||
header.version_ = version_;
|
||||
header.n_vertices_ = _be.n_vertices();
|
||||
header.n_faces_ = _be.n_faces();
|
||||
header.n_edges_ = _be.n_edges();
|
||||
|
||||
bytes += store( _os, header, swap );
|
||||
|
||||
// ---------------------------------------- write chunks
|
||||
|
||||
OMFormat::Chunk::Header chunk_header;
|
||||
|
||||
|
||||
// -------------------- write vertex data
|
||||
|
||||
// ---------- write vertex position
|
||||
if (_be.n_vertices())
|
||||
{
|
||||
v = _be.point(VertexHandle(0));
|
||||
chunk_header.reserved_ = 0;
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Pos;
|
||||
chunk_header.signed_ = OMFormat::is_signed(v[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(v[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(v);
|
||||
chunk_header.bits_ = OMFormat::bits(v[0]);
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.point(VertexHandle(i)), swap );
|
||||
}
|
||||
|
||||
|
||||
// ---------- write vertex normal
|
||||
if (_be.n_vertices() && _opt.check( Options::VertexNormal ))
|
||||
{
|
||||
Vec3f n = _be.normal(VertexHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Normal;
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.normal(VertexHandle(i)), swap );
|
||||
}
|
||||
|
||||
// ---------- write vertex color
|
||||
#if 1
|
||||
if (_opt.check( Options::VertexColor ) && _be.has_vertex_colors() )
|
||||
{
|
||||
Vec3uc c = _be.color(VertexHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Color;
|
||||
chunk_header.signed_ = OMFormat::is_signed( c );
|
||||
chunk_header.float_ = OMFormat::is_float( c );
|
||||
chunk_header.dim_ = OMFormat::dim( c );
|
||||
chunk_header.bits_ = OMFormat::bits( c );
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.color(VertexHandle(i)), swap );
|
||||
}
|
||||
#endif
|
||||
|
||||
// ---------- write vertex texture coords
|
||||
if (_be.n_vertices() && _opt.check(Options::VertexTexCoord))
|
||||
{
|
||||
t = _be.texcoord(VertexHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Texcoord;
|
||||
chunk_header.signed_ = OMFormat::is_signed(t[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(t[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(t);
|
||||
chunk_header.bits_ = OMFormat::bits(t[0]);
|
||||
|
||||
// std::clog << chunk_header << std::endl;
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.texcoord(VertexHandle(i)), swap );
|
||||
}
|
||||
|
||||
// -------------------- write face data
|
||||
|
||||
// ---------- write topology
|
||||
{
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Topology;
|
||||
chunk_header.signed_ = 0;
|
||||
chunk_header.float_ = 0;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D; // ignored
|
||||
chunk_header.bits_ = OMFormat::needed_bits(_be.n_vertices());
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
if ( header.mesh_ == 'P' )
|
||||
bytes += store( _os, vhandles.size(),
|
||||
OMFormat::Chunk::Integer_16, swap );
|
||||
|
||||
for (size_t j=0; j < vhandles.size(); ++j)
|
||||
{
|
||||
using namespace OMFormat;
|
||||
using namespace GenProg;
|
||||
|
||||
bytes += store( _os, vhandles[j].idx(),
|
||||
Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- write face normals
|
||||
|
||||
if ( _be.has_face_normals() && _opt.check(Options::FaceNormal) )
|
||||
{
|
||||
#define NEW_STYLE 0
|
||||
#if NEW_STYLE
|
||||
const BaseProperty *bp = _be.kernel()._get_fprop("f:normals");
|
||||
|
||||
if (bp)
|
||||
{
|
||||
#endif
|
||||
Vec3f n = _be.normal(FaceHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Normal;
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
#if !NEW_STYLE
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );
|
||||
#else
|
||||
bytes += bp->store(_os, swap );
|
||||
}
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
#undef NEW_STYLE
|
||||
}
|
||||
|
||||
|
||||
// ---------- write face color
|
||||
|
||||
if (_be.has_face_colors() && _opt.check( Options::FaceColor ))
|
||||
{
|
||||
#define NEW_STYLE 0
|
||||
#if NEW_STYLE
|
||||
const BaseProperty *bp = _be.kernel()._get_fprop("f:colors");
|
||||
|
||||
if (bp)
|
||||
{
|
||||
#endif
|
||||
Vec3uc c;
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Color;
|
||||
chunk_header.signed_ = OMFormat::is_signed( c[0] );
|
||||
chunk_header.float_ = OMFormat::is_float( c[0] );
|
||||
chunk_header.dim_ = OMFormat::dim( c );
|
||||
chunk_header.bits_ = OMFormat::bits( c[0] );
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
#if !NEW_STYLE
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
bytes += vector_store( _os, _be.color(FaceHandle(i)), swap );
|
||||
#else
|
||||
bytes += bp->store(_os, swap);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// -------------------- write custom properties
|
||||
|
||||
|
||||
BaseKernel::const_prop_iterator prop;
|
||||
|
||||
for (prop = _be.kernel()->vprops_begin();
|
||||
prop != _be.kernel()->vprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Vertex, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->fprops_begin();
|
||||
prop != _be.kernel()->fprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Face, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->eprops_begin();
|
||||
prop != _be.kernel()->eprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Edge, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->hprops_begin();
|
||||
prop != _be.kernel()->hprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Halfedge, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->mprops_begin();
|
||||
prop != _be.kernel()->mprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Mesh, swap );
|
||||
}
|
||||
|
||||
// std::clog << "#bytes written: " << bytes << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
size_t _OMWriter_::store_binary_custom_chunk(std::ostream& _os,
|
||||
const BaseProperty& _bp,
|
||||
OMFormat::Chunk::Entity _entity,
|
||||
bool _swap) const
|
||||
{
|
||||
omlog() << "Custom Property " << OMFormat::as_string(_entity) << " property ["
|
||||
<< _bp.name() << "]" << std::endl;
|
||||
|
||||
// Don't store if
|
||||
// 1. it is not persistent
|
||||
// 2. it's name is empty
|
||||
if ( !_bp.persistent() || _bp.name().empty() )
|
||||
{
|
||||
omlog() << " skipped\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t bytes = 0;
|
||||
|
||||
OMFormat::Chunk::esize_t element_size = _bp.element_size();
|
||||
OMFormat::Chunk::Header chdr;
|
||||
|
||||
// set header
|
||||
chdr.name_ = true;
|
||||
chdr.entity_ = _entity;
|
||||
chdr.type_ = OMFormat::Chunk::Type_Custom;
|
||||
chdr.signed_ = 0;
|
||||
chdr.float_ = 0;
|
||||
chdr.dim_ = OMFormat::Chunk::Dim_1D; // ignored
|
||||
chdr.bits_ = element_size;
|
||||
|
||||
|
||||
// write custom chunk
|
||||
|
||||
// 1. chunk header
|
||||
bytes += store( _os, chdr, _swap );
|
||||
|
||||
// 2. property name
|
||||
bytes += store( _os, OMFormat::Chunk::PropertyName(_bp.name()), _swap );
|
||||
|
||||
// 3. block size
|
||||
bytes += store( _os, _bp.size_of(), _swap );
|
||||
omlog() << " n_bytes = " << _bp.size_of() << std::endl;
|
||||
|
||||
// 4. data
|
||||
{
|
||||
size_t b;
|
||||
bytes += ( b=_bp.store( _os, _swap ) );
|
||||
omlog() << " b = " << b << std::endl;
|
||||
assert( b == _bp.size_of() );
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
size_t _OMWriter_::binary_size(BaseExporter& /* _be */, Options /* _opt */) const
|
||||
{
|
||||
// std::clog << "[OMWriter]: binary_size()" << std::endl;
|
||||
size_t bytes = sizeof( OMFormat::Header );
|
||||
|
||||
// !!!TODO!!!
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
119
Core/IO/writer/OMWriter.hh
Normal file
119
Core/IO/writer/OMWriter.hh
Normal file
@@ -0,0 +1,119 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements a writer module for OM files
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __OMWRITER_HH__
|
||||
#define __OMWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
// STD C++
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// OpenMesh
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||
#include <OpenMesh/Core/IO/OMFormat.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
//=== FORWARDS ================================================================
|
||||
|
||||
|
||||
class BaseExporter;
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the OM format writer. This class is singleton'ed by
|
||||
* SingletonT to OMWriter.
|
||||
*/
|
||||
class _OMWriter_ : public BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
// constructor
|
||||
_OMWriter_();
|
||||
|
||||
std::string get_description() const
|
||||
{ return "OpenMesh Format"; }
|
||||
|
||||
std::string get_extensions() const
|
||||
{ return "om"; }
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options) const;
|
||||
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
static const OMFormat::uchar magic_[3];
|
||||
static const OMFormat::uint8 version_;
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
bool write_binary(std::ostream&, BaseExporter&, Options) const;
|
||||
|
||||
size_t store_binary_custom_chunk( std::ostream&, const BaseProperty&,
|
||||
OMFormat::Chunk::Entity, bool) const;
|
||||
};
|
||||
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
|
||||
/// Declare the single entity of the OM writer.
|
||||
extern _OMWriter_ __OMWriterInstance;
|
||||
_OMWriter_& OMWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
476
Core/IO/writer/PLYWriter.cc
Normal file
476
Core/IO/writer/PLYWriter.cc
Normal file
@@ -0,0 +1,476 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/IO/writer/PLYWriter.hh>
|
||||
|
||||
#include <OpenMesh/Core/IO/SR_store.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== INSTANCIATE =============================================================
|
||||
|
||||
|
||||
// register the PLYLoader singleton with MeshLoader
|
||||
_PLYWriter_ __PLYWriterInstance;
|
||||
_PLYWriter_& PLYWriter() { return __PLYWriterInstance; }
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
_PLYWriter_::_PLYWriter_() { IOManager().register_module(this); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_PLYWriter_::
|
||||
write(const std::string& _filename, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
// check exporter features
|
||||
if ( !check( _be, _opt ) )
|
||||
return false;
|
||||
|
||||
|
||||
// check writer features
|
||||
if ( _opt.check(Options::FaceNormal) || _opt.check(Options::FaceColor) ) // not supported yet
|
||||
return false;
|
||||
|
||||
options_ = _opt;
|
||||
|
||||
// open file
|
||||
std::fstream out(_filename.c_str(), (_opt.check(Options::Binary) ? std::ios_base::binary | std::ios_base::out
|
||||
: std::ios_base::out) );
|
||||
if (!out)
|
||||
{
|
||||
omerr() << "[PLYWriter] : cannot open file "
|
||||
<< _filename
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// write to file
|
||||
bool result = (_opt.check(Options::Binary) ?
|
||||
write_binary(out, _be, _opt) :
|
||||
write_ascii(out, _be, _opt));
|
||||
|
||||
// return result
|
||||
out.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_PLYWriter_::
|
||||
write_ascii(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
omlog() << "[PLYWriter] : write ascii file\n";
|
||||
|
||||
|
||||
unsigned int i, j, nV, nF;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
OpenMesh::Vec3f c;
|
||||
OpenMesh::Vec4f cA;
|
||||
VertexHandle vh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
//writing header
|
||||
_out << "ply" << std::endl;
|
||||
_out << "format ascii 1.0" << std::endl;
|
||||
_out << "element vertex " << _be.n_vertices() << std::endl;
|
||||
|
||||
_out << "property float32 x" << std::endl;
|
||||
_out << "property float32 y" << std::endl;
|
||||
_out << "property float32 z" << std::endl;
|
||||
|
||||
if ( _opt.vertex_has_color() ){
|
||||
_out << "property int32 red" << std::endl;
|
||||
_out << "property int32 green" << std::endl;
|
||||
_out << "property int32 blue" << std::endl;
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
_out << "property int32 alpha" << std::endl;
|
||||
}
|
||||
|
||||
_out << "element face " << _be.n_faces() << std::endl;
|
||||
_out << "property list uint8 int32 vertex_indices" << std::endl;
|
||||
_out << "end_header" << std::endl;
|
||||
|
||||
// vertex data (point, normals, colors, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(i);
|
||||
v = _be.point(vh);
|
||||
|
||||
//Vertex
|
||||
_out << v[0] << " " << v[1] << " " << v[2];
|
||||
|
||||
// VertexColor
|
||||
if ( _opt.vertex_has_color() ) {
|
||||
//with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
cA = _be.colorA(vh);
|
||||
_out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
}else{
|
||||
//without alpha
|
||||
c = _be.color(vh);
|
||||
_out << " " << c[0] << " " << c[1] << " " << c[2];
|
||||
}
|
||||
}
|
||||
|
||||
_out << "\n";
|
||||
}
|
||||
|
||||
// faces (indices starting at 0)
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
_out << 3 << " ";
|
||||
_out << vhandles[0].idx() << " ";
|
||||
_out << vhandles[1].idx() << " ";
|
||||
_out << vhandles[2].idx();
|
||||
|
||||
// //face color
|
||||
// if ( _opt.face_has_color() ){
|
||||
// //with alpha
|
||||
// if ( _opt.color_has_alpha() ){
|
||||
// cA = _be.colorA( FaceHandle(i) );
|
||||
// _out << " " << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
// }else{
|
||||
// //without alpha
|
||||
// c = _be.color( FaceHandle(i) );
|
||||
// _out << " " << c[0] << " " << c[1] << " " << c[2];
|
||||
// }
|
||||
// }
|
||||
_out << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
_out << nV << " ";
|
||||
for (j=0; j<vhandles.size(); ++j)
|
||||
_out << vhandles[j].idx() << " ";
|
||||
|
||||
// //face color
|
||||
// if ( _opt.face_has_color() ){
|
||||
// //with alpha
|
||||
// if ( _opt.color_has_alpha() ){
|
||||
// cA = _be.colorA( FaceHandle(i) );
|
||||
// _out << cA[0] << " " << cA[1] << " " << cA[2] << " " << cA[3];
|
||||
// }else{
|
||||
// //without alpha
|
||||
// c = _be.color( FaceHandle(i) );
|
||||
// _out << c[0] << " " << c[1] << " " << c[2];
|
||||
// }
|
||||
// }
|
||||
|
||||
_out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void _PLYWriter_::writeValue(ValueType _type, std::fstream& _out, int value) const {
|
||||
|
||||
uint32_t tmp32;
|
||||
uint8_t tmp8;
|
||||
|
||||
switch (_type) {
|
||||
case ValueTypeINT:
|
||||
case ValueTypeINT32:
|
||||
tmp32 = value;
|
||||
store(_out, tmp32, options_.check(Options::MSB) );
|
||||
break;
|
||||
// case ValueTypeUINT8:
|
||||
default :
|
||||
tmp8 = value;
|
||||
store(_out, tmp8, options_.check(Options::MSB) );
|
||||
break;
|
||||
// default :
|
||||
// std::cerr << "unsupported conversion type to int: " << _type << std::endl;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
void _PLYWriter_::writeValue(ValueType _type, std::fstream& _out, unsigned int value) const {
|
||||
|
||||
uint32_t tmp32;
|
||||
uint8_t tmp8;
|
||||
|
||||
switch (_type) {
|
||||
case ValueTypeINT:
|
||||
case ValueTypeINT32:
|
||||
tmp32 = value;
|
||||
store(_out, tmp32, options_.check(Options::MSB) );
|
||||
break;
|
||||
// case ValueTypeUINT8:
|
||||
default :
|
||||
tmp8 = value;
|
||||
store(_out, tmp8, options_.check(Options::MSB) );
|
||||
break;
|
||||
// default :
|
||||
// std::cerr << "unsupported conversion type to int: " << _type << std::endl;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
void _PLYWriter_::writeValue(ValueType _type, std::fstream& _out, float value) const {
|
||||
|
||||
float32_t tmp;
|
||||
|
||||
switch (_type) {
|
||||
case ValueTypeFLOAT32:
|
||||
case ValueTypeFLOAT:
|
||||
tmp = value;
|
||||
store( _out , tmp, options_.check(Options::MSB) );
|
||||
break;
|
||||
default :
|
||||
std::cerr << "unsupported conversion type to float: " << _type << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
_PLYWriter_::
|
||||
write_binary(std::fstream& _out, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
omlog() << "[PLYWriter] : write binary file\n";
|
||||
|
||||
unsigned int i, j, nV, nF;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
OpenMesh::Vec4f c;
|
||||
VertexHandle vh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
|
||||
//writing header
|
||||
_out << "ply" << std::endl;
|
||||
_out << "format ";
|
||||
|
||||
if ( options_.check(Options::MSB) )
|
||||
_out << "binary_big_endian ";
|
||||
else
|
||||
_out << "binary_little_endian ";
|
||||
|
||||
_out << "1.0" << std::endl;
|
||||
|
||||
_out << "element vertex " << _be.n_vertices() << std::endl;
|
||||
|
||||
_out << "property float32 x" << std::endl;
|
||||
_out << "property float32 y" << std::endl;
|
||||
_out << "property float32 z" << std::endl;
|
||||
|
||||
if ( _opt.vertex_has_color() ){
|
||||
_out << "property int32 red" << std::endl;
|
||||
_out << "property int32 green" << std::endl;
|
||||
_out << "property int32 blue" << std::endl;
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
_out << "property int32 alpha" << std::endl;
|
||||
}
|
||||
|
||||
_out << "element face " << _be.n_faces() << std::endl;
|
||||
_out << "property list uchar int32 vertex_indices" << std::endl;
|
||||
_out << "end_header" << std::endl;
|
||||
|
||||
// vertex data (point, normals, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(i);
|
||||
v = _be.point(vh);
|
||||
|
||||
//vertex
|
||||
writeValue(ValueTypeFLOAT, _out, v[0]);
|
||||
writeValue(ValueTypeFLOAT, _out, v[1]);
|
||||
writeValue(ValueTypeFLOAT, _out, v[2]);
|
||||
|
||||
// vertex color
|
||||
if ( _opt.vertex_has_color() ) {
|
||||
c = _be.colorA(vh);
|
||||
writeValue(ValueTypeINT32, _out, (int)c[0]);
|
||||
writeValue(ValueTypeINT32, _out, (int)c[1]);
|
||||
writeValue(ValueTypeINT32, _out, (int)c[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(ValueTypeINT32, _out, (int)c[3]);
|
||||
}
|
||||
}
|
||||
|
||||
// faces (indices starting at 0)
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
//face
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
writeValue(ValueTypeUINT8, _out, 3);
|
||||
writeValue(ValueTypeINT32, _out, vhandles[0].idx());
|
||||
writeValue(ValueTypeINT32, _out, vhandles[1].idx());
|
||||
writeValue(ValueTypeINT32, _out, vhandles[2].idx());
|
||||
|
||||
// //face color
|
||||
// if ( _opt.face_has_color() ){
|
||||
// c = _be.colorA( FaceHandle(i) );
|
||||
// writeValue(_out, c[0]);
|
||||
// writeValue(_out, c[1]);
|
||||
// writeValue(_out, c[2]);
|
||||
//
|
||||
// if ( _opt.color_has_alpha() )
|
||||
// writeValue(_out, c[3]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
//face
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
writeValue(ValueTypeUINT8, _out, nV);
|
||||
for (j=0; j<vhandles.size(); ++j)
|
||||
writeValue(ValueTypeINT32, _out, vhandles[j].idx() );
|
||||
|
||||
// //face color
|
||||
// if ( _opt.face_has_color() ){
|
||||
// c = _be.colorA( FaceHandle(i) );
|
||||
// writeValue(_out, c[0]);
|
||||
// writeValue(_out, c[1]);
|
||||
// writeValue(_out, c[2]);
|
||||
//
|
||||
// if ( _opt.color_has_alpha() )
|
||||
// writeValue(_out, c[3]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
size_t
|
||||
_PLYWriter_::
|
||||
binary_size(BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
size_t header(0);
|
||||
size_t data(0);
|
||||
size_t _3longs(3*sizeof(long));
|
||||
size_t _3floats(3*sizeof(float));
|
||||
size_t _3ui(3*sizeof(unsigned int));
|
||||
size_t _4ui(4*sizeof(unsigned int));
|
||||
|
||||
if ( !_opt.is_binary() )
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
header += 11; // 'OFF BINARY\n'
|
||||
header += _3longs; // #V #F #E
|
||||
data += _be.n_vertices() * _3floats; // vertex data
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_normal() && _be.has_vertex_normals() )
|
||||
{
|
||||
header += 1; // N
|
||||
data += _be.n_vertices() * _3floats;
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_color() && _be.has_vertex_colors() )
|
||||
{
|
||||
header += 1; // C
|
||||
data += _be.n_vertices() * _3floats;
|
||||
}
|
||||
|
||||
if ( _opt.vertex_has_texcoord() && _be.has_vertex_texcoords() )
|
||||
{
|
||||
size_t _2floats(2*sizeof(float));
|
||||
header += 2; // ST
|
||||
data += _be.n_vertices() * _2floats;
|
||||
}
|
||||
|
||||
// topology
|
||||
if (_be.is_triangle_mesh())
|
||||
{
|
||||
data += _be.n_faces() * _4ui;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i, nV, nF;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
data += nV * sizeof(unsigned int);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// face colors
|
||||
if ( _opt.face_has_color() && _be.has_face_colors() ){
|
||||
if ( _opt.color_has_alpha() )
|
||||
data += _be.n_faces() * _4ui;
|
||||
else
|
||||
data += _be.n_faces() * _3ui;
|
||||
}
|
||||
|
||||
return header+data;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
116
Core/IO/writer/PLYWriter.hh
Normal file
116
Core/IO/writer/PLYWriter.hh
Normal file
@@ -0,0 +1,116 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements a writer module for PLY files
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __PLYWRITER_HH__
|
||||
#define __PWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
Implementation of the PLY format writer. This class is singleton'ed by
|
||||
SingletonT to PLYWriter.
|
||||
|
||||
currently supported options:
|
||||
- VertexColors
|
||||
- Binary
|
||||
- Binary -> MSB
|
||||
*/
|
||||
class _PLYWriter_ : public BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
_PLYWriter_();
|
||||
|
||||
std::string get_description() const { return "PLY polygon file format"; }
|
||||
std::string get_extensions() const { return "ply"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
|
||||
enum ValueType {
|
||||
Unsupported ,
|
||||
ValueTypeFLOAT32, ValueTypeFLOAT,
|
||||
ValueTypeUINT8, ValueTypeINT32, ValueTypeINT ,
|
||||
ValueTypeUCHAR
|
||||
};
|
||||
|
||||
private:
|
||||
mutable Options options_;
|
||||
|
||||
protected:
|
||||
void writeValue(ValueType _type, std::fstream& _out, int value) const;
|
||||
void writeValue(ValueType _type, std::fstream& _out, unsigned int value) const;
|
||||
void writeValue(ValueType _type, std::fstream& _out, float value) const;
|
||||
|
||||
bool write_ascii(std::fstream& _in, BaseExporter&, Options) const;
|
||||
bool write_binary(std::fstream& _in, BaseExporter&, Options) const;
|
||||
};
|
||||
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
|
||||
/// Declare the single entity of the PLY writer.
|
||||
extern _PLYWriter_ __PLYWriterInstance;
|
||||
_PLYWriter_& PLYWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
278
Core/IO/writer/STLWriter.cc
Normal file
278
Core/IO/writer/STLWriter.cc
Normal file
@@ -0,0 +1,278 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
//STL
|
||||
#include <fstream>
|
||||
|
||||
// OpenMesh
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/System/omstream.hh>
|
||||
#include <OpenMesh/Core/Geometry/VectorT.hh>
|
||||
#include <OpenMesh/Core/IO/BinaryHelper.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
#include <OpenMesh/Core/IO/writer/STLWriter.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== INSTANCIATE =============================================================
|
||||
|
||||
|
||||
_STLWriter_ __STLWriterInstance;
|
||||
_STLWriter_& STLWriter() { return __STLWriterInstance; }
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
_STLWriter_::_STLWriter_() { IOManager().register_module(this); }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_STLWriter_::
|
||||
write(const std::string& _filename, BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
// check exporter features
|
||||
if (!check(_be, _opt)) return false;
|
||||
|
||||
|
||||
// check writer features
|
||||
if (_opt.check(Options::VertexNormal) ||
|
||||
_opt.check(Options::VertexTexCoord) ||
|
||||
_opt.check(Options::FaceColor))
|
||||
return false;
|
||||
|
||||
|
||||
// binary or ascii ?
|
||||
if (_filename.rfind(".stla") != std::string::npos)
|
||||
{
|
||||
_opt -= Options::Binary;
|
||||
return write_stla(_filename, _be, _opt);
|
||||
}
|
||||
else if (_filename.rfind(".stlb") != std::string::npos)
|
||||
{
|
||||
_opt += Options::Binary;
|
||||
return write_stlb(_filename, _be, _opt);
|
||||
}
|
||||
else if (_filename.rfind(".stl") != std::string::npos)
|
||||
{
|
||||
return (_opt.check( Options::Binary )
|
||||
? write_stlb(_filename, _be, _opt)
|
||||
: write_stla(_filename, _be, _opt) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_STLWriter_::
|
||||
write_stla(const std::string& _filename, BaseExporter& _be, Options /* _opt */) const
|
||||
{
|
||||
omlog() << "[STLWriter] : write ascii file\n";
|
||||
|
||||
|
||||
// open file
|
||||
FILE* out = fopen(_filename.c_str(), "w");
|
||||
if (!out)
|
||||
{
|
||||
omerr() << "[STLWriter] : cannot open file " << _filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned int i, nF(_be.n_faces()), nV;
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
|
||||
|
||||
// header
|
||||
fprintf(out, "solid\n");
|
||||
|
||||
|
||||
// write face set
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
a = _be.point(vhandles[0]);
|
||||
b = _be.point(vhandles[1]);
|
||||
c = _be.point(vhandles[2]);
|
||||
n = (_be.has_face_normals() ?
|
||||
_be.normal(fh) :
|
||||
((c-b) % (a-b)).normalize());
|
||||
|
||||
fprintf(out, "facet normal %f %f %f\nouter loop\n", n[0], n[1], n[2]);
|
||||
fprintf(out, "vertex %.10f %.10f %.10f\n", a[0], a[1], a[2]);
|
||||
fprintf(out, "vertex %.10f %.10f %.10f\n", b[0], b[1], b[2]);
|
||||
fprintf(out, "vertex %.10f %.10f %.10f", c[0], c[1], c[2]);
|
||||
}
|
||||
else
|
||||
omerr() << "[STLWriter] : Warning non-triangle data!\n";
|
||||
|
||||
fprintf(out, "\nendloop\nendfacet\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
fclose(out);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
_STLWriter_::
|
||||
write_stlb(const std::string& _filename, BaseExporter& _be, Options /* _opt */) const
|
||||
{
|
||||
omlog() << "[STLWriter] : write binary file\n";
|
||||
|
||||
|
||||
// open file
|
||||
FILE* out = fopen(_filename.c_str(), "wb");
|
||||
if (!out)
|
||||
{
|
||||
omerr() << "[STLWriter] : cannot open file " << _filename << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
unsigned int i, nF(_be.n_faces()), nV;
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
|
||||
|
||||
// write header
|
||||
const char header[80] =
|
||||
"binary stl file"
|
||||
" ";
|
||||
fwrite(header, 1, 80, out);
|
||||
|
||||
|
||||
// number of faces
|
||||
write_int(_be.n_faces(), out);
|
||||
|
||||
|
||||
// write face set
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
a = _be.point(vhandles[0]);
|
||||
b = _be.point(vhandles[1]);
|
||||
c = _be.point(vhandles[2]);
|
||||
n = (_be.has_face_normals() ?
|
||||
_be.normal(fh) :
|
||||
((c-b) % (a-b)).normalize());
|
||||
|
||||
// face normal
|
||||
write_float(n[0], out);
|
||||
write_float(n[1], out);
|
||||
write_float(n[2], out);
|
||||
|
||||
// face vertices
|
||||
write_float(a[0], out);
|
||||
write_float(a[1], out);
|
||||
write_float(a[2], out);
|
||||
|
||||
write_float(b[0], out);
|
||||
write_float(b[1], out);
|
||||
write_float(b[2], out);
|
||||
|
||||
write_float(c[0], out);
|
||||
write_float(c[1], out);
|
||||
write_float(c[2], out);
|
||||
|
||||
// space filler
|
||||
write_short(0, out);
|
||||
}
|
||||
else
|
||||
omerr() << "[STLWriter] : Warning: Skipped non-triangle data!\n";
|
||||
}
|
||||
|
||||
|
||||
fclose(out);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
size_t
|
||||
_STLWriter_::
|
||||
binary_size(BaseExporter& _be, Options /* _opt */) const
|
||||
{
|
||||
size_t bytes(0);
|
||||
size_t _12floats(12*sizeof(float));
|
||||
|
||||
bytes += 80; // header
|
||||
bytes += 4; // #faces
|
||||
|
||||
|
||||
unsigned int i, nF(_be.n_faces());
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
for (i=0; i<nF; ++i)
|
||||
if (_be.get_vhandles(FaceHandle(i), vhandles) == 3)
|
||||
bytes += _12floats + sizeof(short);
|
||||
else
|
||||
omerr() << "[STLWriter] : Warning: Skipped non-triangle data!\n";
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
100
Core/IO/writer/STLWriter.hh
Normal file
100
Core/IO/writer/STLWriter.hh
Normal file
@@ -0,0 +1,100 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* License *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as published *
|
||||
* by the Free Software Foundation, version 2.1. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Implements a writer module for STL ascii files
|
||||
//
|
||||
//=============================================================================
|
||||
// $Id: STLWriter.hh,v 1.2 2007-05-18 15:17:43 habbecke Exp $
|
||||
|
||||
#ifndef __STLWRITER_HH__
|
||||
#define __STLWRITER_HH__
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
// -------------------- STL
|
||||
#if defined( OM_CC_MIPS )
|
||||
# include <stdio.h>
|
||||
#else
|
||||
# include <cstdio>
|
||||
#endif
|
||||
#include <string>
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Utils/SingletonT.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/BaseWriter.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
namespace IO {
|
||||
|
||||
|
||||
//=== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/**
|
||||
Implementation of the STL format writer. This class is singleton'ed by
|
||||
SingletonT to STLWriter.
|
||||
*/
|
||||
class _STLWriter_ : public BaseWriter
|
||||
{
|
||||
public:
|
||||
|
||||
_STLWriter_();
|
||||
|
||||
std::string get_description() const { return "Stereolithography Format"; }
|
||||
std::string get_extensions() const { return "stla stlb"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
size_t binary_size(BaseExporter&, Options) const;
|
||||
|
||||
private:
|
||||
bool write_stla(const std::string&, BaseExporter&, Options) const;
|
||||
bool write_stlb(const std::string&, BaseExporter&, Options) const;
|
||||
};
|
||||
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
|
||||
// Declare the single entity of STL writer.
|
||||
extern _STLWriter_ __STLWriterInstance;
|
||||
_STLWriter_& STLWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
Reference in New Issue
Block a user