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"
126std::vector<std::string> shapes2D;
127std::vector<std::string> shapesDesc;
128std::vector<std::string> shapesParam1;
129std::vector<std::string> shapesParam2;
130std::vector<std::string> shapesParam3;
131std::vector<std::string> shapesParam4;
140 shapes2D.push_back(
"ball");
141 shapesDesc.push_back(
"Ball for the Euclidean metric.");
142 shapesParam1.push_back(
"--radius [-R]");
143 shapesParam2.push_back(
"");
144 shapesParam3.push_back(
"");
145 shapesParam4.push_back(
"");
147 shapes2D.push_back(
"square");
148 shapesDesc.push_back(
"square (no signature).");
149 shapesParam1.push_back(
"--width [-w]");
150 shapesParam2.push_back(
"");
151 shapesParam3.push_back(
"");
152 shapesParam4.push_back(
"");
154 shapes2D.push_back(
"lpball");
155 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
156 shapesParam1.push_back(
"--radius [-R],");
157 shapesParam2.push_back(
"--power [-p]");
158 shapesParam3.push_back(
"");
159 shapesParam4.push_back(
"");
161 shapes2D.push_back(
"flower");
162 shapesDesc.push_back(
"Flower with k petals.");
163 shapesParam1.push_back(
"--radius [-R],");
164 shapesParam2.push_back(
"--varsmallradius [-v],");
165 shapesParam3.push_back(
"--k [-k],");
166 shapesParam4.push_back(
"--phi");
168 shapes2D.push_back(
"ngon");
169 shapesDesc.push_back(
"Regular k-gon.");
170 shapesParam1.push_back(
"--radius [-R],");
171 shapesParam2.push_back(
"--k [-k],");
172 shapesParam3.push_back(
"--phi");
173 shapesParam4.push_back(
"");
175 shapes2D.push_back(
"accflower");
176 shapesDesc.push_back(
"Accelerated Flower with k petals.");
177 shapesParam1.push_back(
"--radius [-R],");
178 shapesParam2.push_back(
"--varsmallradius [-v],");
179 shapesParam3.push_back(
"--k [-k],");
180 shapesParam4.push_back(
"--phi");
182 shapes2D.push_back(
"ellipse");
183 shapesDesc.push_back(
"Ellipse.");
184 shapesParam1.push_back(
"--axis1 [-A],");
185 shapesParam2.push_back(
"--axis2 [-a],");
186 shapesParam3.push_back(
"--phi");
187 shapesParam4.push_back(
"");
198 trace.emphase()<<
"2D Shapes:"<<std::endl;
199 for(
unsigned int i=0; i<shapes2D.size(); ++i)
200 trace.info()<<
"\t"<<shapes2D[i]<<
"\t"
201 <<shapesDesc[i]<<std::endl
202 <<
"\t\tRequired parameter(s): "
203 << shapesParam1[i]<<
" "
204 << shapesParam2[i]<<
" "
205 << shapesParam3[i]<<
" "
206 << shapesParam4[i]<<std::endl;
219unsigned int checkAndRetrunIndex(
const std::string &shapeName)
223 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
226 if (pos == shapes2D.size())
228 trace.error() <<
"The specified shape has not found.";
229 trace.info()<<std::endl;
244template <
typename Set,
typename Image>
257 void save(
const Set &aSet,
258 const std::string outputName,
259 const std::string outputFormat)
262 Image image = ImageFromSet<Image>::template create<Set>(aSet, 255,
true);
264 if (outputFormat ==
"pgm")
265 PGMWriter<Image>::exportPGM(outputName+
"."+outputFormat,image);
267 if (outputFormat ==
"raw")
268 RawWriter<Image>::exportRaw8(outputName+
"."+outputFormat,image);
270 if (outputFormat ==
"svg")
274 board.saveSVG((outputName+
"."+outputFormat).c_str());
277#ifdef DGTAL_WITH_CAIRO
278 if (outputFormat ==
"pdf")
282 board.saveCairo((outputName+
"."+outputFormat).c_str(), Board2D::CairoPDF);
286 if (outputFormat ==
"png")
290 board.saveCairo((outputName+
"."+outputFormat).c_str(), Board2D::CairoPNG);
295 trace.error()<<
"Output format: "<<outputFormat<<
" not recognized."<<std::endl;
313 template <
typename Shape>
315 void exportSignature(
const Shape & aShape, Set &aSet,
const Z2i::Domain &aDomain)
317 trace.beginBlock(
"Extracting the boundary");
319 bool space_ok = ks.init( aDomain.lowerBound(),aDomain.upperBound(),
true );
320 SurfelAdjacency<2> sAdj(
true );
323 trace.info() << aSet << std::endl;
325 << ( space_ok ?
" Successfully instantiated" :
" Error" )
328 std::vector< std::vector< Z2i::Point > > vectContoursBdryPointels;
329 Surfaces<Z2i::KSpace>::extractAllPointContours4C( vectContoursBdryPointels,
334 std::cout<<
"## shapeGenerator signature export"<<std::endl;
335 std::cout<<
"## shape: "<<aShape<<std::endl;
336 std::cout<<
"## x\ty\tdx\tdy\tddx\tddy"<<std::endl;
337 for(
unsigned int i=0; i<vectContoursBdryPointels.size(); i++)
338 for(
unsigned int j=0 ; j< vectContoursBdryPointels.at(i).size() - 1; j++)
340 Z2i::Space::Point point = (vectContoursBdryPointels.at(i).at(j)
341 + vectContoursBdryPointels.at(i).at(j+1));
342 Z2i::Space::RealPoint midpoint (point[0]/2.0,point[1]/2.0);
344 Z2i::Space::RealPoint xp,xpp;
345 double t = aShape.parameter(midpoint);
347 xpp = aShape.xpp( t );
349 std::cout<< midpoint[0]<<
"\t"<<midpoint[1]<<
"\t"
350 << xp[0]<<
"\t"<<xp[1]<<
"\t"
351 << xpp[0]<<
"\t"<<xpp[1]<<std::endl;
363void missingParam(std::string param)
365 trace.error() <<
" Parameter: "<<param<<
" is required..";
366 trace.info()<<std::endl;
372int main(
int argc,
char** argv )
376 std::string shapeName;
377 std::string outputName;
378 std::string outputFormat {
"pgm"};
381 double smallradius {5};
382 double varsmallradius {5};
388 app.description(
"Generates shapes using DGtal library.\n Typical use example:\n \t shapeGenerator [options] --shape <shapeName> --output <outputBasename>\n");
389 auto listOpt = app.add_flag(
"--list,-l",
"List all available shapes");
390 auto shapeNameOpt = app.add_option(
"--shape,-s", shapeName,
"Shape name");
391 auto radiusOpt = app.add_option(
"--radius,-R", radius,
"Radius of the shape" );
392 auto axis1Opt = app.add_option(
"--axis1,-A", axis1,
"Half big axis of the shape (ellipse)" );
393 auto axis2Opt = app.add_option(
"--axis2,-a", axis2,
"Half small axis of the shape (ellipse)" );
394 auto smallradiusOpt = app.add_option(
"--smallradius,-r", smallradius,
"Small radius of the shape (default 5)");
395 auto varsmallradiusOpt = app.add_option(
"--varsmallradius,-v", varsmallradius,
"Variable small radius of the shape (default 5)" );
396 auto kOpt = app.add_option(
"-k", k,
"Number of branches or corners the shape (default 3)" );
397 auto phiOpt = app.add_option(
"--phi", phi,
"Phase of the shape (in radian, default 0.0)" );
398 auto widthOpt = app.add_option(
"--width,-w", width,
"Width of the shape (default 10.0)" );
399 auto powerOpt = app.add_option(
"--power,-p", power,
"Power of the metric (default 2.0)" );
400 auto outputNameOpt = app.add_option(
"--output,-o", outputName,
"Basename of the output file");
401 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)");
402 app.add_option(
"--format,-f", outputFormat,
"Output format:\n\t Bitmap {pgm, raw}\n\t Vector {svg} (+ {png,pdf} if libCairo installed) (default pgm)" );
404 app.get_formatter()->column_width(40);
405 CLI11_PARSE(app, argc, argv);
411 if ( listOpt->count() > 0 )
417 if(shapeNameOpt->count()==0) missingParam(
"--shape");
418 if(outputNameOpt->count()==0) missingParam(
"--output");
421 unsigned int id = checkAndRetrunIndex(shapeName);
422 typedef ImageContainerBySTLVector<Z2i::Domain,unsigned char> Image;
426 if (radiusOpt->count()==0) missingParam(
"--radius");
427 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), radius);
428 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
429 Z2i::DigitalSet aSet(domain);
431 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
432 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
434 if (signatureOpt->count()>0)
435 Exporter<Z2i::DigitalSet,Image>::exportSignature(ball,aSet,domain);
443 ImplicitHyperCube<Z2i::Space> object(Z2i::Point(0,0), width/2.0);
444 Z2i::Domain domain(
object.getLowerBound(),
object.getUpperBound());
445 Z2i::DigitalSet aSet(domain);
447 Shapes<Z2i::Domain>::euclideanShaper(aSet,
object);
448 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
450 if (signatureOpt->count()>0)
452 trace.error()<<
"No signature export for this shape.";
453 trace.info()<<std::endl;
462 if (radiusOpt->count()==0) missingParam(
"--radius");
463 ImplicitRoundedHyperCube<Z2i::Space> ball(Z2i::Point(0,0), radius, power);
464 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
465 Z2i::DigitalSet aSet(domain);
467 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
468 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
470 if (signatureOpt->count()>0)
472 trace.error()<<
"No signature export for this shape.";
473 trace.info()<<std::endl;
482 if (radiusOpt->count()==0) missingParam(
"--radius");
485 Flower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
486 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
487 Z2i::DigitalSet aSet(domain);
489 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
490 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
492 if (signatureOpt->count()>0)
493 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
500 if (radiusOpt->count()==0) missingParam(
"--radius");
503 NGon2D<Z2i::Space> object(Z2i::Point(0,0), radius,k,phi);
504 Z2i::Domain domain(
object.getLowerBound(),
object.getUpperBound());
505 Z2i::DigitalSet aSet(domain);
507 Shapes<Z2i::Domain>::euclideanShaper(aSet,
object);
508 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
510 if (signatureOpt->count()>0)
511 Exporter<Z2i::DigitalSet,Image>::exportSignature(
object,aSet,domain);
519 if (radiusOpt->count()==0) missingParam(
"--radius");
522 AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
523 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
524 Z2i::DigitalSet aSet(domain);
526 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
527 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
529 if (signatureOpt->count()>0)
530 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
537 if (axis1Opt->count()==0) missingParam(
"--axis1");
538 if (axis2Opt->count()==0) missingParam(
"--axis2");
540 Ellipse2D<Z2i::Space> ell(Z2i::Point(0,0), axis1, axis2,phi);
541 Z2i::Domain domain(ell.getLowerBound(), ell.getUpperBound());
542 Z2i::DigitalSet aSet(domain);
544 Shapes<Z2i::Domain>::euclideanShaper(aSet, ell);
545 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
547 if (signatureOpt->count()>0)
548 Exporter<Z2i::DigitalSet,Image>::exportSignature(ell,aSet,domain);