1 /*
2 * plymc_main.cpp
3 * filter_plymc
4 *
5 * Created by Paolo Cignoni on 10/23/09.
6 * Copyright 2009 ISTI - CNR. All rights reserved.
7 *
8 */
9
10 #include <vcg/complex/algorithms/create/plymc/plymc.h>
11 #include "simplemeshprovider.h"
12 #define _PLYMC_VER "4.0"
13
14 using namespace std;
15 using namespace vcg;
16
17
18
19 string MYbasename = "plymcout";
20 string VolumeBaseName;
21 string subtag=""; // la stringa da appendere al nome di file per generare i nomi di file relativi a vari sottopezzi
22 string alnfile;
23
24 /************ Command Line Parameters *******/
25
26 int saveMask=vcg::tri::io::Mask::IOM_ALL;
usage()27 void usage()
28 {
29 printf(
30 "\nUsage:\n"
31 " plymc [options] filein.ply [filein.ply...]\n"
32 " plymc [options] filein.aln \n"
33 "Options: (no leading space before numeric values!) \n"
34 " -oname Set the base output name (default plymcout, without 'ply' extension)\n"
35 " -vname Enable the saving of the final volume with the specified filename\n"
36 " -C## Set numbers mesh that can be cached (default: 6)\n"
37 " -c## Set numbers of k cells (default: 10000)\n"
38 " -V# Set the required voxel size (override -c)\n"
39 " -s... Compute only a subvolume (specify 6 integers) \n"
40 " -S... Compute all the subvolumes of a partition (specify 3 int) \n"
41 " -X... Compute a range of the the subvolumes of a partition (specify 9 int)\n"
42 " -M Apply a 'safe' simplification step that removes only the unecessary triangles\n"
43 " -w# Set distance field Expansion factor in voxel (default 3)\n"
44 " -W# Set distance field Exp. as an absolute dist (override -w)\n"
45 " -a# Set angle threshold for distance field expansion (default 30)\n"
46 " -f# Set the fill threshold (default 12: all voxel having less \n"
47 " than 12 adjacent are not automaticall filled)\n"
48 " -L# Set Number of smoothing passes to be done after merging of all meshes\n"
49 " -R# Set Number of Refill passes to be done after merging of all meshes\n"
50 " -l# Make a single smoothing step after each expansion\n"
51 " -G# Disable Geodesic Quality\n"
52 " -F# Use per vertex quality defined in plyfile (geodesic is disabled)\n"
53 " -O# Set an Offset (<0!) threshold and build a double surface\n"
54 " -q# Set Quality threshold for smoothing. Only whose distance (in voxel)\n"
55 " is lower than the specified one are smoothed (default 3 voxel)\n"
56 " -Q# Same of above but expressed in absolute units.\n"
57 " -p use vertex splatting instead face rasterizing\n"
58 " -d# set <n> as verbose level (default 0)\n"
59 " -D# save <n> debug slices during processing\n"
60
61 "\nNotes:\n\n"
62 "The Quality threshold can be expressed in voxel unit or in absolute units.\n"
63 "It represents the geodetic distance from the mesh border.\n"
64 "I.e. -q3 means that all voxels that are within 3voxel from the mesh border\n"
65 "are smoothed.\n\n"
66
67 "A partition in the working volume is defined using 3 integers, that \n"
68 "specify the subdivision along the three axis.\n"
69 "To automatically compute ALL subvolumes of a given subdivision use '-S' \n"
70 "-S 1 1 1 default no subdivision at all\n"
71 "-S 2 2 2 compute all the octant of a octree-like subdivision\n"
72 "-S 1 1 4 compute four Z-slices\n\n"
73
74 "To work only on a SINGLE subvolume of the partition you have to specify \n"
75 "six integers: the first three ints specify the subdivision along the\n"
76 "three axis and the last three ones which subvolume you desire.\n"
77 "the parameter to be used is '-s' \n"
78 "-s 1 1 1 0 0 0 default no subdivision at all\n"
79 "-s 1 1 3 0 0 1 make three Z-slices and take the middle one \n"
80 "-s 2 2 2 1 1 1 the last octant in a octree-like subdivision\n\n"
81
82 "To START FROM a specific subvolume of the partition you have to specify \n"
83 "six integers: the first three ints specify the subdivision along the\n"
84 "three axis and the last three ones which subvolume you want to start\n"
85 "the process will go on using lexicographic order. Subvolumes are ordered\n"
86 "by Z, then by Y, then by X\n"
87 "The parameter to be used is '-K' \n"
88 "-K 4 4 4 0 0 0 a partition of 64 blocks, starting from the first one\n"
89 "-K 4 4 4 1 0 3 a partition of 64 blocks, starting from block 19 (index 1 0 3)\n\n"
90
91 "To work only on a specific subvolume range of the partition you have \n"
92 "to specify nine integers: the first three ints specify the subdivision\n"
93 "along the three axis and, the next three which is the starting subvolume\n"
94 "and the last three which is the last subvolume to be computed.\n"
95 "the process will compute all blocks with x,y,z index included in the interval\n"
96 "specified: Xstart<=X<=Xend Ystart<=Y<=Yend Zstart<=Z<=Zend\n"
97 "-X 3 3 3 0 0 0 2 2 2 three subdivision on each axis, all subvolumes\n"
98 "-X 2 2 2 1 0 0 1 1 1 three subdivision on each axis, only the 'right' part\n\n"
99 );
100 exit(-1);
101 }
102
103
104
main(int argc,char * argv[])105 int main(int argc, char *argv[])
106 {
107
108 Histogram<float> h;
109 tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> > pmc;
110 tri::PlyMC<SMesh,SimpleMeshProvider<SMesh> >::Parameter &p = pmc.p;
111
112
113 // This line is required to be sure that the decimal separatore is ALWAYS the . and not the ,
114 // see the comment at the beginning of the file
115 setlocale(LC_ALL, "En_US");
116
117 printf( "\n PlyMC " _PLYMC_VER " (" __DATE__ ")\n"
118 " Copyright 2002-2016 Visual Computing Group I.S.T.I. C.N.R.\n"
119 " Paolo Cignoni (p.cignoni@isti.cnr.it)\n\n");
120 //// Parameters
121 int i=1;
122 if(argc<2) usage();
123 while(argv[i][0]=='-')
124 {
125 switch(argv[i][1])
126 {
127 case 'o' : p.basename=argv[i]+2;printf("Setting Basename to %s\n",MYbasename.c_str());break;
128 case 'C' : pmc.MP.setCacheSize(atoi(argv[i]+2));printf("Setting MaxSize of MeshCache to %i\n",atoi(argv[i]+2)); break;
129 case 'c' : p.NCell =atoi(argv[i]+2);printf("Setting NCell to %i\n",p.NCell); break;
130 case 'v' : p.SaveVolumeFlag=true; VolumeBaseName=argv[i]+2; printf("Saving Volume enabled: volume Basename to %s\n",VolumeBaseName.c_str());break;
131 case 'V' : p.VoxSize =atof(argv[i]+2);printf("Setting VoxSize to %f; overridden NCell\n",p.VoxSize);p.NCell=0;break;
132 case 'w' : p.WideNum =atoi(argv[i]+2);printf("Setting WideNum to %i\n",p.WideNum);break;
133 case 'W' : p.WideSize=atof(argv[i]+2);printf("Setting WideSize to %f;overridden WideNum\n",p.WideSize);break;
134 case 'L' : p.SmoothNum =atoi(argv[i]+2);printf("Setting Laplacian SmoothNum to %i\n",p.SmoothNum);break;
135 case 'R' : p.RefillNum =atoi(argv[i]+2);printf("Setting Refilling Num to %i\n",p.RefillNum);break;
136 case 'q' : p.QualitySmoothVox=atof(argv[i]+2);printf("Setting QualitySmoothThr to %f; \n",p.QualitySmoothVox);break;
137 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;
138 case 'l' : p.IntraSmoothFlag=true; printf("Setting Laplacian Smooth after expansion \n");break;
139 case 'G' : p.GeodesicQualityFlag=false; printf("Disabling Geodesic Quality\n");break;
140 case 'F' : p.PLYFileQualityFlag=true; p.GeodesicQualityFlag=false; printf("Enabling PlyFile (and disabling Geodesic) Quality\n");break;
141 case 'f' : p.FillThr=atoi(argv[i]+2);printf("Setting Fill Threshold to %i\n",p.FillThr);break;
142 case 'a' : p.ExpAngleDeg=atoi(argv[i]+2);printf("Setting Expanding Angle Threshold to %f Degree\n",p.ExpAngleDeg);break;
143 case 'O' : p.OffsetThr=atof(argv[i]+2);printf("Setting Offset Threshold to %f \n",p.OffsetThr);p.OffsetFlag=true;break;
144 case 's' :
145 p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]); p.IDiv[2]=atoi(argv[++i]);
146 p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]);
147 p.IPosE[0]=p.IPosS[0]; p.IPosE[1]=p.IPosS[1]; p.IPosE[2]=p.IPosS[2];
148 if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2]))
149 {
150 printf("the subvolume you have requested is invalid (out of bounds)");
151 exit(-1);
152 }
153 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]);
154 break;
155 case 'S' :
156 p.IDiv[0]=atoi(argv[++i]);p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
157 p.IPosS=Point3i(0,0,0);
158 p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1;
159 printf("Autocomputing ALL subvolumes on a %ix%ix%i\n",p.IDiv[0],p.IDiv[1],p.IDiv[2]);
160 break;
161 case 'K' :
162 p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
163 p.IPosB[0]=atoi(argv[++i]);p.IPosB[1]=atoi(argv[++i]);p.IPosB[2]=atoi(argv[++i]);
164 p.IPosS=Point3i(0,0,0);
165 p.IPosE[0]=p.IDiv[0]-1; p.IPosE[1]=p.IDiv[1]-1; p.IPosE[2]=p.IDiv[2]-1;
166 if((p.IPosB[0]>=p.IDiv[0]) || (p.IPosB[1]>=p.IDiv[1]) || (p.IPosB[2]>=p.IDiv[2]))
167 {
168 printf("the start subvolume you have requested is invalid (out of bounds)");
169 exit(-1);
170 }
171 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]);
172 break;
173 case 'X' :
174 p.IDiv[0]=atoi(argv[++i]); p.IDiv[1]=atoi(argv[++i]);p.IDiv[2]=atoi(argv[++i]);
175 p.IPosS[0]=atoi(argv[++i]);p.IPosS[1]=atoi(argv[++i]);p.IPosS[2]=atoi(argv[++i]);
176 p.IPosE[0]=atoi(argv[++i]);p.IPosE[1]=atoi(argv[++i]);p.IPosE[2]=atoi(argv[++i]);
177 // test if the interval is ok
178 int Istart,Iend;
179 Istart = p.IPosS[2] + (p.IPosS[1]*p.IDiv[2]) + (p.IPosS[0]*p.IDiv[2]*p.IDiv[1]);
180 Iend = p.IPosE[2] + (p.IPosE[1]*p.IDiv[2]) + (p.IPosE[0]*p.IDiv[2]*p.IDiv[1]);
181 if((Iend-Istart)<=0)
182 {
183 printf("the range you have requested is invalid (reversed or empty)");
184 exit(-1);
185 }
186 if((p.IPosS[0]>=p.IDiv[0]) || (p.IPosS[1]>=p.IDiv[1]) || (p.IPosS[2]>=p.IDiv[2]) ||
187 (p.IPosE[0]>=p.IDiv[0]) || (p.IPosE[1]>=p.IDiv[1]) || (p.IPosE[2]>=p.IDiv[2]))
188 {
189 printf("the subvolume you have requested is invalid (out of bounds)");
190 exit(-1);
191 }
192 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]);
193 break;
194 // 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;
195 case 'p' : p.VertSplatFlag =true; printf("Enabling VertexSplatting instead of face rasterization\n");break;
196 case 'd' : p.VerboseLevel=atoi(argv[i]+2);printf("Enabling VerboseLevel= %i )\n",p.VerboseLevel);break;
197 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;
198 case 'M' : p.SimplificationFlag =true; printf("Enabling PostReconstruction simplification\n"); break;
199 default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
200 }
201 ++i;
202 }
203
204
205
206 Matrix44f Identity;
207 Identity.SetIdentity();
208 string alnfile;
209 while(i<argc)
210 {
211 if(strcmp(strrchr(argv[i],'.'),".aln")==0)
212 pmc.MP.openALN(argv[i]);
213 else
214 pmc.MP.AddSingleMesh(argv[i]);
215 ++i;
216 }
217
218 if(pmc.MP.size()==0) usage();
219 printf("End Parsing\n\n");
220 pmc.Process();
221
222 return 0;
223 }
224