*** empty log message ***
This commit is contained in:
parent
a055c90d6d
commit
dd50627cba
|
@ -1,49 +0,0 @@
|
||||||
#ifndef __METRO__VCG__HAUS
|
|
||||||
#define __METRO__VCG__HAUS
|
|
||||||
|
|
||||||
#include "sampling.h"
|
|
||||||
|
|
||||||
template <class MESH_TYPE>
|
|
||||||
double Distance(MESH_TYPE & S1,MESH_TYPE & S2){
|
|
||||||
int flags = 0x18;
|
|
||||||
int n_samples_target = 1.5 * __max(S1.fn,S2.fn);
|
|
||||||
|
|
||||||
double dist12_max,dist21_max;
|
|
||||||
// compute face information
|
|
||||||
tri::UpdateEdges::Set(S1);
|
|
||||||
tri::UpdateEdges::Set(S2);
|
|
||||||
|
|
||||||
// set bounding boxes for S1 and S2
|
|
||||||
tri::UpdateBounding::Box(S1);
|
|
||||||
tri::UpdateBounding::Box(S2);
|
|
||||||
|
|
||||||
// set Bounding Box.
|
|
||||||
Box3<typename MESH_TYPE::ScalarType> bbox, tmp_bbox_M1=S1.bbox, tmp_bbox_M2=S2.bbox;
|
|
||||||
bbox.Add(S1.bbox);
|
|
||||||
bbox.Add(S2.bbox);
|
|
||||||
bbox.InflateFix(0.1);
|
|
||||||
S1.bbox = bbox;
|
|
||||||
S2.bbox = bbox;
|
|
||||||
|
|
||||||
Sampling<MESH_TYPE> ForwardSampling(S1,S2);
|
|
||||||
Sampling<MESH_TYPE> BackwardSampling(S2,S1);
|
|
||||||
|
|
||||||
ForwardSampling.SetFlags(flags);
|
|
||||||
BackwardSampling.SetFlags(flags);
|
|
||||||
|
|
||||||
ForwardSampling.SetSamplesTarget(n_samples_target);
|
|
||||||
BackwardSampling.SetSamplesTarget(n_samples_target);
|
|
||||||
|
|
||||||
ForwardSampling.Hausdorff();
|
|
||||||
dist12_max = ForwardSampling.GetDistMax();
|
|
||||||
|
|
||||||
BackwardSampling.Hausdorff();
|
|
||||||
dist21_max = BackwardSampling.GetDistMax();
|
|
||||||
|
|
||||||
return math::Max(dist12_max,dist12_max);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
|
@ -1,375 +0,0 @@
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// standard libraries
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
// project definitions.
|
|
||||||
#include "defs.h"
|
|
||||||
#include "sampling.h"
|
|
||||||
#include "mesh_type.h"
|
|
||||||
#include <vcg/complex/trimesh/update/edges.h>
|
|
||||||
#include <vcg/complex/trimesh/update/bounding.h>
|
|
||||||
//#include <wrap/io_trimesh/import_smf.h>
|
|
||||||
#include <wrap/io_trimesh/import_ply.h>
|
|
||||||
#include <wrap/io_trimesh/export_ply.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
////////////////// 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 SamplesPerAreaUnit = false;
|
|
||||||
bool SaveErrorDisplacement = false;
|
|
||||||
bool SaveErrorAsColour = false;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
inline char* GetExtension(char* filename)
|
|
||||||
{
|
|
||||||
for(int i=strlen(filename)-1; i >= 0; i--)
|
|
||||||
if(filename[i] == '.')
|
|
||||||
break;
|
|
||||||
if(i > 0)
|
|
||||||
return &(filename[i+1]);
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main(int argc, char**argv)
|
|
||||||
{
|
|
||||||
CMesh S1, S2;
|
|
||||||
double dist1_max, dist1_mean, dist1_RMS, volume_1;
|
|
||||||
double dist2_max, dist2_mean, dist2_RMS, volume_2;
|
|
||||||
double mesh_dist_max;
|
|
||||||
unsigned long n_samples_target, n_samples_output, elapsed_time;
|
|
||||||
double n_samples_per_area_unit;
|
|
||||||
int flags, flags_fwd, flags_back, n_samples_area, n_samples_edge, n_samples_vertex, err;
|
|
||||||
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
|
|
||||||
printf("-------------------------------\n"
|
|
||||||
" Metro\n"
|
|
||||||
" release date: "__DATE__"\n"
|
|
||||||
"-------------------------------\n\n");
|
|
||||||
|
|
||||||
// load input meshes.
|
|
||||||
if(argc <= 2)
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_N_ARGS);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load mesh M1.
|
|
||||||
if(!(fmt = GetExtension(argv[1])))
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(!_stricmp(FILE_EXT_PLY, fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[1]);
|
|
||||||
err = tri::io::ImporterPLY<CMesh>::Open(S1,argv[1]);
|
|
||||||
}
|
|
||||||
/* else
|
|
||||||
if(!_stricmp(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);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("done\n");
|
|
||||||
|
|
||||||
// load mesh M2.
|
|
||||||
if(!(fmt = GetExtension(argv[2])))
|
|
||||||
{
|
|
||||||
printf(MSG_ERR_UNKNOWN_FORMAT, fmt);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if(!_stricmp(FILE_EXT_PLY, fmt))
|
|
||||||
{
|
|
||||||
printf("reading the mesh `%s'...", argv[2]);
|
|
||||||
err = tri::io::ImporterPLY<CMesh>::Open(S2,argv[2]);
|
|
||||||
}
|
|
||||||
/*else
|
|
||||||
if(!_stricmp(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.
|
|
||||||
for(int i=3; i < argc;)
|
|
||||||
{
|
|
||||||
if(argv[i][0]=='-')
|
|
||||||
switch(argv[i][1])
|
|
||||||
{
|
|
||||||
case CMD_LINE_ARG_HIST : ComputeHistFlag = true; hist_filename = &(argv[i][2]);
|
|
||||||
if(hist_filename[0] == '\0')
|
|
||||||
strcpy(hist_filename, STR_HIST_FILENAME_DEFAULT);
|
|
||||||
break;
|
|
||||||
case CMD_LINE_ARG_VERTEX_SAMPLE : VertexSampleFlag = false; 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])
|
|
||||||
{
|
|
||||||
case CMD_LINE_ARG_MONTECARLO_SAMPLING : MontecarloSamplingFlag = true; break;
|
|
||||||
case CMD_LINE_ARG_SUBDIVISION_SAMPLING : SubdivisionSamplingFlag = true; break;
|
|
||||||
case CMD_LINE_ARG_SIMILAR_TRIANGLES_SAMPLING : SimilarTrianglesSamplingFlag = true; break;
|
|
||||||
default : printf(MSG_ERR_INVALID_OPTION, argv[i]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CMD_LINE_ARG_N_SAMPLES : NumberOfSamples = true; n_samples_target = atoi(&(argv[i][2])); break;
|
|
||||||
case CMD_LINE_ARG_SAMPLES_PER_AREA_UNIT : SamplesPerAreaUnit = true; n_samples_per_area_unit = (double) atof(&(argv[i][2])); break;
|
|
||||||
case CMD_LINE_ARG_SAVE_DISPLACEMENT : SaveErrorDisplacement = true; new_mesh_filename = &(argv[i][2]);
|
|
||||||
if(new_mesh_filename[0] == '\0')
|
|
||||||
new_mesh_filename = fname_1;
|
|
||||||
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]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set sampling scheme
|
|
||||||
int sampling_method = MontecarloSamplingFlag + SubdivisionSamplingFlag + SimilarTrianglesSamplingFlag;
|
|
||||||
// defaults
|
|
||||||
if(!sampling_method)
|
|
||||||
SimilarTrianglesSamplingFlag = true;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
NumberOfSamples = true;
|
|
||||||
n_samples_target = NO_SAMPLES_PER_FACE * max(S1.fn,S2.fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute face information
|
|
||||||
tri::UpdateEdges<CMesh>::Set(S1);
|
|
||||||
tri::UpdateEdges<CMesh>::Set(S2);
|
|
||||||
|
|
||||||
// set bounding boxes for S1 and S2
|
|
||||||
tri::UpdateBounding<CMesh>::Box(S1);
|
|
||||||
tri::UpdateBounding<CMesh>::Box(S2);
|
|
||||||
|
|
||||||
// set Bounding Box.
|
|
||||||
Box3d bbox, tmp_bbox_M1=S1.bbox, tmp_bbox_M2=S2.bbox;
|
|
||||||
bbox.Add(S1.bbox);
|
|
||||||
bbox.Add(S2.bbox);
|
|
||||||
bbox.InflateFix(INFLATE_PERCENTAGE);
|
|
||||||
S1.bbox = bbox;
|
|
||||||
S2.bbox = bbox;
|
|
||||||
|
|
||||||
// set flags.
|
|
||||||
flags = 0;
|
|
||||||
if(ComputeHistFlag)
|
|
||||||
flags |= FLAG_HIST;
|
|
||||||
if(VertexSampleFlag)
|
|
||||||
flags |= FLAG_VERTEX_SAMPLING;
|
|
||||||
if(EdgeSampleFlag)
|
|
||||||
flags |= FLAG_EDGE_SAMPLING;
|
|
||||||
if(FaceSampleFlag)
|
|
||||||
flags |= FLAG_FACE_SAMPLING;
|
|
||||||
if(MontecarloSamplingFlag)
|
|
||||||
flags |= FLAG_MONTECARLO_SAMPLING;
|
|
||||||
if(SubdivisionSamplingFlag)
|
|
||||||
flags |= FLAG_SUBDIVISION_SAMPLING;
|
|
||||||
if(SimilarTrianglesSamplingFlag)
|
|
||||||
flags |= FLAG_SIMILAR_TRIANGLES_SAMPLING;
|
|
||||||
flags_fwd = flags;
|
|
||||||
flags_back = flags;
|
|
||||||
if(SaveErrorDisplacement)
|
|
||||||
{
|
|
||||||
if(S1.vn >= S2.vn)
|
|
||||||
flags_fwd |= FLAG_SAVE_ERROR_DISPLACEMENT;
|
|
||||||
else
|
|
||||||
flags_back |= FLAG_SAVE_ERROR_DISPLACEMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SaveErrorAsColour)
|
|
||||||
{
|
|
||||||
if(S1.vn >= S2.vn)
|
|
||||||
flags_fwd |= FLAG_SAVE_ERROR_AS_COLOUR;
|
|
||||||
else
|
|
||||||
flags_back |= FLAG_SAVE_ERROR_AS_COLOUR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize time info.
|
|
||||||
int t0=clock();
|
|
||||||
|
|
||||||
// print mesh info.
|
|
||||||
Sampling<CMesh> ForwardSampling(S1,S2);
|
|
||||||
Sampling<CMesh> BackwardSampling(S2,S1);
|
|
||||||
|
|
||||||
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("\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 diagonal %f\n", (float)tmp_bbox_M1.Diag());
|
|
||||||
printf(" M2: '%s'\n\t%vertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[2], S2.vn, S2.fn, BackwardSampling.GetArea());
|
|
||||||
printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M2.min[0], tmp_bbox_M2.min[1], tmp_bbox_M2.min[2], tmp_bbox_M2.max[0], tmp_bbox_M2.max[1], tmp_bbox_M2.max[2]);
|
|
||||||
printf("\tbbox diagonal %f\n", (float)tmp_bbox_M2.Diag());
|
|
||||||
|
|
||||||
// Forward distance.
|
|
||||||
printf("\nForward distance (M1 -> M2):\n");
|
|
||||||
ForwardSampling.SetFlags(flags_fwd);
|
|
||||||
if(NumberOfSamples)
|
|
||||||
{
|
|
||||||
ForwardSampling.SetSamplesTarget(n_samples_target);
|
|
||||||
n_samples_per_area_unit = ForwardSampling.GetNSamplesPerAreaUnit();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ForwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit);
|
|
||||||
n_samples_target = ForwardSampling.GetNSamplesTarget();
|
|
||||||
}
|
|
||||||
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
|
||||||
ForwardSampling.Hausdorff();
|
|
||||||
dist1_max = ForwardSampling.GetDistMax();
|
|
||||||
dist1_mean = ForwardSampling.GetDistMean();
|
|
||||||
dist1_RMS = ForwardSampling.GetDistRMS();
|
|
||||||
volume_1 = ForwardSampling.GetDistVolume();
|
|
||||||
n_samples_output = ForwardSampling.GetNSamples();
|
|
||||||
n_samples_area = ForwardSampling.GetNAreaSamples();
|
|
||||||
n_samples_edge = ForwardSampling.GetNEdgeSamples();
|
|
||||||
n_samples_vertex = ForwardSampling.GetNVertexSamples();
|
|
||||||
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);
|
|
||||||
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.
|
|
||||||
printf("\nBackward distance (M2 -> M1):\n");
|
|
||||||
BackwardSampling.SetFlags(flags_back);
|
|
||||||
if(NumberOfSamples)
|
|
||||||
{
|
|
||||||
BackwardSampling.SetSamplesTarget(n_samples_target);
|
|
||||||
n_samples_per_area_unit = BackwardSampling.GetNSamplesPerAreaUnit();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BackwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit);
|
|
||||||
n_samples_target = BackwardSampling.GetNSamplesTarget();
|
|
||||||
}
|
|
||||||
printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit);
|
|
||||||
BackwardSampling.Hausdorff();
|
|
||||||
dist2_max = BackwardSampling.GetDistMax();
|
|
||||||
dist2_mean = BackwardSampling.GetDistMean();
|
|
||||||
dist2_RMS = BackwardSampling.GetDistRMS();
|
|
||||||
volume_2 = BackwardSampling.GetDistVolume();
|
|
||||||
n_samples_output = BackwardSampling.GetNSamples();
|
|
||||||
n_samples_area = BackwardSampling.GetNAreaSamples();
|
|
||||||
n_samples_edge = BackwardSampling.GetNEdgeSamples();
|
|
||||||
n_samples_vertex = BackwardSampling.GetNVertexSamples();
|
|
||||||
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);
|
|
||||||
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.
|
|
||||||
elapsed_time = clock() - t0;
|
|
||||||
|
|
||||||
// save error distribution histogram
|
|
||||||
/*if(ComputeHistFlag)
|
|
||||||
{
|
|
||||||
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.
|
|
||||||
if((flags_fwd & FLAG_SAVE_ERROR_DISPLACEMENT) && (flags_fwd & FLAG_SAVE_ERROR_AS_COLOUR))
|
|
||||||
if(!strcmp(new_mesh_filename, new_mesh_filename_2))
|
|
||||||
{
|
|
||||||
tri::io::ExporterPLY<CMesh>::Save( S1,new_mesh_filename);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if((flags_back & FLAG_SAVE_ERROR_DISPLACEMENT) && (flags_back & FLAG_SAVE_ERROR_AS_COLOUR))
|
|
||||||
if(!strcmp(new_mesh_filename, new_mesh_filename_2))
|
|
||||||
{
|
|
||||||
tri::io::ExporterPLY<CMesh>::Save( S2,new_mesh_filename_2);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(flags_fwd & FLAG_SAVE_ERROR_DISPLACEMENT)
|
|
||||||
// S1.SavePly(new_mesh_filename, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTCOLOR));
|
|
||||||
//else
|
|
||||||
// if(flags_back & FLAG_SAVE_ERROR_DISPLACEMENT)
|
|
||||||
// S2.SavePly(new_mesh_filename, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTCOLOR));
|
|
||||||
//if(flags_fwd & FLAG_SAVE_ERROR_AS_COLOUR)
|
|
||||||
// S1.SavePly(new_mesh_filename_2, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTQUALITY));
|
|
||||||
//else
|
|
||||||
// if(flags_back & FLAG_SAVE_ERROR_AS_COLOUR)
|
|
||||||
// S2.SavePly(new_mesh_filename_2, CMesh::SM_ALL & (CMesh::SM_ALL ^ CMesh::SM_VERTQUALITY));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
|
@ -1,127 +0,0 @@
|
||||||
# Microsoft Developer Studio Project File - Name="Metro" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
|
||||||
|
|
||||||
CFG=Metro - Win32 Debug
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "Metro.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "Metro.mak" CFG="Metro - Win32 Debug"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "Metro - Win32 Release" (based on "Win32 (x86) Console Application")
|
|
||||||
!MESSAGE "Metro - Win32 Debug" (based on "Win32 (x86) Console Application")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP AllowPerConfigDependencies 0
|
|
||||||
# PROP Scc_ProjName ""$/Metro", MDEAAAAA"
|
|
||||||
# PROP Scc_LocalPath "."
|
|
||||||
CPP=cl.exe
|
|
||||||
RSC=rc.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "Metro - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "bin"
|
|
||||||
# PROP Intermediate_Dir "obj\release"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
|
||||||
# ADD BASE RSC /l 0x410 /d "NDEBUG"
|
|
||||||
# ADD RSC /l 0x410 /d "NDEBUG"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "Metro - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 2
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "bin"
|
|
||||||
# PROP Intermediate_Dir "obj\debug"
|
|
||||||
# PROP Ignore_Export_Lib 0
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_AFXDLL" /YX /FD /GZ /c
|
|
||||||
# ADD BASE RSC /l 0x410 /d "_DEBUG"
|
|
||||||
# ADD RSC /l 0x410 /d "_DEBUG" /d "_AFXDLL"
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LINK32=link.exe
|
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
|
||||||
# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
|
||||||
# SUBTRACT LINK32 /pdb:none
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "Metro - Win32 Release"
|
|
||||||
# Name "Metro - Win32 Debug"
|
|
||||||
# Begin Group "VCG_lib"
|
|
||||||
|
|
||||||
# PROP Default_Filter ""
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=D:\include\vcg\tools\align\Hist.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=D:\include\vcg\tools\align\Hist.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=D:\include\vcg\tools\plylib.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=D:\include\vcg\tools\plylib.h
|
|
||||||
# End Source File
|
|
||||||
# End Group
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CMesh.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\defs.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\Metro.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\Sampling.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\Sampling.h
|
|
||||||
# End Source File
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
|
@ -1,145 +0,0 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="7.10"
|
|
||||||
Name="Metro"
|
|
||||||
ProjectGUID="{855161EC-E66F-4211-B165-0B8A6A82E3E9}"
|
|
||||||
Keyword="ManagedCProj">
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"/>
|
|
||||||
</Platforms>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="Debug"
|
|
||||||
IntermediateDirectory="Debug"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="2"
|
|
||||||
ManagedExtensions="TRUE"
|
|
||||||
WholeProgramOptimization="FALSE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalOptions=""
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories="d:\sf"
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG"
|
|
||||||
MinimalRebuild="FALSE"
|
|
||||||
BasicRuntimeChecks="0"
|
|
||||||
RuntimeLibrary="1"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalOptions="/FORCE:MULTIPLE"
|
|
||||||
OutputFile="$(OutDir)/Metro.exe"
|
|
||||||
LinkIncremental="2"
|
|
||||||
SuppressStartupBanner="TRUE"
|
|
||||||
GenerateDebugInformation="TRUE"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="Release"
|
|
||||||
IntermediateDirectory="Release"
|
|
||||||
ConfigurationType="1"
|
|
||||||
CharacterSet="2"
|
|
||||||
ManagedExtensions="TRUE"
|
|
||||||
WholeProgramOptimization="FALSE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalOptions=""
|
|
||||||
Optimization="2"
|
|
||||||
InlineFunctionExpansion="1"
|
|
||||||
AdditionalIncludeDirectories="d:\sf"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG"
|
|
||||||
MinimalRebuild="FALSE"
|
|
||||||
WarningLevel="3"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
IgnoreImportLibrary="TRUE"
|
|
||||||
AdditionalOptions="/FORCE:MULTIPLE"
|
|
||||||
OutputFile="$(OutDir)/Metro.exe"
|
|
||||||
LinkIncremental="1"
|
|
||||||
SuppressStartupBanner="TRUE"
|
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ImportLibrary=""/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
|
||||||
<File
|
|
||||||
RelativePath="Metro.cpp">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc">
|
|
||||||
<File
|
|
||||||
RelativePath="defs.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\mesh_type.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\min_dist_point.h">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="VCG_lib"
|
|
||||||
Filter="">
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\..\wrap\ply\plylib.cpp">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
|
@ -1,63 +0,0 @@
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
#ifndef _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'
|
|
||||||
|
|
||||||
|
|
||||||
// error messages
|
|
||||||
#define MSG_ERR_N_ARGS "\nUsage: "\
|
|
||||||
"metro file1 file2 [opt]\n"\
|
|
||||||
"where opt can be:\n"\
|
|
||||||
"-V disable vertex sampling\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_INVALID_OPTION "unable to parse option '%s'\n"
|
|
||||||
#define MSG_ERR_FILE_OPEN "unable to open the output file.'n"
|
|
||||||
#define MSG_ERR_UNKNOWN_FORMAT "unknown file format '%s'.\n"
|
|
||||||
|
|
||||||
// global constants
|
|
||||||
#define NO_SAMPLES_PER_FACE 10
|
|
||||||
#define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1
|
|
||||||
#define BBOX_FACTOR 0.1
|
|
||||||
#define INFLATE_PERCENTAGE 0.02
|
|
||||||
#define MIN_SIZE 125 /* 125 = 5^3 */
|
|
||||||
#define N_HIST_BINS 256
|
|
||||||
#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
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* VCGLib *
|
|
||||||
* *
|
|
||||||
* Visual Computing Group o> *
|
|
||||||
* IEI Institute, CNUCE Institute, CNR Pisa <| *
|
|
||||||
* / \ *
|
|
||||||
* Copyright(C) 1999 by Paolo Cignoni, Claudio Rocchini *
|
|
||||||
* All rights reserved. *
|
|
||||||
* *
|
|
||||||
* Permission to use, copy, modify, distribute and sell this software and *
|
|
||||||
* its documentation for any purpose is hereby granted without fee, provided *
|
|
||||||
* that the above copyright notice appear in all copies and that both that *
|
|
||||||
* copyright notice and this permission notice appear in supporting *
|
|
||||||
* documentation. the author makes no representations about the suitability *
|
|
||||||
* of this software for any purpose. It is provided "as is" without express *
|
|
||||||
* or implied warranty. *
|
|
||||||
* *
|
|
||||||
*****************************************************************************/
|
|
||||||
/****************************************************************************
|
|
||||||
History
|
|
||||||
2003 Dic 17 modifiche per conversione alla versione template (gano)
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
#ifndef _CMESH_H
|
|
||||||
#define _CMESH_H
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma warning(disable:4786 4804 4666)
|
|
||||||
// standard libraries.
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
// VCG library.
|
|
||||||
//#include <vcg/tools/plylib.h>
|
|
||||||
#include <vcg/simplex/vertex/with/cmnq.h>
|
|
||||||
#include <vcg/simplex/face/with/rtfmfn.h>
|
|
||||||
#include <vcg/space/index/grid_static_obj.h>
|
|
||||||
#include <vcg/complex/trimesh/base.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace vcg;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// Vertex, Face, Mesh and Grid definitions.
|
|
||||||
class MyEdge;
|
|
||||||
class CFace;
|
|
||||||
class CVertex : public VertexCMNQ< double,MyEdge,CFace > {};
|
|
||||||
class CFace : public FaceRTFMFN< CVertex > {public:
|
|
||||||
CFace*& F(const int j){ return (CFace*&) FaceRTFMFN<CVertex>::F(j);}
|
|
||||||
};
|
|
||||||
class CMesh : public tri::TriMesh< vector<CVertex>, vector<CFace> > {};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
#endif
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
|
@ -1,206 +0,0 @@
|
||||||
/*#***************************************************************************
|
|
||||||
* MinDistPoint.h o o *
|
|
||||||
* o o *
|
|
||||||
* Visual Computing Group _ O _ *
|
|
||||||
* IEI Institute, CNUCE Institute, CNR Pisa \/)\/ *
|
|
||||||
* /\/| *
|
|
||||||
* Copyright(C) 1999 by Paolo Cignoni, Paolo Pingi, Claudio Rocchini | *
|
|
||||||
* All rights reserved. \ *
|
|
||||||
* *
|
|
||||||
* Permission to use, copy, modify, distribute and sell this software and *
|
|
||||||
* its documentation for any purpose is hereby granted without fee, provided *
|
|
||||||
* that the above copyright notice appear in all copies and that both that *
|
|
||||||
* copyright notice and this permission notice appear in supporting *
|
|
||||||
* documentation. the author makes no representations about the suitability *
|
|
||||||
* of this software for any purpose. It is provided "as is" without express *
|
|
||||||
* or implied warranty. *
|
|
||||||
* *
|
|
||||||
* NOTE THAT THIS FILE SHOULD NOT DIRECTL BE INCLUDED *
|
|
||||||
* It is automatically included by Mesh.h *
|
|
||||||
* *
|
|
||||||
***************************************************************************#*/
|
|
||||||
/*#**************************************************************************
|
|
||||||
History
|
|
||||||
|
|
||||||
2000 Nov 06 First Working release (pc)
|
|
||||||
08 Aggiunto if(gr.bbox.IsIn(p)) per evitare piantamenti se si chiede
|
|
||||||
un punto fuori.
|
|
||||||
Tolto un Normalize inutile
|
|
||||||
2001 May 17 Aggiunta versione della Mindistpoint che da anche le coord
|
|
||||||
baricentriche del punto trovato (pc); aggiunto wrapper per la vecchia
|
|
||||||
versione.
|
|
||||||
Dec 10 Corretto prodotto scalare vettore nell'ordine giusto in un paio di posti
|
|
||||||
2002 Mar 29 Templatata anche in funzione del tipo scalare. (pc)
|
|
||||||
Oct 24 Corretti warning (unsigned mismatch) del vc7,
|
|
||||||
2003 Apr 15 Corretti mismatch iterator / pointer
|
|
||||||
Jun 08 Aggiornato UGridLink -> UGrid::Link
|
|
||||||
2004 Gen 09 Aggiunte le inclusioni a Point3[4].h
|
|
||||||
2004 Gen 19 Corretto qualche ->Normal() in ->cN()
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef __VCG_MINDISTPOINT
|
|
||||||
#define __VCG_MINDISTPOINT
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include <vcg/space/point3.h>
|
|
||||||
#include <vcg/space/Point4.h>
|
|
||||||
#include <vcg/math/base.h>
|
|
||||||
using namespace vcg;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
aka MetroCore
|
|
||||||
data una mesh m e una ug sulle sue facce trova il punto di m piu' vicino ad
|
|
||||||
un punto dato.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// input: mesh, punto, griglia, distanza limite
|
|
||||||
// output: normale alla faccia e punto piu' vicino su di essa
|
|
||||||
|
|
||||||
// Nota che il parametro template GRID non ci dovrebbe essere, visto che deve essere
|
|
||||||
// UGrid<MESH::FaceContainer >, ma non sono riuscito a definirlo implicitamente
|
|
||||||
|
|
||||||
template <class MESH, class GRID, class SCALAR>
|
|
||||||
void MinDistPoint( MESH & mesh, const Point3<SCALAR> & p, GRID & gr, SCALAR & mdist,
|
|
||||||
Point3<SCALAR> & normf, Point3<SCALAR> & bestq, typename MESH::FaceType * &f, Point3<SCALAR> &ip)
|
|
||||||
{
|
|
||||||
typedef SCALAR scalar;
|
|
||||||
typedef Point3<scalar> Point3x;
|
|
||||||
typedef Box3<SCALAR> Box3x;
|
|
||||||
|
|
||||||
if(!gr.bbox.IsIn(p)) return;
|
|
||||||
typedef GridStaticObj<typename MESH::FaceContainer>::Link A2UGridLink;
|
|
||||||
scalar ax = p[0] - gr.bbox.min[0]; // Real coodinate of point refer to
|
|
||||||
scalar ay = p[1] - gr.bbox.min[1];
|
|
||||||
scalar az = p[2] - gr.bbox.min[2];
|
|
||||||
|
|
||||||
int gx = int( ax/gr.voxel[0] ); // Integer coordinate of the point
|
|
||||||
int gy = int( ay/gr.voxel[1] ); // voxel
|
|
||||||
int gz = int( az/gr.voxel[2] );
|
|
||||||
|
|
||||||
scalar vx = gr.bbox.min[0]+gx*gr.voxel[0]; // Real world coordinate of the Voxel
|
|
||||||
scalar vy = gr.bbox.min[1]+gy*gr.voxel[1]; // origin
|
|
||||||
scalar vz = gr.bbox.min[2]+gz*gr.voxel[2];
|
|
||||||
|
|
||||||
scalar dx = math::Min(p[0] - vx, vx+gr.voxel[0]-p[0]); // Dist from the voxel
|
|
||||||
scalar dy = math::Min(p[1] - vy, vy+gr.voxel[1]-p[1]);
|
|
||||||
scalar dz = math::Min(p[2] - vz, vz+gr.voxel[2]-p[2]);
|
|
||||||
|
|
||||||
scalar vdist,vstep;
|
|
||||||
|
|
||||||
if(dx<dy && dx<dz)
|
|
||||||
{
|
|
||||||
vdist = dx;
|
|
||||||
vstep = gr.voxel[0];
|
|
||||||
}
|
|
||||||
else if(dy<dz)
|
|
||||||
{
|
|
||||||
vdist = dy;
|
|
||||||
vstep = gr.voxel[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vdist = dz;
|
|
||||||
vstep = gr.voxel[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
//scalar error = gr.bbox.SquaredDiag();
|
|
||||||
//scalar error = gr.bbox.Diag();
|
|
||||||
scalar error = mdist;
|
|
||||||
Point3x q;
|
|
||||||
MESH::FaceIterator bestf = 0;
|
|
||||||
|
|
||||||
mesh.UnMarkAll();
|
|
||||||
|
|
||||||
int mxsd = gr.siz[0];
|
|
||||||
if(mxsd<gr.siz[1]) mxsd = gr.siz[1];
|
|
||||||
if(mxsd<gr.siz[2]) mxsd = gr.siz[2];
|
|
||||||
for(int s=0;s<mxsd;++s)
|
|
||||||
{
|
|
||||||
if(s==0)
|
|
||||||
{
|
|
||||||
|
|
||||||
A2UGridLink *first, *last, *l;
|
|
||||||
gr.Grid( gx, gy, gz, first, last );
|
|
||||||
for(l=first;l!=last;++l)
|
|
||||||
|
|
||||||
if( ! mesh.IsMarked( &*(l->Elem())) )
|
|
||||||
{
|
|
||||||
if( (*(l->Elem())).Dist( p, error, q) )
|
|
||||||
{
|
|
||||||
bestq = q;
|
|
||||||
bestf = l->Elem();
|
|
||||||
MESH::ScalarType alfa=1, beta=1, gamma=1;
|
|
||||||
|
|
||||||
//bestf->InterpolationParameters(q, alfa, beta);
|
|
||||||
//calcolo normale con interpolazione trilineare
|
|
||||||
/*normf = (1-(alfa+beta))*(bestf->V(0)->Normal())+
|
|
||||||
(alfa*(bestf->V(1)->Normal()))+
|
|
||||||
(beta*(bestf->V(2)->Normal()));*/
|
|
||||||
bool ret=bestf->InterpolationParameters(q, alfa, beta, gamma);
|
|
||||||
//assert(ret);
|
|
||||||
normf = (bestf->V(0)->cN())*alfa+
|
|
||||||
(bestf->V(1)->cN())*beta+
|
|
||||||
(bestf->V(2)->cN())*gamma;
|
|
||||||
normf.Normalize();
|
|
||||||
ip[0]=alfa;ip[1]=beta;ip[2]=gamma;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.Mark( &*(l->Elem()) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int ix=gx-s;ix<=gx+s;++ix)
|
|
||||||
if( ix>=0 && ix<gr.siz[0] )
|
|
||||||
{
|
|
||||||
for(int iy=gy-s;iy<=gy+s;++iy)
|
|
||||||
if( iy>=0 && iy<gr.siz[1] )
|
|
||||||
{
|
|
||||||
int sz = ( ix==gx-s || ix==gx+s ||
|
|
||||||
iy==gy-s || iy==gy+s )?1:2*s;
|
|
||||||
for(int iz=gz-s;iz<=gz+s;iz+=sz)
|
|
||||||
if( iz>=0 && iz<gr.siz[2] )
|
|
||||||
{
|
|
||||||
A2UGridLink *first, *last, *l;
|
|
||||||
gr.Grid( ix, iy, iz, first, last );
|
|
||||||
for(l=first;l!=last;++l)
|
|
||||||
if( ! mesh.IsMarked( &*(l->Elem())) )
|
|
||||||
{
|
|
||||||
if( (*(l->Elem())).Dist( p, error, q) )
|
|
||||||
{
|
|
||||||
bestq = q;
|
|
||||||
bestf = l->Elem();
|
|
||||||
MESH::ScalarType alfa, beta, gamma;
|
|
||||||
//bestf->InterpolationParameters(q, alfa, beta);
|
|
||||||
//calcolo normale con interpolazione trilineare
|
|
||||||
bestf->InterpolationParameters(q, alfa, beta, gamma);
|
|
||||||
normf = (bestf->V(0)->cN())*alfa+
|
|
||||||
(bestf->V(1)->cN())*beta+
|
|
||||||
(bestf->V(2)->cN())*gamma ;
|
|
||||||
ip[0]=alfa;ip[1]=beta;ip[2]=gamma;
|
|
||||||
//normf.Normalize(); inutile si assume le normali ai vertici benfatte
|
|
||||||
}
|
|
||||||
mesh.Mark(&*l->Elem());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( fabs(error)<vdist )
|
|
||||||
break;
|
|
||||||
vdist += vstep;
|
|
||||||
}
|
|
||||||
f=&*bestf;
|
|
||||||
mdist = scalar(fabs(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MESH, class GRID, class SCALAR>
|
|
||||||
void MinDistPoint( MESH & mesh, const Point3<SCALAR> & p, GRID & gr, SCALAR & mdist,
|
|
||||||
Point3<SCALAR> & normf, Point3<SCALAR> & bestq, typename MESH::face_type * &f)
|
|
||||||
{
|
|
||||||
Point3<SCALAR> ip;
|
|
||||||
MinDistPoint(mesh,p,gr,mdist,normf,bestq,f,ip);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,607 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
* VCGLib *
|
|
||||||
* *
|
|
||||||
* Visual Computing Group o> *
|
|
||||||
* IEI Institute, CNUCE Institute, CNR Pisa <| *
|
|
||||||
* / \ *
|
|
||||||
* Copyright(C) 1999 by Paolo Cignoni, Claudio Rocchini *
|
|
||||||
* All rights reserved. *
|
|
||||||
* *
|
|
||||||
* Permission to use, copy, modify, distribute and sell this software and *
|
|
||||||
* its documentation for any purpose is hereby granted without fee, provided *
|
|
||||||
* that the above copyright notice appear in all copies and that both that *
|
|
||||||
* copyright notice and this permission notice appear in supporting *
|
|
||||||
* documentation. the author makes no representations about the suitability *
|
|
||||||
* of this software for any purpose. It is provided "as is" without express *
|
|
||||||
* or implied warranty. *
|
|
||||||
* *
|
|
||||||
*****************************************************************************/
|
|
||||||
/****************************************************************************
|
|
||||||
History
|
|
||||||
2003 Dic 17 modifiche per conversione alla versione template (gano)
|
|
||||||
2004 Jan 19 qualche ->P() in ->cP() (Snarf)
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
#ifndef _SAMPLING_H
|
|
||||||
#define _SAMPLING_H
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// standard libraries.
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
// VCG library.
|
|
||||||
//#include <vcg/tools/xml/xml.h>
|
|
||||||
#include "min_dist_point.h"
|
|
||||||
//#include <vcg/tools/Align/Hist.h>
|
|
||||||
#include <vcg/space/box3.h>
|
|
||||||
#include <vcg/space/color4.h>
|
|
||||||
#include <vcg/space/index/grid_static_obj.h>
|
|
||||||
using namespace vcg;
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// flags.
|
|
||||||
#define FLAG_HIST 0x0001
|
|
||||||
#define FLAG_VERTEX_SAMPLING 0x0002
|
|
||||||
#define FLAG_EDGE_SAMPLING 0x0004
|
|
||||||
#define FLAG_FACE_SAMPLING 0x0008
|
|
||||||
#define FLAG_MONTECARLO_SAMPLING 0x0010
|
|
||||||
#define FLAG_SUBDIVISION_SAMPLING 0x0020
|
|
||||||
#define FLAG_SIMILAR_TRIANGLES_SAMPLING 0x0040
|
|
||||||
#define FLAG_SAVE_ERROR_DISPLACEMENT 0x0080
|
|
||||||
#define FLAG_SAVE_ERROR_AS_COLOUR 0x0100
|
|
||||||
|
|
||||||
// global constants
|
|
||||||
#define NO_SAMPLES_PER_FACE 10
|
|
||||||
#define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1
|
|
||||||
#define BBOX_FACTOR 0.1
|
|
||||||
#define INFLATE_PERCENTAGE 0.02
|
|
||||||
#define MIN_SIZE 125 /* 125 = 5^3 */
|
|
||||||
#define N_HIST_BINS 256
|
|
||||||
#define PRINT_EVERY_N_ELEMENTS 1000
|
|
||||||
#define FILE_EXT_SMF "smf"
|
|
||||||
#define FILE_EXT_PLY "ply"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
template <class MetroMesh>
|
|
||||||
class Sampling
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef GridStaticObj< typename MetroMesh::FaceContainer > MetroMeshGrid;
|
|
||||||
typedef Point3<typename MetroMesh::ScalarType> Point3x;
|
|
||||||
|
|
||||||
// data structures
|
|
||||||
MetroMesh &S1;
|
|
||||||
MetroMesh &S2;
|
|
||||||
MetroMeshGrid gS2;
|
|
||||||
|
|
||||||
|
|
||||||
// parameters
|
|
||||||
double dist_upper_bound;
|
|
||||||
double n_samples_per_area_unit;
|
|
||||||
double n_samples_target;
|
|
||||||
int Flags;
|
|
||||||
|
|
||||||
// results
|
|
||||||
// Hist hist;
|
|
||||||
unsigned long n_total_samples;
|
|
||||||
unsigned long n_total_area_samples;
|
|
||||||
unsigned long n_total_edge_samples;
|
|
||||||
unsigned long n_total_vertex_samples;
|
|
||||||
double max_dist;
|
|
||||||
double mean_dist;
|
|
||||||
double RMS_dist;
|
|
||||||
double volume;
|
|
||||||
double area_S1;
|
|
||||||
|
|
||||||
// globals
|
|
||||||
int n_samples;
|
|
||||||
|
|
||||||
// private methods
|
|
||||||
inline double ComputeMeshArea(MetroMesh & mesh);
|
|
||||||
float AddSample(const Point3x &p);
|
|
||||||
inline void AddRandomSample(typename MetroMesh::FaceIterator &T);
|
|
||||||
inline void SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge);
|
|
||||||
void VertexSampling();
|
|
||||||
void EdgeSampling();
|
|
||||||
void FaceSubdiv(const Point3x & v0, const Point3x &v1, const Point3x & v2, int maxdepth);
|
|
||||||
void SimilarTriangles(const Point3x &v0, const Point3x &v1, const Point3x &v2, int n_samples_per_edge);
|
|
||||||
void MontecarloFaceSampling();
|
|
||||||
void SubdivFaceSampling();
|
|
||||||
void SimilarFaceSampling();
|
|
||||||
|
|
||||||
public :
|
|
||||||
// public methods
|
|
||||||
Sampling(MetroMesh &_s1, MetroMesh &_s2);
|
|
||||||
void Hausdorff();
|
|
||||||
double GetArea() {return area_S1;}
|
|
||||||
double GetDistMax() {return max_dist;}
|
|
||||||
double GetDistMean() {return mean_dist;}
|
|
||||||
double GetDistRMS() {return RMS_dist;}
|
|
||||||
double GetDistVolume() {return volume;}
|
|
||||||
double GetNSamples() {return n_total_samples;}
|
|
||||||
double GetNAreaSamples() {return n_total_area_samples;}
|
|
||||||
double GetNEdgeSamples() {return n_total_edge_samples;}
|
|
||||||
double GetNVertexSamples() {return n_total_vertex_samples;}
|
|
||||||
double GetNSamplesPerAreaUnit() {return n_samples_per_area_unit;}
|
|
||||||
double GetNSamplesTarget() {return n_samples_target;}
|
|
||||||
// Hist &GetHist() {return hist;}
|
|
||||||
void SetFlags(int flags) {Flags = flags;}
|
|
||||||
void ClearFlag(int flag) {Flags &= (flag ^ -1);}
|
|
||||||
void SetParam(double _n_samp) {n_samples_target = _n_samp;}
|
|
||||||
void SetSamplesTarget(int _n_samp);
|
|
||||||
void SetSamplesPerAreaUnit(double _n_samp);
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
template <class MetroMesh>
|
|
||||||
Sampling<MetroMesh>::Sampling(MetroMesh &_s1, MetroMesh &_s2):S1(_s1),S2(_s2)
|
|
||||||
{
|
|
||||||
Flags = 0;
|
|
||||||
area_S1 = ComputeMeshArea(_s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set sampling parameters
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::SetSamplesTarget(int _n_samp)
|
|
||||||
{
|
|
||||||
n_samples_target = _n_samp;
|
|
||||||
n_samples_per_area_unit = (double) n_samples_target / area_S1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::SetSamplesPerAreaUnit(double _n_samp)
|
|
||||||
{
|
|
||||||
n_samples_per_area_unit = _n_samp;
|
|
||||||
n_samples_target = (int)((double) n_samples_per_area_unit * area_S1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// auxiliary functions
|
|
||||||
template <class MetroMesh>
|
|
||||||
inline double Sampling<MetroMesh>::ComputeMeshArea(MetroMesh & mesh)
|
|
||||||
{
|
|
||||||
MetroMesh::FaceIterator face;
|
|
||||||
double area = 0.0;
|
|
||||||
|
|
||||||
for(face=mesh.face.begin(); face != mesh.face.end(); face++)
|
|
||||||
if(!(*face).IsD())
|
|
||||||
area += face->Area();
|
|
||||||
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
float Sampling<MetroMesh>::AddSample(const Point3x &p)
|
|
||||||
{
|
|
||||||
MetroMesh::FaceType *f=0;
|
|
||||||
Point3x normf, bestq, ip;
|
|
||||||
MetroMesh::ScalarType dist;
|
|
||||||
|
|
||||||
dist = dist_upper_bound;
|
|
||||||
|
|
||||||
// compute distance between p_i and the mesh S2
|
|
||||||
MinDistPoint(S2, p, gS2, dist, normf, bestq, f, ip);
|
|
||||||
|
|
||||||
// update distance measures
|
|
||||||
if(dist == dist_upper_bound)
|
|
||||||
return -1.0;
|
|
||||||
|
|
||||||
if(dist > max_dist)
|
|
||||||
max_dist = dist; // L_inf
|
|
||||||
mean_dist += dist; // L_1
|
|
||||||
RMS_dist += dist*dist; // L_2
|
|
||||||
n_total_samples++;
|
|
||||||
|
|
||||||
//if(Flags & FLAG_HIST)
|
|
||||||
// hist.Add((float)fabs(dist));
|
|
||||||
|
|
||||||
return (float)dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
// --- Vertex Sampling ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::VertexSampling()
|
|
||||||
{
|
|
||||||
// Vertex sampling.
|
|
||||||
int cnt = 0;
|
|
||||||
float error;
|
|
||||||
|
|
||||||
printf("Vertex sampling\n");
|
|
||||||
MetroMesh::VertexIterator vi;
|
|
||||||
for(vi=S1.vert.begin();vi!=S1.vert.end();++vi)
|
|
||||||
{
|
|
||||||
error = AddSample((*vi).cP());
|
|
||||||
n_total_vertex_samples++;
|
|
||||||
|
|
||||||
// save vertex quality
|
|
||||||
if(Flags & (FLAG_SAVE_ERROR_DISPLACEMENT | FLAG_SAVE_ERROR_AS_COLOUR))
|
|
||||||
(*vi).Q() = error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if(Flags & FLAG_SAVE_ERROR_AS_COLOUR)
|
|
||||||
{
|
|
||||||
ColorUB col = ColorUB(ColorUB::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
|
|
||||||
if(!(++cnt % PRINT_EVERY_N_ELEMENTS))
|
|
||||||
printf("Sampling vertices %d%%\r", (100 * cnt/S1.vn));
|
|
||||||
}
|
|
||||||
printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
// --- Edge Sampling -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
inline void Sampling<MetroMesh>::SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge)
|
|
||||||
{
|
|
||||||
// uniform sampling of the segment v0v1.
|
|
||||||
Point3x e((v1-v0)/(double)(n_samples_per_edge+1));
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=1; i <= n_samples_per_edge; i++)
|
|
||||||
{
|
|
||||||
AddSample(v0 + e*i);
|
|
||||||
n_total_edge_samples++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::EdgeSampling()
|
|
||||||
{
|
|
||||||
// Edge sampling.
|
|
||||||
typedef pair<typename MetroMesh::VertexPointer, typename MetroMesh::VertexPointer> pvv;
|
|
||||||
vector< pvv > Edges;
|
|
||||||
|
|
||||||
printf("Edge sampling\n");
|
|
||||||
|
|
||||||
// compute edge list.
|
|
||||||
MetroMesh::FaceIterator fi;
|
|
||||||
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
|
|
||||||
for(int i=0; i<3; ++i)
|
|
||||||
{
|
|
||||||
Edges.push_back(make_pair((*fi).V0(i),(*fi).V1(i)));
|
|
||||||
if(Edges.back().first > Edges.back().second)
|
|
||||||
swap(Edges.back().first, Edges.back().second);
|
|
||||||
}
|
|
||||||
sort(Edges.begin(), Edges.end());
|
|
||||||
vector<pvv>::iterator edgeend = unique(Edges.begin(), Edges.end());
|
|
||||||
Edges.resize(edgeend-Edges.begin());
|
|
||||||
|
|
||||||
// sample edges.
|
|
||||||
vector<pvv>::iterator ei;
|
|
||||||
double n_samples_per_length_unit;
|
|
||||||
double n_samples_decimal = 0.0;
|
|
||||||
int cnt=0;
|
|
||||||
if(Flags & FLAG_FACE_SAMPLING)
|
|
||||||
n_samples_per_length_unit = sqrt(n_samples_per_area_unit);
|
|
||||||
else
|
|
||||||
n_samples_per_length_unit = n_samples_per_area_unit;
|
|
||||||
for(ei=Edges.begin(); ei!=Edges.end(); ++ei)
|
|
||||||
{
|
|
||||||
n_samples_decimal += Distance((*ei).first->cP(),(*ei).second->cP()) * n_samples_per_length_unit;
|
|
||||||
n_samples = (int) n_samples_decimal;
|
|
||||||
SampleEdge((*ei).first->cP(), (*ei).second->cP(), (int) n_samples);
|
|
||||||
n_samples_decimal -= (double) n_samples;
|
|
||||||
|
|
||||||
// print progress information
|
|
||||||
if(!(++cnt % PRINT_EVERY_N_ELEMENTS))
|
|
||||||
printf("Sampling edge %d%%\r", (100 * cnt/Edges.size()));
|
|
||||||
}
|
|
||||||
printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
// --- Face Sampling -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Montecarlo sampling.
|
|
||||||
template <class MetroMesh>
|
|
||||||
inline void Sampling<MetroMesh>::AddRandomSample(typename MetroMesh::FaceIterator &T)
|
|
||||||
{
|
|
||||||
// random sampling over the input face.
|
|
||||||
double rnd_1, rnd_2;
|
|
||||||
|
|
||||||
// vertices of the face T.
|
|
||||||
Point3x p0(T->V(0)->cP());
|
|
||||||
Point3x p1(T->V(1)->cP());
|
|
||||||
Point3x p2(T->V(2)->cP());
|
|
||||||
// calculate two edges of T.
|
|
||||||
Point3x v1(p1 - p0);
|
|
||||||
Point3x v2(p2 - p0);
|
|
||||||
|
|
||||||
// choose two random numbers.
|
|
||||||
rnd_1 = (double)rand() / (double)RAND_MAX;
|
|
||||||
rnd_2 = (double)rand() / (double)RAND_MAX;
|
|
||||||
if(rnd_1 + rnd_2 > 1.0)
|
|
||||||
{
|
|
||||||
rnd_1 = 1.0 - rnd_1;
|
|
||||||
rnd_2 = 1.0 - rnd_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a random point on the face T.
|
|
||||||
AddSample (p0 + (v1 * rnd_1 + v2 * rnd_2));
|
|
||||||
n_total_area_samples++;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::MontecarloFaceSampling()
|
|
||||||
{
|
|
||||||
// Montecarlo sampling.
|
|
||||||
int cnt = 0;
|
|
||||||
double n_samples_decimal = 0.0;
|
|
||||||
MetroMesh::FaceIterator fi;
|
|
||||||
|
|
||||||
srand(clock());
|
|
||||||
// printf("Montecarlo face sampling\n");
|
|
||||||
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
|
|
||||||
if(!(*fi).IsD())
|
|
||||||
{
|
|
||||||
// compute # samples in the current face.
|
|
||||||
n_samples_decimal += fi->Area() * n_samples_per_area_unit;
|
|
||||||
n_samples = (int) n_samples_decimal;
|
|
||||||
|
|
||||||
// for every sample p_i in T...
|
|
||||||
for(int i=0; i < n_samples; i++)
|
|
||||||
AddRandomSample(fi);
|
|
||||||
|
|
||||||
n_samples_decimal -= (double) n_samples;
|
|
||||||
|
|
||||||
// print progress information
|
|
||||||
// if(!(++cnt % PRINT_EVERY_N_ELEMENTS))
|
|
||||||
// printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
|
|
||||||
}
|
|
||||||
// printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Subdivision sampling.
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::FaceSubdiv(const Point3x & v0, const Point3x & v1, const Point3x & v2, int maxdepth)
|
|
||||||
{
|
|
||||||
// recursive face subdivision.
|
|
||||||
if(maxdepth == 0)
|
|
||||||
{
|
|
||||||
// ground case.
|
|
||||||
AddSample((v0+v1+v2)/3.0f);
|
|
||||||
n_total_area_samples++;
|
|
||||||
n_samples++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the longest edge.
|
|
||||||
double maxd01 = SquaredDistance(v0,v1);
|
|
||||||
double maxd12 = SquaredDistance(v1,v2);
|
|
||||||
double maxd20 = SquaredDistance(v2,v0);
|
|
||||||
int res;
|
|
||||||
if(maxd01 > maxd12)
|
|
||||||
if(maxd01 > maxd20) res = 0;
|
|
||||||
else res = 2;
|
|
||||||
else
|
|
||||||
if(maxd12 > maxd20) res = 1;
|
|
||||||
else res = 2;
|
|
||||||
|
|
||||||
// break the input triangle along the median to the the longest edge.
|
|
||||||
Point3x pp;
|
|
||||||
switch(res)
|
|
||||||
{
|
|
||||||
case 0 : pp = (v0+v1)/2;
|
|
||||||
FaceSubdiv(v0,pp,v2,maxdepth-1);
|
|
||||||
FaceSubdiv(pp,v1,v2,maxdepth-1);
|
|
||||||
break;
|
|
||||||
case 1 : pp = (v1+v2)/2;
|
|
||||||
FaceSubdiv(v0,v1,pp,maxdepth-1);
|
|
||||||
FaceSubdiv(v0,pp,v2,maxdepth-1);
|
|
||||||
break;
|
|
||||||
case 2 : pp = (v2+v0)/2;
|
|
||||||
FaceSubdiv(v0,v1,pp,maxdepth-1);
|
|
||||||
FaceSubdiv(pp,v1,v2,maxdepth-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::SubdivFaceSampling()
|
|
||||||
{
|
|
||||||
// Subdivision sampling.
|
|
||||||
int cnt = 0, maxdepth;
|
|
||||||
double n_samples_decimal = 0.0;
|
|
||||||
MetroMesh::FaceIterator fi;
|
|
||||||
|
|
||||||
printf("Subdivision face sampling\n");
|
|
||||||
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
|
|
||||||
{
|
|
||||||
// compute # samples in the current face.
|
|
||||||
n_samples_decimal += fi->Area() * n_samples_per_area_unit;
|
|
||||||
n_samples = (int) n_samples_decimal;
|
|
||||||
if(n_samples)
|
|
||||||
{
|
|
||||||
// face sampling.
|
|
||||||
maxdepth = (int)log((double)n_samples)/log(2.0);
|
|
||||||
n_samples = 0;
|
|
||||||
FaceSubdiv((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), maxdepth);
|
|
||||||
}
|
|
||||||
n_samples_decimal -= (double) n_samples;
|
|
||||||
|
|
||||||
// print progress information
|
|
||||||
if(!(++cnt % PRINT_EVERY_N_ELEMENTS))
|
|
||||||
printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
|
|
||||||
}
|
|
||||||
printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Similar Triangles sampling.
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::SimilarTriangles(const Point3x & v0, const Point3x & v1, const Point3x & v2, int n_samples_per_edge)
|
|
||||||
{
|
|
||||||
Point3x V1((v1-v0)/(double)(n_samples_per_edge-1));
|
|
||||||
Point3x V2((v2-v0)/(double)(n_samples_per_edge-1));
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// face sampling.
|
|
||||||
for(i=1; i < n_samples_per_edge-1; i++)
|
|
||||||
for(j=1; j < n_samples_per_edge-1-i; j++)
|
|
||||||
{
|
|
||||||
AddSample( v0 + (V1*(double)i + V2*(double)j) );
|
|
||||||
n_total_area_samples++;
|
|
||||||
n_samples++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::SimilarFaceSampling()
|
|
||||||
{
|
|
||||||
// Similar Triangles sampling.
|
|
||||||
int cnt = 0, n_samples_per_edge;
|
|
||||||
double n_samples_decimal = 0.0;
|
|
||||||
MetroMesh::FaceIterator fi;
|
|
||||||
|
|
||||||
printf("Similar Triangles face sampling\n");
|
|
||||||
for(fi=S1.face.begin(); fi != S1.face.end(); fi++)
|
|
||||||
{
|
|
||||||
// compute # samples in the current face.
|
|
||||||
n_samples_decimal += fi->Area() * n_samples_per_area_unit;
|
|
||||||
n_samples = (int) n_samples_decimal;
|
|
||||||
if(n_samples)
|
|
||||||
{
|
|
||||||
// face sampling.
|
|
||||||
n_samples_per_edge = (int)((sqrt(1.0+8.0*(double)n_samples) +5.0)/2.0);
|
|
||||||
n_samples = 0;
|
|
||||||
SimilarTriangles((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), n_samples_per_edge);
|
|
||||||
}
|
|
||||||
n_samples_decimal -= (double) n_samples;
|
|
||||||
|
|
||||||
// print progress information
|
|
||||||
if(!(++cnt % PRINT_EVERY_N_ELEMENTS))
|
|
||||||
printf("Sampling face %d%%\r", (100 * cnt/S1.fn));
|
|
||||||
}
|
|
||||||
printf(" \r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
// --- Distance ----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <class MetroMesh>
|
|
||||||
void Sampling<MetroMesh>::Hausdorff()
|
|
||||||
{
|
|
||||||
Box3< MetroMesh::ScalarType> bbox;
|
|
||||||
|
|
||||||
// set grid meshes.
|
|
||||||
gS2.SetBBox(S2.bbox);
|
|
||||||
if(S2.face.size() < MIN_SIZE)
|
|
||||||
gS2.Set(S2.face, MIN_SIZE);
|
|
||||||
else
|
|
||||||
gS2.Set(S2.face);
|
|
||||||
|
|
||||||
// set bounding box
|
|
||||||
bbox = S2.bbox;
|
|
||||||
dist_upper_bound = /*BBOX_FACTOR * */bbox.Diag();
|
|
||||||
//if(Flags & FLAG_HIST)
|
|
||||||
// hist.SetRange(0.0, dist_upper_bound, N_HIST_BINS);
|
|
||||||
|
|
||||||
// initialize sampling statistics.
|
|
||||||
n_total_area_samples = n_total_edge_samples = n_total_vertex_samples = n_total_samples = n_samples = 0;
|
|
||||||
max_dist = -HUGE_VAL;
|
|
||||||
mean_dist = RMS_dist = 0;
|
|
||||||
|
|
||||||
// Vertex sampling.
|
|
||||||
if(Flags & FLAG_VERTEX_SAMPLING)
|
|
||||||
VertexSampling();
|
|
||||||
// Edge sammpling.
|
|
||||||
n_samples_target -= (int) n_total_samples;
|
|
||||||
if(n_samples_target > 0)
|
|
||||||
{
|
|
||||||
n_samples_per_area_unit = n_samples_target / area_S1;
|
|
||||||
if(Flags & FLAG_EDGE_SAMPLING)
|
|
||||||
{
|
|
||||||
EdgeSampling();
|
|
||||||
n_samples_target -= (int) n_total_samples;
|
|
||||||
}
|
|
||||||
// Face sampling.
|
|
||||||
if((Flags & FLAG_FACE_SAMPLING) && (n_samples_target > 0))
|
|
||||||
{
|
|
||||||
n_samples_per_area_unit = n_samples_target / area_S1;
|
|
||||||
if(Flags & FLAG_MONTECARLO_SAMPLING) MontecarloFaceSampling();
|
|
||||||
if(Flags & FLAG_SUBDIVISION_SAMPLING) SubdivFaceSampling();
|
|
||||||
if(Flags & FLAG_SIMILAR_TRIANGLES_SAMPLING) SimilarFaceSampling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute vertex colour
|
|
||||||
if(Flags & FLAG_SAVE_ERROR_AS_COLOUR)
|
|
||||||
{
|
|
||||||
MetroMesh::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
|
|
||||||
n_samples_per_area_unit = (double) n_total_samples / area_S1;
|
|
||||||
volume = mean_dist / n_samples_per_area_unit / 2.0;
|
|
||||||
mean_dist /= n_total_samples;
|
|
||||||
RMS_dist = sqrt(RMS_dist / n_total_samples);
|
|
||||||
}
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
||||||
//#undef FLAG_HIST
|
|
||||||
//#undef FLAG_VERTEX_SAMPLING
|
|
||||||
//#undef FLAG_EDGE_SAMPLING
|
|
||||||
//#undef FLAG_FACE_SAMPLING
|
|
||||||
//#undef FLAG_MONTECARLO_SAMPLING
|
|
||||||
//#undef FLAG_SUBDIVISION_SAMPLING
|
|
||||||
//#undef FLAG_SIMILAR_TRIANGLES_SAMPLING
|
|
||||||
//#undef FLAG_SAVE_ERROR_DISPLACEMENT
|
|
||||||
//#undef FLAG_SAVE_ERROR_AS_COLOUR
|
|
||||||
//
|
|
||||||
//// global constants
|
|
||||||
//#undef NO_SAMPLES_PER_FACE
|
|
||||||
//#undef N_SAMPLES_EDGE_TO_FACE_RATIO
|
|
||||||
//#undef BBOX_FACTOR
|
|
||||||
//#undef INFLATE_PERCENTAGE
|
|
||||||
//#undef MIN_SIZE
|
|
||||||
//#undef N_HIST_BINS
|
|
||||||
//#undef PRINT_EVERY_N_ELEMENTS
|
|
||||||
//#undef FILE_EXT_SMF
|
|
||||||
//#undef FILE_EXT_PLY
|
|
||||||
//
|
|
||||||
|
|
||||||
#endif
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
|
Loading…
Reference in New Issue