36 #include "DGtal/base/Common.h"
38 #include "DGtal/shapes/ShapeFactory.h"
39 #include "DGtal/shapes/Shapes.h"
40 #include "DGtal/helpers/StdDefs.h"
41 #include "DGtal/topology/helpers/Surfaces.h"
43 #include "DGtal/images/imagesSetsUtils/ImageFromSet.h"
44 #include "DGtal/images/imagesSetsUtils/SetFromImage.h"
45 #include "DGtal/images/ImageContainerBySTLVector.h"
47 #include "DGtal/io/writers/PGMWriter.h"
48 #include "DGtal/io/writers/RawWriter.h"
49 #include "DGtal/io/writers/VolWriter.h"
50 #include "DGtal/io/boards/Board2D.h"
53 using namespace DGtal;
125 std::vector<std::string> shapes2D;
126 std::vector<std::string> shapesDesc;
127 std::vector<std::string> shapesParam1;
128 std::vector<std::string> shapesParam2;
129 std::vector<std::string> shapesParam3;
130 std::vector<std::string> shapesParam4;
139 shapes2D.push_back(
"ball");
140 shapesDesc.push_back(
"Ball for the Euclidean metric.");
141 shapesParam1.push_back(
"--radius [-R]");
142 shapesParam2.push_back(
"");
143 shapesParam3.push_back(
"");
144 shapesParam4.push_back(
"");
146 shapes2D.push_back(
"square");
147 shapesDesc.push_back(
"square (no signature).");
148 shapesParam1.push_back(
"--width [-w]");
149 shapesParam2.push_back(
"");
150 shapesParam3.push_back(
"");
151 shapesParam4.push_back(
"");
153 shapes2D.push_back(
"lpball");
154 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
155 shapesParam1.push_back(
"--radius [-R],");
156 shapesParam2.push_back(
"--power [-p]");
157 shapesParam3.push_back(
"");
158 shapesParam4.push_back(
"");
160 shapes2D.push_back(
"flower");
161 shapesDesc.push_back(
"Flower with k petals.");
162 shapesParam1.push_back(
"--radius [-R],");
163 shapesParam2.push_back(
"--varsmallradius [-v],");
164 shapesParam3.push_back(
"--k [-k],");
165 shapesParam4.push_back(
"--phi");
167 shapes2D.push_back(
"ngon");
168 shapesDesc.push_back(
"Regular k-gon.");
169 shapesParam1.push_back(
"--radius [-R],");
170 shapesParam2.push_back(
"--k [-k],");
171 shapesParam3.push_back(
"--phi");
172 shapesParam4.push_back(
"");
174 shapes2D.push_back(
"accflower");
175 shapesDesc.push_back(
"Accelerated Flower with k petals.");
176 shapesParam1.push_back(
"--radius [-R],");
177 shapesParam2.push_back(
"--varsmallradius [-v],");
178 shapesParam3.push_back(
"--k [-k],");
179 shapesParam4.push_back(
"--phi");
181 shapes2D.push_back(
"ellipse");
182 shapesDesc.push_back(
"Ellipse.");
183 shapesParam1.push_back(
"--axis1 [-A],");
184 shapesParam2.push_back(
"--axis2 [-a],");
185 shapesParam3.push_back(
"--phi");
186 shapesParam4.push_back(
"");
197 trace.emphase()<<
"2D Shapes:"<<std::endl;
198 for(
unsigned int i=0; i<shapes2D.size(); ++i)
199 trace.info()<<
"\t"<<shapes2D[i]<<
"\t"
200 <<shapesDesc[i]<<std::endl
201 <<
"\t\tRequired parameter(s): "
202 << shapesParam1[i]<<
" "
203 << shapesParam2[i]<<
" "
204 << shapesParam3[i]<<
" "
205 << shapesParam4[i]<<std::endl;
218 unsigned int checkAndRetrunIndex(
const std::string &shapeName)
222 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
225 if (pos == shapes2D.size())
227 trace.error() <<
"The specified shape has not found.";
228 trace.info()<<std::endl;
243 template <
typename Set,
typename Image>
256 void save(
const Set &aSet,
257 const std::string outputName,
258 const std::string outputFormat)
261 Image image = ImageFromSet<Image>::template create<Set>(aSet, 255,
true);
263 if (outputFormat ==
"pgm")
264 PGMWriter<Image>::exportPGM(outputName+
"."+outputFormat,image);
266 if (outputFormat ==
"raw")
267 RawWriter<Image>::exportRaw8(outputName+
"."+outputFormat,image);
269 if (outputFormat ==
"svg")
273 board.saveSVG((outputName+
"."+outputFormat).c_str());
277 if (outputFormat ==
"pdf")
281 board.saveCairo((outputName+
"."+outputFormat).c_str(), Board2D::CairoPDF);
285 if (outputFormat ==
"png")
289 board.saveCairo((outputName+
"."+outputFormat).c_str(), Board2D::CairoPNG);
294 trace.error()<<
"Output format: "<<outputFormat<<
" not recognized."<<std::endl;
312 template <
typename Shape>
314 void exportSignature(
const Shape & aShape, Set &aSet,
const Z2i::Domain &aDomain)
316 trace.beginBlock(
"Extracting the boundary");
318 bool space_ok = ks.init( aDomain.lowerBound(),aDomain.upperBound(),
true );
319 SurfelAdjacency<2> sAdj(
true );
322 trace.info() << aSet << std::endl;
324 << ( space_ok ?
" Successfully instantiated" :
" Error" )
327 std::vector< std::vector< Z2i::Point > > vectContoursBdryPointels;
328 Surfaces<Z2i::KSpace>::extractAllPointContours4C( vectContoursBdryPointels,
333 std::cout<<
"## shapeGenerator signature export"<<std::endl;
334 std::cout<<
"## shape: "<<aShape<<std::endl;
335 std::cout<<
"## x\ty\tdx\tdy\tddx\tddy"<<std::endl;
336 for(
unsigned int i=0; i<vectContoursBdryPointels.size(); i++)
337 for(
unsigned int j=0 ; j< vectContoursBdryPointels.at(i).size() - 1; j++)
339 Z2i::Space::Point point = (vectContoursBdryPointels.at(i).at(j)
340 + vectContoursBdryPointels.at(i).at(j+1));
341 Z2i::Space::RealPoint midpoint (point[0]/2.0,point[1]/2.0);
343 Z2i::Space::RealPoint xp,xpp;
344 double t = aShape.parameter(midpoint);
346 xpp = aShape.xpp( t );
348 std::cout<< midpoint[0]<<
"\t"<<midpoint[1]<<
"\t"
349 << xp[0]<<
"\t"<<xp[1]<<
"\t"
350 << xpp[0]<<
"\t"<<xpp[1]<<std::endl;
362 void missingParam(std::string param)
364 trace.error() <<
" Parameter: "<<param<<
" is required..";
365 trace.info()<<std::endl;
371 int main(
int argc,
char** argv )
375 std::string shapeName;
376 std::string outputName;
377 std::string outputFormat {
"pgm"};
380 double smallradius {5};
381 double varsmallradius {5};
387 app.description(
"Generates shapes using DGtal library.\n Typical use example:\n \t shapeGenerator [options] --shape <shapeName> --output <outputBasename>\n");
388 auto listOpt = app.add_flag(
"--list,-l",
"List all available shapes");
389 auto shapeNameOpt = app.add_option(
"--shape,-s", shapeName,
"Shape name");
390 auto radiusOpt = app.add_option(
"--radius,-R", radius,
"Radius of the shape" );
391 auto axis1Opt = app.add_option(
"--axis1,-A", axis1,
"Half big axis of the shape (ellipse)" );
392 auto axis2Opt = app.add_option(
"--axis2,-a", axis2,
"Half small axis of the shape (ellipse)" );
393 auto smallradiusOpt = app.add_option(
"--smallradius,-r", smallradius,
"Small radius of the shape (default 5)",
true);
394 auto varsmallradiusOpt = app.add_option(
"--varsmallradius,-v", varsmallradius,
"Variable small radius of the shape (default 5)",
true );
395 auto kOpt = app.add_option(
"-k", k,
"Number of branches or corners the shape (default 3)",
true );
396 auto phiOpt = app.add_option(
"--phi", phi,
"Phase of the shape (in radian, default 0.0)",
true );
397 auto widthOpt = app.add_option(
"--width,-w", width,
"Width of the shape (default 10.0)",
true );
398 auto powerOpt = app.add_option(
"--power,-p", power,
"Power of the metric (default 2.0)",
true );
399 auto outputNameOpt = app.add_option(
"--output,-o", outputName,
"Basename of the output file");
400 auto signatureOpt = app.add_flag(
"--signature",
"Display to the standard output the signature (normal, curvature) at each point of the specified shape contour (middle point of each contour linel)");
401 app.add_option(
"--format,-f", outputFormat,
"Output format:\n\t Bitmap {pgm, raw}\n\t Vector {svg} (+ {png,pdf} if libCairo installed) (default pgm)" );
403 app.get_formatter()->column_width(40);
404 CLI11_PARSE(app, argc, argv);
410 if ( listOpt->count() > 0 )
416 if(shapeNameOpt->count()==0) missingParam(
"--shape");
417 if(outputNameOpt->count()==0) missingParam(
"--output");
420 unsigned int id = checkAndRetrunIndex(shapeName);
421 typedef ImageContainerBySTLVector<Z2i::Domain,unsigned char> Image;
425 if (radiusOpt->count()==0) missingParam(
"--radius");
426 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), radius);
427 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
428 Z2i::DigitalSet aSet(domain);
430 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
431 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
433 if (signatureOpt->count()>0)
434 Exporter<Z2i::DigitalSet,Image>::exportSignature(ball,aSet,domain);
442 ImplicitHyperCube<Z2i::Space> object(Z2i::Point(0,0), width/2.0);
443 Z2i::Domain domain(
object.getLowerBound(),
object.getUpperBound());
444 Z2i::DigitalSet aSet(domain);
446 Shapes<Z2i::Domain>::euclideanShaper(aSet,
object);
447 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
449 if (signatureOpt->count()>0)
451 trace.error()<<
"No signature export for this shape.";
452 trace.info()<<std::endl;
461 if (radiusOpt->count()==0) missingParam(
"--radius");
462 ImplicitRoundedHyperCube<Z2i::Space> ball(Z2i::Point(0,0), radius, power);
463 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
464 Z2i::DigitalSet aSet(domain);
466 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
467 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
469 if (signatureOpt->count()>0)
471 trace.error()<<
"No signature export for this shape.";
472 trace.info()<<std::endl;
481 if (radiusOpt->count()==0) missingParam(
"--radius");
484 Flower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
485 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
486 Z2i::DigitalSet aSet(domain);
488 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
489 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
491 if (signatureOpt->count()>0)
492 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
499 if (radiusOpt->count()==0) missingParam(
"--radius");
502 NGon2D<Z2i::Space> object(Z2i::Point(0,0), radius,k,phi);
503 Z2i::Domain domain(
object.getLowerBound(),
object.getUpperBound());
504 Z2i::DigitalSet aSet(domain);
506 Shapes<Z2i::Domain>::euclideanShaper(aSet,
object);
507 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
509 if (signatureOpt->count()>0)
510 Exporter<Z2i::DigitalSet,Image>::exportSignature(
object,aSet,domain);
518 if (radiusOpt->count()==0) missingParam(
"--radius");
521 AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
522 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
523 Z2i::DigitalSet aSet(domain);
525 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
526 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
528 if (signatureOpt->count()>0)
529 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
536 if (axis1Opt->count()==0) missingParam(
"--axis1");
537 if (axis2Opt->count()==0) missingParam(
"--axis2");
539 Ellipse2D<Z2i::Space> ell(Z2i::Point(0,0), axis1, axis2,phi);
540 Z2i::Domain domain(ell.getLowerBound(), ell.getUpperBound());
541 Z2i::DigitalSet aSet(domain);
543 Shapes<Z2i::Domain>::euclideanShaper(aSet, ell);
544 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
546 if (signatureOpt->count()>0)
547 Exporter<Z2i::DigitalSet,Image>::exportSignature(ell,aSet,domain);