11 #include <ui_commandLineDlg.h>
30 #include <QElapsedTimer>
31 #include <QMessageBox>
34 #include <unordered_set>
61 if (!args || nargs < 2) {
69 parser->registerBuiltInCommands();
71 for (
int i = 1; i < nargs;
74 parser->arguments().push_back(QString(args[i]));
77 assert(!parser->arguments().empty());
83 parser->arguments().pop_front();
84 parser->toggleSilentMode(
true);
87 QScopedPointer<QDialog> consoleDlg(
nullptr);
88 if (!parser->silentMode()) {
90 consoleDlg.reset(
new QDialog);
91 Ui_commandLineDlg commandLineDlg;
92 commandLineDlg.setupUi(consoleDlg.data());
95 parser->fileLoadingParams().parentWidget = consoleDlg.data();
96 QApplication::processEvents();
110 plugin->registerCommands(parser.data());
114 int result = parser->start(consoleDlg.data());
116 if (!parser->silentMode()) {
117 if (
result == EXIT_SUCCESS)
118 QMessageBox::information(consoleDlg.data(),
"Processed finished",
121 QMessageBox::warning(consoleDlg.data(),
"Processed finished",
122 "An error occurred! Check console");
137 m_cloudExportFormat(
BinFilter::GetFileFilter()),
138 m_cloudExportExt(
BinFilter::GetDefaultExtension()),
139 m_meshExportFormat(
BinFilter::GetFileFilter()),
140 m_meshExportExt(
BinFilter::GetDefaultExtension()),
141 m_hierarchyExportFormat(
BinFilter::GetFileFilter()),
142 m_hierarchyExportExt(
BinFilter::GetDefaultExtension()),
143 m_orphans(
"orphans"),
144 m_progressDialog(nullptr),
145 m_parentWidget(nullptr) {}
148 if (m_progressDialog) {
149 m_progressDialog->close();
150 m_progressDialog->deleteLater();
160 if (m_commands.contains(command->m_keyword)) {
162 warning(QString(
"Internal error: keyword '%1' already registered (by "
164 .arg(command->m_keyword,
165 m_commands[command->m_keyword]->m_name));
169 m_commands.insert(command->m_keyword, command);
178 QString* baseOutputFilename ,
179 bool forceNoTimestamp )
const {
184 warning(
"[ExportEntity] Internal error: invalid input entity!");
190 if (suffix.isEmpty())
191 suffix = QString(
"%1").arg(entityDesc.
indexInFile);
193 suffix.prepend(QString(
"%1_").arg(entityDesc.
indexInFile));
196 QString baseName = entityDesc.
basename;
197 if (!suffix.isEmpty()) {
198 baseName += QString(
"_") + suffix;
201 QString outputFilename = baseName;
204 QString(
"_%1").arg(QDateTime::currentDateTime().
toString(
205 "yyyy-MM-dd_hh'h'mm_ss_zzz"));
208 if (!extension.isEmpty()) {
209 outputFilename += QString(
".%1").arg(extension);
212 if (baseOutputFilename) {
213 *baseOutputFilename = outputFilename;
216 if (!entityDesc.
path.isEmpty()) {
217 outputFilename.prepend(QString(
"%1/").arg(entityDesc.
path));
220 return outputFilename;
225 const QString& suffix ,
226 QString* baseOutputFilename ,
227 ccCommandLineInterface::ExportOptions
235 return "[ExportEntity] Internal error: invalid input entity!";
249 QString extension = isCloud ? m_cloudExportExt
250 : isMesh ? m_meshExportExt
251 : m_hierarchyExportExt;
252 QString
format = isCloud ? m_cloudExportFormat
253 : isMesh ? m_meshExportFormat
254 : m_hierarchyExportFormat;
257 extension = m_cloudExportExt;
258 format = m_cloudExportFormat;
261 extension = m_meshExportExt;
262 format = m_meshExportFormat;
265 extension = m_hierarchyExportExt;
266 format = m_hierarchyExportFormat;
269 QString outputFilename =
272 if (outputFilename.isEmpty()) {
278 QString entName = entity->
getName();
279 if (entName.isEmpty()) {
283 if (!suffix.isEmpty()) {
284 entName += QString(
"_") + suffix;
290 bool tempDependencyCreated =
false;
304 tempDependencyCreated =
true;
319 print(
"Output filename: " + outputFilename);
325 if (tempDependencyCreated) {
326 if (mesh && entity) {
334 ? QString(
"Failed to save result in file '%1'")
363 static bool s_firstCoordinatesShiftEnabled =
false;
372 switch (globalShiftOptions.
mode) {
384 s_firstCoordinatesShiftEnabled;
417 static bool s_firstTime =
true;
420 s_firstCoordinatesShiftEnabled =
427 std::unordered_set<unsigned> verticesIDs;
436 for (
size_t i = 0; i <
meshes.size(); ++i) {
445 print(QString(
"Found one mesh with %1 faces and %2 "
452 count == 1 ? -1 :
static_cast<int>(i));
464 size_t countBefore =
count;
466 for (
size_t i = 0; i <
meshes.size(); ++i) {
473 print(QString(
"Found one kind of mesh with %1 faces and %2 "
481 :
static_cast<int>(countBefore + i));
496 for (
size_t i = 0; i <
count; ++i) {
503 if (verticesIDs.find(pc->
getUniqueID()) != verticesIDs.end()) {
507 print(QString(
"Found one cloud with %1 points").arg(pc->
size()));
509 count == 1 ? -1 :
static_cast<int>(i));
521 const QString* allAtOnceFileName ) {
526 bool multiple =
false;
528 bool exclusive =
true;
536 tempContainer.
addChild(desc.getEntity(),
544 if (allAtOnceFileName) {
550 if (!errorStr.isEmpty())
551 return error(errorStr);
555 error(QString(
"The currently selected ouput format for clouds (%1) "
556 "doesn't handle multiple entities at once!")
557 .arg(m_cloudExportFormat));
567 if (!errorStr.isEmpty())
return error(errorStr);
576 const QString* allAtOnceFileName ) {
581 bool multiple =
false;
583 bool exclusive =
true;
591 tempContainer.
addChild(mesh.getEntity(),
599 if (allAtOnceFileName) {
605 if (!errorStr.isEmpty())
606 return error(errorStr);
610 error(QString(
"The currently selected ouput format for meshes (%1) "
611 "doesn't handle multiple entities at once!")
612 .arg(m_meshExportFormat));
621 if (!errorStr.isEmpty())
return error(errorStr);
702 if (m_arguments.empty()) {
707 m_parentWidget = parent;
716 QElapsedTimer eTimer;
720 while (success && !m_arguments.empty()) {
721 QApplication::processEvents();
724 QString argument = m_arguments.takeFirst();
726 if (!argument.startsWith(
"-")) {
727 error(QString(
"Command expected (commands start with '-'). Found "
733 QString keyword = argument.mid(1).toUpper();
735 if (m_commands.contains(keyword)) {
736 assert(m_commands[keyword]);
737 success = m_commands[keyword]->process(*
this);
741 warning(QString(
"Misplaced command: '%1' (must be first)")
744 print(
"Available commands:");
745 for (
auto it = m_commands.constBegin(); it != m_commands.constEnd();
747 print(QString(
"-%1: %2").arg(it.key().toUpper(),
748 it.value()->m_name));
751 error(QString(
"Unknown or misplaced command: '%1'").arg(argument));
757 print(QString(
"Processed finished in %1 s.")
758 .arg(eTimer.elapsed() / 1.0e3, 0,
'f', 2));
760 return success ? EXIT_SUCCESS : EXIT_FAILURE;
Vector3Tpl< double > CCVector3d
Double 3D Vector.
filament::Texture::InternalFormat format
CC_FILE_ERROR
Typical I/O filter errors.
CLOUDVIEWER dedicated binary point cloud I/O filter.
static QString GetFileFilter()
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static CVLog * TheInstance()
Returns the static and unique instance.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
static CC_FILE_ERROR SaveToFile(ccHObject *entities, const QString &filename, const SaveParameters ¶meters, Shared filter)
static Shared GetFilter(const QString &fileFilter, bool onImport)
Returns the filter corresponding to the given 'file filter'.
QSharedPointer< FileIOFilter > Shared
Shared type.
static ccHObject * LoadFromFile(const QString &filename, LoadParameters ¶meters, Shared filter, CC_FILE_ERROR &result)
Loads one or more entities from a file with a known filter.
std::vector< CLMeshDesc > m_meshes
Currently opened meshes and their filename.
bool m_addTimestamp
Whether a timestamp should be automatically added to output files or not.
std::vector< CLCloudDesc > m_clouds
Currently opened point clouds and their filename.
static bool IsCommand(const QString &token, const char *command)
Test whether a command line token is a valid command keyword or not.
CLLoadParameters m_loadingParameters
File loading parameters.
bool silentMode() const
Returns the silent mode.
virtual std::vector< CLMeshDesc > & meshes()
Currently opened meshes and their filename.
virtual std::vector< CLCloudDesc > & clouds()
Currently opened point clouds and their filename.
int start(QDialog *parent=0)
Parses the command line.
bool error(const QString &message) const override
void print(const QString &message) const override
bool saveClouds(QString suffix=QString(), bool allAtOnce=false, const QString *allAtOnceFileName=nullptr) override
Saves all clouds.
bool saveMeshes(QString suffix=QString(), bool allAtOnce=false, const QString *allAtOnceFileName=nullptr) override
Saves all meshes.
bool importFile(QString filename, const GlobalShiftOptions &globalShiftOptions, FileIOFilter::Shared filter=FileIOFilter::Shared(nullptr)) override
Loads a file with a specific filter.
bool registerCommand(Command::Shared command) override
QString getExportFilename(const CLEntityDesc &entityDesc, QString extension=QString(), QString suffix=QString(), QString *baseOutputFilename=nullptr, bool forceNoTimestamp=false) const override
Returns the name of a to-be-exported entity.
~ccCommandLineParser() override
Destructor.
ccCommandLineParser()
Default constructor.
void registerBuiltInCommands()
void removeClouds(bool onlyLast=false) override
Removes all clouds (or only the last one ;)
QString exportEntity(CLEntityDesc &entityDesc, const QString &suffix=QString(), QString *baseOutputFilename=nullptr, ccCommandLineInterface::ExportOptions options=ExportOption::NoOptions) override
Exports a cloud or a mesh.
void removeMeshes(bool onlyLast=false) override
Removes all meshes (or only the last one ;)
static int Parse(int nargs, char **args, ccPluginInterfaceList &plugins)
Parses the input command.
void warning(const QString &message) const override
virtual ccGenericPointCloud * getAssociatedCloud() const =0
Returns the vertices cloud.
A 3D cloud interface with associated features (color, normals, octree, etc.)
static ccGenericMesh * ToGenericMesh(ccHObject *obj)
Converts current object to ccGenericMesh (if possible)
Hierarchical CLOUDVIEWER Object.
void detachChild(ccHObject *child)
Detaches a specific child.
bool isAncestorOf(const ccHObject *anObject) const
Returns true if the current object is an ancestor of the specified one.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
unsigned filterChildren(Container &filteredChildren, bool recursive=false, CV_CLASS_ENUM filter=CV_TYPES::OBJECT, bool strict=false) const
Collects the children corresponding to a certain pattern.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
virtual QString getName() const
Returns object name.
virtual unsigned getUniqueID() const
Returns object unique ID.
bool isA(CV_CLASS_ENUM type) const
virtual void setName(const QString &name)
Sets object name.
bool isKindOf(CV_CLASS_ENUM type) const
Standard ECV plugin interface.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
virtual unsigned size() const =0
Returns the number of points.
virtual unsigned size() const =0
Returns the number of triangles.
unsigned size() const override
static void ReleaseInstance(bool flush=true)
Releases unique instance.
static void Init(QListWidget *textDisplay=nullptr, QWidget *parentWidget=nullptr, MainWindow *parentWindow=nullptr, bool redirectToStdOut=false)
Inits console (and optionaly associates it with a text output widget)
constexpr char COMMAND_SILENT_MODE[]
constexpr char COMMAND_HELP[]
QVector< ccPluginInterface * > ccPluginInterfaceList
Simply a list of.
std::string toString(T x)
Loaded cloud description.
Loaded entity description.
virtual CL_ENTITY_TYPE getCLEntityType() const =0
virtual ccHObject * getEntity()=0
Loaded group description.
static void SetFileDesc(CLEntityDesc &desc, const QString &fileName)
ecvGlobalShiftManager::Mode shiftHandlingMode
How to handle big coordinates.
Generic saving parameters.
QWidget * parentWidget
Parent widget (if any)
bool alwaysDisplaySaveDialog
bool m_coordinatesShiftEnabled
CCVector3d m_coordinatesShift
QSharedPointer< Command > Shared
Shared type.
CCVector3d customGlobalShift