mirror of
https://github.com/leozide/leocad.git
synced 2026-09-12 01:23:35 +00:00
Rewrote how loose model files are loaded.
This commit is contained in:
+39
-54
@@ -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<lcLibraryTextureMap>& 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)
|
||||
{
|
||||
|
||||
+10
-8
@@ -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<lcLibraryTextureMap>& 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];
|
||||
|
||||
@@ -1822,8 +1822,6 @@ void lcMainWindow::NewProject()
|
||||
if (!SaveProjectIfModified())
|
||||
return;
|
||||
|
||||
lcGetPiecesLibrary()->SetCurrentModelPath(QString());
|
||||
|
||||
Project* NewProject = new Project();
|
||||
g_App->SetProject(NewProject);
|
||||
lcGetPiecesLibrary()->UnloadUnusedParts();
|
||||
|
||||
+52
-50
@@ -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<PieceInfo*> 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<lcModelPartsEntry> 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<lcObject*> 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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -181,7 +181,6 @@ public:
|
||||
void SetPieceSteps(const QList<QPair<lcPiece*, lcStep>>& 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()
|
||||
|
||||
+1
-1
@@ -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));
|
||||
|
||||
+4
-4
@@ -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;
|
||||
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+62
-6
@@ -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<lcModel*>& UpdatedModels)
|
||||
{
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
mModel->UpdatePieceInfo(UpdatedModels);
|
||||
else if (mFlags & LC_PIECE_PROJECT)
|
||||
mProject->UpdatePieceInfo(this);
|
||||
}
|
||||
|
||||
+11
-3
@@ -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;
|
||||
|
||||
+3
-3
@@ -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];
|
||||
|
||||
+24
-19
@@ -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<lcModelPartsEntry>& 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<lcModel*> UpdatedModels;
|
||||
mModels[0]->UpdatePieceInfo(UpdatedModels);
|
||||
|
||||
lcBoundingBox BoundingBox = mModels[0]->GetPieceInfo()->GetBoundingBox();
|
||||
Info->SetBoundingBox(BoundingBox.Min, BoundingBox.Max);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -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<lcModelPartsEntry>& ModelParts);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user