Add new lcResult class to handle task failures more cleanly.

This commit is contained in:
Leonardo Zide
2026-07-29 22:48:12 -07:00
parent 9590852a29
commit 9dbe3695b7
10 changed files with 263 additions and 136 deletions
+28 -7
View File
@@ -1156,9 +1156,13 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
FileName = FileName.left(FileName.length() - Extension.length() - 1);
FileName += ".obj";
}
lcResult<void> ExportResult = mProject->ExportWavefront(FileName);
if (mProject->ExportWavefront(FileName))
if (ExportResult)
StdOut << tr("Saved '%1'.\n").arg(FileName);
else if (!ExportResult.error().isEmpty())
StdErr << ExportResult.error();
}
if (Options.Save3DS)
@@ -1181,9 +1185,13 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
FileName = FileName.left(FileName.length() - Extension.length() - 1);
FileName += ".3ds";
}
if (mProject->Export3DStudio(FileName))
lcResult<void> ExportResult = mProject->Export3DStudio(FileName);
if (ExportResult)
StdOut << tr("Saved '%1'.\n").arg(FileName);
else if (!ExportResult.error().isEmpty())
StdErr << ExportResult.error();
}
if (Options.SaveCOLLADA)
@@ -1206,9 +1214,13 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
FileName = FileName.left(FileName.length() - Extension.length() - 1);
FileName += ".dae";
}
lcResult<void> ExportResult = mProject->ExportCOLLADA(FileName);
if (mProject->ExportCOLLADA(FileName))
if (ExportResult)
StdOut << tr("Saved '%1'.\n").arg(FileName);
else if (!ExportResult.error().isEmpty())
StdErr << ExportResult.error();
}
if (Options.SaveCSV)
@@ -1231,9 +1243,13 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
FileName = FileName.left(FileName.length() - Extension.length() - 1);
FileName += ".csv";
}
if (mProject->ExportCSV(FileName))
lcResult<void> ExportResult = mProject->ExportCSV(FileName);
if (ExportResult)
StdOut << tr("Saved '%1'.\n").arg(FileName);
else if (!ExportResult.error().isEmpty())
StdErr << ExportResult.error();
}
if (Options.SaveHTML)
@@ -1243,7 +1259,12 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
if (!Options.SaveHTMLName.isEmpty())
HTMLOptions.PathName = Options.SaveHTMLName;
mProject->ExportHTML(HTMLOptions);
lcResult<void> ExportResult = mProject->ExportHTML(HTMLOptions);
if (ExportResult)
StdOut << tr("Saved '%1'.\n").arg(HTMLOptions.PathName);
else if (!ExportResult.error().isEmpty())
StdErr << ExportResult.error();
}
}
+6 -6
View File
@@ -1,7 +1,8 @@
#include "lc_global.h"
#include "lc_bricklink.h"
#include "lc_file.h"
#include "lc_library.h"
#include "lc_mainwindow.h"
#include "lc_application.h"
#include "lc_string.h"
#include "pieceinf.h"
#include "lc_colors.h"
@@ -59,7 +60,7 @@ public:
int mCount;
};
void lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList)
lcResult<void> lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList)
{
QJsonDocument Document = lcLoadBrickLinkMapping();
QJsonObject Root = Document.object();
@@ -70,10 +71,7 @@ void lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList
char Line[1024];
if (!BrickLinkFile.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, QObject::tr("LeoCAD"), QObject::tr("Could not open file '%1' for writing.").arg(SaveFileName));
return;
}
return lcUnexpected(QObject::tr("Could not open file '%1' for writing.").arg(SaveFileName));
std::map<std::string, lcBrickLinkItem> Inventory;
@@ -127,4 +125,6 @@ void lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList
}
BrickLinkFile.WriteLine("</INVENTORY>\n");
return lcResult<void>();
}
+3 -1
View File
@@ -1,3 +1,5 @@
#pragma once
void lcExportBrickLink(const QString& FileName, const lcPartsList& PartsList);
#include "lc_result.h"
lcResult<void> lcExportBrickLink(const QString& FileName, const lcPartsList& PartsList);
+17 -11
View File
@@ -1321,15 +1321,15 @@ void lcMainWindow::ShowHTMLDialog()
return;
Options.SaveDefaults();
lcGetActiveProject()->ExportHTML(Options);
ShowResultMessageBox(lcGetActiveProject()->ExportHTML(Options));
}
void lcMainWindow::ShowExportPOVRayDialog()
{
auto [Success, ErrorMessage] = lcGetActiveProject()->ExportPOVRay(QString());
lcResult<void> ExportResult = lcGetActiveProject()->ExportPOVRay(QString());
if (!Success && !ErrorMessage.isEmpty())
QMessageBox::warning(this, tr("POV-Ray Export" ), ErrorMessage);
if (!ExportResult && !ExportResult.error().isEmpty())
QMessageBox::warning(this, tr("POV-Ray Export" ), ExportResult.error());
}
void lcMainWindow::ShowRenderDialog(lcRenderDialogMode RenderDialogMode)
@@ -1407,6 +1407,12 @@ void lcMainWindow::ShowSelectDialog()
ActiveModel->SetSelectionAndFocusAction(Dialog.mObjects, nullptr, 0, lcSelectionMode::Single);
}
void lcMainWindow::ShowResultMessageBox(const lcResult<void>& Result)
{
if (!Result && !Result.error().isEmpty())
QMessageBox::information(this, tr("LeoCAD"), Result.error());
}
void lcMainWindow::SetShadingMode(lcShadingMode ShadingMode)
{
lcGetPreferences().mShadingMode = ShadingMode;
@@ -2483,8 +2489,8 @@ void lcMainWindow::ShowMergeDialog()
lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(LoadFileNames.first()).absolutePath());
std::vector<std::unique_ptr<Project>> ProjectsToMerge;
for (const QString& LoadFileName : LoadFileNames)
for (const QString& LoadFileName : std::as_const(LoadFileNames))
{
std::unique_ptr<Project>& NewProject = ProjectsToMerge.emplace_back(std::make_unique<Project>());
@@ -2706,11 +2712,11 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
break;
case LC_FILE_EXPORT_3DS:
lcGetActiveProject()->Export3DStudio(QString());
ShowResultMessageBox(lcGetActiveProject()->Export3DStudio(QString()));
break;
case LC_FILE_EXPORT_COLLADA:
lcGetActiveProject()->ExportCOLLADA(QString());
ShowResultMessageBox(lcGetActiveProject()->ExportCOLLADA(QString()));
break;
case LC_FILE_EXPORT_HTML:
@@ -2718,11 +2724,11 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
break;
case LC_FILE_EXPORT_BRICKLINK:
lcGetActiveProject()->ExportBrickLink();
ShowResultMessageBox(lcGetActiveProject()->ExportBrickLink());
break;
case LC_FILE_EXPORT_CSV:
lcGetActiveProject()->ExportCSV(QString());
ShowResultMessageBox(lcGetActiveProject()->ExportCSV(QString()));
break;
case LC_FILE_EXPORT_POVRAY:
@@ -2730,7 +2736,7 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
break;
case LC_FILE_EXPORT_WAVEFRONT:
lcGetActiveProject()->ExportWavefront(QString());
ShowResultMessageBox(lcGetActiveProject()->ExportWavefront(QString()));
break;
case LC_FILE_RENDER_POVRAY:
+2
View File
@@ -2,6 +2,7 @@
#include "lc_application.h"
#include "lc_shortcuts.h"
#include "lc_result.h"
#include "lc_commands.h"
#include "lc_model.h"
@@ -310,6 +311,7 @@ protected:
void ShowPrintDialog();
void ShowImageDialog();
void ShowSelectDialog();
void ShowResultMessageBox(const lcResult<void>& Result);
void CreatePreviewWidget();
bool OpenProjectFile(const QString& FileName);
+134
View File
@@ -0,0 +1,134 @@
#pragma once
// We can't use std::expected because we only require C++17.
#include <stdexcept>
class lcUnexpected
{
public:
explicit lcUnexpected(const QString& Error)
: mError(Error)
{
}
explicit lcUnexpected(QString&& Error)
: mError(std::move(Error))
{
}
const QString& error() const
{
return mError;
}
QString& error()
{
return mError;
}
protected:
QString mError;
};
template <typename T>
class [[nodiscard]] lcResult
{
using internal_t = std::conditional_t<std::is_void_v<T>, char, T>;
public:
template <typename U = T, typename = std::enable_if_t<!std::is_void_v<U> && std::is_convertible_v<U, T>>>
lcResult(U&& Value)
: mHasValue(true)
{
::new (static_cast<void*>(&mValue)) internal_t(std::forward<U>(Value));
}
template <typename U = T, typename = std::enable_if_t<std::is_void_v<U>>>
lcResult()
: mHasValue(true)
{
}
lcResult(lcUnexpected Unexpected)
: mHasValue(false)
{
::new (static_cast<void*>(&mUnexpected)) lcUnexpected(std::move(Unexpected.error()));
}
~lcResult() noexcept
{
if (mHasValue)
{
if constexpr (!std::is_void_v<T>)
mValue.~internal_t();
}
else
{
mUnexpected.~lcUnexpected();
}
}
lcResult(const lcResult& Other) :
mHasValue(Other.mHasValue)
{
if (mHasValue)
{
if constexpr (!std::is_void_v<T>)
::new (static_cast<void*>(&mValue)) internal_t(Other.mValue);
}
else
{
::new (static_cast<void*>(&mUnexpected)) lcUnexpected(Other.mUnexpected);
}
}
lcResult(lcResult&& Other) noexcept(std::is_nothrow_move_constructible_v<internal_t> && std::is_nothrow_move_constructible_v<lcUnexpected>)
: mHasValue(Other.mHasValue)
{
if (mHasValue)
{
if constexpr (!std::is_void_v<T>)
::new (static_cast<void*>(&mValue)) internal_t(std::move(Other.mValue));
}
else
{
::new (static_cast<void*>(&mUnexpected)) lcUnexpected(std::move(Other.mUnexpected));
}
}
bool has_value() const
{
return mHasValue;
}
explicit operator bool() const
{
return has_value();
}
template <typename U = T, typename = std::enable_if_t<!std::is_void_v<U>>>
constexpr const U& value() const
{
if (!mHasValue)
throw std::logic_error("bad lcResult access");
return mValue;
}
constexpr const QString& error() const
{
if (mHasValue)
throw std::logic_error("bad lcResult access");
return mUnexpected.error();
}
protected:
union
{
internal_t mValue;
lcUnexpected mUnexpected;
};
bool mHasValue;
};
+51 -95
View File
@@ -650,15 +650,12 @@ std::vector<lcModelPartsEntry> Project::GetModelParts()
return ModelParts;
}
bool Project::ExportCurrentStep(const QString& FileName)
lcResult<void> Project::ExportCurrentStep(const QString& FileName)
{
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return false;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QStringList Models;
@@ -749,8 +746,8 @@ bool Project::ExportCurrentStep(const QString& FileName)
File.close();
lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(FileName).absolutePath());
return true;
return lcResult<void>();
}
bool Project::ExportModel(const QString& FileName, lcModel* Model) const
@@ -795,28 +792,22 @@ QString Project::GetExportFileName(const QString& FileName, const QString& Defau
return QFileDialog::getSaveFileName(gMainWindow, DialogTitle, SaveFileName, DialogFilter);
}
bool Project::Export3DStudio(const QString& FileName)
lcResult<void> Project::Export3DStudio(const QString& FileName)
{
std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
if (ModelParts.empty())
{
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export."));
return false;
}
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(FileName, "3ds", tr("Export 3D Studio"), tr("3DS Files (*.3ds);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return false;
return lcUnexpected(QString());
lcDiskFile File(SaveFileName);
if (!File.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return false;
}
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
long M3DStart = File.GetPosition();
File.WriteU16(0x4D4D); // CHK_M3DMAGIC
@@ -1232,11 +1223,11 @@ bool Project::Export3DStudio(const QString& FileName)
File.Seek(M3DStart + 2, SEEK_SET);
File.WriteU32(M3DEnd - M3DStart);
File.Seek(M3DEnd, SEEK_SET);
return true;
return lcResult<void>();
}
void Project::ExportBrickLink()
lcResult<void> Project::ExportBrickLink()
{
lcPartsList PartsList;
@@ -1244,41 +1235,32 @@ void Project::ExportBrickLink()
mModels[0]->GetPartsList(gDefaultColor, true, false, PartsList);
if (PartsList.empty())
{
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export."));
return;
}
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(QString(), "xml", tr("Export BrickLink"), tr("XML Files (*.xml);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return;
return lcUnexpected(QString());
lcExportBrickLink(SaveFileName, PartsList);
return lcExportBrickLink(SaveFileName, PartsList);
}
bool Project::ExportCOLLADA(const QString& FileName)
lcResult<void> Project::ExportCOLLADA(const QString& FileName)
{
std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
if (ModelParts.empty())
{
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export."));
return false;
}
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(FileName, "dae", tr("Export COLLADA"), tr("COLLADA Files (*.dae);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return false;
return lcUnexpected(QString());
QFile File(SaveFileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return false;
}
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
QTextStream Stream(&File);
@@ -1525,11 +1507,11 @@ bool Project::ExportCOLLADA(const QString& FileName)
Stream << "</scene>\r\n";
Stream << "</COLLADA>\r\n";
return true;
return lcResult<void>();
}
bool Project::ExportCSV(const QString& FileName)
lcResult<void> Project::ExportCSV(const QString& FileName)
{
lcPartsList PartsList;
@@ -1537,24 +1519,18 @@ bool Project::ExportCSV(const QString& FileName)
mModels[0]->GetPartsList(gDefaultColor, true, false, PartsList);
if (PartsList.empty())
{
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export."));
return false;
}
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(FileName, "csv", tr("Export CSV"), tr("CSV Files (*.csv);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return false;
return lcUnexpected(QString());
lcDiskFile CSVFile(SaveFileName);
char Line[1024];
if (!CSVFile.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return false;
}
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
CSVFile.WriteLine("Part Name,Color,Quantity,Part ID,Color Code\n");
@@ -1571,8 +1547,8 @@ bool Project::ExportCSV(const QString& FileName)
CSVFile.WriteLine(Line);
}
}
return true;
return lcResult<void>();
}
lcInstructions* Project::GetInstructions()
@@ -1583,7 +1559,7 @@ lcInstructions* Project::GetInstructions()
return mInstructions.get();
}
void Project::ExportHTML(const lcHTMLExportOptions& Options)
lcResult<void> Project::ExportHTML(const lcHTMLExportOptions& Options)
{
QDir Dir(Options.PathName);
Dir.mkpath(QLatin1String("."));
@@ -1641,10 +1617,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QTextStream Stream(&File);
@@ -1672,10 +1645,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QTextStream Stream(&File);
@@ -1697,10 +1667,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QTextStream Stream(&File);
@@ -1731,10 +1698,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QTextStream Stream(&File);
@@ -1763,10 +1727,7 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
QFile File(FileName);
if (!File.open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
return;
}
return lcUnexpected(tr("Error writing to file '%1':\n%2").arg(FileName, File.errorString()));
QTextStream Stream(&File);
@@ -1803,24 +1764,26 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
Stream << QLatin1String("</CENTER>\r\n<BR><HR><BR><B><I>Created by <A HREF=\"https://www.leocad.org\">LeoCAD</A></B></I><BR></HTML>\r\n");
}
return lcResult<void>();
}
std::pair<bool, QString> Project::ExportPOVRay(const QString& FileName)
lcResult<void> Project::ExportPOVRay(const QString& FileName)
{
std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
if (ModelParts.empty())
return { false, tr("Nothing to export.") };
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(FileName, QLatin1String("pov"), tr("Export POV-Ray"), tr("POV-Ray Files (*.pov);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return { false, QString() };
return lcUnexpected(QString());
lcDiskFile POVFile(SaveFileName);
if (!POVFile.Open(QIODevice::WriteOnly))
return { false, tr("Could not open file '%1' for writing.").arg(SaveFileName) };
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
enum
{
@@ -2225,7 +2188,7 @@ std::pair<bool, QString> Project::ExportPOVRay(const QString& FileName)
lcDiskFile TableFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath());
if (!TableFile.Open(QIODevice::ReadOnly))
return { false, tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath) };
return lcUnexpected(tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath));
while (TableFile.ReadLine(Line, sizeof(Line)))
{
@@ -2271,7 +2234,7 @@ std::pair<bool, QString> Project::ExportPOVRay(const QString& FileName)
lcDiskFile LgeoColorFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath());
if (!LgeoColorFile.Open(QIODevice::ReadOnly))
return { false, tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath) };
return lcUnexpected(tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath));
while (LgeoColorFile.ReadLine(Line, sizeof(Line)))
{
@@ -2487,33 +2450,27 @@ std::pair<bool, QString> Project::ExportPOVRay(const QString& FileName)
snprintf(Line, sizeof(Line), "\n#include \"%s\"\n", POVRayOptions.FooterIncludeFile.toLatin1().constData());
POVFile.WriteLine(Line);
}
return { true, QString() };
return lcResult<void>();
}
bool Project::ExportWavefront(const QString& FileName)
lcResult<void> Project::ExportWavefront(const QString& FileName)
{
std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
if (ModelParts.empty())
{
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Nothing to export."));
return false;
}
return lcUnexpected(tr("Nothing to export."));
QString SaveFileName = GetExportFileName(FileName, QLatin1String("obj"), tr("Export Wavefront"), tr("Wavefront Files (*.obj);;All Files (*.*)"));
if (SaveFileName.isEmpty())
return false;
return lcUnexpected(QString());
lcDiskFile OBJFile(SaveFileName);
char Line[1024];
if (!OBJFile.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(SaveFileName));
return false;
}
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(SaveFileName));
quint32 vert = 1;
@@ -2526,13 +2483,12 @@ bool Project::ExportWavefront(const QString& FileName)
OBJFile.WriteLine(Line);
lcDiskFile MaterialFile(MaterialFileName);
if (!MaterialFile.Open(QIODevice::WriteOnly))
{
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not open file '%1' for writing.").arg(MaterialFileName));
return false;
}
return lcUnexpected(tr("Could not open file '%1' for writing.").arg(MaterialFileName));
MaterialFile.WriteLine("# Colors used by LeoCAD\n\n");
for (const lcColor& Color : gColorList)
{
if (Color.Translucent)
@@ -2596,8 +2552,8 @@ bool Project::ExportWavefront(const QString& FileName)
vert += Mesh->mNumVertices;
}
}
return true;
return lcResult<void>();
}
void Project::SaveImage(const lcImageDialogOptions& Options)
+9 -8
View File
@@ -1,6 +1,7 @@
#pragma once
#include "lc_application.h"
#include "lc_result.h"
#define LC_HTML_SINGLEPAGE 0x01
#define LC_HTML_INDEX 0x02
@@ -100,15 +101,15 @@ public:
bool ImportInventory(const std::vector<lcSetInventoryItem>& SetInventory, const QString& Name, const QString& Description);
void SaveImage(const lcImageDialogOptions& Options);
bool ExportCurrentStep(const QString& FileName);
lcResult<void> ExportCurrentStep(const QString& FileName);
bool ExportModel(const QString& FileName, lcModel* Model) const;
bool Export3DStudio(const QString& FileName);
void ExportBrickLink();
bool ExportCOLLADA(const QString& FileName);
bool ExportCSV(const QString& FileName);
void ExportHTML(const lcHTMLExportOptions& Options);
std::pair<bool, QString> ExportPOVRay(const QString& FileName);
bool ExportWavefront(const QString& FileName);
lcResult<void> Export3DStudio(const QString& FileName);
lcResult<void> ExportBrickLink();
lcResult<void> ExportCOLLADA(const QString& FileName);
lcResult<void> ExportCSV(const QString& FileName);
lcResult<void> ExportHTML(const lcHTMLExportOptions& Options);
lcResult<void> ExportPOVRay(const QString& FileName);
lcResult<void> ExportWavefront(const QString& FileName);
void UpdatePieceInfo(PieceInfo* Info) const;