Official Release of Metro 4.00
This commit is contained in:
parent
4333c2177d
commit
21df27313d
|
@ -3,40 +3,7 @@
|
||||||
#define _DEFS_H
|
#define _DEFS_H
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// command line parameters
|
|
||||||
#define CMD_LINE_ARG_HIST 'H'
|
|
||||||
#define CMD_LINE_ARG_VERTEX_SAMPLE 'V'
|
|
||||||
#define CMD_LINE_ARG_EDGE_SAMPLE 'E'
|
|
||||||
#define CMD_LINE_ARG_FACE_SAMPLE 'F'
|
|
||||||
#define CMD_LINE_ARG_SAMPLE_TYPE 'S'
|
|
||||||
#define CMD_LINE_ARG_MONTECARLO_SAMPLING 'M'
|
|
||||||
#define CMD_LINE_ARG_SUBDIVISION_SAMPLING 'S'
|
|
||||||
#define CMD_LINE_ARG_SIMILAR_TRIANGLES_SAMPLING 'T'
|
|
||||||
#define CMD_LINE_ARG_N_SAMPLES 'N'
|
|
||||||
#define CMD_LINE_ARG_SAMPLES_PER_AREA_UNIT 'A'
|
|
||||||
#define CMD_LINE_ARG_SAVE_DISPLACEMENT 'O'
|
|
||||||
#define CMD_LINE_ARG_SAVE_ERROR_AS_COLOUR 'C'
|
|
||||||
#define CMR_LINE_ARG_INCLUDE_UNREF 'U'
|
|
||||||
|
|
||||||
// error messages
|
// error messages
|
||||||
#define MSG_ERR_N_ARGS "\nUsage: "\
|
|
||||||
"metro file1 file2 [opt]\n"\
|
|
||||||
"where opt can be:\n"\
|
|
||||||
"-V disable vertex sampling\n"\
|
|
||||||
"-U ignore unreferred vertices\n"\
|
|
||||||
"-E disable edge sampling\n"\
|
|
||||||
"-F disable face sampling\n"\
|
|
||||||
"-Sx set the face sampling mode\n"\
|
|
||||||
" where x can be:\n"\
|
|
||||||
" -M montecarlo sampling\n"\
|
|
||||||
" -S subdivision sampling\n"\
|
|
||||||
" -T similar triangles sampling\n"\
|
|
||||||
"-N# set the required number of samples (overrides -A)\n"\
|
|
||||||
"-A# set the required number of samples per area unit (overrides -N)\n"\
|
|
||||||
"-Hxxx.yyy save histogram of error values in the file xxx.yyy\n"\
|
|
||||||
"-O save error as vertex quality\n"\
|
|
||||||
"-C save error as vertex colour"\
|
|
||||||
"\n"
|
|
||||||
|
|
||||||
#define MSG_ERR_MESH_LOAD "error loading the input meshes.\n"
|
#define MSG_ERR_MESH_LOAD "error loading the input meshes.\n"
|
||||||
#define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n"
|
#define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n"
|
||||||
|
@ -51,13 +18,6 @@
|
||||||
#define MIN_SIZE 125 /* 125 = 5^3 */
|
#define MIN_SIZE 125 /* 125 = 5^3 */
|
||||||
#define N_HIST_BINS 256
|
#define N_HIST_BINS 256
|
||||||
#define PRINT_EVERY_N_ELEMENTS 1000
|
#define PRINT_EVERY_N_ELEMENTS 1000
|
||||||
#define FILE_EXT_SMF "smf"
|
|
||||||
#define FILE_EXT_PLY "ply"
|
|
||||||
|
|
||||||
// strings
|
|
||||||
#define STR_HIST_FILENAME_DEFAULT "hist.txt"
|
|
||||||
#define STR_NEW_MESH_FILENAME_DEFAULT "error.ply"
|
|
||||||
#define STR_NEW_MESH_FILENAME_DEFAULT_2 "error_colour.ply"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,12 +24,16 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.4 2004/05/14 13:53:12 ganovelli
|
||||||
|
GPL added
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// standard libraries
|
// standard libraries
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
// project definitions.
|
// project definitions.
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
@ -37,131 +41,124 @@ $Log: not supported by cvs2svn $
|
||||||
#include "mesh_type.h"
|
#include "mesh_type.h"
|
||||||
#include <vcg/complex/trimesh/update/edges.h>
|
#include <vcg/complex/trimesh/update/edges.h>
|
||||||
#include <vcg/complex/trimesh/update/bounding.h>
|
#include <vcg/complex/trimesh/update/bounding.h>
|
||||||
|
#include <vcg/math/histogram.h>
|
||||||
|
#include <vcg/complex/trimesh/clean.h>
|
||||||
//#include <wrap/io_trimesh/import_smf.h>
|
//#include <wrap/io_trimesh/import_smf.h>
|
||||||
#include <wrap/io_trimesh/import_ply.h>
|
#include <wrap/io_trimesh/import_ply.h>
|
||||||
|
#include <wrap/io_trimesh/import_stl.h>
|
||||||
#include <wrap/io_trimesh/export_ply.h>
|
#include <wrap/io_trimesh/export_ply.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
////////////////// Command line Flags and parameters
|
////////////////// Command line Flags and parameters
|
||||||
bool ComputeHistFlag = false;
|
|
||||||
bool VertexSampleFlag = true;
|
|
||||||
bool EdgeSampleFlag = true;
|
|
||||||
bool FaceSampleFlag = true;
|
|
||||||
bool MontecarloSamplingFlag = false;
|
|
||||||
bool SubdivisionSamplingFlag = false;
|
|
||||||
bool SimilarTrianglesSamplingFlag = false;
|
|
||||||
bool NumberOfSamples = false;
|
bool NumberOfSamples = false;
|
||||||
bool SamplesPerAreaUnit = false;
|
bool SamplesPerAreaUnit = false;
|
||||||
bool SaveErrorDisplacement = false;
|
bool CleaningFlag=false;
|
||||||
bool SaveErrorAsColour = false;
|
|
||||||
bool IncludeUnreferred = false;
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Usage()
|
||||||
inline char* GetExtension(char* filename)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
printf("\nUsage: "\
|
||||||
for( i=strlen(filename)-1; i >= 0; i--)
|
"metro file1 file2 [opt]\n"\
|
||||||
if(filename[i] == '.')
|
"where opt can be:\n"\
|
||||||
break;
|
"-v disable vertex sampling\n"\
|
||||||
if(i > 0)
|
"-e disable edge sampling\n"\
|
||||||
return &(filename[i+1]);
|
"-f disable face sampling\n"\
|
||||||
else
|
"-u ignore unreferred vertices\n"\
|
||||||
return NULL;
|
"-Sx set the face sampling mode\n"\
|
||||||
|
" where x can be:\n"\
|
||||||
|
" -S0 montecarlo sampling\n"\
|
||||||
|
" -S1 subdivision sampling\n"\
|
||||||
|
" -S2 similar triangles sampling (Default)\n"\
|
||||||
|
"-n# set the required number of samples (overrides -A)\n"\
|
||||||
|
"-a# set the required number of samples per area unit (overrides -N)\n"\
|
||||||
|
"-c save error as vertex colour and quality"\
|
||||||
|
"-C # # Set the min/max values used for color mapping"\
|
||||||
|
"-L Remove duplicated and unreferenced vertices before processing"\
|
||||||
|
"\n"
|
||||||
|
"Default options are to sample vertexes, edge and faces, to take a number of sample that is \n"
|
||||||
|
);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// simple aux function that compute the name for the file containing the stored computations
|
||||||
|
string SaveFileName(const string &filename)
|
||||||
|
{
|
||||||
|
int pos=filename.find_last_of('.',filename.length());
|
||||||
|
string fileout=filename.substr(0,pos)+"_metro.ply";
|
||||||
|
return fileout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// simple aux function that returns true if a given file has a given extesnion
|
||||||
|
bool FileExtension(string filename, string extension)
|
||||||
|
{
|
||||||
|
locale loc1 ;
|
||||||
|
use_facet<ctype<char> > ( loc1 ).tolower(&*filename.begin(),&*filename.end());
|
||||||
|
use_facet<ctype<char> > ( loc1 ).tolower(&*extension.begin(),&*extension.end());
|
||||||
|
string end=filename.substr(filename.length()-extension.length(),extension.length());
|
||||||
|
return end==extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Mesh
|
||||||
|
void OpenMesh(const char *filename, CMesh &m)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
if(FileExtension(filename,"ply"))
|
||||||
|
{
|
||||||
|
err = tri::io::ImporterPLY<CMesh>::Open(m,filename);
|
||||||
|
if(err) {
|
||||||
|
printf("Error in reading %s: '%s'\n",filename,tri::io::ImporterPLY<CMesh>::ErrorMsg(err));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
printf("read mesh `%s'\n", filename);
|
||||||
|
}
|
||||||
|
else if(FileExtension(filename,"stl"))
|
||||||
|
{
|
||||||
|
err = tri::io::ImporterSTL<CMesh>::Open(m,filename);
|
||||||
|
if(err) {
|
||||||
|
printf("Error in reading %s: '%s'\n",filename,tri::io::ImporterSTL<CMesh>::ErrorMsg(err));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
printf("read mesh `%s'\n", filename);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Unknown file format for mesh '%s'\n",filename);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if(CleaningFlag){
|
||||||
|
int dup = tri::Clean<CMesh>::RemoveDuplicateVertex(m);
|
||||||
|
int unref = tri::Clean<CMesh>::RemoveUnreferencedVertex(m);
|
||||||
|
printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char**argv)
|
int main(int argc, char**argv)
|
||||||
{
|
{
|
||||||
CMesh S1, S2;
|
CMesh S1, S2;
|
||||||
double dist1_max, dist1_mean, dist1_RMS, volume_1;
|
double ColorMin=0, ColorMax=0;
|
||||||
double dist2_max, dist2_mean, dist2_RMS, volume_2;
|
double dist1_max, dist2_max;
|
||||||
double mesh_dist_max;
|
unsigned long n_samples_target, elapsed_time;
|
||||||
unsigned long n_samples_target, n_samples_output, elapsed_time;
|
|
||||||
double n_samples_per_area_unit;
|
double n_samples_per_area_unit;
|
||||||
int flags, flags_fwd, flags_back, n_samples_area, n_samples_edge, n_samples_vertex, err;
|
int flags;
|
||||||
char *fmt, *hist_filename, *new_mesh_filename, *new_mesh_filename_2;
|
|
||||||
char fname_1[] = STR_NEW_MESH_FILENAME_DEFAULT, fname_2[] = STR_NEW_MESH_FILENAME_DEFAULT_2;
|
|
||||||
//FILE *fd;
|
|
||||||
|
|
||||||
// print program info
|
// print program info
|
||||||
printf("-------------------------------\n"
|
printf("-------------------------------\n"
|
||||||
" Metro\n"
|
" Metro V.4.0 \n"
|
||||||
|
" http://vcg.isti.cnr.it\n"
|
||||||
" release date: "__DATE__"\n"
|
" release date: "__DATE__"\n"
|
||||||
"-------------------------------\n\n");
|
"-------------------------------\n\n");
|
||||||
|
|
||||||
// load input meshes.
|
if(argc <= 2) Usage();
|
||||||
if(argc <= 2)
|
// default parameters
|
||||||
{
|
flags = SamplingFlags::VERTEX_SAMPLING |
|
||||||
printf(MSG_ERR_N_ARGS);
|
SamplingFlags::EDGE_SAMPLING |
|
||||||
exit(-1);
|
SamplingFlags::FACE_SAMPLING |
|
||||||
}
|
SamplingFlags::SIMILAR_SAMPLING;
|
||||||
|
|
||||||
// load mesh M1.
|
|
||||||
if(!(fmt = GetExtension(argv[1])))
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(!strcmp("ply", fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[1]);
|
|
||||||
err = tri::io::ImporterPLY<CMesh>::Open(S1,argv[1]);
|
|
||||||
}
|
|
||||||
/* else
|
|
||||||
if(!strcmp(file_ext_smf, fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[1]);
|
|
||||||
err = tri::io::ImporterSMF::Open(S1,argv[1]);
|
|
||||||
}*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(err < 0)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
printf(MSG_ERR_MESH_LOAD);
|
|
||||||
printf(" error number %d",err);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("done\n");
|
|
||||||
|
|
||||||
// load mesh M2.
|
|
||||||
if(!(fmt = GetExtension(argv[2])))
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(!strcmp("ply", fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[2]);
|
|
||||||
err = tri::io::ImporterPLY<CMesh>::Open(S2,argv[2]);
|
|
||||||
}
|
|
||||||
/*else
|
|
||||||
if(!strcmp(file_ext_smf, fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[2]);
|
|
||||||
err = S2.Load_Smf(argv[2]);
|
|
||||||
}*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(err < 0)
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_MESH_LOAD);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("done\n");
|
|
||||||
|
|
||||||
// parse command line.
|
// parse command line.
|
||||||
for(int i=3; i < argc;)
|
for(int i=3; i < argc;)
|
||||||
|
@ -169,52 +166,38 @@ int main(int argc, char**argv)
|
||||||
if(argv[i][0]=='-')
|
if(argv[i][0]=='-')
|
||||||
switch(argv[i][1])
|
switch(argv[i][1])
|
||||||
{
|
{
|
||||||
case CMD_LINE_ARG_HIST : ComputeHistFlag = true; hist_filename = &(argv[i][2]);
|
case 'v' : flags &= ~SamplingFlags::VERTEX_SAMPLING; break;
|
||||||
if(hist_filename[0] == '\0')
|
case 'e' : flags &= ~SamplingFlags::EDGE_SAMPLING; break;
|
||||||
strcpy(hist_filename, STR_HIST_FILENAME_DEFAULT);
|
case 'f' : flags &= ~SamplingFlags::FACE_SAMPLING; break;
|
||||||
break;
|
case 'u' : flags |= SamplingFlags::INCLUDE_UNREFERENCED_VERTICES; break;
|
||||||
case CMD_LINE_ARG_VERTEX_SAMPLE : VertexSampleFlag = false; break;
|
case 's' :
|
||||||
case CMR_LINE_ARG_INCLUDE_UNREF : IncludeUnreferred = true; break;
|
|
||||||
case CMD_LINE_ARG_EDGE_SAMPLE : EdgeSampleFlag = false; break;
|
|
||||||
case CMD_LINE_ARG_FACE_SAMPLE : FaceSampleFlag = false; break;
|
|
||||||
case CMD_LINE_ARG_SAMPLE_TYPE :
|
|
||||||
switch(argv[i][2])
|
switch(argv[i][2])
|
||||||
{
|
{
|
||||||
case CMD_LINE_ARG_MONTECARLO_SAMPLING : MontecarloSamplingFlag = true; break;
|
case 0: flags = (flags | SamplingFlags::MONTECARLO_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
|
||||||
case CMD_LINE_ARG_SUBDIVISION_SAMPLING : SubdivisionSamplingFlag = true; break;
|
case 1: flags = (flags | SamplingFlags::SUBDIVISION_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
|
||||||
case CMD_LINE_ARG_SIMILAR_TRIANGLES_SAMPLING : SimilarTrianglesSamplingFlag = true; break;
|
case 2: flags = (flags | SamplingFlags::SIMILAR_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break;
|
||||||
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
|
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_LINE_ARG_N_SAMPLES : NumberOfSamples = true; n_samples_target = (unsigned long) atoi(&(argv[i][2])); break;
|
case 'n': NumberOfSamples = true; n_samples_target = (unsigned long) atoi(&(argv[i][2])); break;
|
||||||
case CMD_LINE_ARG_SAMPLES_PER_AREA_UNIT : SamplesPerAreaUnit = true; n_samples_per_area_unit = (unsigned long) atoi(&(argv[i][2])); break;
|
case 'a': SamplesPerAreaUnit = true; n_samples_per_area_unit = (unsigned long) atoi(&(argv[i][2])); break;
|
||||||
case CMD_LINE_ARG_SAVE_DISPLACEMENT : SaveErrorDisplacement = true; new_mesh_filename = &(argv[i][2]);
|
case 'c': flags |= SamplingFlags::SAVE_ERROR; break;
|
||||||
if(new_mesh_filename[0] == '\0')
|
case 'L': CleaningFlag=true; break;
|
||||||
new_mesh_filename = fname_1;
|
case 'C': ColorMin=atof(argv[i+1]); ColorMax=atof(argv[i+2]); i+=2; break;
|
||||||
break;
|
|
||||||
case CMD_LINE_ARG_SAVE_ERROR_AS_COLOUR : SaveErrorAsColour = true; new_mesh_filename_2 = &(argv[i][2]);
|
|
||||||
if(new_mesh_filename_2[0] == '\0')
|
|
||||||
new_mesh_filename_2 = fname_2;
|
|
||||||
break;
|
|
||||||
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
|
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set sampling scheme
|
// load input meshes.
|
||||||
int sampling_method = MontecarloSamplingFlag + SubdivisionSamplingFlag + SimilarTrianglesSamplingFlag;
|
OpenMesh(argv[1],S1);
|
||||||
// defaults
|
OpenMesh(argv[2],S2);
|
||||||
if(!sampling_method)
|
string S1NewName=SaveFileName(argv[1]);
|
||||||
SimilarTrianglesSamplingFlag = true;
|
string S2NewName=SaveFileName(argv[2]);
|
||||||
if(sampling_method > 1)
|
|
||||||
{
|
|
||||||
printf("Cannot choose more than one sampling method. Similar Triangles sampling assumed.\n");
|
|
||||||
SimilarTrianglesSamplingFlag = true;
|
|
||||||
MontecarloSamplingFlag = false;
|
|
||||||
SubdivisionSamplingFlag = false;
|
|
||||||
}
|
|
||||||
if(!NumberOfSamples && !SamplesPerAreaUnit)
|
if(!NumberOfSamples && !SamplesPerAreaUnit)
|
||||||
{
|
{
|
||||||
NumberOfSamples = true;
|
NumberOfSamples = true;
|
||||||
|
@ -237,49 +220,13 @@ int main(int argc, char**argv)
|
||||||
S1.bbox = bbox;
|
S1.bbox = bbox;
|
||||||
S2.bbox = bbox;
|
S2.bbox = bbox;
|
||||||
|
|
||||||
// set flags.
|
|
||||||
flags = 0;
|
|
||||||
if(IncludeUnreferred)
|
|
||||||
flags |= SamplingFlags::INCLUDE_UNREFERENCED_VERTICES;
|
|
||||||
if(ComputeHistFlag)
|
|
||||||
flags |= SamplingFlags::HIST;
|
|
||||||
if(VertexSampleFlag)
|
|
||||||
flags |= SamplingFlags::VERTEX_SAMPLING;
|
|
||||||
if(EdgeSampleFlag)
|
|
||||||
flags |= SamplingFlags::EDGE_SAMPLING;
|
|
||||||
if(FaceSampleFlag)
|
|
||||||
flags |= SamplingFlags::FACE_SAMPLING;
|
|
||||||
if(MontecarloSamplingFlag)
|
|
||||||
flags |= SamplingFlags::MONTECARLO_SAMPLING;
|
|
||||||
if(SubdivisionSamplingFlag)
|
|
||||||
flags |= SamplingFlags::SUBDIVISION_SAMPLING;
|
|
||||||
if(SimilarTrianglesSamplingFlag)
|
|
||||||
flags |= SamplingFlags::SIMILAR_TRIANGLES_SAMPLING;
|
|
||||||
flags_fwd = flags;
|
|
||||||
flags_back = flags;
|
|
||||||
if(SaveErrorDisplacement)
|
|
||||||
{
|
|
||||||
if(S1.vn >= S2.vn)
|
|
||||||
flags_fwd |= SamplingFlags::SAVE_ERROR_DISPLACEMENT;
|
|
||||||
else
|
|
||||||
flags_back |= SamplingFlags::SAVE_ERROR_DISPLACEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SaveErrorAsColour)
|
|
||||||
{
|
|
||||||
if(S1.vn >= S2.vn)
|
|
||||||
flags_fwd |= SamplingFlags::SAVE_ERROR_AS_COLOUR;
|
|
||||||
else
|
|
||||||
flags_back |= SamplingFlags::SAVE_ERROR_AS_COLOUR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize time info.
|
// initialize time info.
|
||||||
int t0=clock();
|
int t0=clock();
|
||||||
|
|
||||||
// print mesh info.
|
|
||||||
Sampling<CMesh> ForwardSampling(S1,S2);
|
Sampling<CMesh> ForwardSampling(S1,S2);
|
||||||
Sampling<CMesh> BackwardSampling(S2,S1);
|
Sampling<CMesh> BackwardSampling(S2,S1);
|
||||||
|
|
||||||
|
// print mesh info.
|
||||||
printf("Mesh info:\n");
|
printf("Mesh info:\n");
|
||||||
printf(" M1: '%s'\n\t%vertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[1], S1.vn, S1.fn, ForwardSampling.GetArea());
|
printf(" M1: '%s'\n\t%vertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[1], S1.vn, S1.fn, ForwardSampling.GetArea());
|
||||||
printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M1.min[0], tmp_bbox_M1.min[1], tmp_bbox_M1.min[2], tmp_bbox_M1.max[0], tmp_bbox_M1.max[1], tmp_bbox_M1.max[2]);
|
printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M1.min[0], tmp_bbox_M1.min[1], tmp_bbox_M1.min[2], tmp_bbox_M1.max[0], tmp_bbox_M1.max[1], tmp_bbox_M1.max[2]);
|
||||||
|
@ -290,7 +237,7 @@ int main(int argc, char**argv)
|
||||||
|
|
||||||
// Forward distance.
|
// Forward distance.
|
||||||
printf("\nForward distance (M1 -> M2):\n");
|
printf("\nForward distance (M1 -> M2):\n");
|
||||||
ForwardSampling.SetFlags(flags_fwd);
|
ForwardSampling.SetFlags(flags);
|
||||||
if(NumberOfSamples)
|
if(NumberOfSamples)
|
||||||
{
|
{
|
||||||
ForwardSampling.SetSamplesTarget(n_samples_target);
|
ForwardSampling.SetSamplesTarget(n_samples_target);
|
||||||
|
@ -304,23 +251,18 @@ int main(int argc, char**argv)
|
||||||
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
||||||
ForwardSampling.Hausdorff();
|
ForwardSampling.Hausdorff();
|
||||||
dist1_max = ForwardSampling.GetDistMax();
|
dist1_max = ForwardSampling.GetDistMax();
|
||||||
dist1_mean = ForwardSampling.GetDistMean();
|
printf("\ndistance:\n max : %f (%f with respect to bounding box diagonal)\n", (float)dist1_max, (float)dist1_max/bbox.Diag());
|
||||||
dist1_RMS = ForwardSampling.GetDistRMS();
|
printf(" mean : %f\n", ForwardSampling.GetDistMean());
|
||||||
volume_1 = ForwardSampling.GetDistVolume();
|
printf(" RMS : %f\n", ForwardSampling.GetDistRMS());
|
||||||
n_samples_output = ForwardSampling.GetNSamples();
|
printf("# vertex samples %9d\n", ForwardSampling.GetNVertexSamples());
|
||||||
n_samples_area = ForwardSampling.GetNAreaSamples();
|
printf("# edge samples %9d\n", ForwardSampling.GetNEdgeSamples());
|
||||||
n_samples_edge = ForwardSampling.GetNEdgeSamples();
|
printf("# area samples %9d\n", ForwardSampling.GetNAreaSamples());
|
||||||
n_samples_vertex = ForwardSampling.GetNVertexSamples();
|
printf("# total samples %9d\n", ForwardSampling.GetNSamples());
|
||||||
printf("\ndistance:\n max : %f (%f with respect to bounding box diagonal)\n mean : %f\n RMS : %f\n", (float)dist1_max, (float)dist1_max/bbox.Diag(), (float)dist1_mean, (float)dist1_RMS);
|
printf("# samples per area unit: %f\n\n", ForwardSampling.GetNSamplesPerAreaUnit());
|
||||||
if(VertexSampleFlag)
|
|
||||||
printf("# vertex samples %d\n", n_samples_vertex);
|
|
||||||
if(EdgeSampleFlag)
|
|
||||||
printf("# edge samples %d\n", n_samples_edge);
|
|
||||||
printf("# area samples %d\n# total samples %d\nsamples per area unit: %f\n\n", n_samples_area, n_samples_output, ForwardSampling.GetNSamplesPerAreaUnit());
|
|
||||||
|
|
||||||
// Backward distance.
|
// Backward distance.
|
||||||
printf("\nBackward distance (M2 -> M1):\n");
|
printf("\nBackward distance (M2 -> M1):\n");
|
||||||
BackwardSampling.SetFlags(flags_back);
|
BackwardSampling.SetFlags(flags);
|
||||||
if(NumberOfSamples)
|
if(NumberOfSamples)
|
||||||
{
|
{
|
||||||
BackwardSampling.SetSamplesTarget(n_samples_target);
|
BackwardSampling.SetSamplesTarget(n_samples_target);
|
||||||
|
@ -334,80 +276,37 @@ int main(int argc, char**argv)
|
||||||
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
||||||
BackwardSampling.Hausdorff();
|
BackwardSampling.Hausdorff();
|
||||||
dist2_max = BackwardSampling.GetDistMax();
|
dist2_max = BackwardSampling.GetDistMax();
|
||||||
dist2_mean = BackwardSampling.GetDistMean();
|
printf("\ndistance:\n max : %f (%f with respect to bounding box diagonal)\n", (float)dist1_max, (float)dist1_max/bbox.Diag());
|
||||||
dist2_RMS = BackwardSampling.GetDistRMS();
|
printf("mean : %f\n", BackwardSampling.GetDistMean());
|
||||||
volume_2 = BackwardSampling.GetDistVolume();
|
printf("RMS : %f\n", BackwardSampling.GetDistRMS());
|
||||||
n_samples_output = BackwardSampling.GetNSamples();
|
printf("# vertex samples %9d\n", BackwardSampling.GetNVertexSamples());
|
||||||
n_samples_area = BackwardSampling.GetNAreaSamples();
|
printf("# edge samples %9d\n", BackwardSampling.GetNEdgeSamples());
|
||||||
n_samples_edge = BackwardSampling.GetNEdgeSamples();
|
printf("# area samples %9d\n", BackwardSampling.GetNAreaSamples());
|
||||||
n_samples_vertex = BackwardSampling.GetNVertexSamples();
|
printf("# total samples %9d\n", BackwardSampling.GetNSamples());
|
||||||
printf("\ndistance:\n max : %f (%f with respect to bounding box diagonal)\n mean : %f\n RMS : %f\n", (float)dist2_max, (float)dist2_max/bbox.Diag(), (float)dist2_mean, (float)dist2_RMS);
|
printf("# samples per area unit: %f\n\n", BackwardSampling.GetNSamplesPerAreaUnit());
|
||||||
if(VertexSampleFlag)
|
|
||||||
printf("# vertex samples %d\n", n_samples_vertex);
|
|
||||||
if(EdgeSampleFlag)
|
|
||||||
printf("# edge samples %d\n", n_samples_edge);
|
|
||||||
printf("# area samples %d\n# total samples %d\nsamples per area unit: %f\n\n", n_samples_area, n_samples_output, BackwardSampling.GetNSamplesPerAreaUnit());
|
|
||||||
|
|
||||||
// compute time info.
|
// compute time info.
|
||||||
elapsed_time = clock() - t0;
|
elapsed_time = clock() - t0;
|
||||||
|
int n_total_sample=ForwardSampling.GetNSamples()+BackwardSampling.GetNSamples();
|
||||||
|
float mesh_dist_max = max(dist1_max , dist2_max);
|
||||||
|
|
||||||
// save error distribution histogram
|
printf("\nHausdorff distance: %f (%f with respect to bounding box diagonal)\n",(float)mesh_dist_max,(float)mesh_dist_max/bbox.Diag());
|
||||||
/*if(ComputeHistFlag)
|
printf(" Computation time : %d ms\n", (int)elapsed_time);
|
||||||
{
|
printf(" # samples/second : %f\n\n", (float)n_total_sample/((float)elapsed_time/1000.0));
|
||||||
const Hist &hist1 = ForwardSampling.GetHist();
|
|
||||||
const Hist &hist2 = BackwardSampling.GetHist();
|
|
||||||
if(!(fd = fopen(hist_filename, "w")))
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_FILE_OPEN);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
vector<int>::const_iterator ii;
|
|
||||||
vector<float>::const_iterator fi;
|
|
||||||
|
|
||||||
fprintf(fd, "error distribution histogram (forward distance)\n\n");
|
|
||||||
for(ii=hist1.H.begin(), fi=hist1.R.begin(); ii != hist1.H.end(); ++fi,ii++)
|
|
||||||
fprintf(fd, "%6.4f\t%d\n", *fi, *ii);
|
|
||||||
|
|
||||||
fprintf(fd, "\n\nerror distribution histogram (backward distance)\n");
|
|
||||||
for(ii=hist2.H.begin(), fi=hist2.R.begin(); ii != hist2.H.end(); ++fi,ii++)
|
|
||||||
fprintf(fd, "%6.4f\t%d\n", *fi, *ii);
|
|
||||||
|
|
||||||
fclose(fd);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// max distance.
|
|
||||||
mesh_dist_max = max(dist1_max , dist2_max);
|
|
||||||
printf("\nHausdorff distance: %f (%f with respect to bounding box diagonal)\nComputation time : %d ms\n# samples/second : %f\n\n", (float)mesh_dist_max, (float)mesh_dist_max/bbox.Diag(), (int)elapsed_time, (float)n_samples_output/(float)elapsed_time*2000.0F);
|
|
||||||
|
|
||||||
// save error files.
|
// save error files.
|
||||||
if((flags_fwd & SamplingFlags::SAVE_ERROR_DISPLACEMENT) && (flags_fwd & SamplingFlags::SAVE_ERROR_AS_COLOUR))
|
if(flags & SamplingFlags::SAVE_ERROR)
|
||||||
// if(strcmp(new_mesh_filename, new_mesh_filename_2))
|
|
||||||
{
|
{
|
||||||
vcg::tri::io::PlyInfo p;
|
vcg::tri::io::PlyInfo p;
|
||||||
p.mask|=vcg::tri::io::PLYMask::PM_VERTCOLOR|vcg::tri::io::PLYMask::PM_VERTQUALITY;
|
p.mask|=vcg::ply::PLYMask::PM_VERTCOLOR|vcg::ply::PLYMask::PM_VERTQUALITY;
|
||||||
|
if(ColorMax!=0 || ColorMin != 0){
|
||||||
tri::io::ExporterPLY<CMesh>::Save( S1,new_mesh_filename,true,p);
|
vcg::tri::UpdateColor<CMesh>::VertexQuality(S1,ColorMin,ColorMax);
|
||||||
exit(0);
|
vcg::tri::UpdateColor<CMesh>::VertexQuality(S2,ColorMin,ColorMax);
|
||||||
}
|
}
|
||||||
if((flags_back & SamplingFlags::SAVE_ERROR_DISPLACEMENT) && (flags_back & SamplingFlags::SAVE_ERROR_AS_COLOUR))
|
tri::io::ExporterPLY<CMesh>::Save( S1,S1NewName.c_str(),true,p);
|
||||||
// if(strcmp(new_mesh_filename, new_mesh_filename_2))
|
tri::io::ExporterPLY<CMesh>::Save( S2,S2NewName.c_str(),true,p);
|
||||||
{
|
|
||||||
vcg::tri::io::PlyInfo p;
|
|
||||||
p.mask|=vcg::tri::io::PLYMask::PM_VERTCOLOR|vcg::tri::io::PLYMask::PM_VERTQUALITY;
|
|
||||||
tri::io::ExporterPLY<CMesh>::Save( S2,new_mesh_filename,true,p);
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//if(flags_fwd & SamplingFlags::SAVE_ERROR_DISPLACEMENT)
|
|
||||||
// S1.SavePly(new_mesh_filename, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTCOLOR));
|
|
||||||
//else
|
|
||||||
// if(flags_back & SamplingFlags::SAVE_ERROR_DISPLACEMENT)
|
|
||||||
// S2.SavePly(new_mesh_filename, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTCOLOR));
|
|
||||||
//if(flags_fwd & SamplingFlags::SAVE_ERROR_AS_COLOUR)
|
|
||||||
// S1.SavePly(new_mesh_filename_2, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTQUALITY));
|
|
||||||
//else
|
|
||||||
// if(flags_back & SamplingFlags::SAVE_ERROR_AS_COLOUR)
|
|
||||||
// S2.SavePly(new_mesh_filename_2, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTQUALITY));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
VCGLib http://vcg.sf.net o o
|
||||||
|
Visual and Computer Graphics Library o o
|
||||||
|
_ O _
|
||||||
|
Copyright(C) 2004 \/)\/
|
||||||
|
Visual Computing Lab http://vcg.isti.cnr.it /\/|
|
||||||
|
ISTI - Italian National Research Council |
|
||||||
|
\
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Metro is a tool designed to evaluate the difference between two triangular meshes.
|
||||||
|
Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation.
|
||||||
|
Please, when using this tool cite the following reference:
|
||||||
|
|
||||||
|
Papers
|
||||||
|
P. Cignoni, C. Rocchini and R. Scopigno
|
||||||
|
"Metro: measuring error on simplified surfaces"
|
||||||
|
Computer Graphics Forum, Blackwell Publishers, vol. 17(2), June 1998, pp 167-174
|
||||||
|
|
||||||
|
|
||||||
|
For any question about this software please contact:
|
||||||
|
Paolo Cignoni ( p.cignoni@isti.cnr.it )
|
||||||
|
|
||||||
|
|
||||||
|
Three different surface sampling methods are implemented:
|
||||||
|
|
||||||
|
* Montecarlo sampling (pick k random samples in the interior of each face)
|
||||||
|
* Subdivision sampling (recursively subdivide each face along the longest edge and choose the sample in the center of each cell)
|
||||||
|
* Similar Triangles sampling (subdivide each face F in k polygons similar to F and sample the face in correspondence with the vertices of these polygons, internal to F)
|
||||||
|
|
||||||
|
Note that the three methods described above are used to sample only the interior of each face.
|
||||||
|
A different scheme is used to sample vertices and edges: vertices are sampled in the straightforward manner,
|
||||||
|
while edges are sampled by uniformly interleaving samples along each edge.
|
||||||
|
|
||||||
|
Basic usage
|
||||||
|
|
||||||
|
Metro is a command-line tool which allows the user to select among different sampling schemes.
|
||||||
|
A list of the command-line parameters accepted by the tool is shown in the following.
|
||||||
|
|
||||||
|
Usage: Metro file1 file2 [opts]
|
||||||
|
|
||||||
|
where "file1" and "file2" are the input meshes in PLY or STL format, and opts can be:
|
||||||
|
|
||||||
|
-v disable vertex sampling
|
||||||
|
-e disable edge sampling
|
||||||
|
-f disable face sampling
|
||||||
|
-u does not ignore unreferred vertices (sample also unreferenced vertices
|
||||||
|
(useful for sampling point clouds against meshes)
|
||||||
|
-Sx set the face sampling mode
|
||||||
|
where x can be:
|
||||||
|
-S0 montecarlo sampling
|
||||||
|
-S1 subdivision sampling
|
||||||
|
-S2 similar triangles sampling (Default)
|
||||||
|
-n# set the required number of samples (overrides -A)
|
||||||
|
-a# set the required number of samples per area unit (overrides -N)
|
||||||
|
-c save computed error as vertex colour and quality in two ply files
|
||||||
|
-C # # Set the min/max values used for color mapping (useful for taking snapshot with coherent color ramp)
|
||||||
|
-L Remove duplicated and unreferenced vertices before processing to avoid
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.7 2004/05/14 13:49:07 ganovelli
|
||||||
|
created
|
||||||
|
|
||||||
Revision 1.6 2004/05/14 00:38:01 ganovelli
|
Revision 1.6 2004/05/14 00:38:01 ganovelli
|
||||||
a bit of cleaning:
|
a bit of cleaning:
|
||||||
SamplingFlags struct added
|
SamplingFlags struct added
|
||||||
|
@ -45,6 +48,7 @@ instantiate GridStaticPtr on the simplexClass template.
|
||||||
#include <vcg/space/box3.h>
|
#include <vcg/space/box3.h>
|
||||||
#include <vcg/space/color4.h>
|
#include <vcg/space/color4.h>
|
||||||
#include <vcg/simplex/face/distance.h>
|
#include <vcg/simplex/face/distance.h>
|
||||||
|
#include <vcg/complex/trimesh/update/color.h>
|
||||||
#include <vcg/space/index/grid_static_ptr.h>
|
#include <vcg/space/index/grid_static_ptr.h>
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
|
|
||||||
|
@ -56,10 +60,10 @@ struct SamplingFlags{
|
||||||
FACE_SAMPLING = 0x0008,
|
FACE_SAMPLING = 0x0008,
|
||||||
MONTECARLO_SAMPLING = 0x0010,
|
MONTECARLO_SAMPLING = 0x0010,
|
||||||
SUBDIVISION_SAMPLING = 0x0020,
|
SUBDIVISION_SAMPLING = 0x0020,
|
||||||
SIMILAR_TRIANGLES_SAMPLING = 0x0040,
|
SIMILAR_SAMPLING = 0x0040,
|
||||||
SAVE_ERROR_DISPLACEMENT = 0x0080,
|
NO_SAMPLING = 0x0070,
|
||||||
SAVE_ERROR_AS_COLOUR = 0x0100,
|
SAVE_ERROR = 0x0100,
|
||||||
INCLUDE_UNREFERENCED_VERTICES = 0x0200
|
INCLUDE_UNREFERENCED_VERTICES = 0x0200,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
@ -170,7 +174,7 @@ Sampling<MetroMesh>::Sampling(MetroMesh &_s1, MetroMesh &_s2):S1(_s1),S2(_s2)
|
||||||
inflate_percentage = 0.02;
|
inflate_percentage = 0.02;
|
||||||
min_size = 125; /* 125 = 5^3 */
|
min_size = 125; /* 125 = 5^3 */
|
||||||
n_hist_bins = 256;
|
n_hist_bins = 256;
|
||||||
print_every_n_elements = 1000;
|
print_every_n_elements = S1.fn/100;
|
||||||
|
|
||||||
referredBit = VertexType::NewUserBit();
|
referredBit = VertexType::NewUserBit();
|
||||||
// store the unreferred vertices
|
// store the unreferred vertices
|
||||||
|
@ -267,23 +271,7 @@ void Sampling<MetroMesh>::VertexSampling()
|
||||||
n_total_vertex_samples++;
|
n_total_vertex_samples++;
|
||||||
|
|
||||||
// save vertex quality
|
// save vertex quality
|
||||||
if(Flags & (SamplingFlags::SAVE_ERROR_DISPLACEMENT | SamplingFlags::SAVE_ERROR_AS_COLOUR))
|
if(Flags & SamplingFlags::SAVE_ERROR) (*vi).Q() = error;
|
||||||
(*vi).Q() = error;
|
|
||||||
|
|
||||||
|
|
||||||
if(Flags & SamplingFlags::SAVE_ERROR_AS_COLOUR)
|
|
||||||
{
|
|
||||||
Color4b col = Color4b(Color4b::White);
|
|
||||||
|
|
||||||
if(error < dist_upper_bound)
|
|
||||||
// colour mapped distance
|
|
||||||
col.ColorRamp(0, dist_upper_bound, dist_upper_bound-error);
|
|
||||||
//else
|
|
||||||
// no matching mesh patches -> white
|
|
||||||
|
|
||||||
(*vi).C() = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// print progress information
|
// print progress information
|
||||||
if(!(++cnt % print_every_n_elements))
|
if(!(++cnt % print_every_n_elements))
|
||||||
|
@ -582,7 +570,8 @@ void Sampling<MetroMesh>::Hausdorff()
|
||||||
if(Flags & SamplingFlags::EDGE_SAMPLING)
|
if(Flags & SamplingFlags::EDGE_SAMPLING)
|
||||||
{
|
{
|
||||||
EdgeSampling();
|
EdgeSampling();
|
||||||
n_samples_target -= (int) n_total_samples;
|
if(n_samples_target > n_total_samples) n_samples_target -= (int) n_total_samples;
|
||||||
|
else n_samples_target=0;
|
||||||
}
|
}
|
||||||
// Face sampling.
|
// Face sampling.
|
||||||
if((Flags & SamplingFlags::FACE_SAMPLING) && (n_samples_target > 0))
|
if((Flags & SamplingFlags::FACE_SAMPLING) && (n_samples_target > 0))
|
||||||
|
@ -590,35 +579,13 @@ void Sampling<MetroMesh>::Hausdorff()
|
||||||
n_samples_per_area_unit = n_samples_target / area_S1;
|
n_samples_per_area_unit = n_samples_target / area_S1;
|
||||||
if(Flags & SamplingFlags::MONTECARLO_SAMPLING) MontecarloFaceSampling();
|
if(Flags & SamplingFlags::MONTECARLO_SAMPLING) MontecarloFaceSampling();
|
||||||
if(Flags & SamplingFlags::SUBDIVISION_SAMPLING) SubdivFaceSampling();
|
if(Flags & SamplingFlags::SUBDIVISION_SAMPLING) SubdivFaceSampling();
|
||||||
if(Flags & SamplingFlags::SIMILAR_TRIANGLES_SAMPLING) SimilarFaceSampling();
|
if(Flags & SamplingFlags::SIMILAR_SAMPLING) SimilarFaceSampling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute vertex colour
|
// compute vertex colour
|
||||||
if(Flags & SamplingFlags::SAVE_ERROR_AS_COLOUR)
|
if(Flags & SamplingFlags::SAVE_ERROR)
|
||||||
{
|
vcg::tri::UpdateColor<MetroMesh>::VertexQuality(S1);
|
||||||
VertexIterator vi;
|
|
||||||
float error;
|
|
||||||
int cnt = 0;
|
|
||||||
for(vi=S1.vert.begin();vi!=S1.vert.end();++vi)
|
|
||||||
{
|
|
||||||
Color4b col = Color4b(Color4b::White);
|
|
||||||
error = (*vi).Q();
|
|
||||||
|
|
||||||
if(error < dist_upper_bound)
|
|
||||||
// colour mapped distance
|
|
||||||
col.ColorRamp(0, (float)max_dist, (float)max_dist-error);
|
|
||||||
//else
|
|
||||||
// no matching mesh patches -> white
|
|
||||||
|
|
||||||
(*vi).C() = col;
|
|
||||||
|
|
||||||
// print progress information
|
|
||||||
if(!(++cnt % print_every_n_elements))
|
|
||||||
printf("Computing vertex colour %d%%\r", (100 * cnt/S1.vn));
|
|
||||||
}
|
|
||||||
printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute statistics
|
// compute statistics
|
||||||
n_samples_per_area_unit = (double) n_total_samples / area_S1;
|
n_samples_per_area_unit = (double) n_total_samples / area_S1;
|
||||||
|
|
Loading…
Reference in New Issue