diff --git a/common/lc_library.cpp b/common/lc_library.cpp index 8b99af00..5c30712a 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -95,8 +95,17 @@ void lcPiecesLibrary::RemovePiece(PieceInfo* Info) delete Info; } -PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder) +PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentProject, bool CreatePlaceholder, bool SearchProjectFolder) { + QString ProjectPath; + if (SearchProjectFolder) + { + QString FileName = CurrentProject->GetFileName(); + + if (!FileName.isEmpty()) + ProjectPath = QFileInfo(FileName).absolutePath(); + } + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { PieceInfo* Info = mPieces[PieceIdx]; @@ -104,12 +113,37 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* Project, b if (strcmp(PieceName, Info->m_strName)) continue; - if (Project && Info->IsModel() && Project->GetModels().FindIndex(Info->GetModel()) == -1) + if (CurrentProject && Info->IsModel() && CurrentProject->GetModels().FindIndex(Info->GetModel()) == -1) + continue; + + if (ProjectPath.isEmpty() && Info->IsProject()) continue; return Info; } + if (!ProjectPath.isEmpty()) + { + QFileInfo ProjectFile = QFileInfo(ProjectPath + QDir::separator() + PieceName); + + if (ProjectFile.isFile()) + { + Project* NewProject = new Project(); + + if (NewProject->Load(ProjectFile.absoluteFilePath())) + { + PieceInfo* Info = new PieceInfo(); + + Info->SetProject(NewProject, PieceName); + mPieces.Add(Info); + + return Info; + } + else + delete NewProject; + } + } + if (CreatePlaceholder) { PieceInfo* Info = new PieceInfo(); @@ -270,7 +304,7 @@ bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileT if (memcmp(Name, "S/", 2)) { - PieceInfo* Info = FindPiece(Name, NULL, false); + PieceInfo* Info = FindPiece(Name, NULL, false, false); if (!Info) { @@ -918,19 +952,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info) setlocale(LC_NUMERIC, OldLocale); } } - - if (!Loaded && !mCurrentModelPath.isEmpty()) - { - 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); - setlocale(LC_NUMERIC, OldLocale); - UpdateBoundingBox = true; - } - } - + if (!Loaded) return false; @@ -1406,32 +1428,6 @@ 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]; @@ -1714,17 +1710,6 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf break; } - - if (!Loaded && !mCurrentModelPath.isEmpty()) - { - lcMemFile IncludeFile; - if (LoadAndInlineFile(OriginalFileName, IncludeFile)) - { - const char* OldLocale = setlocale(LC_NUMERIC, "C"); - Loaded = ReadMeshData(File, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize); - setlocale(LC_NUMERIC, OldLocale); - } - } } } break; @@ -2368,7 +2353,7 @@ void lcPiecesLibrary::GetCategoryEntries(const String& CategoryKeywords, bool Gr strcpy(ParentName, Info->m_strName); *strchr(ParentName, 'P') = '\0'; - Parent = FindPiece(ParentName, NULL, false); + Parent = FindPiece(ParentName, NULL, false, false); if (Parent) { diff --git a/common/lc_library.h b/common/lc_library.h index d154de13..eb2ab4a0 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -69,6 +69,15 @@ public: mSections[MeshDataIdx].DeleteAll(); } + bool IsEmpty() const + { + for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + if (!mSections[MeshDataIdx].IsEmpty()) + return false; + + return true; + } + lcLibraryMeshSection* AddSection(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, lcuint32 ColorCode, lcTexture* Texture); void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcVertex** VertexBuffer); void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, lcuint32 ColorCode, int IndexCount, lcuint32** IndexBuffer); @@ -125,7 +134,7 @@ public: void RemoveTemporaryPieces(); void RemovePiece(PieceInfo* Info); - PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder); + PieceInfo* FindPiece(const char* PieceName, Project* Project, bool CreatePlaceholder, bool SearchProjectFolder); bool LoadPiece(PieceInfo* Info); bool LoadBuiltinPieces(); @@ -149,11 +158,6 @@ public: mNumOfficialPieces = mPieces.GetSize(); } - void SetCurrentModelPath(const QString& ModelPath) - { - mCurrentModelPath = ModelPath; - } - bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize); lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData); void UpdateBuffers(lcContext* Context); @@ -186,10 +190,8 @@ protected: int FindPrimitiveIndex(const char* Name) const; bool LoadPrimitive(int PrimitiveIndex); - bool LoadAndInlineFile(const char* FileName, lcMemFile& File); QString mCachePath; - QString mCurrentModelPath; qint64 mArchiveCheckSum[4]; char mLibraryFileName[LC_MAXPATH]; char mUnofficialFileName[LC_MAXPATH]; diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 414f8d8e..bb7cd6b9 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -1822,8 +1822,6 @@ void lcMainWindow::NewProject() if (!SaveProjectIfModified()) return; - lcGetPiecesLibrary()->SetCurrentModelPath(QString()); - Project* NewProject = new Project(); g_App->SetProject(NewProject); lcGetPiecesLibrary()->UnloadUnusedParts(); diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 2a77ff9d..7a2daed1 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -169,7 +169,7 @@ lcModel::~lcModel() if (mPieceInfo->GetModel() == this) mPieceInfo->SetPlaceholder(); - mPieceInfo->Release(true); + mPieceInfo->Release(); } DeleteModel(); @@ -226,7 +226,7 @@ void lcModel::DeleteModel() void lcModel::CreatePieceInfo(Project* Project) { - mPieceInfo = lcGetPiecesLibrary()->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true); + mPieceInfo = lcGetPiecesLibrary()->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true, false); mPieceInfo->SetModel(this, true); mPieceInfo->AddRef(); } @@ -427,6 +427,40 @@ void lcModel::SaveLDraw(QTextStream& Stream, bool SelectedOnly) const Stream.flush(); } +void lcModel::SplitMPD(QIODevice& Device) +{ + while (!Device.atEnd()) + { + qint64 Pos = Device.pos(); + QString OriginalLine = Device.readLine(); + QString Line = OriginalLine.trimmed(); + QTextStream LineStream(&Line, QIODevice::ReadOnly); + + QString Token; + LineStream >> Token; + + if (Token == QLatin1String("0")) + { + LineStream >> Token; + + if (Token == QLatin1String("FILE")) + { + if (!mProperties.mName.isEmpty()) + { + Device.seek(Pos); + break; + } + + mProperties.mName = LineStream.readAll().trimmed(); + } + else if (Token == QLatin1String("NOFILE")) + { + break; + } + } + } +} + void lcModel::LoadLDraw(QIODevice& Device, Project* Project) { lcPiece* Piece = NULL; @@ -589,10 +623,10 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project) if (!CurrentGroups.IsEmpty()) Piece->SetGroup(CurrentGroups[CurrentGroups.GetSize() - 1]); - PieceInfo* Info = Library->FindPiece(PartID.toLatin1().constData(), Project, false); + PieceInfo* Info = Library->FindPiece(PartID.toLatin1().constData(), Project, false, true); if (!Info) - Info = Library->FindPiece(File.toLatin1().constData(), Project, true); + Info = Library->FindPiece(File.toLatin1().constData(), Project, true, true); float* Matrix = IncludeTransform; lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f), @@ -696,7 +730,7 @@ bool lcModel::LoadBinary(lcFile* file) lcMatrix44 WorldMatrix = lcMul(lcMatrix44RotationZ(rot[2] * LC_DTOR), lcMul(lcMatrix44RotationY(rot[1] * LC_DTOR), lcMatrix44RotationX(rot[0] * LC_DTOR))); WorldMatrix.SetTranslation(pos); - PieceInfo* pInfo = Library->FindPiece(name, NULL, true); + PieceInfo* pInfo = Library->FindPiece(name, NULL, true, false); lcPiece* pPiece = new lcPiece(pInfo); pPiece->Initialize(WorldMatrix, step); @@ -1304,6 +1338,15 @@ void lcModel::SaveCheckpoint(const QString& Description) void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) { + lcArray Infos; + + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + PieceInfo* Info = mPieces[PieceIdx]->mPieceInfo; + Info->AddRef(); + Infos.Add(Info); + } + DeleteModel(); QBuffer Buffer(&CheckPoint->File); @@ -1315,6 +1358,9 @@ void lcModel::LoadCheckPoint(lcModelHistoryEntry* CheckPoint) gMainWindow->UpdateCurrentStep(); gMainWindow->UpdateSelectedObjects(true); gMainWindow->UpdateAllViews(); + + for (int InfoIdx = 0; InfoIdx < Infos.GetSize(); InfoIdx++) + Infos[InfoIdx]->Release(); } void lcModel::SetActive(bool Active) @@ -2180,50 +2226,6 @@ 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; @@ -2570,7 +2572,7 @@ void lcModel::SetSelectedPiecesPieceInfo(PieceInfo* Info) if (Piece->IsSelected() && Piece->mPieceInfo != Info) { - Piece->mPieceInfo->Release(true); + Piece->mPieceInfo->Release(); Piece->SetPieceInfo(Info); Modified = true; } diff --git a/common/lc_model.h b/common/lc_model.h index b0166643..35ada581 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -181,7 +181,6 @@ public: void SetPieceSteps(const QList>& PieceSteps); void MoveSelectionToModel(lcModel* Model); - void InlineAllModels(); void InlineSelectedModels(); lcGroup* AddGroup(const QString& Prefix, lcGroup* Parent); @@ -196,6 +195,7 @@ public: void SaveLDraw(QTextStream& Stream, bool SelectedOnly) const; void LoadLDraw(QIODevice& Device, Project* Project); bool LoadBinary(lcFile* File); + void SplitMPD(QIODevice& Device); void Merge(lcModel* Other); void SetSaved() diff --git a/common/lc_synth.cpp b/common/lc_synth.cpp index c71a5960..db295b78 100644 --- a/common/lc_synth.cpp +++ b/common/lc_synth.cpp @@ -45,7 +45,7 @@ void lcSynthInit() for (unsigned int InfoIdx = 0; InfoIdx < sizeof(HoseInfo) / sizeof(HoseInfo[0]); InfoIdx++) { - PieceInfo* Info = Library->FindPiece(HoseInfo[InfoIdx].PartID, NULL, false); + PieceInfo* Info = Library->FindPiece(HoseInfo[InfoIdx].PartID, NULL, false, false); if (Info) Info->SetSynthInfo(new lcSynthInfo(HoseInfo[InfoIdx].Type, HoseInfo[InfoIdx].Length, HoseInfo[InfoIdx].NumSections, Info)); diff --git a/common/minifig.cpp b/common/minifig.cpp index febe548e..aa43f21a 100644 --- a/common/minifig.cpp +++ b/common/minifig.cpp @@ -63,7 +63,7 @@ void MinifigWizard::OnInitialUpdate() { mMinifig.Colors[i] = lcGetColorIndex(ColorCodes[i]); - PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Pieces[i], NULL, false); + PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(Pieces[i], NULL, false, false); if (Info) { mMinifig.Parts[i] = Info; @@ -78,7 +78,7 @@ MinifigWizard::~MinifigWizard() { for (int i = 0; i < LC_MFW_NUMITEMS; i++) if (mMinifig.Parts[i]) - mMinifig.Parts[i]->Release(true); + mMinifig.Parts[i]->Release(); } void MinifigWizard::ParseSettings(lcFile& Settings) @@ -173,7 +173,7 @@ void MinifigWizard::ParseSettings(lcFile& Settings) *Ext = 0; } - PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(NameStart, NULL, false); + PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(NameStart, NULL, false, false); if (!Info && *NameStart) continue; @@ -550,7 +550,7 @@ void MinifigWizard::SetSelectionIndex(int Type, int Index) MakeCurrent(); if (mMinifig.Parts[Type]) - mMinifig.Parts[Type]->Release(true); + mMinifig.Parts[Type]->Release(); mMinifig.Parts[Type] = mSettings[Type][Index].Info; diff --git a/common/piece.cpp b/common/piece.cpp index 75de1b9d..9579570e 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -37,7 +37,7 @@ lcPiece::lcPiece(PieceInfo* Info) lcPiece::~lcPiece() { if (mPieceInfo) - mPieceInfo->Release(false); + mPieceInfo->Release(); delete mMesh; } @@ -265,7 +265,7 @@ bool lcPiece::FileLoad(lcFile& file) else file.ReadBuffer(name, LC_PIECE_NAME_LEN); - PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, NULL, true); + PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, NULL, true, false); SetPieceInfo(pInfo); // 11 (0.77) diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 3c94ae21..1ad7a1bc 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -7,6 +7,7 @@ #include "lc_library.h" #include "lc_application.h" #include "lc_model.h" +#include "project.h" #include "lc_context.h" #include "lc_synth.h" #include "lc_file.h" @@ -21,20 +22,21 @@ PieceInfo::PieceInfo() mRefCount = 0; mMesh = NULL; mModel = NULL; + mProject = NULL; mSynthInfo = NULL; } PieceInfo::~PieceInfo() { + delete mSynthInfo; + if (mLoaded) Unload(); - - delete mSynthInfo; } QString PieceInfo::GetSaveID() const { - if (mFlags & LC_PIECE_MODEL) + if (mFlags & (LC_PIECE_MODEL | LC_PIECE_PROJECT)) return QString::fromLatin1(m_strName); return QString::fromLatin1(m_strName) + QLatin1String(".DAT"); @@ -47,6 +49,7 @@ void PieceInfo::SetPlaceholder() mFlags = LC_PIECE_PLACEHOLDER | LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES; mModel = NULL; + mProject = NULL; delete mMesh; mMesh = NULL; @@ -86,11 +89,26 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh) bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, true); setlocale(LC_NUMERIC, OldLocale); - if (Ret) + if (Ret && !MeshData.IsEmpty()) lcGetPiecesLibrary()->CreateMesh(this, MeshData); } } +void PieceInfo::SetProject(Project* Project, const char* PieceName) +{ + if (mProject != Project) + { + mFlags = LC_PIECE_PROJECT; + mProject = Project; + mLoaded = true; + } + + strncpy(m_strName, PieceName, sizeof(m_strName)); + m_strName[sizeof(m_strName)-1] = 0; + strncpy(m_strDescription, Project->GetFileName().toLatin1().data(), sizeof(m_strDescription)); + m_strDescription[sizeof(m_strDescription)-1] = 0; +} + bool PieceInfo::IncludesModel(const lcModel* Model) const { if (mFlags & LC_PIECE_MODEL) @@ -118,7 +136,7 @@ void PieceInfo::Load() { mLoaded = true; - if (mFlags & LC_PIECE_MODEL) + if (mFlags & (LC_PIECE_MODEL | LC_PIECE_PROJECT)) return; else if (mFlags & LC_PIECE_PLACEHOLDER) { @@ -161,13 +179,19 @@ void PieceInfo::Unload() if (IsModel()) lcGetPiecesLibrary()->RemovePiece(this); + else if (IsProject()) + { + delete mProject; + mProject = NULL; + lcGetPiecesLibrary()->RemovePiece(this); + } } bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const { bool Intersect = false; - if (mFlags & (LC_PIECE_PLACEHOLDER | LC_PIECE_MODEL)) + if (mFlags & (LC_PIECE_PLACEHOLDER | LC_PIECE_MODEL | LC_PIECE_PROJECT)) { float Distance; if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, NULL) || (Distance >= MinDistance)) @@ -178,6 +202,12 @@ bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, f if (mFlags & LC_PIECE_MODEL) Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance); + else if (mFlags & LC_PIECE_PROJECT) + { + lcModel* Model = mProject->GetMainModel(); + if (Model) + Intersect |= Model->SubModelMinIntersectDist(Start, End, MinDistance); + } } if (mMesh) @@ -238,6 +268,11 @@ bool PieceInfo::BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 WorldPlan if (mFlags & LC_PIECE_MODEL) return mModel->SubModelBoxTest(LocalPlanes); + else if (mFlags & LC_PIECE_PROJECT) + { + lcModel* Model = mProject->GetMainModel(); + return Model ? Model->SubModelBoxTest(LocalPlanes) : false; + } return false; } @@ -314,12 +349,24 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i if (mFlags & LC_PIECE_MODEL) mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected); + else if (mFlags & LC_PIECE_PROJECT) + { + lcModel* Model = mProject->GetMainModel(); + if (Model) + Model->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected); + } } void PieceInfo::GetPartsList(int DefaultColorIndex, lcPartsList& PartsList) const { if (mFlags & LC_PIECE_MODEL) mModel->GetPartsList(DefaultColorIndex, PartsList); + else if (mFlags & LC_PIECE_PROJECT) + { + lcModel* Model = mProject->GetMainModel(); + if (Model) + Model->GetPartsList(DefaultColorIndex, PartsList); + } else PartsList[this][DefaultColorIndex]++; } @@ -331,6 +378,13 @@ void PieceInfo::GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorInd mModel->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts); return; } + else if (mFlags & LC_PIECE_PROJECT) + { + lcModel* Model = mProject->GetMainModel(); + if (Model) + Model->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts); + return; + } lcModelPartsEntry& ModelPartsEntry = ModelParts.Add(); ModelPartsEntry.WorldMatrix = WorldMatrix; @@ -342,4 +396,6 @@ void PieceInfo::UpdateBoundingBox(lcArray& UpdatedModels) { if (mFlags & LC_PIECE_MODEL) mModel->UpdatePieceInfo(UpdatedModels); + else if (mFlags & LC_PIECE_PROJECT) + mProject->UpdatePieceInfo(this); } diff --git a/common/pieceinf.h b/common/pieceinf.h index 691ebcda..f43955f9 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -11,6 +11,7 @@ #define LC_PIECE_HAS_LINES 0x08 // Piece has lines #define LC_PIECE_PLACEHOLDER 0x10 // Placeholder for a piece not in the library #define LC_PIECE_MODEL 0x20 // Piece is a model +#define LC_PIECE_PROJECT 0x40 // Piece is a project #define LC_PIECE_NAME_LEN 256 @@ -68,11 +69,11 @@ public: Load(); } - void Release(bool AllowUnload) + void Release() { mRefCount--; - if (!mRefCount && AllowUnload) + if (!mRefCount) Unload(); } @@ -97,9 +98,14 @@ public: return (mFlags & LC_PIECE_MODEL) != 0; } + bool IsProject() const + { + return (mFlags & LC_PIECE_PROJECT) != 0; + } + bool IsTemporary() const { - return (mFlags & (LC_PIECE_PLACEHOLDER | LC_PIECE_MODEL)) != 0; + return (mFlags & (LC_PIECE_PLACEHOLDER | LC_PIECE_MODEL | LC_PIECE_PROJECT)) != 0; } void SetZipFile(int ZipFileType, int ZipFileIndex) @@ -139,6 +145,7 @@ public: void SetPlaceholder(); void SetModel(lcModel* Model, bool UpdateMesh); + void SetProject(Project* Project, const char* PieceName); bool IncludesModel(const lcModel* Model) const; bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const; bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const; @@ -158,6 +165,7 @@ protected: bool mLoaded; int mRefCount; lcModel* mModel; + Project* mProject; lcMesh* mMesh; lcBoundingBox mBoundingBox; lcSynthInfo* mSynthInfo; diff --git a/common/preview.cpp b/common/preview.cpp index f6eab1f6..c315ec97 100644 --- a/common/preview.cpp +++ b/common/preview.cpp @@ -20,7 +20,7 @@ PiecePreview::PiecePreview() PiecePreview::~PiecePreview() { if (m_PieceInfo) - m_PieceInfo->Release(true); + m_PieceInfo->Release(); } void PiecePreview::OnDraw() @@ -84,7 +84,7 @@ void PiecePreview::SetCurrentPiece(PieceInfo *pInfo) MakeCurrent(); if (m_PieceInfo != NULL) - m_PieceInfo->Release(true); + m_PieceInfo->Release(); m_PieceInfo = pInfo; @@ -98,7 +98,7 @@ void PiecePreview::SetCurrentPiece(PieceInfo *pInfo) void PiecePreview::SetDefaultPiece() { lcPiecesLibrary* Library = lcGetPiecesLibrary(); - PieceInfo* Info = Library->FindPiece("3005", NULL, false); + PieceInfo* Info = Library->FindPiece("3005", NULL, false, false); if (!Info) Info = Library->mPieces[0]; diff --git a/common/project.cpp b/common/project.cpp index 7110254b..e40bf03c 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -237,10 +237,10 @@ bool Project::Load(const QString& FileName) } mModels.DeleteAll(); + mFileName = FileName; QFileInfo FileInfo(FileName); QString Extension = FileInfo.suffix().toLower(); - lcGetPiecesLibrary()->SetCurrentModelPath(FileInfo.absolutePath()); QByteArray FileData = File.readAll(); bool LoadDAT; @@ -259,16 +259,22 @@ bool Project::Load(const QString& FileName) while (!Buffer.atEnd()) { lcModel* Model = new lcModel(QString()); - Model->LoadLDraw(Buffer, this); + Model->SplitMPD(Buffer); if (mModels.IsEmpty() || !Model->GetProperties().mName.isEmpty()) - { mModels.Add(Model); - Model->SetSaved(); - } else delete Model; } + + Buffer.seek(0); + + for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) + { + lcModel* Model = mModels[ModelIdx]; + Model->LoadLDraw(Buffer, this); + Model->SetSaved(); + } } else { @@ -307,7 +313,6 @@ bool Project::Load(const QString& FileName) for (int ModelIdx = 0; ModelIdx < mModels.GetSize(); ModelIdx++) mModels[ModelIdx]->UpdatePieceInfo(UpdatedModels); - mFileName = FileName; mModified = false; return true; @@ -323,8 +328,6 @@ bool Project::Save(const QString& FileName) return false; } - lcGetPiecesLibrary()->SetCurrentModelPath(QFileInfo(FileName).absolutePath()); - QTextStream Stream(&File); bool Success = Save(Stream); @@ -388,16 +391,6 @@ 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()) @@ -1477,7 +1470,7 @@ void Project::ExportPOVRay() strupr(Src); - PieceInfo* Info = Library->FindPiece(Src, NULL, false); + PieceInfo* Info = Library->FindPiece(Src, NULL, false, false); if (!Info) continue; @@ -1797,3 +1790,15 @@ void Project::SaveImage() mActiveModel->SaveStepImages(Dialog.mFileName, Dialog.mWidth, Dialog.mHeight, Dialog.mStart, Dialog.mEnd); } + +void Project::UpdatePieceInfo(PieceInfo* Info) const +{ + if (!mModels.IsEmpty()) + { + lcArray UpdatedModels; + mModels[0]->UpdatePieceInfo(UpdatedModels); + + lcBoundingBox BoundingBox = mModels[0]->GetPieceInfo()->GetBoundingBox(); + Info->SetBoundingBox(BoundingBox.Min, BoundingBox.Max); + } +} diff --git a/common/project.h b/common/project.h index 3007f96f..2a5b871d 100644 --- a/common/project.h +++ b/common/project.h @@ -42,6 +42,11 @@ public: return mActiveModel; } + lcModel* GetMainModel() const + { + return !mModels.IsEmpty() ? mModels[0] : NULL; + } + bool IsModified() const; QString GetTitle() const; @@ -55,7 +60,6 @@ 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); @@ -70,6 +74,8 @@ public: void ExportPOVRay(); void ExportWavefront(const QString& FileName); + void UpdatePieceInfo(PieceInfo* Info) const; + protected: QString GetExportFileName(const QString& FileName, const QString& DefaultExtension, const QString& DialogTitle, const QString& DialogFilter) const; void GetModelParts(lcArray& ModelParts); diff --git a/qt/lc_qpartstree.cpp b/qt/lc_qpartstree.cpp index 24ad9f78..98a27abf 100644 --- a/qt/lc_qpartstree.cpp +++ b/qt/lc_qpartstree.cpp @@ -221,7 +221,7 @@ void lcQPartsTree::setCurrentPart(PieceInfo *part) strcpy(parentName, part->m_strName); *strchr(parentName, 'P') = '\0'; - PieceInfo *parentPart = library->FindPiece(parentName, NULL, false); + PieceInfo *parentPart = library->FindPiece(parentName, NULL, false, false); if (parentPart) {