mirror of
https://github.com/leozide/leocad
synced 2025-01-29 20:34:50 +01:00
Support loading textures from the same folder of the model being loaded.
This commit is contained in:
parent
0305c4964b
commit
bca9b205af
9 changed files with 87 additions and 28 deletions
|
@ -165,12 +165,37 @@ PieceInfo* lcPiecesLibrary::FindPiece(const char* PieceName, Project* CurrentPro
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName)
|
||||
lcTexture* lcPiecesLibrary::FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder)
|
||||
{
|
||||
for (int TextureIdx = 0; TextureIdx < mTextures.GetSize(); TextureIdx++)
|
||||
if (!strcmp(TextureName, mTextures[TextureIdx]->mName))
|
||||
return mTextures[TextureIdx];
|
||||
|
||||
QString ProjectPath;
|
||||
if (SearchProjectFolder)
|
||||
{
|
||||
QString FileName = CurrentProject->GetFileName();
|
||||
|
||||
if (!FileName.isEmpty())
|
||||
ProjectPath = QFileInfo(FileName).absolutePath();
|
||||
}
|
||||
|
||||
if (!ProjectPath.isEmpty())
|
||||
{
|
||||
QFileInfo TextureFile = QFileInfo(ProjectPath + QDir::separator() + TextureName + ".png");
|
||||
|
||||
if (TextureFile.isFile())
|
||||
{
|
||||
lcTexture* Texture = lcLoadTexture(TextureFile.absoluteFilePath(), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV);
|
||||
|
||||
if (Texture)
|
||||
{
|
||||
mTextures.Add(Texture);
|
||||
return Texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1059,7 +1084,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
|
|||
lcMemFile PieceFile;
|
||||
|
||||
if (mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, PieceFile))
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
|
||||
|
||||
SaveCache = Loaded && (Info->mZipFileType == LC_ZIPFILE_OFFICIAL);
|
||||
}
|
||||
|
@ -1077,7 +1102,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
|
|||
sprintf(FileName, "unofficial/parts/%s.dat", Name);
|
||||
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
|
||||
if (PieceFile.Open(QIODevice::ReadOnly))
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
|
||||
}
|
||||
|
||||
if (!Loaded)
|
||||
|
@ -1085,7 +1110,7 @@ bool lcPiecesLibrary::LoadPieceData(PieceInfo* Info)
|
|||
sprintf(FileName, "parts/%s.dat", Name);
|
||||
PieceFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String(FileName)));
|
||||
if (PieceFile.Open(QIODevice::ReadOnly))
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
Loaded = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, nullptr, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1497,6 +1522,17 @@ bool lcPiecesLibrary::LoadTexture(lcTexture* Texture)
|
|||
return true;
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::ReleaseTexture(lcTexture* Texture)
|
||||
{
|
||||
QMutexLocker LoadLock(&mLoadMutex);
|
||||
|
||||
if (Texture->Release() == 0 && Texture->IsTemporary())
|
||||
{
|
||||
mTextures.Remove(Texture);
|
||||
delete Texture;
|
||||
}
|
||||
}
|
||||
|
||||
int lcPiecesLibrary::FindPrimitiveIndex(const char* Name) const
|
||||
{
|
||||
int Count = mPrimitives.GetSize();
|
||||
|
@ -1553,12 +1589,12 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
|
||||
if (LowPrimitiveIndex == -1)
|
||||
{
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true, nullptr, false))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH, true))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH, true, nullptr, false))
|
||||
return false;
|
||||
|
||||
lcLibraryPrimitive* LowPrimitive = mPrimitives[LowPrimitiveIndex];
|
||||
|
@ -1568,7 +1604,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
|
||||
TextureStack.RemoveAll();
|
||||
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW, true))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW, true, nullptr, false))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1602,7 +1638,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
Found = PrimFile.Open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
|
||||
if (!Found || !ReadMeshData(PrimFile, lcMatrix44Identity(), 16, false, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true, nullptr, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1611,7 +1647,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize)
|
||||
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder)
|
||||
{
|
||||
char Buffer[1024];
|
||||
char* Line;
|
||||
|
@ -1712,7 +1748,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
lcLibraryTextureMap& Map = TextureStack.Add();
|
||||
Map.Next = false;
|
||||
Map.Fallback = false;
|
||||
Map.Texture = FindTexture(FileName);
|
||||
Map.Texture = FindTexture(FileName, CurrentProject, SearchProjectFolder);
|
||||
|
||||
for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++)
|
||||
{
|
||||
|
@ -1863,7 +1899,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
lcMemFile IncludeFile;
|
||||
|
||||
if (mZipFiles[Primitive->mZipFileType]->ExtractFile(Primitive->mZipFileIndex, IncludeFile))
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1894,7 +1930,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
Found = IncludeFile.Open(QIODevice::ReadOnly);
|
||||
}
|
||||
if (Found)
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1912,7 +1948,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
lcMemFile IncludeFile;
|
||||
|
||||
if (mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, IncludeFile))
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1938,7 +1974,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
}
|
||||
|
||||
if (Found)
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize);
|
||||
ReadMeshData(IncludeFile, IncludeTransform, ColorCode, Mirror ^ InvertNext, TextureStack, MeshData, MeshDataType, Optimize, CurrentProject, SearchProjectFolder);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -162,8 +162,9 @@ public:
|
|||
void LoadQueuedPiece();
|
||||
void WaitForLoadQueue();
|
||||
|
||||
lcTexture* FindTexture(const char* TextureName);
|
||||
lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
|
||||
bool LoadTexture(lcTexture* Texture);
|
||||
void ReleaseTexture(lcTexture* Texture);
|
||||
|
||||
bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const;
|
||||
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
|
||||
|
@ -182,7 +183,7 @@ public:
|
|||
mNumOfficialPieces = mPieces.GetSize();
|
||||
}
|
||||
|
||||
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize);
|
||||
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, bool InvertWinding, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize, Project* CurrentProject, bool SearchProjectFolder);
|
||||
lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
|
||||
void ReleaseBuffers(lcContext* Context);
|
||||
void UpdateBuffers(lcContext* Context);
|
||||
|
|
|
@ -389,7 +389,7 @@ bool lcMesh::FileLoad(lcMemFile& File)
|
|||
File.ReadBuffer(FileName, Length);
|
||||
FileName[Length] = 0;
|
||||
|
||||
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName);
|
||||
Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName, nullptr, false);
|
||||
}
|
||||
else
|
||||
Section.Texture = nullptr;
|
||||
|
|
|
@ -225,7 +225,7 @@ void lcModel::CreatePieceInfo(Project* Project)
|
|||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
mPieceInfo = Library->FindPiece(mProperties.mName.toUpper().toLatin1().constData(), Project, true, false);
|
||||
mPieceInfo->SetModel(this, true);
|
||||
mPieceInfo->SetModel(this, true, Project, true);
|
||||
Library->LoadPieceInfo(mPieceInfo, true, true);
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ void lcModel::UpdatePieceInfo(lcArray<lcModel*>& UpdatedModels)
|
|||
if (UpdatedModels.FindIndex(this) != -1)
|
||||
return;
|
||||
|
||||
mPieceInfo->SetModel(this, false);
|
||||
mPieceInfo->SetModel(this, false, nullptr, false);
|
||||
UpdatedModels.Add(this);
|
||||
|
||||
lcMesh* Mesh = mPieceInfo->GetMesh();
|
||||
|
|
|
@ -690,7 +690,7 @@ lcMesh* lcSynthInfo::CreateMesh(const lcArray<lcPieceControlPoint>& ControlPoint
|
|||
lcArray<lcLibraryTextureMap> TextureStack;
|
||||
File.Seek(0, SEEK_SET);
|
||||
|
||||
if (lcGetPiecesLibrary()->ReadMeshData(File, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, false))
|
||||
if (lcGetPiecesLibrary()->ReadMeshData(File, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, false, nullptr, false))
|
||||
return lcGetPiecesLibrary()->CreateMesh(nullptr, MeshData);
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -16,6 +16,11 @@ lcTexture* lcLoadTexture(const QString& FileName, int Flags)
|
|||
delete Texture;
|
||||
Texture = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(Texture->mName, QFileInfo(FileName).baseName().toLatin1());
|
||||
Texture->SetTemporary(true);
|
||||
}
|
||||
|
||||
return Texture;
|
||||
}
|
||||
|
@ -30,6 +35,7 @@ lcTexture::lcTexture()
|
|||
{
|
||||
mTexture = 0;
|
||||
mRefCount = 0;
|
||||
mTemporary = false;
|
||||
}
|
||||
|
||||
lcTexture::~lcTexture()
|
||||
|
|
|
@ -51,6 +51,16 @@ public:
|
|||
return mRefCount;
|
||||
}
|
||||
|
||||
void SetTemporary(bool Temporary)
|
||||
{
|
||||
mTemporary = Temporary;
|
||||
}
|
||||
|
||||
bool IsTemporary() const
|
||||
{
|
||||
return mTemporary;
|
||||
}
|
||||
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
char mName[LC_TEXTURE_NAME_LEN];
|
||||
|
@ -59,6 +69,7 @@ public:
|
|||
protected:
|
||||
bool Load();
|
||||
|
||||
bool mTemporary;
|
||||
int mRefCount;
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ QString PieceInfo::GetSaveID() const
|
|||
void PieceInfo::SetMesh(lcMesh* Mesh)
|
||||
{
|
||||
mBoundingBox = Mesh->mBoundingBox;
|
||||
ReleaseMesh();
|
||||
mMesh = Mesh;
|
||||
}
|
||||
|
||||
|
@ -52,16 +53,14 @@ void PieceInfo::SetPlaceholder()
|
|||
{
|
||||
mBoundingBox.Min = lcVector3(-10.0f, -10.0f, -24.0f);
|
||||
mBoundingBox.Max = lcVector3(10.0f, 10.0f, 4.0f);
|
||||
ReleaseMesh();
|
||||
|
||||
mFlags = LC_PIECE_PLACEHOLDER | LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
|
||||
mModel = nullptr;
|
||||
mProject = nullptr;
|
||||
|
||||
delete mMesh;
|
||||
mMesh = nullptr;
|
||||
}
|
||||
|
||||
void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
|
||||
void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder)
|
||||
{
|
||||
if (mModel != Model)
|
||||
{
|
||||
|
@ -91,7 +90,7 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
|
|||
lcArray<lcLibraryTextureMap> TextureStack;
|
||||
PieceFile.Seek(0, SEEK_SET);
|
||||
|
||||
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, false, TextureStack, MeshData, LC_MESHDATA_SHARED, true, CurrentProject, SearchProjectFolder);
|
||||
|
||||
if (Ret && !MeshData.IsEmpty())
|
||||
lcGetPiecesLibrary()->CreateMesh(this, MeshData);
|
||||
|
@ -159,7 +158,7 @@ void PieceInfo::Load()
|
|||
mState = LC_PIECEINFO_LOADED;
|
||||
}
|
||||
|
||||
void PieceInfo::Unload()
|
||||
void PieceInfo::ReleaseMesh()
|
||||
{
|
||||
if (mMesh)
|
||||
{
|
||||
|
@ -170,14 +169,18 @@ void PieceInfo::Unload()
|
|||
lcMeshSection& Section = mMesh->mLods[LodIdx].Sections[SectionIdx];
|
||||
|
||||
if (Section.Texture)
|
||||
Section.Texture->Release();
|
||||
lcGetPiecesLibrary()->ReleaseTexture(Section.Texture);
|
||||
}
|
||||
}
|
||||
|
||||
delete mMesh;
|
||||
mMesh = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PieceInfo::Unload()
|
||||
{
|
||||
ReleaseMesh();
|
||||
mState = LC_PIECEINFO_UNLOADED;
|
||||
mModel = nullptr;
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ public:
|
|||
void CreatePlaceholder(const char* Name);
|
||||
|
||||
void SetPlaceholder();
|
||||
void SetModel(lcModel* Model, bool UpdateMesh);
|
||||
void SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProject, bool SearchProjectFolder);
|
||||
void SetProject(Project* Project, const char* PieceName);
|
||||
bool IncludesModel(const lcModel* Model) const;
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const;
|
||||
|
@ -160,6 +160,8 @@ public:
|
|||
lcPieceInfoState mState;
|
||||
|
||||
protected:
|
||||
void ReleaseMesh();
|
||||
|
||||
int mRefCount;
|
||||
lcModel* mModel;
|
||||
Project* mProject;
|
||||
|
|
Loading…
Add table
Reference in a new issue