Commit 1ba42445 authored by Jan Möbius's avatar Jan Möbius

Plugin Collections for file, type and postprocessor plugins



git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15803 383ad7c9-94d9-4d36-a494-682f7c89f535
parents
include (plugin)
openflipper_plugin ()
This diff is collapsed.
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper 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, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef FILEOFFPLUGIN_HH
#define FILEOFFPLUGIN_HH
#include <QObject>
#include <OpenFlipper/common/Types.hh>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/FileInterface.hh>
#include <OpenFlipper/BasePlugin/LoadSaveInterface.hh>
#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
#include <OpenFlipper/BasePlugin/TypeInterface.hh>
#include <OpenFlipper/BasePlugin/StatusbarInterface.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
// Binary file support
#include <OpenMesh/Core/IO/SR_store.hh>
#include <limits>
#include "OFFImporter.hh"
class FileOFFPlugin : public QObject, BaseInterface, FileInterface, LoadSaveInterface,
LoggingInterface, ScriptInterface, StatusbarInterface
{
Q_OBJECT
Q_INTERFACES(FileInterface)
Q_INTERFACES(LoadSaveInterface)
Q_INTERFACES(LoggingInterface)
Q_INTERFACES(BaseInterface)
Q_INTERFACES(ScriptInterface)
Q_INTERFACES(StatusbarInterface)
signals:
void openedFile( int _id );
void addEmptyObject( DataType _type, int& _id);
void load(QString _filename, DataType _type, int& _id);
void save(int _id , QString _filename );
void log(Logtype _type, QString _message);
void log(QString _message);
void updateView();
void deleteObject( int _id );
// StatusbarInterface
void showStatusMessage(QString _message, int _timeout = 0);
void setStatus( ApplicationStatus::applicationStatus _status);
private slots:
void fileOpened( int /*_id*/ ){};
void noguiSupported( ) {} ;
void initializePlugin();
/// Slot called when user wants to save the given Load options as default
void slotLoadDefault();
/// Slot called when user wants to save the given Save options as default
void slotSaveDefault();
public :
FileOFFPlugin();
~FileOFFPlugin() {};
QString name() { return (QString("FileOFF")); };
QString description( ) { return (QString(tr("Load/Save OFF-Files"))); };
DataType supportedType();
QString getSaveFilters();
QString getLoadFilters();
QWidget* saveOptionsWidget(QString /*_currentFilter*/);
QWidget* loadOptionsWidget(QString /*_currentFilter*/);
public slots:
/// Loads Object and converts it to a triangle mesh if possible
int loadObject(QString _filename);
/// Loads Object with given datatype
int loadObject(QString _filename, DataType _type);
bool saveObject(int _id, QString _filename);
QString version() { return QString("1.1"); };
private:
/// Before Parsing the actual file, read all features supported
bool readFileOptions(QString _filename, OFFImporter& _importer);
/// Read OFF file and parse it
bool readOFFFile(QString _filename, OFFImporter& _importer);
/// Parse ascii OFF file
bool parseASCII(std::istream& _in, OFFImporter& _importer, DataType _type, QString& _objectName);
/// Parse binary OFF file
bool parseBinary(std::istream& _in, OFFImporter& _importer, DataType _type, QString& _objectName);
/// Get color type
int getColorType(std::string& _line, bool _texCoordsAvailable);
/// Update user options depending on which options have been selected
/// on the load dialog
void updateUserOptions();
/// Test if there are face color components (_nV is the initial face valence)
bool extendedFaceColorTest(std::istream& _in, uint _nV, uint _nF, int _nB) const;
// Binary reader and writer helpers
void readValue(std::istream& _in, float& _value) const {
float tmp;
OpenMesh::IO::restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
void readValue(std::istream& _in, int& _value) const {
OpenMesh::IO::int32_t tmp;
OpenMesh::IO::restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
void readValue(std::istream& _in, unsigned int& _value) const {
OpenMesh::IO::uint32_t tmp;
OpenMesh::IO::restore( _in , tmp, false ); //assuming LSB byte order
_value = tmp;
}
void writeValue(std::ostream& _out, int value) const {
OpenMesh::IO::uint32_t tmp = value;
OpenMesh::IO::store(_out, tmp, false);
}
void writeValue(std::ostream& _out, unsigned int value) const {
OpenMesh::IO::uint32_t tmp = value;
OpenMesh::IO::store(_out, tmp, false);
}
void writeValue(std::ostream& _out, float value) const {
float tmp = value;
OpenMesh::IO::store(_out, tmp, false);
}
void trimString( std::string& _string);
/** \brief Function to retrieve next line
*
* @param ifs The input stream we operate on
* @param _string This will be the output string
* @param _skipEmptyLines Skip empty/comment lines? If not, empty strings will be returned if comment or (remaining) line is empty
* @return
*/
bool getCleanLine( std::istream& ifs , std::string& _string, bool _skipEmptyLines = true);
/// Check for degenerate faces before adding them
bool checkDegenerateFace(const std::vector<VertexHandle>& _v);
/// Writer function
template< class MeshT >
bool writeMesh(std::ostream& _out, MeshT& _mesh );
/// Write binary mesh data to file
template< class MeshT >
bool writeBinaryData(std::ostream& _out, MeshT& _mesh );
/// Write ASCII mesh data to file
template< class MeshT >
bool writeASCIIData(std::ostream& _out, MeshT& _mesh );
/// backup per vertex/face texture coordinates
template <class MeshT>
void backupTextureCoordinates(MeshT& _mesh);
//Option Widgets
QWidget* loadOptions_;
QWidget* saveOptions_;
QCheckBox* saveBinary_;
QCheckBox* saveVertexColor_;
QCheckBox* saveFaceColor_;
QCheckBox* saveAlpha_;
QCheckBox* saveNormals_;
QCheckBox* saveTexCoords_;
QLabel* savePrecisionLabel_;
QSpinBox* savePrecision_;
QPushButton* saveDefaultButton_;
QComboBox* triMeshHandling_;
QCheckBox* loadVertexColor_;
QCheckBox* loadFaceColor_;
QCheckBox* loadAlpha_;
QCheckBox* loadNormals_;
QCheckBox* loadTexCoords_;
QCheckBox* loadCheckManifold_;
QPushButton* loadDefaultButton_;
unsigned int userReadOptions_;
unsigned int userWriteOptions_;
bool forceTriangleMesh_;
bool forcePolyMesh_;
bool readColorComp_;
};
#if defined(INCLUDE_TEMPLATES) && !defined(FILEOFFPLUGIN_C)
#define FILEOFFPLUGIN_TEMPLATES
#include "FileOFFT.cc"
#endif
#endif //FILEOFFPLUGIN_HH
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper 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, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#define FILEOFFPLUGIN_C
#include "FileOFF.hh"
#include <OpenMesh/Core/Utils/color_cast.hh>
#include <OpenMesh/Core/Geometry/VectorT.hh>
template< class MeshT >
bool FileOFFPlugin::writeMesh(std::ostream& _out, MeshT& _mesh ){
/*****************
* HEADER
******************/
// Write option ST
if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS) ) {
_out << "ST ";
}
// Write option C
if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR) ) {
_out << "C ";
}
// Write option N
if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL) ) {
_out << "N ";
}
// Write
_out << "OFF";
// Write BINARY
if(userWriteOptions_ & OFFImporter::BINARY) {
_out << " BINARY";
}
_out << "\n";
/*****************
* DATA
******************/
// Call corresponding write routine
if(userWriteOptions_ & OFFImporter::BINARY) {
return writeBinaryData(_out, _mesh);
} else {
if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
_out.precision(savePrecision_->value());
return writeASCIIData(_out, _mesh);
}
}
//------------------------------------------------------------------------------------------------------
template< class MeshT >
bool FileOFFPlugin::writeASCIIData(std::ostream& _out, MeshT& _mesh ) {
typename MeshT::Point p;
typename MeshT::Normal n;
typename OpenMesh::Vec4f c;
typename MeshT::TexCoord2D t;
typename MeshT::VertexIter vit = _mesh.vertices_begin();
typename MeshT::VertexIter end_vit = _mesh.vertices_end();
// #V #F #E
_out << _mesh.n_vertices() << " " << _mesh.n_faces() << " " << _mesh.n_edges();
// Write vertex data
for(; vit != end_vit; ++vit) {
_out << "\n";
// Write vertex p[0] p[1] p[2]
p = _mesh.point(vit.handle());
_out << p[0] << " " << p[1] << " " << p[2];
// Write vertex normals
if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL)) {
n = _mesh.normal(vit.handle());
_out << " " << n[0] << " " << n[1] << " " << n[2];
}
// Write vertex colors
// Note: Vertex colors always have only three components.
// This has to be determined since it can not be read dynamically in binary files.
if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR)) {
c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(vit.handle()));
_out << " " << std::showpoint << c[0] << " " << std::showpoint << c[1] << " " << std::showpoint << c[2] << " " << std::showpoint << c[3];
}
// Write vertex texcoords
if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS)) {
t = _mesh.texcoord2D(vit.handle());
_out << " " << t[0] << " " << t[1];
}
}
typename MeshT::FaceIter fit = _mesh.faces_begin();
typename MeshT::FaceIter end_fit = _mesh.faces_end();
typename MeshT::FaceVertexIter fvit;
// Write face data
for(; fit != end_fit; ++fit) {
_out << "\n";
// Write face valence
_out << _mesh.valence(fit.handle());
// Get face-vertex iterator
fvit = _mesh.fv_iter(fit.handle());
// Write vertex indices
for(;fvit; ++fvit) {
_out << " " << fvit.handle().idx();
}
// Write face colors
if(_mesh.has_face_colors() && (userWriteOptions_ & OFFImporter::FACECOLOR ) ) {
c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(fit.handle()));
_out << " " << std::showpoint << c[0] << " " << std::showpoint << c[1] << " " << std::showpoint << c[2] << " " << std::showpoint << c[3];
if(userWriteOptions_ & OFFImporter::COLORALPHA) _out << " " << std::showpoint << c[3];
}
}
return true;
}
//------------------------------------------------------------------------------------------------------
template< class MeshT >
bool FileOFFPlugin::writeBinaryData(std::ostream& _out, MeshT& _mesh ){
Vec3f v, n;
Vec2f t;
OpenMesh::Vec4f c(1.0,1.0,1.0,1.0);
OpenMesh::Vec3f p;
typename MeshT::VertexIter vit = _mesh.vertices_begin();
typename MeshT::VertexIter end_vit = _mesh.vertices_end();
// #vertices, #faces, #edges
writeValue(_out, (uint)_mesh.n_vertices() );
writeValue(_out, (uint)_mesh.n_faces() );
writeValue(_out, (uint)_mesh.n_edges() );
// Write vertex data
for(; vit != end_vit; ++vit) {
// Write vertex p[0] p[1] p[2]
p = _mesh.point(vit.handle());
writeValue(_out, p[0]);
writeValue(_out, p[1]);
writeValue(_out, p[2]);
// Write vertex normals
if(_mesh.has_vertex_normals() && (userWriteOptions_ & OFFImporter::VERTEXNORMAL)) {
n = _mesh.normal(vit.handle());
writeValue(_out, n[0]);
writeValue(_out, n[1]);
writeValue(_out, n[2]);
}
// Write vertex colors
// Note: Vertex colors always have only three components.
// This has to be determined since it can not be read dynamically in binary files.
if(_mesh.has_vertex_colors() && (userWriteOptions_ & OFFImporter::VERTEXCOLOR)) {
c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(vit.handle()));
writeValue(_out, c[0]);
writeValue(_out, c[1]);
writeValue(_out, c[2]);
}
// Write vertex texcoords
if(_mesh.has_vertex_texcoords2D() && (userWriteOptions_ & OFFImporter::VERTEXTEXCOORDS)) {
t = _mesh.texcoord2D(vit.handle());
writeValue(_out, t[0]);
writeValue(_out, t[1]);
}
}
typename MeshT::FaceIter fit = _mesh.faces_begin();
typename MeshT::FaceIter end_fit = _mesh.faces_end();
typename MeshT::FaceVertexIter fvit;
// Write face data
for(; fit != end_fit; ++fit) {
// Write face valence
writeValue(_out, _mesh.valence(fit.handle()));
// Get face-vertex iterator
fvit = _mesh.fv_iter(fit.handle());
// Write vertex indices
for(;fvit; ++fvit) {
writeValue(_out, fvit.handle().idx());
}
// Write face colors
if(_mesh.has_face_colors() && (userWriteOptions_ & OFFImporter::FACECOLOR)) {
// Number of color components
if(userWriteOptions_ & OFFImporter::COLORALPHA) writeValue(_out, (uint)4);
else writeValue(_out, (uint)3);
// Color itself
c = OpenMesh::color_cast<OpenMesh::Vec4f> (_mesh.color(fit.handle()));
writeValue(_out, c[0]);
writeValue(_out, c[1]);
writeValue(_out, c[2]);
if(userWriteOptions_ & OFFImporter::COLORALPHA) writeValue(_out, c[3]);
}
}
return true;
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper 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, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#include "OFFImporter.hh"
#include <OpenMesh/Core/Utils/vector_cast.hh>
//-----------------------------------------------------------------------------
/// base class needs virtual destructor
OFFImporter::~OFFImporter(){
}
//-----------------------------------------------------------------------------
/// constructor
OFFImporter::OFFImporter() :
polyMesh_(0),
triMesh_(0),
object_(0),
objectOptions_(0),
maxFaceValence_(0) {}
//-----------------------------------------------------------------------------
/// add a mesh
void OFFImporter::addObject( BaseObject* _object ){
PolyMeshObject* polyMeshObj = dynamic_cast< PolyMeshObject* > (_object);
TriMeshObject* triMeshObj = dynamic_cast< TriMeshObject* > (_object);
if ( polyMeshObj ){
polyMesh_ = polyMeshObj->mesh();
object_ = _object;
objectOptions_ |= POLYMESH;
objectOptions_ &= ~TRIMESH;
} else if ( triMeshObj ){
triMesh_ = triMeshObj->mesh();
object_ = _object;
objectOptions_ |= TRIMESH;
objectOptions_ &= ~POLYMESH;
} else {
std::cerr << "Error: Cannot add object. Type is unknown!" << std::endl;
}
}
//-----------------------------------------------------------------------------
/// get vertex with given index
Vec3f OFFImporter::vertex(uint _index){
if ( vertices_.size() > _index )
return vertices_[ _index ];
else
return Vec3f();
}
//-----------------------------------------------------------------------------
/// add texture coordinates
int OFFImporter::addTexCoord(const Vec2f& _coord){
texCoords_.push_back( _coord );
return texCoords_.size()-1;
}
//-----------------------------------------------------------------------------
/// add a normal
int OFFImporter::addNormal(const Vec3f& _normal){
normals_.push_back( _normal );