Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleTriangleMesh.cpp

Example for TriangleMesh object, writes a wrl with an image using level of detail ,TriangleMesh

Author
MIP
/*
This file is part of the BIAS library (Basic ImageAlgorithmS).
Copyright (C) 2003-2009 (see file CONTACT for details)
Multimediale Systeme der Informationsverarbeitung
Institut fuer Informatik
Christian-Albrechts-Universitaet Kiel
BIAS 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 2.1 of the License, or
(at your option) any later version.
BIAS 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 BIAS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @example ExampleTriangleMesh.cpp
* @relates ThreeDOut,TriangleMesh
@ingroup g_examples
@brief Example for TriangleMesh object, writes a wrl with an image using level of detail
@author MIP */
#include <Utils/TriangleMesh.hh>
#include <Utils/ThreeDOut.hh>
#include <Base/Image/ImageIO.hh>
#include <Filter/Rescale.hh>
#include <Base/Common/FileHandling.hh>
#include <Image/Camera.hh>
#include <sstream>
#include <iostream>
using namespace std;
using namespace BIAS;
//#define TILE_MODE
#define TILE_WIDTH 129
#define TILE_HEIGHT 129
void usage(char* name)
{
cout<<"usage:\n";
cout<<name<<" <depthmap> <projection> <texture> [minCornerAngleDEG] [outputFile] [LevelOfDetail]\n";
cout<<endl<<endl;
cout<<"minCornerAngleDEG: discard triangle which contain a smaller angle"
<<endl;
cout<<"LevelOfDetail: 1:vertex for each pixel of full resolution, 2:"
<<" of half resolution"<<endl;
}
int main(int argc, char* argv[])
{
bool TileMode = true;
if(argc<3) {
usage(argv[0]);
return -1;
}
if(ImageIO::Load(argv[3], texture)!=0) {
cout<<"texture could not be loaded!\n";
usage(argv[0]);
return -1;
}
texture.ParseMetaData();
Camera<float> depthMap;
if(ImageIO::Load(argv[1], depthMap)!=0) {
cout<<"depth map could not be loaded!\n";
usage(argv[0]);
if (string(argv[1])==string("UNITSPHERE")) {
depthMap.Init(texture.GetWidth(), texture.GetHeight(), 1);
depthMap.FillImageWithConstValue(1.0f);
}
else return -1;
}
depthMap.ParseMetaData();
if (P.Load(argv[2])!=0) {
if (texture.IsProjValid()) {
P = texture.GetProj();
} else if (depthMap.IsProjValid()) {
P = depthMap.GetProj();
} else {
cout<<"Projection could not be loaded from file or meta data!\n";
usage(argv[0]);
return -1;
}
}
cout<<"meshing..."; cout.flush();
double minCornerAngle = 3.0*M_PI/180.0;
double maxViewingAngle = 91.0 * M_PI / 180.0;
if(argc>4) {
minCornerAngle = atof(argv[4])*M_PI/180.0;
}
cout<<"minCornerAngle = "<<minCornerAngle<<endl;
TriangleMesh mesh(minCornerAngle, maxViewingAngle);
double LevelOfDetail = -1.0;
if(argc>6) {
LevelOfDetail = atof(argv[6]);
}
if (LevelOfDetail>=0.0) TileMode = false;
else TileMode = true;
cout<<"Level of detail is "<< LevelOfDetail<<endl;
if (fabs(LevelOfDetail)!=1.0) {
//double maxlevel = log(double(depthMap.GetWidth()))/log(2.0)-6;
//cout<<"maximum level is "<<maxlevel<<endl;
for (double curLevel = 1.0;
curLevel<fabs(LevelOfDetail); curLevel += 1.0) {
Gauss<float, float> DepthSmooth;
DepthSmooth.SetSigma(sqrt(1.0*1.0 - 0.5*0.5));
Image<float> copyOfDepth = depthMap;
DepthSmooth.Filter7x7GreyIgnoreBelowThreshold(depthMap, copyOfDepth,
0.0f);
depthMap.Release();
depthMap.Init(copyOfDepth.GetWidth()/2, copyOfDepth.GetHeight()/2);
for (unsigned int y=0; y<depthMap.GetHeight(); y++) {
for (unsigned int x=0; x<depthMap.GetWidth(); x++) {
depthMap.GetImageDataArray()[y][x] =
copyOfDepth.GetImageDataArray()[2*y][2*x];
}
}
P.Rescale(2.0);
//ImageIO::Save("depth"+FileHandling::toString(curLevel), depthMap);
ImageIO::Save("depth"+FileHandling::toString(curLevel), depthMap);
}
}
string vrmlfilename = "DenseTriangleMesh.wrl";
if(argc>5) vrmlfilename = argv[5];
ThreeDOut vrmlOut;
if (!TileMode) {
mesh.GenerateSimplifiedMesh(depthMap, P, texture, 0, 0,
depthMap.GetWidth(),
depthMap.GetHeight(), 0.7, 3.0);
cout<<"finished\n"<<flush;
vrmlOut.AddTriangleMesh(mesh, "mesh_from_"+string(argv[1]),
argv[3], true);
cout<<"Writing VRML to "<<vrmlfilename<<flush<<endl;
vrmlOut.VRMLOut(vrmlfilename);
cout<<"finished\n";
} else {
// tile here into small image blocks, allows for writing of huge files
ofstream vrmlfile(vrmlfilename.c_str());
vrmlOut.VRMLOutWriteHeader(vrmlfile);
unsigned int width, height;
P.GetParameters()->GetImageSize(width, height);
unsigned int tileWidth, tileHeight;
bool xFinished = false;
bool yFinished = false;
// bool finished = false;
unsigned int xStart, yStart;
unsigned int tileNum = 0;
yStart = 0;
int numTiles = (height/(TILE_HEIGHT-1)+1)*(width/(TILE_WIDTH-1)+1);
cout<<"Writing "<< numTiles
<<" tiles: "<<flush;
while(!yFinished) {
if(yStart+TILE_HEIGHT >= height) {
yFinished = true;
tileHeight = height-yStart;
}
else tileHeight = TILE_HEIGHT;
cout<< double(tileNum)/double(numTiles)*100.0<<"% "<<flush;
xFinished = false;
xStart = 0;
while(!xFinished) {
stringstream ss;
ss<<"mesh_from_"<<string(argv[1])<<"_t"<<tileNum;
tileNum++;
if(xStart+TILE_WIDTH >= width) {
xFinished = true;
tileWidth = width -xStart;
}
else
tileWidth = TILE_WIDTH;
if(mesh.GenerateDenseMesh(depthMap, P, texture,
xStart, yStart, tileWidth, tileHeight)==0) {
vrmlOut.AddTriangleMesh(mesh, ss.str(),
argv[3], false);
vrmlOut.VRMLOutIndexedFaceSets(vrmlfile);
vrmlOut.RemoveAll();
}
xStart+=(tileWidth-1);
}
yStart+=(tileHeight-1);
}
cout<< " finished."<<endl<<flush;
}
return 0;
}