mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
Allow outputs with missing geometry and fit available meshes
This commit is contained in:
1 parent
dcd2ef5a3b
commit
8ceceb95ba
14 files changed
+192
-237
No files matched your search
@@ -1139,14 +1139,7 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
|
||||
if (Options.SetHighlightColor)
|
||||
mPreferences.mHighlightNewPartsColor = Options.HighlightColor;
|
||||
|
||||
const lcResult<void> Ready = ActiveModel->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
StdErr << Ready.error() << '\n';
|
||||
|
||||
return lcStartupMode::Error;
|
||||
}
|
||||
ActiveModel->WaitForAssets();
|
||||
|
||||
const bool UsesCameraPosition = Options.SetCameraPosition && Options.Viewpoint == lcViewpoint::Count && !Options.SetCameraAngles;
|
||||
|
||||
@@ -1154,7 +1147,7 @@ lcStartupMode lcApplication::Initialize(const QList<QPair<QString, bool>>& Libra
|
||||
{
|
||||
const lcStep FitStep = Options.ImageStart == Options.ImageEnd ? Options.ImageStart : ActiveModel->GetLastStep();
|
||||
|
||||
ActiveModel->ZoomExtentsAtStep(ActiveView->GetCamera(), (float)ActiveView->GetWidth() / (float)ActiveView->GetHeight(), FitStep);
|
||||
ActiveModel->ZoomExtentsAtStep(ActiveView->GetCamera(), (float)ActiveView->GetWidth() / (float)ActiveView->GetHeight(), FitStep, lcGeometryBoundsMode::AvailableGeometryOnly);
|
||||
}
|
||||
|
||||
auto ProgressCallback = [&StdOut](const QString& FileName)
|
||||
|
||||
@@ -63,6 +63,12 @@ class QPrinter;
|
||||
typedef quint32 lcStep;
|
||||
#define LC_STEP_MAX 0xffffffff
|
||||
|
||||
enum class lcGeometryBoundsMode
|
||||
{
|
||||
IncludeFallbackGeometry,
|
||||
AvailableGeometryOnly
|
||||
};
|
||||
|
||||
// Version number.
|
||||
#define LC_VERSION_MAJOR 26
|
||||
#define LC_VERSION_MINOR 9
|
||||
|
||||
@@ -65,7 +65,7 @@ void lcInstructionsPartsListItem::Update()
|
||||
QFont Font = mInstructions->GetFontProperty(lcInstructionsPropertyType::PLIFont, mModel, mStep);
|
||||
QColor TextColor = mInstructions->GetColorProperty(lcInstructionsPropertyType::PLITextColor, mModel, mStep);
|
||||
|
||||
QImage PartsImage = mModel->GetPartsListImage(300, mStep, lcRGBAFromQColor(BackgroundColor), Font, TextColor);
|
||||
QImage PartsImage = mModel->GetPartsListImage(300, mStep, lcRGBAFromQColor(BackgroundColor), Font, TextColor, false);
|
||||
setPixmap(QPixmap::fromImage(PartsImage));
|
||||
}
|
||||
|
||||
|
||||
@@ -1347,13 +1347,7 @@ void lcMainWindow::ProjectFileChanged(const QString& Path)
|
||||
void lcMainWindow::Print(QPrinter* Printer)
|
||||
{
|
||||
#ifndef QT_NO_PRINTER
|
||||
const lcResult<void> Ready = lcGetActiveProject()->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
QMessageBox::warning(this, tr("LeoCAD"), Ready.error());
|
||||
return;
|
||||
}
|
||||
lcGetActiveProject()->GetMainModel()->WaitForAssets();
|
||||
|
||||
int DocCopies;
|
||||
int PageCopies;
|
||||
@@ -1521,13 +1515,7 @@ void lcMainWindow::ShowRenderDialog(lcRenderDialogMode RenderDialogMode)
|
||||
|
||||
void lcMainWindow::ShowInstructionsDialog()
|
||||
{
|
||||
const lcResult<void> Ready = lcGetActiveProject()->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
QMessageBox::warning(this, tr("LeoCAD"), Ready.error());
|
||||
return;
|
||||
}
|
||||
lcGetActiveProject()->GetMainModel()->WaitForAssets();
|
||||
|
||||
lcInstructionsDialog* Dialog = new lcInstructionsDialog(this, lcGetActiveProject());
|
||||
Dialog->setWindowModality(Qt::ApplicationModal);
|
||||
@@ -1537,13 +1525,7 @@ void lcMainWindow::ShowInstructionsDialog()
|
||||
|
||||
void lcMainWindow::ShowPrintDialog()
|
||||
{
|
||||
const lcResult<void> Ready = lcGetActiveProject()->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
QMessageBox::warning(this, tr("LeoCAD"), Ready.error());
|
||||
return;
|
||||
}
|
||||
lcGetActiveProject()->GetMainModel()->WaitForAssets();
|
||||
|
||||
#ifndef QT_NO_PRINTER
|
||||
int PageCount = static_cast<int>(lcGetActiveProject()->GetInstructions()->mPages.size());
|
||||
|
||||
+94
-86
@@ -513,42 +513,13 @@ std::vector<lcPiece*> lcModel::GetRequiredSynthPieces() const
|
||||
return Required;
|
||||
}
|
||||
|
||||
lcResult<void> lcModel::EnsureAssetsReady() const
|
||||
void lcModel::WaitForAssets() const
|
||||
{
|
||||
const std::vector<PieceInfo*> Required = GetRequiredPieces();
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
if (!Library->EnsurePiecesReady(Required))
|
||||
{
|
||||
for (const PieceInfo* Info : Required)
|
||||
{
|
||||
if (Info->mState != lcPieceInfoState::Failed)
|
||||
continue;
|
||||
|
||||
const QString Error = Library->GetPieceLoadError(Info);
|
||||
|
||||
if (!Error.isEmpty())
|
||||
return lcUnexpected(Error);
|
||||
}
|
||||
|
||||
return lcUnexpected(tr("Could not load all required pieces."));
|
||||
}
|
||||
|
||||
const std::vector<lcPiece*> GeneratedPieces = GetRequiredSynthPieces();
|
||||
|
||||
if (!Library->EnsureSynthMeshesReady(GeneratedPieces))
|
||||
{
|
||||
for (const lcPiece* Piece : GeneratedPieces)
|
||||
if (!Piece->HasGeneratedMesh())
|
||||
{
|
||||
QString Error = Library->GetSynthMeshError(Piece);
|
||||
|
||||
if (Error.isEmpty())
|
||||
Error = tr("Could not generate geometry for piece '%1'.").arg(QString::fromLatin1(Piece->mPieceInfo->mFileName));
|
||||
|
||||
return lcUnexpected(Error);
|
||||
}
|
||||
}
|
||||
Library->EnsurePiecesReady(Required);
|
||||
Library->EnsureSynthMeshesReady(GetRequiredSynthPieces());
|
||||
|
||||
// Temporary minifigure and thumbnail models have no container piece to update.
|
||||
if (mPieceInfo)
|
||||
@@ -556,6 +527,40 @@ lcResult<void> lcModel::EnsureAssetsReady() const
|
||||
std::vector<lcModel*> UpdatedModels;
|
||||
const_cast<lcModel*>(this)->UpdatePieceInfo(UpdatedModels);
|
||||
}
|
||||
}
|
||||
|
||||
lcResult<void> lcModel::EnsureAssetsReady() const
|
||||
{
|
||||
WaitForAssets();
|
||||
|
||||
const std::vector<PieceInfo*> Required = GetRequiredPieces();
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
for (const PieceInfo* Info : Required)
|
||||
{
|
||||
if (Info->mState == lcPieceInfoState::Loaded)
|
||||
continue;
|
||||
|
||||
const QString Error = Library->GetPieceLoadError(Info);
|
||||
|
||||
if (!Error.isEmpty())
|
||||
return lcUnexpected(Error);
|
||||
|
||||
return lcUnexpected(tr("Could not load all required pieces."));
|
||||
}
|
||||
|
||||
const std::vector<lcPiece*> GeneratedPieces = GetRequiredSynthPieces();
|
||||
|
||||
for (const lcPiece* Piece : GeneratedPieces)
|
||||
if (!Piece->HasGeneratedMesh())
|
||||
{
|
||||
QString Error = Library->GetSynthMeshError(Piece);
|
||||
|
||||
if (Error.isEmpty())
|
||||
Error = tr("Could not generate geometry for piece '%1'.").arg(QString::fromLatin1(Piece->mPieceInfo->mFileName));
|
||||
|
||||
return lcUnexpected(Error);
|
||||
}
|
||||
|
||||
return lcResult<void>();
|
||||
}
|
||||
@@ -1690,15 +1695,7 @@ void lcModel::AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMat
|
||||
|
||||
QImage lcModel::GetStepImage(bool Zoom, int Width, int Height, lcStep Step)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
if (gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), Ready.error());
|
||||
|
||||
return QImage();
|
||||
}
|
||||
WaitForAssets();
|
||||
|
||||
const lcResult<QImage> Image = RenderStepImageWithReadyAssets(Zoom, Width, Height, Step, nullptr);
|
||||
|
||||
@@ -1729,12 +1726,12 @@ lcResult<QImage> lcModel::RenderStepImageWithReadyAssets(bool Zoom, int Width, i
|
||||
View.MakeCurrent();
|
||||
|
||||
if (!OutputCamera && !ActiveView)
|
||||
ZoomExtentsAtStep(View.GetCamera(), (float)Width / (float)Height, GetLastStep());
|
||||
ZoomExtentsAtStep(View.GetCamera(), (float)Width / (float)Height, GetLastStep(), lcGeometryBoundsMode::AvailableGeometryOnly);
|
||||
|
||||
SetTemporaryStep(Step);
|
||||
|
||||
if (Zoom && ActiveView && !OutputCamera)
|
||||
ZoomExtents(View.GetCamera(), (float)Width / (float)Height, lcMatrix44Identity());
|
||||
ZoomExtents(View.GetCamera(), (float)Width / (float)Height, lcMatrix44Identity(), lcGeometryBoundsMode::AvailableGeometryOnly);
|
||||
|
||||
if (!View.BeginRenderToImage(Width, Height))
|
||||
{
|
||||
@@ -1748,12 +1745,7 @@ lcResult<QImage> lcModel::RenderStepImageWithReadyAssets(bool Zoom, int Width, i
|
||||
|
||||
View.OnDraw();
|
||||
|
||||
QImage Image;
|
||||
|
||||
const bool MissingAssets = View.HasMissingAssets();
|
||||
|
||||
if (!MissingAssets)
|
||||
Image = View.GetRenderImage();
|
||||
QImage Image = View.GetRenderImage();
|
||||
|
||||
View.EndRenderToImage();
|
||||
|
||||
@@ -1762,23 +1754,15 @@ lcResult<QImage> lcModel::RenderStepImageWithReadyAssets(bool Zoom, int Width, i
|
||||
if (!mActive)
|
||||
CalculateStep(LC_STEP_MAX);
|
||||
|
||||
if (MissingAssets || Image.isNull())
|
||||
return lcUnexpected(tr("Could not render all required pieces."));
|
||||
if (Image.isNull())
|
||||
return lcUnexpected(tr("Error creating images."));
|
||||
|
||||
return Image;
|
||||
}
|
||||
|
||||
QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const
|
||||
QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor, bool KeepMissingParts) const
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
if (gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), Ready.error());
|
||||
|
||||
return QImage();
|
||||
}
|
||||
WaitForAssets();
|
||||
|
||||
lcPartsList PartsList;
|
||||
|
||||
@@ -1804,6 +1788,11 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundC
|
||||
|
||||
for (const auto& PartIt : PartsList)
|
||||
{
|
||||
const PieceInfo* Info = PartIt.first;
|
||||
|
||||
if (!KeepMissingParts && !Info->IsModel() && !Info->IsProject() && (Info->mState != lcPieceInfoState::Loaded || !Info->GetMesh()))
|
||||
continue;
|
||||
|
||||
for (const auto& ColorIt : PartIt.second)
|
||||
{
|
||||
Images.push_back(lcPartsListImage());
|
||||
@@ -1814,6 +1803,13 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundC
|
||||
}
|
||||
}
|
||||
|
||||
if (Images.empty())
|
||||
{
|
||||
QImage Image(1, 1, QImage::Format_ARGB32);
|
||||
Image.fill(lcQColorFromRGBA(BackgroundColor));
|
||||
return Image;
|
||||
}
|
||||
|
||||
auto ImageCompare = [](const lcPartsListImage& Image1, const lcPartsListImage& Image2)
|
||||
{
|
||||
if (Image1.ColorIndex != Image2.ColorIndex)
|
||||
@@ -1898,18 +1894,6 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundC
|
||||
|
||||
Scene.End();
|
||||
|
||||
if (Scene.HasMissingAssets())
|
||||
{
|
||||
View.UnbindRenderFramebuffer();
|
||||
View.EndRenderToImage();
|
||||
Context->ClearResources();
|
||||
|
||||
if (gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not render all required pieces."));
|
||||
|
||||
return QImage();
|
||||
}
|
||||
|
||||
Scene.Draw(Context);
|
||||
|
||||
View.UnbindRenderFramebuffer();
|
||||
@@ -1949,6 +1933,27 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundC
|
||||
|
||||
QtConcurrent::blockingMap(Images, CalculateImageBounds);
|
||||
|
||||
if (KeepMissingParts)
|
||||
{
|
||||
for (lcPartsListImage& Image : Images)
|
||||
if (Image.Bounds.isEmpty())
|
||||
Image.Bounds = QRect(0, 0, qMin(64, ThumbnailSize), qMin(64, ThumbnailSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
Images.erase(std::remove_if(Images.begin(), Images.end(), [](const lcPartsListImage& Image)
|
||||
{
|
||||
return Image.Bounds.isEmpty();
|
||||
}), Images.end());
|
||||
}
|
||||
|
||||
if (Images.empty())
|
||||
{
|
||||
QImage Image(1, 1, QImage::Format_ARGB32);
|
||||
Image.fill(lcQColorFromRGBA(BackgroundColor));
|
||||
return Image;
|
||||
}
|
||||
|
||||
QImage DummyImage(16, 16, QImage::Format_ARGB32);
|
||||
QPainter DummyPainter(&DummyImage);
|
||||
|
||||
@@ -2019,10 +2024,7 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundC
|
||||
|
||||
lcResult<void> lcModel::SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
WaitForAssets();
|
||||
|
||||
lcCamera OutputCamera(true);
|
||||
lcCamera* Camera = nullptr;
|
||||
@@ -2030,7 +2032,7 @@ lcResult<void> lcModel::SaveStepImages(const QString& BaseName, bool AddStepSuff
|
||||
if (!gMainWindow || !gMainWindow->GetActiveView())
|
||||
{
|
||||
OutputCamera.SetViewpoint(lcViewpoint::Home);
|
||||
ZoomExtentsAtStep(&OutputCamera, (float)Width / (float)Height, GetLastStep());
|
||||
ZoomExtentsAtStep(&OutputCamera, (float)Width / (float)Height, GetLastStep(), lcGeometryBoundsMode::AvailableGeometryOnly);
|
||||
Camera = &OutputCamera;
|
||||
}
|
||||
|
||||
@@ -2147,10 +2149,13 @@ void lcModel::SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector
|
||||
Piece->SubModelCompareBoundingBox(WorldMatrix, Min, Max);
|
||||
}
|
||||
|
||||
void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const
|
||||
void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const
|
||||
{
|
||||
const lcMesh* Mesh = mPieceInfo ? mPieceInfo->GetDisplayMesh() : nullptr;
|
||||
|
||||
if (Mode == lcGeometryBoundsMode::AvailableGeometryOnly && mPieceInfo && mPieceInfo->mState != lcPieceInfoState::Loaded)
|
||||
Mesh = nullptr;
|
||||
|
||||
if (Mesh)
|
||||
{
|
||||
lcVector3 Box[8];
|
||||
@@ -2162,7 +2167,7 @@ void lcModel::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::v
|
||||
|
||||
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
|
||||
if (Piece->IsVisibleInSubModel())
|
||||
Piece->SubModelAddBoundingBoxPoints(WorldMatrix, Points);
|
||||
Piece->SubModelAddBoundingBoxPoints(WorldMatrix, Points, Mode);
|
||||
}
|
||||
|
||||
void lcModel::AddSelectionHistory(std::function<void()> Callback)
|
||||
@@ -4819,11 +4824,14 @@ bool lcModel::GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const
|
||||
return Valid;
|
||||
}
|
||||
|
||||
std::vector<lcVector3> lcModel::GetPiecesBoundingBoxPoints() const
|
||||
std::vector<lcVector3> lcModel::GetPiecesBoundingBoxPoints(lcGeometryBoundsMode Mode) const
|
||||
{
|
||||
std::vector<lcVector3> Points;
|
||||
const lcMesh* Mesh = mPieceInfo ? mPieceInfo->GetDisplayMesh() : nullptr;
|
||||
|
||||
if (Mode == lcGeometryBoundsMode::AvailableGeometryOnly && mPieceInfo && mPieceInfo->mState != lcPieceInfoState::Loaded)
|
||||
Mesh = nullptr;
|
||||
|
||||
if (Mesh)
|
||||
{
|
||||
lcVector3 Box[8];
|
||||
@@ -4835,7 +4843,7 @@ std::vector<lcVector3> lcModel::GetPiecesBoundingBoxPoints() const
|
||||
|
||||
for (const std::unique_ptr<lcPiece>& Piece : mPieces)
|
||||
if (Piece->IsSelected() || Piece->IsVisible(mCurrentStep))
|
||||
Piece->SubModelAddBoundingBoxPoints(lcMatrix44Identity(), Points);
|
||||
Piece->SubModelAddBoundingBoxPoints(lcMatrix44Identity(), Points, Mode);
|
||||
|
||||
return Points;
|
||||
}
|
||||
@@ -5995,9 +6003,9 @@ void lcModel::MoveCamera(lcCamera* Camera, const lcVector3& Direction)
|
||||
}
|
||||
}
|
||||
|
||||
void lcModel::ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& WorldMatrix)
|
||||
void lcModel::ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& WorldMatrix, lcGeometryBoundsMode Mode)
|
||||
{
|
||||
std::vector<lcVector3> Points = GetPiecesBoundingBoxPoints();
|
||||
std::vector<lcVector3> Points = GetPiecesBoundingBoxPoints(Mode);
|
||||
|
||||
if (Points.empty())
|
||||
return;
|
||||
@@ -6034,12 +6042,12 @@ void lcModel::ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& Worl
|
||||
}
|
||||
}
|
||||
|
||||
void lcModel::ZoomExtentsAtStep(lcCamera* Camera, float Aspect, lcStep Step)
|
||||
void lcModel::ZoomExtentsAtStep(lcCamera* Camera, float Aspect, lcStep Step, lcGeometryBoundsMode Mode)
|
||||
{
|
||||
const lcStep CurrentStep = mCurrentStep;
|
||||
|
||||
SetTemporaryStep(Step);
|
||||
ZoomExtents(Camera, Aspect, lcMatrix44Identity());
|
||||
ZoomExtents(Camera, Aspect, lcMatrix44Identity(), Mode);
|
||||
SetTemporaryStep(CurrentStep);
|
||||
|
||||
if (!mActive)
|
||||
|
||||
+6
-5
@@ -183,6 +183,7 @@ public:
|
||||
void RefreshPreview() const;
|
||||
std::vector<PieceInfo*> GetRequiredPieces() const;
|
||||
std::vector<lcPiece*> GetRequiredSynthPieces() const;
|
||||
void WaitForAssets() const;
|
||||
lcResult<void> EnsureAssetsReady() const;
|
||||
|
||||
PieceInfo* GetPieceInfo() const
|
||||
@@ -331,7 +332,7 @@ public:
|
||||
void GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const;
|
||||
void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
|
||||
QImage GetStepImage(bool Zoom, int Width, int Height, lcStep Step);
|
||||
QImage GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const;
|
||||
QImage GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor, bool KeepMissingParts) const;
|
||||
lcResult<void> SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End);
|
||||
|
||||
void RayTest(lcObjectRayTest& ObjectRayTest) const;
|
||||
@@ -339,7 +340,7 @@ public:
|
||||
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const;
|
||||
bool SubModelBoxTest(const lcVector4 Planes[6]) const;
|
||||
void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
|
||||
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
|
||||
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const;
|
||||
|
||||
bool HasPieces() const
|
||||
{
|
||||
@@ -359,7 +360,7 @@ public:
|
||||
bool GetSelectionCenter(lcVector3& Center) const;
|
||||
lcBoundingBox GetAllPiecesBoundingBox() const;
|
||||
bool GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const;
|
||||
std::vector<lcVector3> GetPiecesBoundingBoxPoints() const;
|
||||
std::vector<lcVector3> GetPiecesBoundingBoxPoints(lcGeometryBoundsMode Mode) const;
|
||||
void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const;
|
||||
void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative) const;
|
||||
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
|
||||
@@ -423,8 +424,8 @@ public:
|
||||
void ZoomRegionToolClicked(lcView* View, float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners);
|
||||
void LookAt(lcCamera* Camera);
|
||||
void MoveCamera(lcCamera* Camera, const lcVector3& Direction);
|
||||
void ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& WorldMatrix);
|
||||
void ZoomExtentsAtStep(lcCamera* Camera, float Aspect, lcStep Step);
|
||||
void ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& WorldMatrix, lcGeometryBoundsMode Mode);
|
||||
void ZoomExtentsAtStep(lcCamera* Camera, float Aspect, lcStep Step, lcGeometryBoundsMode Mode);
|
||||
void Zoom(lcCamera* Camera, float Amount);
|
||||
|
||||
void MoveSelectedObjects(const lcVector3& Distance, lcModelTransformFlags Flags, lcModelHistoryEditMerge ModelHistoryEditMerge)
|
||||
|
||||
+7
-22
@@ -722,15 +722,7 @@ std::vector<lcObject*> lcView::FindObjectsInBox(float x1, float y1, float x2, fl
|
||||
std::vector<QImage> lcView::GetStepImages(lcStep Start, lcStep End)
|
||||
{
|
||||
std::vector<QImage> Images;
|
||||
const lcResult<void> Ready = mModel->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
{
|
||||
if (gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), Ready.error());
|
||||
|
||||
return Images;
|
||||
}
|
||||
mModel->WaitForAssets();
|
||||
|
||||
if (!BeginRenderToImage(mWidth, mHeight))
|
||||
{
|
||||
@@ -741,7 +733,7 @@ std::vector<QImage> lcView::GetStepImages(lcStep Start, lcStep End)
|
||||
}
|
||||
|
||||
const lcStep CurrentStep = mModel->GetCurrentStep();
|
||||
bool MissingAssets = false;
|
||||
bool RenderFailed = false;
|
||||
|
||||
for (lcStep Step = Start; Step <= End; Step++)
|
||||
{
|
||||
@@ -749,18 +741,11 @@ std::vector<QImage> lcView::GetStepImages(lcStep Start, lcStep End)
|
||||
|
||||
OnDraw();
|
||||
|
||||
if (HasMissingAssets())
|
||||
{
|
||||
MissingAssets = true;
|
||||
Images.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
QImage Image = GetRenderImage();
|
||||
|
||||
if (Image.isNull())
|
||||
{
|
||||
MissingAssets = true;
|
||||
RenderFailed = true;
|
||||
Images.clear();
|
||||
break;
|
||||
}
|
||||
@@ -775,8 +760,8 @@ std::vector<QImage> lcView::GetStepImages(lcStep Start, lcStep End)
|
||||
if (!mModel->IsActive())
|
||||
mModel->CalculateStep(LC_STEP_MAX);
|
||||
|
||||
if (MissingAssets && gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Could not render all required pieces."));
|
||||
if (RenderFailed && gMainWindow)
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images."));
|
||||
|
||||
return Images;
|
||||
}
|
||||
@@ -786,7 +771,7 @@ lcResult<void> lcView::SaveStepImages(const QString& BaseName, bool AddStepSuffi
|
||||
std::vector<QImage> Images = GetStepImages(Start, End);
|
||||
|
||||
if (Images.size() != static_cast<size_t>(End - Start + 1))
|
||||
return lcUnexpected(tr("Could not render all required pieces."));
|
||||
return lcUnexpected(tr("Error creating images."));
|
||||
|
||||
for (lcStep Step = Start; Step <= End; Step++)
|
||||
{
|
||||
@@ -1959,7 +1944,7 @@ void lcView::ZoomExtents()
|
||||
{
|
||||
const lcMatrix44 WorldMatrix = mActiveSubmodelInstance ? mActiveSubmodelTransform : lcMatrix44Identity();
|
||||
|
||||
ActiveModel->ZoomExtents(mCamera, (float)mWidth / (float)mHeight, WorldMatrix);
|
||||
ActiveModel->ZoomExtents(mCamera, (float)mWidth / (float)mHeight, WorldMatrix, lcGeometryBoundsMode::IncludeFallbackGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -1074,7 +1074,10 @@ void lcPiece::AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade
|
||||
}
|
||||
|
||||
if (mPieceInfo->GetSynthInfo() && !HasGeneratedMesh() && Scene->GetRequireGeneratedMeshes())
|
||||
{
|
||||
Scene->MarkMissingAssets();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSynthPending && Scene->GetRequireCompleteAssets())
|
||||
Scene->MarkMissingAssets();
|
||||
@@ -1102,7 +1105,10 @@ void lcPiece::AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMat
|
||||
RenderMeshState = IsFocused() ? lcRenderMeshState::Focused : (IsSelected() ? lcRenderMeshState::Selected : lcRenderMeshState::Default);
|
||||
|
||||
if (mPieceInfo->GetSynthInfo() && !HasGeneratedMesh() && Scene->GetRequireGeneratedMeshes())
|
||||
{
|
||||
Scene->MarkMissingAssets();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSynthPending && Scene->GetRequireCompleteAssets())
|
||||
Scene->MarkMissingAssets();
|
||||
@@ -1137,12 +1143,15 @@ void lcPiece::SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector
|
||||
}
|
||||
}
|
||||
|
||||
void lcPiece::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const
|
||||
void lcPiece::SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const
|
||||
{
|
||||
if (Mode == lcGeometryBoundsMode::AvailableGeometryOnly && mPieceInfo->GetSynthInfo() && !HasGeneratedMesh())
|
||||
return;
|
||||
|
||||
lcMesh* Mesh = GetDisplayMesh();
|
||||
|
||||
if (!Mesh || mPieceInfo->IsLoading())
|
||||
mPieceInfo->AddSubModelBoundingBoxPoints(lcMul(mModelWorld, WorldMatrix), Points);
|
||||
mPieceInfo->AddSubModelBoundingBoxPoints(lcMul(mModelWorld, WorldMatrix), Points, Mode);
|
||||
else
|
||||
{
|
||||
lcVector3 BoxPoints[8];
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public:
|
||||
void AddMainModelRenderMeshes(lcScene* Scene, bool Highlight, bool Fade) const;
|
||||
void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
|
||||
void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
|
||||
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
|
||||
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const;
|
||||
|
||||
void InsertTime(lcStep Start, lcStep Time);
|
||||
void RemoveTime(lcStep Start, lcStep Time);
|
||||
|
||||
+22
-2
@@ -420,8 +420,28 @@ void PieceInfo::CompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min
|
||||
}
|
||||
}
|
||||
|
||||
void PieceInfo::AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const
|
||||
void PieceInfo::AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const
|
||||
{
|
||||
if (Mode == lcGeometryBoundsMode::AvailableGeometryOnly)
|
||||
{
|
||||
if (IsModel())
|
||||
{
|
||||
mModel->SubModelAddBoundingBoxPoints(WorldMatrix, Points, Mode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsProject())
|
||||
{
|
||||
if (const lcModel* Model = mProject->GetMainModel())
|
||||
Model->SubModelAddBoundingBoxPoints(WorldMatrix, Points, Mode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState != lcPieceInfoState::Loaded || !mMesh)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsModel())
|
||||
{
|
||||
lcVector3 BoxPoints[8];
|
||||
@@ -436,7 +456,7 @@ void PieceInfo::AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std:
|
||||
}
|
||||
else
|
||||
{
|
||||
mModel->SubModelAddBoundingBoxPoints(WorldMatrix, Points);
|
||||
mModel->SubModelAddBoundingBoxPoints(WorldMatrix, Points, Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -194,7 +194,7 @@ public:
|
||||
void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const;
|
||||
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
|
||||
void CompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
|
||||
void AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
|
||||
void AddSubModelBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points, lcGeometryBoundsMode Mode) const;
|
||||
void UpdateBoundingBox(std::vector<lcModel*>& UpdatedModels);
|
||||
|
||||
void Unload();
|
||||
|
||||
+36
-77
@@ -1123,13 +1123,15 @@ bool Project::ImportInventory(const std::vector<lcSetInventoryItem>& SetInventor
|
||||
return true;
|
||||
}
|
||||
|
||||
lcResult<std::vector<lcModelPartsEntry>> Project::GetModelParts()
|
||||
std::vector<lcModelPartsEntry> Project::GetModelParts()
|
||||
{
|
||||
std::vector<lcModelPartsEntry> ModelParts;
|
||||
|
||||
if (mModels.empty())
|
||||
return ModelParts;
|
||||
|
||||
mModels[0]->WaitForAssets();
|
||||
|
||||
for (const std::unique_ptr<lcModel>& Model : mModels)
|
||||
Model->CalculateStep(LC_STEP_MAX);
|
||||
|
||||
@@ -1137,13 +1139,14 @@ lcResult<std::vector<lcModelPartsEntry>> Project::GetModelParts()
|
||||
|
||||
SetActiveModel(mActiveModel, false);
|
||||
|
||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||
ModelParts.erase(std::remove_if(ModelParts.begin(), ModelParts.end(), [](const lcModelPartsEntry& ModelPart)
|
||||
{
|
||||
if (ModelPart.Info->GetSynthInfo() && !ModelPart.Mesh)
|
||||
return lcUnexpected(tr("Could not generate geometry for piece '%1'.").arg(QString::fromLatin1(ModelPart.Info->mFileName)));
|
||||
}
|
||||
return ModelPart.Info->mState != lcPieceInfoState::Loaded ||
|
||||
(ModelPart.Info->GetSynthInfo() && !ModelPart.Mesh) ||
|
||||
(!ModelPart.Mesh && !ModelPart.Info->GetMesh());
|
||||
}), ModelParts.end());
|
||||
|
||||
return std::move(ModelParts);
|
||||
return ModelParts;
|
||||
}
|
||||
|
||||
std::vector<PieceInfo*> Project::GetRequiredPieces() const
|
||||
@@ -1379,20 +1382,7 @@ QString Project::GetExportFileName(const QString& FileName, const QString& Defau
|
||||
|
||||
lcResult<void> Project::Export3DStudio(const QString& FileName)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
|
||||
const lcResult<std::vector<lcModelPartsEntry>> ModelPartsResult = GetModelParts();
|
||||
|
||||
if (!ModelPartsResult)
|
||||
return lcUnexpected(ModelPartsResult.error());
|
||||
|
||||
const std::vector<lcModelPartsEntry>& ModelParts = ModelPartsResult.value();
|
||||
|
||||
if (ModelParts.empty())
|
||||
return lcUnexpected(tr("Nothing to export."));
|
||||
const std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
|
||||
|
||||
QString SaveFileName = GetExportFileName(FileName, "3ds", tr("Export 3D Studio"), tr("3DS Files (*.3ds);;All Files (*.*)"));
|
||||
|
||||
@@ -1842,20 +1832,7 @@ lcResult<void> Project::ExportBrickLink()
|
||||
|
||||
lcResult<void> Project::ExportCOLLADA(const QString& FileName)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
|
||||
const lcResult<std::vector<lcModelPartsEntry>> ModelPartsResult = GetModelParts();
|
||||
|
||||
if (!ModelPartsResult)
|
||||
return lcUnexpected(ModelPartsResult.error());
|
||||
|
||||
const std::vector<lcModelPartsEntry>& ModelParts = ModelPartsResult.value();
|
||||
|
||||
if (ModelParts.empty())
|
||||
return lcUnexpected(tr("Nothing to export."));
|
||||
const std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
|
||||
|
||||
QString SaveFileName = GetExportFileName(FileName, "dae", tr("Export COLLADA"), tr("COLLADA Files (*.dae);;All Files (*.*)"));
|
||||
|
||||
@@ -2209,12 +2186,7 @@ lcResult<void> Project::ExportHTML(const lcHTMLExportOptions& Options)
|
||||
}
|
||||
|
||||
for (const lcModel* Model : Models)
|
||||
{
|
||||
const lcResult<void> Ready = Model->EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
}
|
||||
Model->WaitForAssets();
|
||||
|
||||
QDir Dir(Options.PathName);
|
||||
Dir.mkpath(QLatin1String("."));
|
||||
@@ -2285,7 +2257,7 @@ lcResult<void> Project::ExportHTML(const lcHTMLExportOptions& Options)
|
||||
if (PartsList.empty())
|
||||
return lcResult<void>();
|
||||
|
||||
QImage Image = Model->GetPartsListImage(1024, Step, LC_RGBA(255, 255, 255, 0), QFont("Arial", 16, QFont::Bold), Qt::black);
|
||||
QImage Image = Model->GetPartsListImage(1024, Step, LC_RGBA(255, 255, 255, 0), QFont("Arial", 16, QFont::Bold), Qt::black, true);
|
||||
|
||||
if (Image.isNull())
|
||||
return lcUnexpected(tr("Could not render the pieces list image."));
|
||||
@@ -2493,20 +2465,7 @@ lcResult<void> Project::ExportHTML(const lcHTMLExportOptions& Options)
|
||||
|
||||
lcResult<void> Project::ExportPOVRay(const QString& FileName)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
|
||||
const lcResult<std::vector<lcModelPartsEntry>> ModelPartsResult = GetModelParts();
|
||||
|
||||
if (!ModelPartsResult)
|
||||
return lcUnexpected(ModelPartsResult.error());
|
||||
|
||||
const std::vector<lcModelPartsEntry>& ModelParts = ModelPartsResult.value();
|
||||
|
||||
if (ModelParts.empty())
|
||||
return lcUnexpected(tr("Nothing to export."));
|
||||
const std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
|
||||
|
||||
QString SaveFileName = GetExportFileName(FileName, QLatin1String("pov"), tr("Export POV-Ray"), tr("POV-Ray Files (*.pov);;All Files (*.*)"));
|
||||
|
||||
@@ -2588,11 +2547,18 @@ lcResult<void> Project::ExportPOVRay(const QString& FileName)
|
||||
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
lcVector3 Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
|
||||
if (ModelParts.empty())
|
||||
{
|
||||
Min = lcVector3(-10.0f, -10.0f, -10.0f);
|
||||
Max = lcVector3(10.0f, 10.0f, 10.0f);
|
||||
}
|
||||
|
||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||
{
|
||||
lcVector3 Points[8];
|
||||
|
||||
lcGetBoxCorners(ModelPart.Info->GetBoundingBox(), Points);
|
||||
const lcMesh* Mesh = ModelPart.Mesh ? ModelPart.Mesh : ModelPart.Info->GetMesh();
|
||||
lcGetBoxCorners(Mesh->mBoundingBox, Points);
|
||||
|
||||
for (int PointIdx = 0; PointIdx < 8; PointIdx++)
|
||||
{
|
||||
@@ -3150,8 +3116,11 @@ lcResult<void> Project::ExportPOVRay(const QString& FileName)
|
||||
POVFile.WriteLine(Line);
|
||||
}
|
||||
|
||||
snprintf(Line, sizeof(Line), "#declare %s = union {\n", TopModelName.toLatin1().constData());
|
||||
POVFile.WriteLine(Line);
|
||||
if (!ModelParts.empty())
|
||||
{
|
||||
snprintf(Line, sizeof(Line), "#declare %s = union {\n", TopModelName.toLatin1().constData());
|
||||
POVFile.WriteLine(Line);
|
||||
}
|
||||
|
||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||
{
|
||||
@@ -3205,12 +3174,15 @@ lcResult<void> Project::ExportPOVRay(const QString& FileName)
|
||||
POVFile.WriteLine(Line);
|
||||
}
|
||||
|
||||
snprintf(Line, sizeof(Line), "\n #if (ModelReflection = 0)\n no_reflection\n #end\n #if (ModelShadow = 0)\n no_shadow\n #end\n}\n\n");
|
||||
POVFile.WriteLine(Line);
|
||||
if (!ModelParts.empty())
|
||||
{
|
||||
snprintf(Line, sizeof(Line), "\n #if (ModelReflection = 0)\n no_reflection\n #end\n #if (ModelShadow = 0)\n no_shadow\n #end\n}\n\n");
|
||||
POVFile.WriteLine(Line);
|
||||
|
||||
snprintf(Line, sizeof(Line), "object {\n %s\n %s { %s }\n}\n\n",
|
||||
TopModelName.toLatin1().constData(), (UseLGEO ? "material" : "texture"), ColorTable[lcGetColorIndex(TopModelColorCode)].data());
|
||||
POVFile.WriteLine(Line);
|
||||
snprintf(Line, sizeof(Line), "object {\n %s\n %s { %s }\n}\n\n",
|
||||
TopModelName.toLatin1().constData(), (UseLGEO ? "material" : "texture"), ColorTable[lcGetColorIndex(TopModelColorCode)].data());
|
||||
POVFile.WriteLine(Line);
|
||||
}
|
||||
|
||||
snprintf(Line, sizeof(Line), "#if (Floor)\n object {\n plane { FloorAxis, FloorLocation hollow }\n texture {\n pigment { color srgb FloorColor }\n finish { emission 0 ambient FloorAmbient diffuse FloorDiffuse }\n }\n }\n#end\n");
|
||||
POVFile.WriteLine(Line);
|
||||
@@ -3226,20 +3198,7 @@ lcResult<void> Project::ExportPOVRay(const QString& FileName)
|
||||
|
||||
lcResult<void> Project::ExportWavefront(const QString& FileName)
|
||||
{
|
||||
const lcResult<void> Ready = EnsureAssetsReady();
|
||||
|
||||
if (!Ready)
|
||||
return Ready;
|
||||
|
||||
const lcResult<std::vector<lcModelPartsEntry>> ModelPartsResult = GetModelParts();
|
||||
|
||||
if (!ModelPartsResult)
|
||||
return lcUnexpected(ModelPartsResult.error());
|
||||
|
||||
const std::vector<lcModelPartsEntry>& ModelParts = ModelPartsResult.value();
|
||||
|
||||
if (ModelParts.empty())
|
||||
return lcUnexpected(tr("Nothing to export."));
|
||||
const std::vector<lcModelPartsEntry> ModelParts = GetModelParts();
|
||||
|
||||
QString SaveFileName = GetExportFileName(FileName, QLatin1String("obj"), tr("Export Wavefront"), tr("Wavefront Files (*.obj);;All Files (*.*)"));
|
||||
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ protected:
|
||||
static bool CanShareMergePiece(const PieceInfo* Existing, const PieceInfo* Incoming);
|
||||
QString GetExportFileName(const QString& FileName, const QString& DefaultExtension, const QString& DialogTitle, const QString& DialogFilter) const;
|
||||
|
||||
lcResult<std::vector<lcModelPartsEntry>> GetModelParts();
|
||||
std::vector<lcModelPartsEntry> GetModelParts();
|
||||
void SetFileName(const QString& FileName);
|
||||
|
||||
bool mIsPreview;
|
||||
|
||||
@@ -234,22 +234,14 @@ void lcRenderDialog::RenderPOVRay()
|
||||
ui->RenderProgress->setValue(ui->RenderProgress->minimum());
|
||||
ui->RenderProgress->setFormat(tr("Exporting Model"));
|
||||
|
||||
QFuture<lcResult<void>> ExportThread = QtConcurrent::run([FileName]()
|
||||
{
|
||||
return lcGetActiveProject()->ExportPOVRay(FileName);
|
||||
});
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
while (!ExportThread.isFinished())
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
lcResult<void> ExportResult = lcGetActiveProject()->ExportPOVRay(FileName);
|
||||
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
|
||||
ui->RenderProgress->setFormat("%p%");
|
||||
|
||||
lcResult<void> ExportResult = ExportThread.result();
|
||||
|
||||
if (!ExportResult)
|
||||
{
|
||||
if (!ExportResult.error().isEmpty())
|
||||
|
||||
Reference in new issue
Block a user