diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 59a1ad1e..754c6014 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -263,7 +263,7 @@ void lcModel::UpdatePieceInfo(std::vector& UpdatedModels) mPieceInfo->SetBoundingBox(Min, Max); } -void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const +void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep CurrentStep) const { const QLatin1String LineEnding("\r\n"); @@ -273,12 +273,16 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const lcStep Step = 1; int CurrentLine = 0; int AddedSteps = 0; + bool Saved = false; for (lcPiece* Piece : mPieces) { if (SelectedOnly && !Piece->IsSelected()) continue; + if ((Saved = CurrentStep && Piece->GetStepShow() > CurrentStep)) + break; + while (Piece->GetFileLine() > CurrentLine && CurrentLine < mFileLines.size()) { QString Line = mFileLines[CurrentLine]; @@ -391,7 +395,7 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const Stream << QLatin1String("0 !LEOCAD SYNTH END\r\n"); } - while (CurrentLine < mFileLines.size()) + while ( !Saved && CurrentLine < mFileLines.size()) { QString Line = mFileLines[CurrentLine]; QTextStream LineStream(&Line, QIODevice::ReadOnly); @@ -3323,11 +3327,11 @@ void lcModel::GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSu } } -void lcModel::GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList) const +void lcModel::GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative) const { for (const lcPiece* Piece : mPieces) { - if (Piece->GetStepShow() != Step || Piece->IsHidden()) + if (Cumulative ? Piece->GetStepShow() > Step : Piece->GetStepShow() != Step || Piece->IsHidden()) continue; int ColorIndex = Piece->GetColorIndex(); diff --git a/common/lc_model.h b/common/lc_model.h index b9637ef4..da4c7a0f 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -205,7 +205,7 @@ public: void RemoveFocusPieceFromGroup(); void ShowEditGroupsDialog(); - void SaveLDraw(QTextStream& Stream, bool SelectedOnly) const; + void SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep CurrentStep = 0) const; void LoadLDraw(QIODevice& Device, Project* Project); bool LoadBinary(lcFile* File); bool LoadLDD(const QString& FileData); @@ -263,7 +263,7 @@ public: bool GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const; std::vector GetPiecesBoundingBoxPoints() const; void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const; - void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList) const; + void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative = false) const; void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector& ModelParts) const; void GetSelectionInformation(int* Flags, lcArray& Selection, lcObject** Focus) const; lcArray GetSelectionModePieces(const lcPiece* SelectedPiece) const; diff --git a/common/project.cpp b/common/project.cpp index 19b634ec..89733b72 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -652,6 +652,109 @@ std::vector Project::GetModelParts() return ModelParts; } +bool 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; + } + + QStringList Models; + + Models.append(lcGetActiveModel()->GetProperties().mFileName); + + std::function ParseStepModel = [&](const QString& ModelName) + { + Models.append(ModelName); + + for (lcModel* Model : mModels) + { + if (Model->GetProperties().mFileName == ModelName) + { + lcPartsList ModelParts; + + Model->GetPartsList(gDefaultColor, false, true, ModelParts); + + for (const auto& PartIt : ModelParts) + { + const PieceInfo* PartInfo = PartIt.first; + + if (PartInfo->IsModel()) + { + ParseStepModel(PartInfo->mFileName); + } + else + continue; + } + + break; + } + } + }; + + const lcStep CurrentStep = lcGetActiveModel()->GetCurrentStep(); + + bool MPD = mModels.GetSize() > 1; + + if (MPD) + { + lcPartsList StepParts; + + lcGetActiveModel()->GetPartsListForStep(CurrentStep, gDefaultColor, StepParts, true); + + if (!StepParts.empty()) + { + for (const auto& PartIt : StepParts) + { + const PieceInfo *PartInfo = PartIt.first; + + if (PartInfo->IsModel()) + { + ParseStepModel(PartInfo->mFileName); + } + else + continue; + } + } + } + + QTextStream Stream(&File); + + for (lcModel* Model : mModels) + { + if (!Models.contains(Model->GetProperties().mFileName)) + continue; + + const lcStep ModelStep = Model->GetCurrentStep(); + + if (!Model->IsActive()) + Model->SetTemporaryStep(CurrentStep); + + if (MPD) + Stream << QLatin1String("0 FILE ") << Model->GetProperties().mFileName << QLatin1String("\r\n"); + + Model->SaveLDraw(Stream, false, CurrentStep); + + if (MPD) + Stream << QLatin1String("0 NOFILE\r\n"); + + if (!Model->IsActive()) + { + Model->SetTemporaryStep(ModelStep); + Model->CalculateStep(LC_STEP_MAX); + } + } + + File.close(); + + lcSetProfileString(LC_PROFILE_PROJECTS_PATH, QFileInfo(FileName).absolutePath()); + + return true; +} + bool Project::ExportModel(const QString& FileName, lcModel* Model) const { QFile File(FileName); diff --git a/common/project.h b/common/project.h index e40efdcf..8b941e0c 100644 --- a/common/project.h +++ b/common/project.h @@ -89,6 +89,7 @@ public: bool ImportInventory(const QByteArray& Inventory, const QString& Name, const QString& Description); void SaveImage(); + bool ExportCurrentStep(const QString& FileName); bool ExportModel(const QString& FileName, lcModel* Model) const; bool Export3DStudio(const QString& FileName); void ExportBrickLink();