diff --git a/common/lc_library.cpp b/common/lc_library.cpp index 276dd5c1..33e12813 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -921,10 +921,8 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info) if (!Loaded && !mCurrentModelPath.isEmpty()) { - QFileInfo FileInfo(QDir(mCurrentModelPath), Info->m_strName); - - lcDiskFile PieceFile; - if (PieceFile.Open(FileInfo.absoluteFilePath().toLatin1().constData(), "rt")) // todo: qstring + lcMemFile PieceFile; + if (LoadAndInlineFile(Info->m_strName, PieceFile)) { const char* OldLocale = setlocale(LC_NUMERIC, "C"); Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, false); @@ -1408,6 +1406,32 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex) return true; } +bool lcPiecesLibrary::LoadAndInlineFile(const char* FileName, lcMemFile& File) +{ + QFileInfo FileInfo(QDir(mCurrentModelPath), FileName); + + if (!FileInfo.isFile()) + return false; + + Project TempProject; + + if (!TempProject.Load(FileInfo.absoluteFilePath())) + return false; + + TempProject.InlineAllModels(); + + QByteArray Data; + QTextStream Stream(&Data); + TempProject.Save(Stream); + Stream.flush(); + + File.Seek(0, SEEK_SET); + File.WriteBuffer(Data.constData(), Data.size()); + File.Seek(0, SEEK_SET); + + return true; +} + bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize) { char Buffer[1024]; @@ -1667,7 +1691,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf if (strcmp(Info->m_strName, FileName)) continue; - if (mZipFiles[LC_ZIPFILE_OFFICIAL]) + if (mZipFiles[LC_ZIPFILE_OFFICIAL] && Info->mZipFileType != LC_NUM_ZIPFILES) { lcMemFile IncludeFile; @@ -1693,13 +1717,11 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf if (!Loaded && !mCurrentModelPath.isEmpty()) { - QFileInfo FileInfo(QDir(mCurrentModelPath), OriginalFileName); - - lcDiskFile IncludeFile; - if (IncludeFile.Open(FileInfo.absoluteFilePath().toLatin1().constData(), "rt")) // todo: qstring + lcMemFile IncludeFile; + if (LoadAndInlineFile(OriginalFileName, IncludeFile)) { const char* OldLocale = setlocale(LC_NUMERIC, "C"); - Loaded = ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize); + Loaded = ReadMeshData(File, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize); setlocale(LC_NUMERIC, OldLocale); } } diff --git a/common/lc_library.h b/common/lc_library.h index 53d77163..d154de13 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -186,6 +186,7 @@ protected: int FindPrimitiveIndex(const char* Name) const; bool LoadPrimitive(int PrimitiveIndex); + bool LoadAndInlineFile(const char* FileName, lcMemFile& File); QString mCachePath; QString mCurrentModelPath; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index bc4470ca..9f143f44 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -2180,6 +2180,50 @@ void lcModel::MoveSelectionToModel(lcModel* Model) ClearSelectionAndSetFocus(ModelPiece, LC_PIECE_SECTION_POSITION); } +void lcModel::InlineAllModels() +{ + for (;;) + { + bool Inlined = false; + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); ) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (!Piece->mPieceInfo->IsModel()) + { + PieceIdx++; + continue; + } + + mPieces.RemoveIndex(PieceIdx); + + lcArray ModelParts; + Piece->mPieceInfo->GetModelParts(Piece->mModelWorld, Piece->mColorIndex, ModelParts); + + for (int InsertIdx = 0; InsertIdx < ModelParts.GetSize(); InsertIdx++) + { + lcModelPartsEntry& Entry = ModelParts[InsertIdx]; + + lcPiece* NewPiece = new lcPiece(Entry.Info); + + NewPiece->Initialize(Entry.WorldMatrix, Piece->GetStepShow()); + NewPiece->SetColorIndex(Entry.ColorIndex); + NewPiece->UpdatePosition(mCurrentStep); + + InsertPiece(NewPiece, PieceIdx); + PieceIdx++; + } + + delete Piece; + Inlined = true; + } + + if (!Inlined) + break; + } +} + void lcModel::InlineSelectedModels() { lcArray NewPieces; diff --git a/common/lc_model.h b/common/lc_model.h index 6ff4b471..deea451f 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -188,6 +188,7 @@ public: void SetPieceSteps(const QList>& PieceSteps); void MoveSelectionToModel(lcModel* Model); + void InlineAllModels(); void InlineSelectedModels(); lcGroup* AddGroup(const QString& Prefix, lcGroup* Parent); diff --git a/common/project.cpp b/common/project.cpp index 7854abf7..790ec768 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -326,6 +326,16 @@ bool Project::Save(const QString& FileName) lcGetPiecesLibrary()->SetCurrentModelPath(QFileInfo(FileName).absolutePath()); QTextStream Stream(&File); + bool Success = Save(Stream); + + mFileName = FileName; + mModified = false; + + return Success; +} + +bool Project::Save(QTextStream& Stream) +{ bool MPD = mModels.GetSize() > 1; for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) @@ -342,9 +352,6 @@ bool Project::Save(const QString& FileName) Stream << QLatin1String("0 NOFILE\r\n"); } - mFileName = FileName; - mModified = false; - return true; } @@ -381,6 +388,16 @@ void Project::Merge(Project* Other) mModified = true; } +void Project::InlineAllModels() +{ + mModels[0]->InlineAllModels(); + + for (int ModelIdx = 1; ModelIdx < mModels.GetSize(); ModelIdx++) + delete mModels[ModelIdx]; + + mModels.SetSize(1); +} + void Project::GetModelParts(lcArray& ModelParts) { if (mModels.IsEmpty()) diff --git a/common/project.h b/common/project.h index 7dc503a8..3007f96f 100644 --- a/common/project.h +++ b/common/project.h @@ -55,8 +55,11 @@ public: lcModel* CreateNewModel(bool ShowModel); QString GetNewModelName(QWidget* ParentWidget, const QString& DialogTitle, const QString& CurrentName, const QStringList& ExistingModels) const; void ShowModelListDialog(); + void InlineAllModels(); + bool Load(const QString& FileName); bool Save(const QString& FileName); + bool Save(QTextStream& Stream); void Merge(Project* Other); void SaveImage();