Load feature list from a file (work in progress)

This commit is contained in:
Daniel Girardeau-Montaut
2018-10-28 21:22:04 +01:00
parent ad18249480
commit 62f3f67210
5 changed files with 204 additions and 2 deletions
+167
View File
@@ -17,11 +17,177 @@
#include "q3DMASCTools.h"
//qCC_io
#include <FileIOFilter.h>
//Qt
#include <QTextStream>
#include <QFile>
//system
#include <assert.h>
using namespace masc;
bool Tools::LoadFile(QString filename, ccPointCloud* pc1, ccPointCloud* pc2, FeatureRule::Set& features)
{
QFile file(filename);
if (!file.exists())
{
ccLog::Warning(QString("Can't find file '%1'").arg(filename));
return false;
}
if (!file.open(QFile::Text | QFile::ReadOnly))
{
ccLog::Warning(QString("Can't open file '%1'").arg(filename));
return false;
}
Scales::Shared scales(new Scales);
assert(features.empty());
QMap<QString, QScopedPointer<ccPointCloud> > clouds;
QTextStream stream(&file);
while (true)
{
QString line = stream.readLine();
if (line.isNull())
{
//eof
break;
}
if (line.startsWith("#"))
{
//comment
continue;
}
//strip out the potential comment at the end of the mine as well
int commentIndex = line.indexOf('#');
if (commentIndex >= 0)
line = line.left(commentIndex);
QString upperLine = line.toUpper();
if (upperLine.startsWith("CLOUD:")) //clouds
{
QString command = line.mid(6);
QStringList tokens = command.split(':');
if (tokens.size() != 2)
{
ccLog::Warning("Malformed file: expecting 2 tokens after 'cloud:'");
return false;
}
QString pcName = tokens[0];
QString pcFilename = tokens[1];
//try to open the cloud
{
FileIOFilter::LoadParameters parameters;
parameters.alwaysDisplayLoadDialog = false;
CC_FILE_ERROR error = CC_FERR_NO_ERROR;
ccHObject* object = FileIOFilter::LoadFromFile(pcFilename, parameters, error);
if (error != CC_FERR_NO_ERROR || !object)
{
ccLog::Warning("Failed to open the file (see console)");
if (object)
delete object;
return false;
}
if (!object->isA(CC_TYPES::POINT_CLOUD))
{
ccLog::Warning("File doesn't contain a single cloud");
delete object;
return false;
}
clouds.insert(pcName, QScopedPointer<ccPointCloud>(static_cast<ccPointCloud*>(object)));
}
}
else if (upperLine.startsWith("SCALES:")) //scales
{
QString command = line.mid(7);
QStringList tokens = command.split(';');
if (tokens.empty())
{
ccLog::Warning("Malformed file: expecting at least one token after 'scales:'");
return false;
}
try
{
for (const QString& token : tokens)
{
if (token.contains(':'))
{
//it's probably a range
QStringList subTokens = token.split(':');
if (subTokens.size() != 3)
{
ccLog::Warning(QString("Malformed file: expecting 3 tokens for a range of scales (%1)").arg(token));
return false;
}
bool ok[3] = { true, true, true };
double start = subTokens[0].toDouble(ok);
double step = subTokens[1].toDouble(ok + 1);
double stop = subTokens[2].toDouble(ok + 2);
if (!ok[0] || !ok[1] || !ok[2])
{
ccLog::Warning(QString("Malformed file: invalid values in scales range (%1)").arg(token));
return false;
}
if (stop < start || step <= 1.0-6)
{
ccLog::Warning(QString("Malformed file: invalid range (%1)").arg(token));
return false;
}
for (double v = start; v <= stop + 1.0 - 6; v += step)
{
scales->values.push_back(v);
}
}
else
{
bool ok = true;
double v = token.toDouble(&ok);
if (!ok)
{
ccLog::Warning(QString("Malformed file: invalid scale value (%1)").arg(token));
return false;
}
scales->values.push_back(v);
}
}
}
catch (const std::bad_alloc&)
{
ccLog::Warning("Not enough memory");
return false;
}
}
else if (upperLine.startsWith("FEATURE:")) //feature
{
QString command = line.mid(8);
QStringList tokens = command.split('_');
if (tokens.empty())
{
ccLog::Warning("Malformed file: expecting at least one token after 'feature:'");
return false;
}
QString typeStr = tokens[0].toUpper();
//TODO
}
else
{
ccLog::Warning("Unrecognized token/line: " + (line.length() < 10 ? line : line.left(10) + "..."));
return false;
}
}
return true;
}
bool Tools::RandomSubset(ccPointCloud* cloud, float ratio, CCLib::ReferenceCloud* inRatioSubset, CCLib::ReferenceCloud* outRatioSubset)
{
if (!cloud)
@@ -106,3 +272,4 @@ bool Tools::RandomSubset(ccPointCloud* cloud, float ratio, CCLib::ReferenceCloud
return true;
}