forked from picciau-g/superfacets-2d
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
executable file
·271 lines (217 loc) · 7.74 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#include "segmenter.h"
#include "meshvisualizer.h"
#include "vertexbasedsegmenter.h"
#include <stdio.h>
#include <QApplication>
using namespace std;
/**
* @author Giulia Picciau
* Submission to Eurographics Symposium on Geometric Processing 2014
*/
/**
* @brief print_help prints instructions on screen
*/
void print_help(){
printf("\n NAME: \n");
printf("\t Superfacets Segmentation \n\n");
printf("\t Author: Giulia Picciau");
printf("\t Date: 04-15-2014");
printf("\nUSAGE:\n");
printf(" -m [input mesh]\n");
printf("\t the mesh to be read as input\n\n");
printf(" -r [radius]\n");
printf("\t approximated radius of a single cluster (mutually exclusive with -nseg)\n\n");
printf(" -nseg [segments]\n");
printf("\t number of desired regions (mutually exclusive with option -r\n\n");
printf(" -a [alpha]\n");
printf("\t parameter that states how much the angular distance will be important in the total one\n\n");
printf(" -e [etaconvex]\n");
printf("\t value of the weight for convex angles\n\n");
printf(" -vis\n");
printf("\t if you want to visualize the output subdivision after the segmentation process\n\n");
printf(" -out [fileout]\n");
printf("\t file on which is written the output segmentation\n\n");
printf(" -ov [segmfile]\n");
printf("\t only calls the visualizer on an already computed segmentation (stored in segmfile)\n\n");
printf(" -h:\n");
printf("\t to put the header in the output segmentation file\n\n");
printf(" -flood [initmode] :\n");
printf("\t specify the initialization mode we want to use (flooding (initmode=1) or squares (initmode=0))\n\n");
printf(" -mult [factor]: \n");
printf("\t specify the number which multiplies the distance threshold in the expansion step (default=2)\n\n");
printf(" -nIter [iters]\n");
printf("\t how many iterative steps we want to perform at most (default=50)\n\n");
printf(" -debug\n");
printf("\t if this flag is specified, a lot of debug messages will be shown\n\n\n");
}
/**
* @brief callVis opens the visualizer window
* @param MN name of the mesh file
* @param SN name of the segmentation file
*/
void callVis(string MN, string SN){
MeshVisualizer *MV = new MeshVisualizer(MN, SN);
MV->resize(800, 600);
MV->show();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
bool debugM=false;
int timesR = 2;
int nIters = 50;
bool triBased = true;
if(argc==1){
print_help();
exit(0);
}
//Parse arguments
string meshfilename;
string segFile;
string fieldFile;
double alpha;
double radius;
int number;
double etaConvex=0.2; //Default value
bool putHeader=false;
bool visualize=false;
bool justvisualize=false;
bool floodI = true;
for(int n_opt=1;n_opt<argc;n_opt+=2){
char* option=argv[n_opt];
if(!strcmp(option, "-m")){ //Mesh name
QString input = argv[n_opt+1];
meshfilename = input.toStdString();
}
else if(!strcmp(option, "-r")){ //Radius (implies radius-based init)
QString input = argv[n_opt+1];
radius = input.toDouble();
number = -1;
}
else if(!strcmp(option, "-nseg")){ //Number of regions
QString input = argv[n_opt+1];
number = input.toInt();
radius = -1.0;
}
else if(!strcmp(option, "-a")){ //Alpha
QString input = argv[n_opt+1];
alpha = input.toDouble();
}
else if(!strcmp(option, "-eta")){ //Value of eta if the angle is convex
QString input = argv[n_opt+1];
etaConvex = input.toDouble();
}
else if(!strcmp(option, "-h")){ //put the header in the file
putHeader = true;
n_opt--;
}
else if(!strcmp(option, "-vis")){ //Launch the visualizer when segmentation is done
visualize = true;
n_opt--;
}
else if(!strcmp(option, "-out")){ //The output file in which we write the segmentation
QString input = argv[n_opt+1];
segFile = input.toStdString();
}
else if(!strcmp(option, "-flood")){ //Radius-based, decide the strategy
QString input = argv[n_opt+1];
floodI = (bool)input.toInt();
}
else if(!strcmp(option, "-mult")){
QString input = argv[n_opt+1];
timesR = input.toInt();
}
else if(!strcmp(option, "-nIter")){
QString input = argv[n_opt+1];
nIters = input.toInt();
}
else if(!strcmp(option, "-ov")){ //Calls only the visualizer
justvisualize = true;
QString input = argv[n_opt+1];
segFile = input.toStdString();
}
else if(!strcmp(option, "-debug")){
debugM=true;
cout<<"Debug mode selected"<<endl;
}
else if(!strcmp(option, "-VB")){
triBased = false;
justvisualize=false;
QString input = argv[n_opt+1];
fieldFile = input.toStdString();
}
else{
cout<<"Uncorrect usage"<<endl;
print_help();
exit(0);
}
}
if(justvisualize){ /// if we only want to call the visualizer on a segmentation
callVis(meshfilename, segFile);
return a.exec();
}
if(!triBased){
cout<<"Loading vertices"<<endl;
VertexBasedSegmenter *VBSuperSeg = new VertexBasedSegmenter;
cout<<"Created"<<endl;
VBSuperSeg->filename = meshfilename;
VBSuperSeg->fieldfilename = fieldFile;
VBSuperSeg->setNCluster(number);
VBSuperSeg->setAlpha(alpha);
VBSuperSeg->callLoad();
VBSuperSeg->startSeg();
cout<<"Converged, now writing"<<endl;
VBSuperSeg->callWriter(segFile);
return 0;
}
/// Create segmenter class
Segmenter *SuperSeg = new Segmenter;
/// set parameters
SuperSeg->filename=meshfilename; /// file to segment
SuperSeg->setAlpha(alpha); /// weight of the angular distance
/// Spatial threshold / number of regions
if(radius > 0)
SuperSeg->setMaxD(radius);
if(number > 0)
SuperSeg->setNCluster(number);
SuperSeg->setEtaConvex(etaConvex); /// weight of convex angle
SuperSeg->putHeader=putHeader;
SuperSeg->setTimesR(timesR); /// factor which multiplies the threshold in the expansion step
SuperSeg->setMaxIters(nIters); /// Number of maximum iterative steps to make
SuperSeg->floodInit = floodI; /// If we know the radius, to decide between flood and grid initialization
SuperSeg->debugMode = debugM; /// If we are running in debug mode (more messages will be displayed)
/// Load the model
SuperSeg->callLoad();
bool haveMoved=true;
int countIter=0;
Timer TMR;
TMR.start();
/// Iterate until convergence
while(haveMoved && countIter<SuperSeg->getMaxIters()){
cout<<"Iteration "<<countIter<<"..."<<endl;
if(haveMoved)
SuperSeg->expansionStep();
if(debugM)
cout<<"Expanded"<<endl;
haveMoved = SuperSeg->updateCenters();
if(debugM)
cout<<"Updated"<<endl;
countIter++;
}
TMR.stop();
double timeForSeg = TMR.getElapsedTimeInMilliSec();
timeForSeg += SuperSeg->initTime;
SuperSeg->setElapsedTime(timeForSeg);
SuperSeg->setIters(countIter);
/// Write to file
if(strcmp(segFile.c_str(), ""))
SuperSeg->writeSegmOnFile(segFile);
else
cout<<"No output file"<<endl;
/// calls the visualizer after the segmentation
if(visualize){
callVis(meshfilename, segFile);
return a.exec();
}
return 0;
}