You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
11 KiB
223 lines
11 KiB
/* |
|
* plymc_main.cpp |
|
* filter_plymc |
|
* |
|
* Created by Paolo Cignoni on 10/23/09. |
|
* Copyright 2009 ISTI - CNR. All rights reserved. |
|
* |
|
*/ |
|
|
|
#include <vcg/complex/algorithms/create/plymc/plymc.h> |
|
#include "simplemeshprovider.h" |
|
#define _PLYMC_VER "4.0" |
|
|
|
using namespace std; |
|
using namespace vcg; |
|
|
|
|
|
|
|
string MYbasename = "plymcout"; |
|
string VolumeBaseName; |
|
string subtag=""; // la stringa da appendere al nome di file per generare i nomi di file relativi a vari sottopezzi |
|
string alnfile; |
|
|
|
/************ Command Line Parameters *******/ |
|
|
|
int saveMask=vcg::tri::io::Mask::IOM_ALL; |
|
void usage() |
|
{ |
|
printf( |
|
"\nUsage:\n" |
|
" plymc [options] filein.ply [filein.ply...]\n" |
|
" plymc [options] filein.aln \n" |
|
"Options: (no leading space before numeric values!) \n" |
|
" -oname Set the base output name (default plymcout, without 'ply' extension)\n" |
|
" -vname Enable the saving of the final volume with the specified filename\n" |
|
" -C## Set numbers mesh that can be cached (default: 6)\n" |
|
" -c## Set numbers of k cells (default: 10000)\n" |
|
" -V# Set the required voxel size (override -c)\n" |
|
" -s... Compute only a subvolume (specify 6 integers) \n" |
|
" -S... Compute all the subvolumes of a partition (specify 3 int) \n" |
|
" -X... Compute a range of the the subvolumes of a partition (specify 9 int)\n" |
|
" -M Apply a 'safe' simplification step that removes only the unecessary triangles\n" |
|
" -w# Set distance field Expansion factor in voxel (default 3)\n" |
|
" -W# Set distance field Exp. as an absolute dist (override -w)\n" |
|
" -a# Set angle threshold for distance field expansion (default 30)\n" |
|
" -f# Set the fill threshold (default 12: all voxel having less \n" |
|
" than 12 adjacent are not automaticall filled)\n" |
|
" -L# Set Number of smoothing passes to be done after merging of all meshes\n" |
|
" -R# Set Number of Refill passes to be done after merging of all meshes\n" |
|
" -l# Make a single smoothing step after each expansion\n" |
|
" -G# Disable Geodesic Quality\n" |
|
" -F# Use per vertex quality defined in plyfile (geodesic is disabled)\n" |
|
" -O# Set an Offset (<0!) threshold and build a double surface\n" |
|
" -q# Set Quality threshold for smoothing. Only whose distance (in voxel)\n" |
|
" is lower than the specified one are smoothed (default 3 voxel)\n" |
|
" -Q# Same of above but expressed in absolute units.\n" |
|
" -p use vertex splatting instead face rasterizing\n" |
|
" -d# set <n> as verbose level (default 0)\n" |
|
" -D# save <n> debug slices during processing\n" |
|
|
|
"\nNotes:\n\n" |
|
"The Quality threshold can be expressed in voxel unit or in absolute units.\n" |
|
"It represents the geodetic distance from the mesh border.\n" |
|
"I.e. -q3 means that all voxels that are within 3voxel from the mesh border\n" |
|
"are smoothed.\n\n" |
|
|
|
"A partition in the working volume is defined using 3 integers, that \n" |
|
"specify the subdivision along the three axis.\n" |
|
"To automatically compute ALL subvolumes of a given subdivision use '-S' \n" |
|
"-S 1 1 1 default no subdivision at all\n" |
|
"-S 2 2 2 compute all the octant of a octree-like subdivision\n" |
|
"-S 1 1 4 compute four Z-slices\n\n" |
|
|
|
"To work only on a SINGLE subvolume of the partition you have to specify \n" |
|
"six integers: the first three ints specify the subdivision along the\n" |
|
"three axis and the last three ones which subvolume you desire.\n" |
|
"the parameter to be used is '-s' \n" |
|
"-s 1 1 1 0 0 0 default no subdivision at all\n" |
|
"-s 1 1 3 0 0 1 make three Z-slices and take the middle one \n" |
|
"-s 2 2 2 1 1 1 the last octant in a octree-like subdivision\n\n" |
|
|
|
"To START FROM a specific subvolume of the partition you have to specify \n" |
|
"six integers: the first three ints specify the subdivision along the\n" |
|
"three axis and the last three ones which subvolume you want to start\n" |
|
"the process will go on using lexicographic order. Subvolumes are ordered\n" |
|
"by Z, then by Y, then by X\n" |
|
"The parameter to be used is '-K' \n" |
|
"-K 4 4 4 0 0 0 a partition of 64 blocks, starting from the first one\n" |
|
"-K 4 4 4 1 0 3 a partition of 64 blocks, starting from block 19 (index 1 0 3)\n\n" |
|
|
|
"To work only on a specific subvolume range of the partition you have \n" |
|
"to specify nine integers: the first three ints specify the subdivision\n" |
|
"along the three axis and, the next three which is the starting subvolume\n" |
|
"and the last three which is the last subvolume to be computed.\n" |
|
"the process will compute all blocks with x,y,z index included in the interval\n" |
|
"specified: Xstart<=X<=Xend Ystart<=Y<=Yend Zstart<=Z<=Zend\n" |
|
"-X 3 3 3 0 0 0 2 2 2 three subdivision on each axis, all subvolumes\n" |
|
"-X 2 2 2 1 0 0 1 1 1 three subdivision on each axis, only the 'right' part\n\n" |
|
); |
|
exit(-1); |
|
} |
|
|
|
|
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
|
|
Histogram<float> h; |
|
tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> > pmc; |
|
tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> >::Parameter &p = pmc.p; |
|
|
|
|
|
// This line is required to be sure that the decimal separatore is ALWAYS the . and not the , |
|
// see the comment at the beginning of the file |
|
setlocale(LC_ALL, "En_US"); |
|
|
|
printf( "\n PlyMC " _PLYMC_VER " (" __DATE__ ")\n" |
|
" Copyright 2002-2016 Visual Computing Group I.S.T.I. C.N.R.\n" |
|
" Paolo Cignoni (p.cignoni@isti.cnr.it)\n\n"); |
|
//// Parameters |
|
int i=1; |
|
if(argc<2) usage(); |
|
while(argv[i][0]=='-') |
|
{ |
|
switch(argv[i][1]) |
|
{ |
|
case 'o' : p.basename=argv[i]+2;printf("Setting Basename to %s\n",MYbasename.c_str());break; |
|
case 'C' : pmc.MP.setCacheSize(atoi(argv[i]+2));printf("Setting MaxSize of MeshCache to %i\n",atoi(argv[i]+2)); break; |
|
case 'c' : p.NCell =atoi(argv[i]+2);printf("Setting NCell to %i\n",p.NCell); break; |
|
case 'v' : p.SaveVolumeFlag=true; VolumeBaseName=argv[i]+2; printf("Saving Volume enabled: volume Basename to %s\n",VolumeBaseName.c_str());break; |
|
case 'V' : p.VoxSize =atof(argv[i]+2);printf("Setting VoxSize to %f; overridden NCell\n",p.VoxSize);p.NCell=0;break; |
|
case 'w' : p.WideNum =atoi(argv[i]+2);printf("Setting WideNum to %i\n",p.WideNum);break; |
|
case 'W' : p.WideSize=atof(argv[i]+2);printf("Setting WideSize to %f;overridden WideNum\n",p.WideSize);break; |
|
case 'L' : p.SmoothNum =atoi(argv[i]+2);printf("Setting Laplacian SmoothNum to %i\n",p.SmoothNum);break; |
|
case 'R' : p.RefillNum =atoi(argv[i]+2);printf("Setting Refilling Num to %i\n",p.RefillNum);break; |
|
case 'q' : p.QualitySmoothVox=atof(argv[i]+2);printf("Setting QualitySmoothThr to %f; \n",p.QualitySmoothVox);break; |
|
case 'Q' : p.QualitySmoothAbs=atof(argv[i]+2);printf("Setting QualitySmoothAbsolute to %f; it will override the default %f voxel value\n",p.QualitySmoothAbs,p.QualitySmoothVox);break; |
|
case 'l' : p.IntraSmoothFlag=true; printf("Setting Laplacian Smooth after expansion \n");break; |
|
case 'G' : p.GeodesicQualityFlag=false; printf("Disabling Geodesic Quality\n");break; |
|
case 'F' : p.PLYFileQualityFlag=true; p.GeodesicQualityFlag=false; printf("Enabling PlyFile (and disabling Geodesic) Quality\n");break; |
|
case 'f' : p.FillThr=atoi(argv[i]+2);printf("Setting Fill Threshold to %i\n",p.FillThr);break; |
|
case 'a' : p.ExpAngleDeg=atoi(argv[i]+2);printf("Setting Expanding Angle Threshold to %f Degree\n",p.ExpAngleDeg);break; |
|
case 'O' : p.OffsetThr=atof(argv[i]+2);printf("Setting Offset Threshold to %f \n",p.OffsetThr);p.OffsetFlag=true;break; |
|
case 's' : |
|
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]); p.IDiv[2]=atoi(argv[++i]); |
|
p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]); |
|
p.IPosE[0]=p.IPosS[0]; p.IPosE[1]=p.IPosS[1]; p.IPosE[2]=p.IPosS[2]; |
|
if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2])) |
|
{ |
|
printf("the subvolume you have requested is invalid (out of bounds)"); |
|
exit(-1); |
|
} |
|
printf("Computing ONLY subvolume [%i,%i,%i] on a %ix%ix%i\n",p.IPosS[0],p.IPosS[1],p.IPosS[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]); |
|
break; |
|
case 'S' : |
|
p.IDiv[0]=atoi(argv[++i]);p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]); |
|
p.IPosS=Point3i(0,0,0); |
|
p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1; |
|
printf("Autocomputing ALL subvolumes on a %ix%ix%i\n",p.IDiv[0],p.IDiv[1],p.IDiv[2]); |
|
break; |
|
case 'K' : |
|
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]); |
|
p.IPosB[0]=atoi(argv[++i]);p.IPosB[1]=atoi(argv[++i]);p.IPosB[2]=atoi(argv[++i]); |
|
p.IPosS=Point3i(0,0,0); |
|
p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1; |
|
if((p.IPosB[0]>=p.IDiv[0]) || (p.IPosB[1]>=p.IDiv[1]) || (p.IPosB[2]>=p.IDiv[2])) |
|
{ |
|
printf("the start subvolume you have requested is invalid (out of bounds)"); |
|
exit(-1); |
|
} |
|
printf("Autocomputing ALL subvolumes FROM [%i,%i,%i] on a %ix%ix%i\n",p.IPosB[0],p.IPosB[1],p.IPosB[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]); |
|
break; |
|
case 'X' : |
|
p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]); |
|
p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]); |
|
p.IPosE[0]=atoi(argv[++i]);p.IPosE[1]=atoi(argv[++i]);p.IPosE[2]=atoi(argv[++i]); |
|
// test if the interval is ok |
|
int Istart,Iend; |
|
Istart = p.IPosS[2] + (p.IPosS[1]*p.IDiv[2]) + (p.IPosS[0]*p.IDiv[2]*p.IDiv[1]); |
|
Iend = p.IPosE[2] + (p.IPosE[1]*p.IDiv[2]) + (p.IPosE[0]*p.IDiv[2]*p.IDiv[1]); |
|
if((Iend-Istart)<=0) |
|
{ |
|
printf("the range you have requested is invalid (reversed or empty)"); |
|
exit(-1); |
|
} |
|
if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2]) || |
|
(p.IPosE[0]>=p.IDiv[0]) || (p.IPosE[1]>=p.IDiv[1]) || (p.IPosE[2]>=p.IDiv[2])) |
|
{ |
|
printf("the subvolume you have requested is invalid (out of bounds)"); |
|
exit(-1); |
|
} |
|
printf("Autocomputing subvolumes FROM [%i,%i,%i] TO [%i,%i,%i] on a %ix%ix%i\n",p.IPosS[0],p.IPosS[1],p.IPosS[2],p.IPosE[0],p.IPosE[1],p.IPosE[2],p.IDiv[0],p.IDiv[1],p.IDiv[2]); |
|
break; |
|
// case 'B' : p.SafeBorder =atoi(argv[i]+2);printf("Setting SafeBorder among blocks to %i*%i (default 1)\n",p.SafeBorder,Volume<Voxelf>::BLOCKSIDE());break; |
|
case 'p' : p.VertSplatFlag =true; printf("Enabling VertexSplatting instead of face rasterization\n");break; |
|
case 'd' : p.VerboseLevel=atoi(argv[i]+2);printf("Enabling VerboseLevel= %i )\n",p.VerboseLevel);break; |
|
case 'D' : p.VerboseLevel=1; p.SliceNum=atoi(argv[i]+2);printf("Enabling Debug Volume saving of %i slices (VerboseLevel=1)\n",p.SliceNum);break; |
|
case 'M' : p.SimplificationFlag =true; printf("Enabling PostReconstruction simplification\n"); break; |
|
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);} |
|
} |
|
++i; |
|
} |
|
|
|
|
|
|
|
Matrix44f Identity; |
|
Identity.SetIdentity(); |
|
string alnfile; |
|
while(i<argc) |
|
{ |
|
if(strcmp(strrchr(argv[i],'.'),".aln")==0) |
|
pmc.MP.openALN(argv[i]); |
|
else |
|
pmc.MP.AddSingleMesh(argv[i]); |
|
++i; |
|
} |
|
|
|
if(pmc.MP.size()==0) usage(); |
|
printf("End Parsing\n\n"); |
|
pmc.Process(); |
|
|
|
return 0; |
|
}
|
|
|