Files
leocad/common/lc_instructions.cpp
T
Leonardo Zide 8e2490c4ba Open LDraw and LDD projects without waiting for meshes
Queue model geometry builds and mesh conversion on workers so project opening can return after parsing. Keep complete-asset waits for previews and output, and show project loading progress in the status bar.

Preserve live pieces when project names overlap, restore mappings after failed loads, and include detached pieces in buffer and stud-style updates.
2026-09-27 10:59:34 -07:00

257 lines
7.2 KiB
C++

#include "lc_global.h"
#include "lc_instructions.h"
#include "project.h"
#include "lc_model.h"
#include "piece.h"
#include "pieceinf.h"
const float lcInstructions::mDisplayDPI = 72.0f;
lcInstructions::lcInstructions(Project* Project)
: mProject(Project)
{
mPageSetup.Width = 8.5f * mDisplayDPI;
mPageSetup.Height = 11.0f * mDisplayDPI;
mPageSetup.MarginLeft = 0.5 * mDisplayDPI;
mPageSetup.MarginRight = 0.5 * mDisplayDPI;
mPageSetup.MarginTop = 0.5 * mDisplayDPI;
mPageSetup.MarginBottom = 0.5 * mDisplayDPI;
mPageSettings.Rows = 1;
mPageSettings.Columns = 1;
mPageSettings.Direction = lcInstructionsDirection::Horizontal;
mStepProperties[static_cast<int>(lcInstructionsPropertyType::ShowStepNumber)].Value = true;
mStepProperties[static_cast<int>(lcInstructionsPropertyType::ShowStepPLI)].Value = true;
mStepProperties[static_cast<int>(lcInstructionsPropertyType::StepNumberFont)].Value = QFont("Arial", 72).toString();
mStepProperties[static_cast<int>(lcInstructionsPropertyType::StepNumberColor)].Value = LC_RGBA(0, 0, 0, 255);
mStepProperties[static_cast<int>(lcInstructionsPropertyType::StepBackgroundColor)].Value = LC_RGBA(255, 255, 255, 0);
mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLIBackgroundColor)].Value = LC_RGBA(255, 255, 255, 255);
mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLIFont)].Value = QFont("Arial", 16, QFont::Bold).toString();
mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLITextColor)].Value = LC_RGBA(0, 0, 0, 255);
mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLIBorderColor)].Value = LC_RGBA(0, 0, 0, 255);
// mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLIBorderWidth)].Value = 2.0f;
// mStepProperties[static_cast<int>(lcInstructionsPropertyType::PLIBorderRound)].Value = true;
static_assert(static_cast<int>(lcInstructionsPropertyType::Count) == 9, "Missing default property");
CreatePages();
}
QString lcInstructions::GetPropertyLabel(lcInstructionsPropertyType Type)
{
switch (Type)
{
case lcInstructionsPropertyType::ShowStepNumber:
return tr("Show Step Number");
case lcInstructionsPropertyType::ShowStepPLI:
return tr("Show Pieces List");
case lcInstructionsPropertyType::StepNumberFont:
return tr("Font:");
case lcInstructionsPropertyType::StepNumberColor:
return tr("Text Color:");
case lcInstructionsPropertyType::StepBackgroundColor:
return tr("Background Color:");
case lcInstructionsPropertyType::PLIBackgroundColor:
return tr("Background Color:");
case lcInstructionsPropertyType::PLIFont:
return tr("Font:");
case lcInstructionsPropertyType::PLITextColor:
return tr("Text Color:");
case lcInstructionsPropertyType::PLIBorderColor:
return tr("Border Color:");
case lcInstructionsPropertyType::Count:
break;
}
return QString();
}
void lcInstructions::SetDefaultPageSettings(const lcInstructionsPageSettings& PageSettings)
{
mPageSettings = PageSettings;
CreatePages();
}
bool lcInstructions::GetBoolProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const
{
QVariant Value = GetProperty(Type, Model, Step);
return Value.toBool();
}
QColor lcInstructions::GetColorProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const
{
QVariant Value = GetProperty(Type, Model, Step);
return lcQColorFromRGBA(Value.toUInt());
}
QFont lcInstructions::GetFontProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const
{
QVariant Value = GetProperty(Type, Model, Step);
QFont Font;
Font.fromString(Value.toString());
return Font;
}
QVariant lcInstructions::GetProperty(lcInstructionsPropertyType Type, lcModel* Model, lcStep Step) const
{
QVariant Value = mStepProperties[static_cast<int>(Type)].Value;
std::map<lcModel*, lcInstructionsModel>::const_iterator ModelIt = mModels.find(Model);
if (ModelIt == mModels.end())
return Value;
const lcInstructionsModel& InstructionModel = ModelIt->second;
for (lcStep StepIndex = 0; StepIndex <= Step; StepIndex++)
{
const lcInstructionsProperties& Properties = InstructionModel.StepProperties[StepIndex];
const lcInstructionsProperty& Property = Properties[static_cast<int>(Type)];
if (Property.Mode == lcInstructionsPropertyMode::NotSet || (Property.Mode == lcInstructionsPropertyMode::StepOnly && StepIndex != Step))
continue;
Value = Property.Value;
}
return Value;
}
void lcInstructions::SetDefaultBool(lcInstructionsPropertyType Type, bool Enabled)
{
SetDefaultProperty(Type, Enabled);
}
void lcInstructions::SetDefaultColor(lcInstructionsPropertyType Type, const QColor& Color)
{
SetDefaultProperty(Type, lcRGBAFromQColor(Color));
}
void lcInstructions::SetDefaultFont(lcInstructionsPropertyType Type, const QFont& Font)
{
SetDefaultProperty(Type, Font.toString());
}
void lcInstructions::SetDefaultProperty(lcInstructionsPropertyType Type, const QVariant& Value)
{
lcInstructionsProperty& Property = mStepProperties[static_cast<int>(Type)];
if (Property.Value == Value)
return;
Property.Value = Value;
emit StepSettingsChanged(nullptr, 0);
}
void lcInstructions::CreatePages()
{
mPages.clear();
if (mProject)
{
std::vector<const lcModel*> AddedModels;
lcModel* Model = mProject->GetMainModel();
if (Model)
AddDefaultPages(Model, AddedModels);
}
}
void lcInstructions::AddDefaultPages(lcModel* Model, std::vector<const lcModel*>& AddedModels)
{
if (std::find(AddedModels.begin(), AddedModels.end(), Model) != AddedModels.end())
return;
AddedModels.push_back(Model);
const lcStep LastStep = Model->GetLastStep();
lcInstructionsPage Page;
int Row = 0, Column = 0;
lcInstructionsModel InstructionModel;
InstructionModel.StepProperties.resize(LastStep + 1);
mModels.emplace(Model, std::move(InstructionModel));
for (lcStep Step = 1; Step <= LastStep; Step++)
{
std::set<lcModel*> StepSubModels;
for (const std::unique_ptr<lcPiece>& Piece : Model->GetPieces())
{
if (!Piece->IsHidden() && Piece->GetStepShow() == Step && Piece->mPieceInfo->IsModel())
{
lcModel* SubModel = Piece->mPieceInfo->GetModel();
if (std::find(AddedModels.begin(), AddedModels.end(), SubModel) == AddedModels.end())
StepSubModels.insert(SubModel);
}
}
if (!StepSubModels.empty())
{
if (!Page.Steps.empty())
{
mPages.emplace_back(std::move(Page));
Row = 0;
Column = 0;
}
for (lcModel* SubModel : StepSubModels)
AddDefaultPages(SubModel, AddedModels);
}
lcInstructionsStep InstructionsStep;
InstructionsStep.Model = Model;
InstructionsStep.Step = Step;
const double Width = 1.0 / (double)mPageSettings.Columns;
const double Height = 1.0 / (double)mPageSettings.Rows;
InstructionsStep.Rect = QRectF(Column * Width, Row * Height, Width, Height);
Page.Steps.push_back(std::move(InstructionsStep));
if (mPageSettings.Direction == lcInstructionsDirection::Horizontal)
{
Column++;
if (Column == mPageSettings.Columns)
{
Row++;
Column = 0;
}
if (Row == mPageSettings.Rows)
{
mPages.emplace_back(std::move(Page));
Row = 0;
Column = 0;
}
}
else
{
Row++;
if (Row == mPageSettings.Rows)
{
Row = 0;
Column++;
}
if (Column == mPageSettings.Columns)
{
mPages.emplace_back(std::move(Page));
Row = 0;
Column = 0;
}
}
}
if (!Page.Steps.empty())
mPages.emplace_back(std::move(Page));
}