Added builtin library as a zip file.

This commit is contained in:
leo 2014-09-11 19:55:34 +00:00
parent 24f74795b8
commit ade4b61155
12 changed files with 91 additions and 361 deletions

View file

@ -248,10 +248,12 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstal
return false;
}
mLibrary->CreateBuiltinPieces();
gMainWindow->DoMessageBox("LeoCAD could not find a compatible Pieces Library so only a small number of pieces will be available.\n\n"
"Please visit http://www.leocad.org for information on how to download and install a library.", LC_MB_OK | LC_MB_ICONERROR);
if (mLibrary->LoadBuiltinPieces())
gMainWindow->DoMessageBox("LeoCAD could not find a compatible Parts Library so only a small number of parts will be available.\n\n"
"Please visit http://www.leocad.org for information on how to download and install a library.", LC_MB_OK | LC_MB_ICONERROR);
else
gMainWindow->DoMessageBox("LeoCAD could not load Parts Library.\n\n"
"Please visit http://www.leocad.org for information on how to download and install a library.", LC_MB_OK | LC_MB_ICONERROR);
}
// Create a new project.

View file

@ -74,6 +74,8 @@ void lcResetCategories(lcArray<lcLibraryCategory>& Categories, bool BuiltInLibra
"Baseplate=^%Baseplate\n"
"Brick=^%Brick\n"
"Plate=^%Plate\n"
"Slope=^%Slope\n"
"Tile=^%Tile\n"
};
lcMemFile File;

View file

@ -186,6 +186,17 @@ void lcMemFile::CopyFrom(lcFile& Source)
Source.ReadBuffer(mBuffer, Length);
}
void lcMemFile::CopyFrom(lcMemFile& Source)
{
size_t Length = Source.GetLength();
SetLength(Length);
Seek(0, SEEK_SET);
Source.Seek(0, SEEK_SET);
Source.ReadBuffer(mBuffer, Length);
}
// =============================================================================
// lcDiskFile

View file

@ -37,6 +37,7 @@ public:
virtual size_t ReadBuffer(void* Buffer, long Bytes) = 0;
virtual size_t WriteBuffer(const void* Buffer, long Bytes) = 0;
virtual void CopyFrom(lcMemFile& Source) = 0;
lcuint8 ReadU8()
{
@ -457,6 +458,7 @@ public:
size_t WriteBuffer(const void* Buffer, long Bytes);
void CopyFrom(lcFile& Source);
void CopyFrom(lcMemFile& Source);
void GrowFile(size_t NewLength);
size_t mGrowBytes;

View file

@ -144,10 +144,23 @@ bool lcPiecesLibrary::Load(const char* LibraryPath, const char* CachePath)
}
bool lcPiecesLibrary::OpenArchive(const char* FileName, lcZipFileType ZipFileType)
{
lcDiskFile* File = new lcDiskFile();
if (!File->Open(FileName, "rb") || !OpenArchive(File, FileName, ZipFileType))
{
delete File;
return false;
}
return true;
}
bool lcPiecesLibrary::OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType)
{
lcZipFile* ZipFile = new lcZipFile();
if (!ZipFile->OpenRead(FileName))
if (!ZipFile->OpenRead(File))
{
delete ZipFile;
return false;
@ -1975,363 +1988,54 @@ void lcPiecesLibrary::GetPatternedPieces(PieceInfo* Parent, lcArray<PieceInfo*>&
}
}
void lcPiecesLibrary::CreateBuiltinPieces()
bool lcPiecesLibrary::LoadBuiltinPieces()
{
const char* Pieces[][2] =
QResource Resource(":/resources/library.zip");
if (!Resource.isValid())
return false;
lcMemFile* File = new lcMemFile();
File->WriteBuffer(Resource.data(), Resource.size());
if (!OpenArchive(File, "builtin", LC_ZIPFILE_OFFICIAL))
{
{ "3005", "Brick 1 x 1" },
{ "3004", "Brick 1 x 2" },
{ "3622", "Brick 1 x 3" },
{ "3010", "Brick 1 x 4" },
{ "3009", "Brick 1 x 6" },
{ "3008", "Brick 1 x 8" },
{ "6111", "Brick 1 x 10" },
{ "6112", "Brick 1 x 12" },
{ "2465", "Brick 1 x 16" },
{ "3003", "Brick 2 x 2" },
{ "3002", "Brick 2 x 3" },
{ "3001", "Brick 2 x 4" },
{ "2456", "Brick 2 x 6" },
{ "3007", "Brick 2 x 8" },
{ "3006", "Brick 2 x 10" },
{ "2356", "Brick 4 x 6" },
{ "6212", "Brick 4 x 10" },
{ "4202", "Brick 4 x 12" },
{ "30400", "Brick 4 x 18" },
{ "4201", "Brick 8 x 8" },
{ "4204", "Brick 8 x 16" },
{ "733", "Brick 10 x 10" },
{ "3024", "Plate 1 x 1" },
{ "3023", "Plate 1 x 2" },
{ "3623", "Plate 1 x 3" },
{ "3710", "Plate 1 x 4" },
{ "3666", "Plate 1 x 6" },
{ "3460", "Plate 1 x 8" },
{ "4477", "Plate 1 x 10" },
{ "60479", "Plate 1 x 12" },
{ "3022", "Plate 2 x 2" },
{ "3021", "Plate 2 x 3" },
{ "3020", "Plate 2 x 4" },
{ "3795", "Plate 2 x 6" },
{ "3034", "Plate 2 x 8" },
{ "3832", "Plate 2 x 10" },
{ "2445", "Plate 2 x 12" },
{ "91988", "Plate 2 x 14" },
{ "4282", "Plate 2 x 16" },
{ "3031", "Plate 4 x 4" },
{ "3032", "Plate 4 x 6" },
{ "3035", "Plate 4 x 8" },
{ "3030", "Plate 4 x 10" },
{ "3029", "Plate 4 x 12" },
{ "3958", "Plate 6 x 6" },
{ "3036", "Plate 6 x 8" },
{ "3033", "Plate 6 x 10" },
{ "3028", "Plate 6 x 12" },
{ "3456", "Plate 6 x 14" },
{ "3027", "Plate 6 x 16" },
{ "3026", "Plate 6 x 24" },
{ "41539", "Plate 8 x 8" },
{ "728", "Plate 8 x 11" },
{ "92438", "Plate 8 x 16" },
{ "819", "Baseplate 8 x 12" },
{ "3865", "Baseplate 8 x 16" },
{ "3497", "Baseplate 8 x 24" },
{ "4187", "Baseplate 8 x 32" },
{ "397", "Baseplate 10 x 16" },
{ "3867", "Baseplate 16 x 16" },
{ "184", "Baseplate 16 x 18" },
{ "210", "Baseplate 16 x 22" },
{ "3334", "Baseplate 16 x 24" },
{ "10", "Baseplate 24 x 32" },
{ "3645", "Baseplate 24 x 40" },
{ "3811", "Baseplate 32 x 32" },
{ "4186", "Baseplate 48 x 48" },
{ "782", "Baseplate 50 x 50" },
};
delete File;
return false;
}
for (unsigned int PieceIdx = 0; PieceIdx < sizeof(Pieces) / sizeof(Pieces[0]); PieceIdx++)
lcMemFile PieceFile;
mSaveCache = false;
for (int PieceInfoIndex = 0; PieceInfoIndex < mPieces.GetSize(); PieceInfoIndex++)
{
PieceInfo* Info = new PieceInfo();
mPieces.Add(Info);
PieceInfo* Info = mPieces[PieceInfoIndex];
strncpy(Info->m_strName, Pieces[PieceIdx][0], sizeof(Info->m_strName));
Info->m_strName[sizeof(Info->m_strName) - 1] = 0;
mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, PieceFile, 256);
PieceFile.Seek(0, SEEK_END);
PieceFile.WriteU8(0);
strncpy(Info->m_strDescription, Pieces[PieceIdx][1], sizeof(Info->m_strDescription));
Info->m_strDescription[sizeof(Info->m_strDescription) - 1] = 0;
char* Src = (char*)PieceFile.mBuffer + 2;
char* Dst = Info->m_strDescription;
Info->mFlags = LC_PIECE_GENERATED;
for (;;)
{
if (*Src != '\r' && *Src != '\n' && *Src && Dst - Info->m_strDescription < (int)sizeof(Info->m_strDescription) - 1)
{
*Dst++ = *Src++;
continue;
}
*Dst = 0;
break;
}
}
lcLoadDefaultColors();
lcLoadDefaultCategories(true);
gMainWindow->UpdateCategories();
}
bool lcPiecesLibrary::GeneratePiece(PieceInfo* Info)
{
const int StudSides = 16;
bool Brick = !strncmp(Info->m_strDescription, "Brick ", 6);
bool Plate = !strncmp(Info->m_strDescription, "Plate ", 6);
bool Baseplate = !strncmp(Info->m_strDescription, "Baseplate ", 10);
int StudsX, StudsY;
float MinZ = Brick ? -24.0f : Plate ? -8.0f : -4.0f;
sscanf(strchr(Info->m_strDescription, ' '), "%d x %d", &StudsY, &StudsX);
Info->mFlags |= LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
Info->m_fDimensions[0] = 10.0f * StudsX;
Info->m_fDimensions[1] = 10.0f * StudsY;
Info->m_fDimensions[2] = 4.0f;
Info->m_fDimensions[3] = -10.0f * StudsX;
Info->m_fDimensions[4] = -10.0f * StudsY;
Info->m_fDimensions[5] = MinZ;
int NumVertices, NumIndices;
if (Brick || Plate)
{
NumVertices = (StudSides * 2 + 1) * StudsX * StudsY + 16;
NumIndices = ((StudSides * 3) * StudsX * StudsY + 28) * 3 + ((StudSides * 2) * StudsX * StudsY + 24) * 2;
}
else if (Baseplate)
{
NumVertices = (StudSides * 2 + 1) * StudsX * StudsY + 8;
NumIndices = ((StudSides * 3) * StudsX * StudsY + 12) * 3 + ((StudSides * 2) * StudsX * StudsY + 24) * 2;
}
lcMesh* Mesh = new lcMesh();
Mesh->Create(2, NumVertices, 0, NumIndices);
Info->mMesh = Mesh;
float* Verts = (float*)Mesh->mVertexBuffer.mData;
if (Brick || Plate || Baseplate)
{
const lcVector3 OutBoxMin(-10.0f * StudsX, -10.0f * StudsY, MinZ);
const lcVector3 OutBoxMax(10.0f * StudsX, 10.0f * StudsY, 0.0f);
*Verts++ = OutBoxMin[0]; *Verts++ = OutBoxMin[1]; *Verts++ = OutBoxMin[2];
*Verts++ = OutBoxMin[0]; *Verts++ = OutBoxMax[1]; *Verts++ = OutBoxMin[2];
*Verts++ = OutBoxMax[0]; *Verts++ = OutBoxMax[1]; *Verts++ = OutBoxMin[2];
*Verts++ = OutBoxMax[0]; *Verts++ = OutBoxMin[1]; *Verts++ = OutBoxMin[2];
*Verts++ = OutBoxMin[0]; *Verts++ = OutBoxMin[1]; *Verts++ = OutBoxMax[2];
*Verts++ = OutBoxMin[0]; *Verts++ = OutBoxMax[1]; *Verts++ = OutBoxMax[2];
*Verts++ = OutBoxMax[0]; *Verts++ = OutBoxMax[1]; *Verts++ = OutBoxMax[2];
*Verts++ = OutBoxMax[0]; *Verts++ = OutBoxMin[1]; *Verts++ = OutBoxMax[2];
}
if (Brick || Plate)
{
const lcVector3 InBoxMin(-10.0f * StudsX + 4.0f, -10.0f * StudsY + 4.0f, MinZ);
const lcVector3 InBoxMax(10.0f * StudsX - 4.0f, 10.0f * StudsY - 4.0f, -4.0f);
*Verts++ = InBoxMin[0]; *Verts++ = InBoxMin[1]; *Verts++ = InBoxMin[2];
*Verts++ = InBoxMin[0]; *Verts++ = InBoxMax[1]; *Verts++ = InBoxMin[2];
*Verts++ = InBoxMax[0]; *Verts++ = InBoxMax[1]; *Verts++ = InBoxMin[2];
*Verts++ = InBoxMax[0]; *Verts++ = InBoxMin[1]; *Verts++ = InBoxMin[2];
*Verts++ = InBoxMin[0]; *Verts++ = InBoxMin[1]; *Verts++ = InBoxMax[2];
*Verts++ = InBoxMin[0]; *Verts++ = InBoxMax[1]; *Verts++ = InBoxMax[2];
*Verts++ = InBoxMax[0]; *Verts++ = InBoxMax[1]; *Verts++ = InBoxMax[2];
*Verts++ = InBoxMax[0]; *Verts++ = InBoxMin[1]; *Verts++ = InBoxMax[2];
}
if (Brick || Plate || Baseplate)
{
for (int x = 0; x < StudsX; x++)
{
for (int y = 0; y < StudsY; y++)
{
const lcVector3 Center(((float)StudsX / 2.0f - x) * 20.0f - 10.0f, ((float)StudsY / 2.0f - y) * 20.0f - 10.0f, 0.0f);
*Verts++ = Center[0]; *Verts++ = Center[1]; *Verts++ = 0.16f;
for (int Step = 0; Step < StudSides; Step++)
{
float s = Center[0] + sinf((float)Step / (float)StudSides * LC_2PI) * 6.0f;
float c = Center[1] + cosf((float)Step / (float)StudSides * LC_2PI) * 6.0f;
*Verts++ = s; *Verts++ = c; *Verts++ = 4.0f;
*Verts++ = s; *Verts++ = c; *Verts++ = 0.0f;
}
}
}
}
if (Mesh->mIndexType == GL_UNSIGNED_SHORT)
return GeneratePieceIndices<GLushort>(Info, Brick, Plate, Baseplate, StudsX, StudsY);
else
return GeneratePieceIndices<GLuint>(Info, Brick, Plate, Baseplate, StudsX, StudsY);
}
template<typename IndexType>
bool lcPiecesLibrary::GeneratePieceIndices(PieceInfo* Info, bool Brick, bool Plate, bool Baseplate, int StudsX, int StudsY)
{
const int StudSides = 16;
lcMesh* Mesh = Info->mMesh;
lcMeshSection* Section = &Mesh->mSections[0];
Section->ColorIndex = gDefaultColor;
Section->IndexOffset = 0;
Section->NumIndices = 0;
Section->PrimitiveType = GL_TRIANGLES;
Section->Texture = NULL;
IndexType* Indices = (IndexType*)Mesh->mIndexBuffer.mData;
if (Brick || Plate || Baseplate)
{
Section->NumIndices += 10 * 3;
*Indices++ = 7; *Indices++ = 6; *Indices++ = 5;
*Indices++ = 7; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 0; *Indices++ = 5; *Indices++ = 4;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 2; *Indices++ = 7; *Indices++ = 6;
*Indices++ = 0; *Indices++ = 3; *Indices++ = 7;
*Indices++ = 0; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 1; *Indices++ = 2; *Indices++ = 6;
*Indices++ = 1; *Indices++ = 6; *Indices++ = 5;
}
if (Brick || Plate)
{
Section->NumIndices += 18 * 3;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 8;
*Indices++ = 1; *Indices++ = 8; *Indices++ = 9;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 10;
*Indices++ = 3; *Indices++ = 10; *Indices++ = 11;
*Indices++ = 0; *Indices++ = 8; *Indices++ = 11;
*Indices++ = 0; *Indices++ = 11; *Indices++ = 3;
*Indices++ = 1; *Indices++ = 9; *Indices++ = 10;
*Indices++ = 1; *Indices++ = 10; *Indices++ = 2;
*Indices++ = 15; *Indices++ = 14; *Indices++ = 13;
*Indices++ = 15; *Indices++ = 13; *Indices++ = 12;
*Indices++ = 8; *Indices++ = 9; *Indices++ = 13;
*Indices++ = 8; *Indices++ = 13; *Indices++ = 12;
*Indices++ = 10; *Indices++ = 11; *Indices++ = 15;
*Indices++ = 10; *Indices++ = 15; *Indices++ = 14;
*Indices++ = 8; *Indices++ = 11; *Indices++ = 15;
*Indices++ = 8; *Indices++ = 15; *Indices++ = 12;
*Indices++ = 9; *Indices++ = 10; *Indices++ = 14;
*Indices++ = 9; *Indices++ = 14; *Indices++ = 13;
}
if (Baseplate)
{
Section->NumIndices += 2 * 3;
*Indices++ = 3; *Indices++ = 2; *Indices++ = 1;
*Indices++ = 3; *Indices++ = 1; *Indices++ = 0;
}
if (Brick || Plate || Baseplate)
{
Section->NumIndices += ((StudSides * 3) * StudsX * StudsY) * 3;
const int FirstVertex = (Brick || Plate) ? 16 : 8;
for (int x = 0; x < StudsX; x++)
{
for (int y = 0; y < StudsY; y++)
{
int CenterIndex = FirstVertex + (StudSides * 2 + 1) * (x + StudsX * y);
int BaseIndex = CenterIndex + 1;
for (int Step = 0; Step < StudSides; Step++)
{
*Indices++ = CenterIndex;
*Indices++ = BaseIndex + Step * 2;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2;
*Indices++ = BaseIndex + Step * 2;
*Indices++ = BaseIndex + Step * 2 + 1;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2;
*Indices++ = BaseIndex + Step * 2 + 1;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2 + 1;
}
}
}
}
Section = &Mesh->mSections[1];
Section->ColorIndex = gEdgeColor;
Section->IndexOffset = (char*)Indices - (char*)Mesh->mIndexBuffer.mData;
Section->NumIndices = 0;
Section->PrimitiveType = GL_LINES;
Section->Texture = NULL;
if (Brick || Plate || Baseplate)
{
Section->NumIndices += 12 * 2;
*Indices++ = 0; *Indices++ = 1; *Indices++ = 1; *Indices++ = 2;
*Indices++ = 2; *Indices++ = 3; *Indices++ = 3; *Indices++ = 0;
*Indices++ = 4; *Indices++ = 5; *Indices++ = 5; *Indices++ = 6;
*Indices++ = 6; *Indices++ = 7; *Indices++ = 7; *Indices++ = 4;
*Indices++ = 0; *Indices++ = 4; *Indices++ = 1; *Indices++ = 5;
*Indices++ = 2; *Indices++ = 6; *Indices++ = 3; *Indices++ = 7;
}
if (Brick || Plate)
{
Section->NumIndices += 12 * 2;
*Indices++ = 8; *Indices++ = 9; *Indices++ = 9; *Indices++ = 10;
*Indices++ = 10; *Indices++ = 11; *Indices++ = 11; *Indices++ = 8;
*Indices++ = 12; *Indices++ = 13; *Indices++ = 13; *Indices++ = 14;
*Indices++ = 14; *Indices++ = 15; *Indices++ = 15; *Indices++ = 12;
*Indices++ = 8; *Indices++ = 12; *Indices++ = 9; *Indices++ = 13;
*Indices++ = 10; *Indices++ = 14; *Indices++ = 11; *Indices++ = 15;
}
if (Brick || Plate || Baseplate)
{
Section->NumIndices += ((StudSides * 2) * StudsX * StudsY) * 2;
const int FirstVertex = (Brick || Plate) ? 16 : 8;
for (int x = 0; x < StudsX; x++)
{
for (int y = 0; y < StudsY; y++)
{
int BaseIndex = FirstVertex + (StudSides * 2 + 1) * (x + StudsX * y) + 1;
for (int Step = 0; Step < StudSides; Step++)
{
*Indices++ = BaseIndex + Step * 2;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2;
*Indices++ = BaseIndex + Step * 2 + 1;
*Indices++ = BaseIndex + ((Step + 1) % StudSides) * 2 + 1;
}
}
}
}
Mesh->UpdateBuffers();
return false;
return true;
}

View file

@ -122,8 +122,7 @@ public:
PieceInfo* FindPiece(const char* PieceName, bool CreatePlaceholderIfMissing);
PieceInfo* CreatePlaceholder(const char* PieceName);
bool LoadPiece(PieceInfo* Info);
bool GeneratePiece(PieceInfo* Info);
void CreateBuiltinPieces();
bool LoadBuiltinPieces();
lcTexture* FindTexture(const char* TextureName);
bool LoadTexture(lcTexture* Texture);
@ -152,6 +151,7 @@ public:
protected:
bool OpenArchive(const char* FileName, lcZipFileType ZipFileType);
bool OpenArchive(lcFile* File, const char* FileName, lcZipFileType ZipFileType);
bool OpenDirectory(const char* Path);
void ReadArchiveDescriptions(const char* OfficialFileName, const char* UnofficialFileName, const char* CachePath);
@ -163,9 +163,6 @@ protected:
bool LoadPrimitive(int PrimitiveIndex);
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData);
template<typename IndexType>
bool GeneratePieceIndices(PieceInfo* Info, bool Brick, bool Plate, bool Baseplate, int StudsX, int StudsY);
char mCacheFileName[LC_MAXPATH];
lcuint64 mCacheFileModifiedTime;
lcZipFile* mCacheFile;

View file

@ -38,6 +38,19 @@ bool lcZipFile::OpenRead(const char* FilePath)
return true;
}
bool lcZipFile::OpenRead(lcFile* File)
{
mFile = File;
if (!Open())
{
mFile = NULL;
return false;
}
return true;
}
bool lcZipFile::OpenWrite(const char* FilePath, bool Append)
{
lcDiskFile* File = new lcDiskFile();

View file

@ -54,6 +54,7 @@ public:
~lcZipFile();
bool OpenRead(const char* FilePath);
bool OpenRead(lcFile* File);
bool OpenWrite(const char* FilePath, bool Append);
bool ExtractFile(int FileIndex, lcMemFile& File, lcuint32 MaxLength = 0xffffffff);
@ -71,7 +72,7 @@ protected:
lcuint64 SearchCentralDir64();
bool CheckFileCoherencyHeader(int FileIndex, lcuint32* SizeVar, lcuint64* OffsetLocalExtraField, lcuint32* SizeLocalExtraField);
lcDiskFile* mFile;
lcFile* mFile;
bool mModified;
bool mZip64;

View file

@ -49,11 +49,9 @@ void PieceInfo::Load()
m_fDimensions[4] = -10.0f;
m_fDimensions[5] = -24.0f;
}
else if (mFlags & LC_PIECE_GENERATED)
lcGetPiecesLibrary()->GeneratePiece(this);
else
lcGetPiecesLibrary()->LoadPiece(this);
}
}
void PieceInfo::Unload()
{

View file

@ -15,7 +15,6 @@
#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_CACHED 0x20 // Piece is saved in the library cache
#define LC_PIECE_GENERATED 0x40 // Mesh is generated in code
#define LC_PIECE_NAME_LEN 256

View file

@ -66,5 +66,6 @@
<file>resources/piece_show_earlier.png</file>
<file>resources/piece_show_later.png</file>
<file>resources/time_add_keys.png</file>
<file>resources/library.zip</file>
</qresource>
</RCC>

BIN
resources/library.zip Normal file

Binary file not shown.