Commit 625300c0 authored by Isaak Lim's avatar Isaak Lim
Browse files

- added precision option for the OpenFlipper FileInterface

- implemented precision option for File plugins where possible
- omitted OpenVolumeMesh implementation for now

refs #1157

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@15657 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 04290b9c
......@@ -245,7 +245,7 @@ add_point(const Point& _p)
// add available properties
if( vertex_normals_available() )
vnormals_.push_back( Point(0,0,0));
if( vertex_binormals_available() )
vbinormals_.push_back( Point(0,0,0));
......@@ -288,14 +288,14 @@ PolyLineT<PointT>::
insert_point(int _idx, const Point& _p)
{
assert(_idx < (int)n_vertices() );
// insert new point
points_.insert(points_.begin()+_idx, _p);
// insert available properties
if( vertex_normals_available() )
vnormals_.insert(vnormals_.begin()+_idx, Point(0,0,0));
if( vertex_binormals_available() )
vbinormals_.insert(vbinormals_.begin()+_idx, Point(0,0,0));
......@@ -332,7 +332,7 @@ insert_point(int _idx, const Point& _p)
//-----------------------------------------------------------------------------
template <class PointT>
void
......@@ -348,7 +348,7 @@ delete_point(int _idx)
// delete available properties
if( vertex_normals_available() )
vnormals_.erase(vnormals_.begin()+_idx);
if( vertex_binormals_available() )
vbinormals_.erase(vbinormals_.begin()+_idx);
......@@ -1029,7 +1029,7 @@ load(const char* _filename)
}
else if(token == "VEHANDLES")
{
if(!vertex_ehandles_available()) request_vertex_ehandles();
if(!vertex_ehandles_available()) request_vertex_ehandles();
for(unsigned int i=0; i<n_vertices(); ++i)
fin >> vertex_ehandle(i);
}
......@@ -1071,10 +1071,12 @@ load(const char* _filename)
template <class PointT>
void
PolyLineT<PointT>::
save(const char* _filename) const
save(const char* _filename, std::streamsize _precision) const
{
std::ofstream fout(_filename, std::ios::out);
fout.precision(_precision);
// is polyline closed?
fout << closed_ << std::endl;
......@@ -1117,7 +1119,7 @@ save(const char* _filename) const
for( unsigned int i=0; i<n_vertices(); ++i)
fout << vertex_fhandle(i) << std::endl;
}
if(vertex_normals_available())
{
fout << "VNORMALS" << std::endl;
......@@ -1128,7 +1130,7 @@ save(const char* _filename) const
fout << vnormals_[i][2] << std::endl;
}
}
if(vertex_binormals_available())
{
fout << "VBINORMALS" << std::endl;
......@@ -1206,7 +1208,7 @@ copy_vertex_complete(const PolyLineT<PointT>& _pl, unsigned int _i, unsigned int
if( _pl.vertex_normals_available())
if( vertex_normals_available())
vertex_normal(_j) = _pl.vertex_normal(_i);
if( _pl.vertex_binormals_available())
if( vertex_binormals_available())
vertex_binormal(_j) = _pl.vertex_binormal(_i);
......
......@@ -160,7 +160,7 @@ public:
const Point& back() const { return points_[n_vertices()-1];}
/// \brief get the i-th oriented edge vector
Point edge_vector(unsigned int _i) const
Point edge_vector(unsigned int _i) const
{ return(point((_i+1)%n_vertices())-point(_i));}
/** \brief Compute the length of the polyline (in future cached method)
......@@ -289,7 +289,7 @@ public:
void load( const char* _filename);
/// \brief Save polyline to a file
void save( const char* _filename) const;
void save( const char* _filename, std::streamsize _precision = 6) const;
// ############################### Standard Property Handling #############################
......@@ -341,7 +341,7 @@ public:
// property access ( no range or availability check! )
Point& vertex_normal(unsigned int _i) { return vnormals_[_i];}
const Point& vertex_normal(unsigned int _i) const { return vnormals_[_i];}
Point& vertex_binormal(unsigned int _i) { return vbinormals_[_i];}
const Point& vertex_binormal(unsigned int _i) const { return vbinormals_[_i];}
......@@ -376,13 +376,13 @@ public:
const unsigned char& edge_selection(unsigned int _i) const {return eselections_[_i];}
// ############################### SelectionWrappers ############################
bool vertex_selected(unsigned int _i) { return (_i < vselections_.size() ? vertex_selection(_i) == 1 : false); }
bool edge_selected(unsigned int _i) { return (_i < eselections_.size() ? edge_selection(_i) == 1 : false); }
void select_vertex(unsigned int _i) { if(_i < vselections_.size()) vertex_selection(_i) = 1; }
void select_edge(unsigned int _i) { if(_i < eselections_.size()) edge_selection(_i) = 1; }
void deselect_vertex(unsigned int _i) { if(_i < vselections_.size()) vertex_selection(_i) = 0; }
void deselect_edge(unsigned int _i) { if(_i < eselections_.size()) edge_selection(_i) = 0; }
......
......@@ -70,7 +70,7 @@ class FileInterface {
public:
/// Destructor
virtual ~FileInterface() {};
virtual ~FileInterface() {};
/** You can provide a special widget showing options for saving your file types
* depending on the current filter
......@@ -184,7 +184,7 @@ public slots:
* provided dataTypes ( see supportedType ).
* Additionally to the filename you get the id of the object to save
*/
virtual bool saveObject(int _id, QString _filename) = 0;
virtual bool saveObject(int _id, QString _filename, std::streamsize _precision = 6) = 0;
/** \brief Save multiple objects to one file
*
......
......@@ -146,34 +146,34 @@ void trimString( std::string& _string) {
//-----------------------------------------------------------------------------------------------------
int FileBVHPlugin::loadObject(QString _filename) {
if ( checkJointScaling_ != 0 )
ignoreJointScaling_ = checkJointScaling_->isChecked();
else
ignoreJointScaling_ = OpenFlipperSettings().value("FileBVH/Load/JointScaling",true).toBool();
//setup filestream
std::fstream input( _filename.toUtf8(), std::ios_base::in );
if ( !input.is_open() || !input.good() ){
emit log(LOGERR, tr("Error: cannot open file %1").arg(_filename) );
return -1;
}
//add a skeleton
int id = -1;
emit addEmptyObject(DATA_SKELETON, id);
BaseObjectData* object = 0;
Skeleton* skeleton = 0;
if(PluginFunctions::getObject( id, object)){
skeleton = PluginFunctions::skeleton( object );
object->setFromFileName(_filename);
object->setName(object->filename());
}
if (skeleton == 0){
emit log(LOGERR, tr("Error: Unable to add skeleton!"));
return -1;
......@@ -181,20 +181,20 @@ int FileBVHPlugin::loadObject(QString _filename) {
Skeleton::Joint* currentParent = 0;
Skeleton::Pose* refPose = skeleton->referencePose();
std::string line;
std::string keyWrd;
std::bitset<4> waitingFor = HIERARCHY;
std::map< Skeleton::Joint* , JointInfo> jointInfos;
uint dataOffset = 0; //Offset of the current channel in the frame data
AnimationHandle animHandle;
uint currentFrame = 0;
uint frameCount = 0;
while( input && !input.eof() )
{
std::getline(input,line);
......@@ -205,7 +205,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
// Trim Both leading and trailing spaces
trimString(line);
// ignore empty lines
if ( line.size() == 0 )
continue;
......@@ -220,10 +220,10 @@ int FileBVHPlugin::loadObject(QString _filename) {
waitingFor = ROOT_DEFINITION;
continue;
}
//ROOT_DEFINITION
if ( (waitingFor == ROOT_DEFINITION) && (keyWrd == "ROOT") ){
std::string name;
stream >> name;
......@@ -236,7 +236,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
waitingFor = OPENED_BRACKET;
continue;
}
//OPENED_BRACKET
if ( (waitingFor == OPENED_BRACKET) && (keyWrd == "{") ){
......@@ -257,23 +257,23 @@ int FileBVHPlugin::loadObject(QString _filename) {
currentParent = currentParent->parent();
continue;
}
//JOINT
if ( (!(waitingFor&JOINT).none()) && (keyWrd == "JOINT") ){
std::string name;
stream >> name;
Skeleton::Joint* newJoint = new Skeleton::Joint(currentParent, name);
skeleton->addJoint(currentParent, newJoint);
JointInfo info; //we found a new Joint, hence we need an ne JointInfo to store the channel inforamtions.
jointInfos[newJoint]=info; //store Joint info for later use in case of CHANNELS
currentParent = newJoint;
waitingFor = OPENED_BRACKET;
continue;
}
//OFFSET
if ( (!(waitingFor&OFFSET).none()) && (keyWrd == "OFFSET") ){
......@@ -282,18 +282,18 @@ int FileBVHPlugin::loadObject(QString _filename) {
stream >> translation[0];
stream >> translation[1];
stream >> translation[2];
refPose->setLocalTranslation(currentParent->id(), translation );
continue;
}
//CHANNELS
if ( (!(waitingFor&CHANNELS).none()) && (keyWrd == "CHANNELS") ){
uint channelCount;
stream >> channelCount;
JointInfo& info=jointInfos[ currentParent ];
if(channelCount>6) //well somethings wrong here...
......@@ -316,9 +316,9 @@ int FileBVHPlugin::loadObject(QString _filename) {
info.dataChannels[info.channelOffset]=YR;
else if (channelType == "Zrotation")
info.dataChannels[info.channelOffset]=ZR;
else
else
{std::cerr << "Error: Unknown channelType. Ignoring." << std::endl;}
if(info.dataChannels[info.channelOffset]!=NotGiven){ //if there is a channel assigned
info.dataOffset[info.channelOffset]=dataOffset; //the value for this channel will be found this data position
info.channelOffset++; //write next info into the next index
......@@ -327,7 +327,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
}
continue;
}
// ENDSITE
if ( (!(waitingFor&ENDSITE).none()) && (keyWrd == "End") ){
......@@ -335,38 +335,38 @@ int FileBVHPlugin::loadObject(QString _filename) {
stream >> site;
std::string name = "End";
Skeleton::Joint* newJoint = new Skeleton::Joint(currentParent, currentParent->name() + name);
skeleton->addJoint(currentParent, newJoint);
currentParent = newJoint;
waitingFor = OPENED_BRACKET;
continue;
}
//MOTION
if ( (waitingFor == MOTION) && (keyWrd == "MOTION") ){
waitingFor = FRAMES;
continue;
}
//Frames
if ( (waitingFor == FRAMES) && (keyWrd == "Frames:") ){
stream >> frameCount;
if (frameCount > 0){
FrameAnimationT<ACG::Vec3d>* animation = new FrameAnimationT<ACG::Vec3d>(skeleton, frameCount);
animHandle = skeleton->addAnimation(object->filename().toStdString(), animation);
}
waitingFor = FRAME_TIME;
continue;
}
//Frame Time
if ( (waitingFor == FRAME_TIME) && (keyWrd == "Frame") ){
std::string time;
stream >> time;
......@@ -382,12 +382,12 @@ int FileBVHPlugin::loadObject(QString _filename) {
//Channel Data
if ( (waitingFor == CHANNEL_DATA) ){
// a vector to store all the data for this frame
std::vector<double> data(dataOffset,0.0);
Skeleton::Pose* pose = 0;
if ( currentFrame < frameCount ){
animHandle.setFrame( currentFrame );
pose = skeleton->pose(animHandle);
......@@ -408,9 +408,9 @@ int FileBVHPlugin::loadObject(QString _filename) {
if ( currentFrame < frameCount )
for (unsigned long jointID=0; jointID < skeleton->jointCount(); jointID++ ){
Skeleton::Joint* joint = skeleton->joint( jointID );
// special case: end-effector joints
// they don't have animation data
if ( jointInfos.find(joint) == jointInfos.end() ){
......@@ -420,7 +420,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
}
JointInfo& info=jointInfos[joint]; //get the cahnnels info for the current joint
ACG::Vec3d translation(0.0,0.0,0.0); //setup translation
ACG::GLMatrixd matRot; //setup rotation
......@@ -431,7 +431,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
if(info.dataChannels[i]==NotGiven) break; //stop at the first empty channel
double val=data[info.dataOffset[i]]; //read one value from the data
switch(info.dataChannels[i]){ //apply the transformation
case XP: translation[0]=val; break; //translation (order doesnt matter)
case YP: translation[1]=val; break;
......@@ -439,23 +439,23 @@ int FileBVHPlugin::loadObject(QString _filename) {
case XR: matRot.rotateX(val); break; //rotation (order does matter)
case YR: matRot.rotateY(val); break;
case ZR: matRot.rotateZ(val); break;
default: break; //stop at the first empty channel
default: break; //stop at the first empty channel
}
}
ACG::GLMatrixd matTrans;
matTrans.identity();
if ( (!ignoreJointScaling_) || //translate only if there is no need to preserve the scale
(joint->parent() == 0) ) //or if the joint is the rootjoint
matTrans.translate(translation);
ACG::Matrix4x4d matRef = refPose->localMatrix(jointID);
ACG::Matrix4x4d matRef = refPose->localMatrix(jointID);
pose->setLocalMatrix(jointID, matRef * matTrans * matRot);
}
currentFrame++;
continue;
}
......@@ -463,7 +463,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
std::cerr << "Error: No match for keyword '" << keyWrd << "' ";
std::cerr << "waiting for : " << waitingFor.to_string<char,std::char_traits<char>,std::allocator<char> >() << std::endl;
}
//general stuff
object->source( PluginFunctions::objectCount() > 4 );
......@@ -476,7 +476,7 @@ int FileBVHPlugin::loadObject(QString _filename) {
//-----------------------------------------------------------------------------------------------------
bool FileBVHPlugin::saveObject(int _id, QString _filename)
bool FileBVHPlugin::saveObject(int _id, QString _filename, std::streamsize _precision)
{
BaseObjectData* object;
......@@ -494,6 +494,8 @@ bool FileBVHPlugin::saveObject(int _id, QString _filename)
return false;
}
stream.precision(_precision);
//write object
if ( object->dataType( DATA_SKELETON ) ) {
......@@ -503,21 +505,21 @@ bool FileBVHPlugin::saveObject(int _id, QString _filename)
Skeleton* skeleton = PluginFunctions::skeleton(object);
if ( writeSkeleton( stream, *skeleton ) ){
emit log(LOGINFO, tr("Saved object to ") + _filename );
stream.close();
return true;
} else {
emit log(LOGERR, tr("Unable to save ") + _filename);
stream.close();
QFile( QString(filename.c_str()) ).remove();
return false;
}
} else {
emit log(LOGERR, tr("Unable to save (object is not a skeleton)"));
stream.close();
QFile( QString(filename.c_str()) ).remove();
......@@ -554,15 +556,15 @@ ACG::Vec3d MatrixToEuler(ACG::Matrix4x4d _matrix){
//-----------------------------------------------------------------------------------------------------
bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
Skeleton::Pose* refPose = _skeleton.referencePose();
_out << "HIERARCHY" << std::endl;
std::string indent = "";
Skeleton::Joint* lastJoint = 0;
for (Skeleton::Iterator it = _skeleton.begin(); it != _skeleton.end(); ++it )
{
......@@ -573,27 +575,27 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
lastJoint = lastJoint->parent();
}
ACG::Vec3d translation;
if ( (*it)->parent() == 0 ){
//ROOT Joint
_out << "ROOT " << (*it)->name() << std::endl;
translation = refPose->globalTranslation( (*it)->id() );
} else if ( (*it)->size() > 0 ){
//normal joint
_out << indent << "JOINT " << (*it)->name() << std::endl;
translation = refPose->globalTranslation( (*it)->id() ) - refPose->globalTranslation( (*it)->parent()->id() );
} else {
//end-effector
_out << indent << "End Site" << std::endl;
translation = refPose->globalTranslation( (*it)->id() ) - refPose->globalTranslation( (*it)->parent()->id() );
}
......@@ -601,23 +603,23 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
indent += "\t";
_out << indent << "OFFSET " << translation[0] << " " << translation[1] << " " << translation[2] << std::endl;
if ( (*it)->size() > 0 ){ //end-effectors have no channel
if ( (*it)->parent() == 0)
_out << indent << "CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation" << std::endl;
else
_out << indent << "CHANNELS 3 Zrotation Yrotation Xrotation" << std::endl;
lastJoint = *it;
} else {
indent = indent.substr(0, indent.size()-1);
_out << indent << "}" << std::endl;
lastJoint = (*it)->parent();
}
}
//close brackets
while ( lastJoint->parent() != 0 ){
indent = indent.substr(0, indent.size()-1);
......@@ -626,7 +628,7 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
lastJoint = lastJoint->parent();
}
_out << "}" << std::endl;
//now hierarchy is set up
// save the motion
AnimationT<ACG::Vec3d>* animation = 0;
......@@ -634,7 +636,7 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
//get first animation with name
for (uint i = 0; i < _skeleton.animationCount(); i++){
animation = _skeleton.animation( AnimationHandle(i, 0 ) );
if (animation->name() == "")
animation = 0;
else{
......@@ -648,10 +650,10 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
_out << "MOTION" << std::endl;
_out << "Frames: 0" << std::endl;
_out << "Frame Time: 0.1" << std::endl;
return true;
}
_out << "MOTION" << std::endl;
_out << "Frames: " << animation->frameCount() << std::endl;
_out << "Frame Time: " << animation->fps() / 1000.0 << std::endl;
......@@ -659,15 +661,15 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
std::string name = _skeleton.animationName(iAnimation);
AnimationHandle animHandle = _skeleton.animationHandle(name);
// and every frame of that animation
for(unsigned long k = 0; k < animation->frameCount(); ++k)
{
animHandle.setFrame(k);
Skeleton::Pose* pose = _skeleton.pose( animHandle );
for (Skeleton::Iterator it = _skeleton.begin(); it != _skeleton.end(); ++it )
{
//skip end-effectors
......@@ -680,23 +682,23 @@ bool FileBVHPlugin::writeSkeleton( std::ostream& _out, Skeleton& _skeleton ) {
_out << translation[0] << " " << translation[1] << " " << translation[2];