added function Dist
This commit is contained in:
parent
c601fcd17f
commit
12553b7c66
|
@ -0,0 +1,49 @@
|
|||
#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
|
||||
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
|
@ -0,0 +1,127 @@
|
|||
# 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
|
|
@ -0,0 +1,145 @@
|
|||
<?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>
|
|
@ -0,0 +1,63 @@
|
|||
// -----------------------------------------------------------------------------------------------
|
||||
#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
|
||||
// -----------------------------------------------------------------------------------------------
|
|
@ -0,0 +1,56 @@
|
|||
/*****************************************************************************
|
||||
* 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
|
||||
// -----------------------------------------------------------------------------------------------
|
|
@ -0,0 +1,206 @@
|
|||
/*#***************************************************************************
|
||||
* 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
|
|
@ -0,0 +1,607 @@
|
|||
/*****************************************************************************
|
||||
* 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