diff --git a/common/lc_application.cpp b/common/lc_application.cpp index c8d1d546..e6365724 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -656,7 +656,7 @@ lcCommandLineOptions lcApplication::ParseCommandLineOptions() } else if (Option == QLatin1String("-sl") || Option == QLatin1String("--stud-logo")) { - ParseInteger(Options.StudLogo, 0, 5); + ParseInteger(Options.StudLogo, 0, 7); if (Options.StudLogo != lcGetProfileInt(LC_PROFILE_STUD_LOGO)) lcGetPiecesLibrary()->SetStudLogo(Options.StudLogo, false); diff --git a/common/lc_colors.cpp b/common/lc_colors.cpp index 3915e8e4..16e81bb5 100644 --- a/common/lc_colors.cpp +++ b/common/lc_colors.cpp @@ -209,46 +209,76 @@ int lcGetBrickLinkColor(int ColorIndex) return 0; } -bool lcLoadColorFile(lcFile& File) +bool lcLoadColorFile(lcFile& File, bool Update) { char Line[1024], Token[1024]; std::vector& Colors = gColorList; lcColor Color, MainColor, EdgeColor; - Colors.clear(); + if (Update) + { + EdgeColor = Colors[lcGetColorIndex(24)]; + for (auto EdgeColorIt = Colors.begin(); EdgeColorIt != Colors.end() ; EdgeColorIt++) + { + if (EdgeColorIt->Code == 24) + { + Colors.erase(EdgeColorIt); + break; + } + } - for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++) - gColorGroups[GroupIdx].Colors.clear(); + MainColor = Colors[lcGetColorIndex(16)]; + for (auto MainColorIt = Colors.begin(); MainColorIt != Colors.end() ; MainColorIt++) + { + if (MainColorIt->Code == 16) + { + Colors.erase(MainColorIt); + break; + } + } - gColorGroups[0].Name = QApplication::tr("Solid", "Colors"); - gColorGroups[1].Name = QApplication::tr("Translucent", "Colors"); - gColorGroups[2].Name = QApplication::tr("Special", "Colors"); + std::vector& SolidColors = gColorGroups[LC_COLORGROUP_SOLID].Colors; + const auto& DefaultColorIt = std::find(SolidColors.begin(), SolidColors.end(), gDefaultColor); + if (DefaultColorIt != SolidColors.end()) + SolidColors.erase(DefaultColorIt); + } + else + { + Colors.clear(); - MainColor.Code = 16; - MainColor.Translucent = false; - MainColor.Value[0] = 1.0f; - MainColor.Value[1] = 1.0f; - MainColor.Value[2] = 0.5f; - MainColor.Value[3] = 1.0f; - MainColor.Edge[0] = 0.2f; - MainColor.Edge[1] = 0.2f; - MainColor.Edge[2] = 0.2f; - MainColor.Edge[3] = 1.0f; - strcpy(MainColor.Name, "Main Color"); - strcpy(MainColor.SafeName, "Main_Color"); + for (int GroupIdx = 0; GroupIdx < LC_NUM_COLORGROUPS; GroupIdx++) + gColorGroups[GroupIdx].Colors.clear(); - EdgeColor.Code = 24; - EdgeColor.Translucent = false; - EdgeColor.Value[0] = 0.5f; - EdgeColor.Value[1] = 0.5f; - EdgeColor.Value[2] = 0.5f; - EdgeColor.Value[3] = 1.0f; - EdgeColor.Edge[0] = 0.2f; - EdgeColor.Edge[1] = 0.2f; - EdgeColor.Edge[2] = 0.2f; - EdgeColor.Edge[3] = 1.0f; - strcpy(EdgeColor.Name, "Edge Color"); - strcpy(EdgeColor.SafeName, "Edge_Color"); + gColorGroups[0].Name = QApplication::tr("Solid", "Colors"); + gColorGroups[1].Name = QApplication::tr("Translucent", "Colors"); + gColorGroups[2].Name = QApplication::tr("Special", "Colors"); + + MainColor.Code = 16; + MainColor.Translucent = false; + MainColor.Value[0] = 1.0f; + MainColor.Value[1] = 1.0f; + MainColor.Value[2] = 0.5f; + MainColor.Value[3] = 1.0f; + MainColor.Edge[0] = 0.2f; + MainColor.Edge[1] = 0.2f; + MainColor.Edge[2] = 0.2f; + MainColor.Edge[3] = 1.0f; + strcpy(MainColor.Name, "Main Color"); + strcpy(MainColor.SafeName, "Main_Color"); + + EdgeColor.Code = 24; + EdgeColor.Translucent = false; + EdgeColor.Value[0] = 0.5f; + EdgeColor.Value[1] = 0.5f; + EdgeColor.Value[2] = 0.5f; + EdgeColor.Value[3] = 1.0f; + EdgeColor.Edge[0] = 0.2f; + EdgeColor.Edge[1] = 0.2f; + EdgeColor.Edge[2] = 0.2f; + EdgeColor.Edge[3] = 1.0f; + strcpy(EdgeColor.Name, "Edge Color"); + strcpy(EdgeColor.SafeName, "Edge_Color"); + } while (File.ReadLine(Line, sizeof(Line))) { @@ -340,7 +370,7 @@ bool lcLoadColorFile(lcFile& File) GroupSpecial = true; } else if (!strcmp(Token, "CHROME") || !strcmp(Token, "PEARLESCENT") || !strcmp(Token, "RUBBER") || - !strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE")) + !strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE")) { GroupSpecial = true; } @@ -361,19 +391,19 @@ bool lcLoadColorFile(lcFile& File) Color.Edge[2] = 33.0f / 255.0f; } - bool Duplicate = false; + bool ExistingColorUpdate = false; for (lcColor& ExistingColor : Colors) { if (ExistingColor.Code == Color.Code) { ExistingColor = Color; - Duplicate = true; + ExistingColorUpdate = true; break; } } - if (Duplicate) + if (ExistingColorUpdate) continue; if (Color.Code == 16) @@ -399,6 +429,7 @@ bool lcLoadColorFile(lcFile& File) } gDefaultColor = (int)Colors.size(); + Colors.push_back(MainColor); gColorGroups[LC_COLORGROUP_SOLID].Colors.push_back(gDefaultColor); @@ -415,7 +446,7 @@ void lcLoadDefaultColors() lcDiskFile ConfigFile(":/resources/ldconfig.ldr"); if (ConfigFile.Open(QIODevice::ReadOnly)) - lcLoadColorFile(ConfigFile); + lcLoadColorFile(ConfigFile, false); } int lcGetColorIndex(quint32 ColorCode) @@ -455,3 +486,72 @@ int lcGetColorIndex(quint32 ColorCode) gColorList.push_back(Color); return (int)gColorList.size() - 1; } + +void lcLoadLegoStyleDisplayColors() +{ + QByteArray ColorData; + const char *ColorEntry = "0 !COLOUR Stud_Style_Black CODE 4242 VALUE #1B2A34 EDGE #000000\r\n"; + ColorData.append(ColorEntry); + lcMemFile ColorMemFile; + ColorMemFile.WriteBuffer(ColorData.constData(), ColorData.size()); + ColorMemFile.Seek(0, SEEK_SET); + + lcLoadColorFile(ColorMemFile, true); + + lcColor* DarkGrey = &gColorList[lcGetColorIndexByName("Stud Style Dark Gray Edge")]; + lcColor* Black = &gColorList[lcGetColorIndexByName("Stud Style Black Edge")]; + + for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++) + { + lcColor* Color = &gColorList[ColorIdx]; + if (Color->Code == 4242) + continue; + + float r = 0.0f, g = 0.0f, b = 0.0f; + float rr = Color->Value[0] * 255.0f, + gg = Color->Value[1] * 255.0f, + bb = Color->Value[2] * 255.0f; + if (30 * rr + 59 * gg + 11 * bb <= 3600) + { + if (DarkGrey) + { + r = DarkGrey->Edge[0]; + g = DarkGrey->Edge[1]; + b = DarkGrey->Edge[2]; + } + else + { + r = 27.0f; + g = 42.0f; + b = 52.0f; + } + } + else + { + if (Color->Code == 0) + { + r = 255.0f; + g = 255.0f; + b = 255.0f; + } + else if (Black) + { + r = Black->Edge[0]; + g = Black->Edge[1]; + b = Black->Edge[2]; + } + } + + Color->Edge[0] = r / 255.0f; + Color->Edge[1] = g / 255.0f; + Color->Edge[2] = b / 255.0f; + } +} + +int lcGetColorIndexByName(const char * ColorName) +{ + for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++) + if (gColorList[ColorIdx].Name == ColorName) + return (int)ColorIdx; + return 0x0; +} diff --git a/common/lc_colors.h b/common/lc_colors.h index 50dad8eb..bb102d96 100644 --- a/common/lc_colors.h +++ b/common/lc_colors.h @@ -49,8 +49,10 @@ extern int gEdgeColor; extern int gDefaultColor; void lcLoadDefaultColors(); -bool lcLoadColorFile(lcFile& File); +void lcLoadLegoStyleDisplayColors(); +bool lcLoadColorFile(lcFile& File, bool Update); int lcGetColorIndex(quint32 ColorCode); +int lcGetColorIndexByName(const char * ColorName); int lcGetBrickLinkColor(int ColorIndex); inline quint32 lcGetColorCodeFromExtendedColor(int Color) diff --git a/common/lc_library.cpp b/common/lc_library.cpp index eefadbee..3491fda5 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -238,24 +238,9 @@ bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress) { Unload(); - auto LoadCustomColors = []() - { - QString CustomColorsPath = lcGetProfileString(LC_PROFILE_COLOR_CONFIG); - - if (CustomColorsPath.isEmpty()) - return false; - - lcDiskFile ColorFile(CustomColorsPath); - return ColorFile.Open(QIODevice::ReadOnly) && lcLoadColorFile(ColorFile); - }; - if (OpenArchive(LibraryPath, lcZipFileType::Official)) { - lcMemFile ColorFile; - - if (!LoadCustomColors()) - if (!mZipFiles[static_cast(lcZipFileType::Official)]->ExtractFile("ldraw/ldconfig.ldr", ColorFile) || !lcLoadColorFile(ColorFile)) - lcLoadDefaultColors(); + LoadColors(false); mLibraryDir = QFileInfo(LibraryPath).absoluteDir(); QString UnofficialFileName = mLibraryDir.absoluteFilePath(QLatin1String("ldrawunf.zip")); @@ -270,20 +255,7 @@ bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress) mLibraryDir.setPath(LibraryPath); if (OpenDirectory(mLibraryDir, ShowProgress)) - { - if (!LoadCustomColors()) - { - lcDiskFile ColorFile(mLibraryDir.absoluteFilePath(QLatin1String("ldconfig.ldr"))); - - if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile)) - { - ColorFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String("LDConfig.ldr"))); - - if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile)) - lcLoadDefaultColors(); - } - } - } + LoadColors(false); else return false; } @@ -295,6 +267,44 @@ bool lcPiecesLibrary::Load(const QString& LibraryPath, bool ShowProgress) return true; } +void lcPiecesLibrary::LoadColors(bool Update) +{ + auto LoadCustomColors = [&Update]() + { + QString CustomColorsPath = lcGetProfileString(LC_PROFILE_COLOR_CONFIG); + + if (CustomColorsPath.isEmpty()) + return false; + + lcDiskFile ColorFile(CustomColorsPath); + return ColorFile.Open(QIODevice::ReadOnly) && lcLoadColorFile(ColorFile, Update); + }; + + if (mZipFiles[static_cast(lcZipFileType::Official)]) + { + lcMemFile ColorFile; + + if (!LoadCustomColors()) + if (!mZipFiles[static_cast(lcZipFileType::Official)]->ExtractFile("ldraw/ldconfig.ldr", ColorFile) || !lcLoadColorFile(ColorFile, Update)) + lcLoadDefaultColors(); + } + else + { + if (!LoadCustomColors()) + { + lcDiskFile ColorFile(mLibraryDir.absoluteFilePath(QLatin1String("ldconfig.ldr"))); + + if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile, Update)) + { + ColorFile.SetFileName(mLibraryDir.absoluteFilePath(QLatin1String("LDConfig.ldr"))); + + if (!ColorFile.Open(QIODevice::ReadOnly) || !lcLoadColorFile(ColorFile, Update)) + lcLoadDefaultColors(); + } + } + } +} + void lcPiecesLibrary::UpdateStudLogoSource() { if (!mSources.empty() && mSources.front()->Type == lcLibrarySourceType::StudLogo) @@ -305,7 +315,16 @@ void lcPiecesLibrary::UpdateStudLogoSource() if (!mStudLogo) return; - std::unique_ptr StudLogoFile(new lcDiskFile(QString(":/resources/studlogo%1.zip").arg(QString::number(mStudLogo)))); + if (mStudLogo > 5) + lcLoadLegoStyleDisplayColors(); + + std::unique_ptr StudLogoFile; + if (mStudLogo < 6) + StudLogoFile = std::unique_ptr(new lcDiskFile(QString(":/resources/studlogo%1.zip").arg(QString::number(mStudLogo)))); + else if (mStudLogo == 6) + StudLogoFile = std::unique_ptr(new lcDiskFile(QString(":/resources/studslegostyle1.zip"))); + else + StudLogoFile = std::unique_ptr(new lcDiskFile(QString(":/resources/studslegostyle2.zip"))); if (StudLogoFile->Open(QIODevice::ReadOnly)) OpenArchive(std::move(StudLogoFile), lcZipFileType::StudLogo); @@ -1520,6 +1539,9 @@ bool lcPiecesLibrary::SupportsStudLogo() const void lcPiecesLibrary::SetStudLogo(int StudLogo, bool Reload) { + if (mStudLogo > 5 && StudLogo < 6 && Reload) + LoadColors(Reload); + mStudLogo = StudLogo; UpdateStudLogoSource(); @@ -1602,6 +1624,21 @@ bool lcPiecesLibrary::LoadPrimitive(lcLibraryPrimitive* Primitive) lcMeshLoader MeshLoader(Primitive->mMeshData, true, nullptr, false); + auto StudLogoPrimitive = [this, &Primitive] () + { + if (!mSources.empty() && mSources.front()->Type == lcLibrarySourceType::StudLogo) + { + char Name[LC_PIECE_NAME_LEN]; + strcpy(Name, Primitive->mName); + strupr(Name); + const std::unique_ptr& Source = mSources.front(); + const auto& PrimitiveIt = Source->Primitives.find(Name); + if (PrimitiveIt != Source->Primitives.end()) + return true; + } + return false; + }; + if (mZipFiles[static_cast(lcZipFileType::Official)]) { lcLibraryPrimitive* LowPrimitive = nullptr; @@ -1610,7 +1647,7 @@ bool lcPiecesLibrary::LoadPrimitive(lcLibraryPrimitive* Primitive) if (Primitive->mStud) { - if (!strcmp(Primitive->mName, "stud.dat") || !strcmp(Primitive->mName, "stud2.dat")) + if (StudLogoPrimitive()) Primitive->mMeshData.mHasLogoStud = true; else if (strncmp(Primitive->mName, "8/", 2)) // todo: this is currently the only place that uses mName so use mFileName instead. this should also be done for the loose file libraries. { @@ -1647,7 +1684,7 @@ bool lcPiecesLibrary::LoadPrimitive(lcLibraryPrimitive* Primitive) { if (Primitive->mStud) { - if (!strcmp(Primitive->mName,"stud.dat") || !strcmp(Primitive->mName, "stud2.dat")) + if (StudLogoPrimitive()) Primitive->mMeshData.mHasLogoStud = true; } diff --git a/common/lc_library.h b/common/lc_library.h index d7c70bd9..1592f859 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -102,6 +102,7 @@ public: lcPiecesLibrary& operator=(lcPiecesLibrary&&) = delete; bool Load(const QString& LibraryPath, bool ShowProgress); + void LoadColors(bool Update); void Unload(); void RemoveTemporaryPieces(); void RemovePiece(PieceInfo* Info); diff --git a/leocad.qrc b/leocad.qrc index f9a05af1..a5e03d3c 100644 --- a/leocad.qrc +++ b/leocad.qrc @@ -101,6 +101,8 @@ resources/studlogo3.zip resources/studlogo4.zip resources/studlogo5.zip + resources/studslegostyle1.zip + resources/studslegostyle2.zip resources/ldconfig.ldr resources/minifig.ini resources/ldraw.xml diff --git a/qt/lc_qpreferencesdialog.h b/qt/lc_qpreferencesdialog.h index fa448dd8..c2ca24b4 100644 --- a/qt/lc_qpreferencesdialog.h +++ b/qt/lc_qpreferencesdialog.h @@ -41,7 +41,7 @@ class lcQPreferencesDialog; class lcQPreferencesDialog : public QDialog { Q_OBJECT - + public: lcQPreferencesDialog(QWidget* Parent, lcPreferencesDialogOptions* Options); ~lcQPreferencesDialog(); diff --git a/qt/lc_qpreferencesdialog.ui b/qt/lc_qpreferencesdialog.ui index 5a92909b..3aed1786 100644 --- a/qt/lc_qpreferencesdialog.ui +++ b/qt/lc_qpreferencesdialog.ui @@ -390,27 +390,37 @@ - Logo1 + 1 LDraw Single Wire - Logo2 + 2 LDraw Double Wire - Logo3 + 3 LDraw Raised Floating - Logo4 + 4 LDraw Raised Rounded - Logo5 + 5 LDraw Subtle Rounded + + + + + 6 LEGO Without Logo + + + + + 7 LEGO Single Wire diff --git a/resources/studslegostyle1.zip b/resources/studslegostyle1.zip new file mode 100644 index 00000000..245efb6f Binary files /dev/null and b/resources/studslegostyle1.zip differ diff --git a/resources/studslegostyle2.zip b/resources/studslegostyle2.zip new file mode 100644 index 00000000..c4426e11 Binary files /dev/null and b/resources/studslegostyle2.zip differ