From 0e74aea5fa484d9dede13a18ed2a2b2c41f4a424 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sun, 19 Nov 2023 18:05:43 -0800 Subject: [PATCH] Fixed POV-Ray area light grid. --- common/lc_math.h | 15 ++++++++++++ common/lc_model.cpp | 14 ++++++++++- common/lc_model.h | 3 ++- common/light.cpp | 17 ++++++++++++++ common/light.h | 9 +++++++ common/object.cpp | 1 + common/project.cpp | 12 +++++----- qt/lc_qpropertiestree.cpp | 49 ++++++++++++++++++++++++++++++++++++++- qt/lc_qpropertiestree.h | 3 +++ 9 files changed, 114 insertions(+), 9 deletions(-) diff --git a/common/lc_math.h b/common/lc_math.h index 4e2e7090..fb89a6b3 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -51,6 +51,21 @@ inline T lcClamp(const T& Value, const T& Min, const T& Max) return Value; } +class lcVector2i +{ +public: + lcVector2i() + { + } + + constexpr lcVector2i(const int _x, const int _y) + : x(_x), y(_y) + { + } + + int x, y; +}; + class lcVector2 { public: diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 37836427..cb339a65 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -3215,7 +3215,7 @@ void lcModel::SetSpotLightTightness(lcLight* Light, float Tightness) UpdateAllViews(); } -void lcModel::SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape) +void lcModel::SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape) { if (!Light->SetAreaShape(LightAreaShape)) return; @@ -3227,6 +3227,18 @@ void lcModel::SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape) UpdateAllViews(); } +void lcModel::SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid) +{ + if (!Light->SetAreaGrid(AreaGrid, mCurrentStep, gMainWindow->GetAddKeys())) + return; + + Light->UpdatePosition(mCurrentStep); + + SaveCheckpoint(tr("Changing Area Light Size")); + gMainWindow->UpdateSelectedObjects(false); + UpdateAllViews(); +} + void lcModel::SetLightSize(lcLight* Light, lcVector2 LightAreaSize) { Light->SetSize(LightAreaSize, mCurrentStep, gMainWindow->GetAddKeys()); diff --git a/common/lc_model.h b/common/lc_model.h index 7ec1349b..dd99f74c 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -373,7 +373,8 @@ public: void SetSpotLightConeAngle(lcLight* Light, float Angle); void SetSpotLightPenumbraAngle(lcLight* Light, float Angle); void SetSpotLightTightness(lcLight* Light, float Tightness); - void SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape); + void SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape); + void SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid); void SetLightSize(lcLight* Light, lcVector2 LightAreaSize); void SetLightPower(lcLight* Light, float Power); void SetLightCastShadow(lcLight* Light, bool CastShadow); diff --git a/common/light.cpp b/common/light.cpp index d1fb7fd7..ccb8819b 100644 --- a/common/light.cpp +++ b/common/light.cpp @@ -43,6 +43,7 @@ lcLight::lcLight(const lcVector3& Position, lcLightType LightType) mSpotConeAngleKeys.ChangeKey(mSpotConeAngle, 1, true); mSpotPenumbraAngleKeys.ChangeKey(mSpotPenumbraAngle, 1, true); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); + mAreaGridKeys.ChangeKey(mAreaGrid, 1, true); mAttenuationKeys.ChangeKey(mAttenuation, 1, true); mLightDiffuseKeys.ChangeKey(mLightDiffuse, 1, true); @@ -189,6 +190,7 @@ void lcLight::SaveLDraw(QTextStream& Stream) const case lcLightType::Area: Stream << QLatin1String("0 !LEOCAD LIGHT AREA_SHAPE ") << gLightAreaShapes[static_cast(mAreaShape)] << LineEnding; + SaveAttribute(Stream, mAreaGrid, mAreaGridKeys, "LIGHT", "AREA_GRID"); break; } @@ -324,6 +326,8 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream) } } } + else if (LoadAttribute(Stream, Token, mAreaGrid, mAreaGridKeys, "AREA_GRID")) + continue; // else if (Token == QLatin1String("POWER") || Token == QLatin1String("STRENGTH")) // { @@ -690,6 +694,13 @@ bool lcLight::SetAreaShape(lcLightAreaShape AreaShape) return false; } +bool lcLight::SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey) +{ + mAreaGridKeys.ChangeKey(AreaGrid, Step, AddKey); + + return true; +} + void lcLight::SetSize(lcVector2 Size, lcStep Step, bool AddKey) { if (mLightType == lcLightType::Area && (mAreaShape == lcLightAreaShape::Square || mAreaShape == lcLightAreaShape::Disk)) @@ -722,6 +733,7 @@ void lcLight::InsertTime(lcStep Start, lcStep Time) mSpotConeAngleKeys.InsertTime(Start, Time); mSpotPenumbraAngleKeys.InsertTime(Start, Time); mSpotTightnessKeys.InsertTime(Start, Time); + mAreaGridKeys.InsertTime(Start, Time); mSizeKeys.InsertTime(Start, Time); mPowerKeys.InsertTime(Start, Time); @@ -740,6 +752,7 @@ void lcLight::RemoveTime(lcStep Start, lcStep Time) mSpotConeAngleKeys.RemoveTime(Start, Time); mSpotPenumbraAngleKeys.RemoveTime(Start, Time); mSpotTightnessKeys.RemoveTime(Start, Time); + mAreaGridKeys.RemoveTime(Start, Time); mSizeKeys.RemoveTime(Start, Time); mPowerKeys.RemoveTime(Start, Time); @@ -769,6 +782,7 @@ void lcLight::UpdatePosition(lcStep Step) mSpotConeAngle = mSpotConeAngleKeys.CalculateKey(Step); mSpotPenumbraAngle = mSpotPenumbraAngleKeys.CalculateKey(Step); mSpotTightness = mSpotTightnessKeys.CalculateKey(Step); + mAreaGrid = mAreaGridKeys.CalculateKey(Step); mSize = mSizeKeys.CalculateKey(Step); mPower = mPowerKeys.CalculateKey(Step); @@ -1207,6 +1221,9 @@ void lcLight::RemoveKeyFrames() mSpotTightnessKeys.RemoveAll(); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); + mAreaGridKeys.RemoveAll(); + mAreaGridKeys.ChangeKey(mAreaGrid, 1, true); + mSizeKeys.RemoveAll(); mSizeKeys.ChangeKey(mSize, 1, true); diff --git a/common/light.h b/common/light.h index 2dc73b04..3f4faf68 100644 --- a/common/light.h +++ b/common/light.h @@ -276,6 +276,13 @@ public: return mAreaShape; } + bool SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey); + + lcVector2i GetAreaGrid() const + { + return mAreaGrid; + } + void SetSize(lcVector2 Size, lcStep Step, bool AddKey); lcVector2 GetSize() const @@ -364,6 +371,7 @@ protected: float mSpotPenumbraAngle = 0.0f; float mSpotTightness = 0.0f; lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle; + lcVector2i mAreaGrid = lcVector2i(2, 2); quint32 mState = 0; bool mSelected = false; @@ -378,6 +386,7 @@ protected: lcObjectKeyArray mSpotConeAngleKeys; lcObjectKeyArray mSpotPenumbraAngleKeys; lcObjectKeyArray mSpotTightnessKeys; + lcObjectKeyArray mAreaGridKeys; lcObjectKeyArray mAttenuationKeys; lcObjectKeyArray mLightSpecularKeys; diff --git a/common/object.cpp b/common/object.cpp index fefc71f6..4eed9443 100644 --- a/common/object.cpp +++ b/common/object.cpp @@ -12,6 +12,7 @@ template bool lcObject::LoadAttribute(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray& Keys, const char* VariableName) LC_OBJECT_ATTRIBUTE(float); +LC_OBJECT_ATTRIBUTE(lcVector2i); LC_OBJECT_ATTRIBUTE(lcVector2); LC_OBJECT_ATTRIBUTE(lcVector3); LC_OBJECT_ATTRIBUTE(lcVector4); diff --git a/common/project.cpp b/common/project.cpp index 5e77ad7a..d8a6a64c 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -2140,7 +2140,7 @@ bool Project::ExportPOVRay(const QString& FileName) POVFile.WriteLine(Line); lcVector3 AreaX(1.0f, 0.0f, 0.0f), AreaY(0.0f, 1.0f, 0.0f); - lcVector2 AreaSize(200.0f, 200.0f); + lcVector2i AreaGrid(1, 1); int AreaCircle = 0, Shadowless = 0; lcLightType LightType = lcLightType::Area; float Power = 0, SpotRadius = 0, SpotFalloff = 0, SpotTightness = 0; @@ -2167,7 +2167,7 @@ bool Project::ExportPOVRay(const QString& FileName) LightColor[0], LightColor[1], LightColor[2], Power, SpotRadius, SpotFalloff, SpotTightness, - AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], (int)AreaSize[0], (int)AreaSize[1]); + AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y); POVFile.WriteLine(Line); } } @@ -2198,9 +2198,9 @@ bool Project::ExportPOVRay(const QString& FileName) case lcLightType::Area: AreaCircle = (Light->GetAreaShape() == lcLightAreaShape::Disk || Light->GetAreaShape() == lcLightAreaShape::Ellipse) ? 1 : 0; - AreaSize = Light->GetSize(); - AreaX = lcVector3(Light->GetWorldMatrix()[0]); - AreaY = lcVector3(Light->GetWorldMatrix()[1]); + AreaX = lcVector3(Light->GetWorldMatrix()[0]) * Light->GetSize().x; + AreaY = lcVector3(Light->GetWorldMatrix()[1]) * Light->GetSize().y; + AreaGrid = Light->GetAreaGrid(); break; case lcLightType::Count: @@ -2216,7 +2216,7 @@ bool Project::ExportPOVRay(const QString& FileName) LightColor[0], LightColor[1], LightColor[2], Power, SpotRadius, SpotFalloff, SpotTightness, - AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], (int)AreaSize[0], (int)AreaSize[1]); + AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y); POVFile.WriteLine(Line); } } diff --git a/qt/lc_qpropertiestree.cpp b/qt/lc_qpropertiestree.cpp index c4a07d32..24ff25bb 100644 --- a/qt/lc_qpropertiestree.cpp +++ b/qt/lc_qpropertiestree.cpp @@ -447,6 +447,20 @@ QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item) return Editor; } + case PropertyInteger: + { + QLineEdit* Editor = new QLineEdit(Parent); + int Value = Item->data(0, PropertyValueRole).toInt(); + QPoint Range = Item->data(0, PropertyRangeRole).toPoint(); + + Editor->setValidator(Range.isNull() ? new QIntValidator(Editor) : new QIntValidator(Range.x(), Range.y(), Editor)); + Editor->setText(QString::number(Value)); + + connect(Editor, &QLineEdit::returnPressed, this, &lcQPropertiesTree::slotReturnPressed); + + return Editor; + } + case PropertyStep: { QLineEdit* Editor = new QLineEdit(Parent); @@ -842,6 +856,20 @@ void lcQPropertiesTree::slotReturnPressed() Model->SetSpotLightTightness(Light, Value); } + else if (Item == mLightAreaGridXItem) + { + lcVector2i AreaGrid = Light->GetAreaGrid(); + AreaGrid.x = Editor->text().toInt(); + + Model->SetLightAreaGrid(Light, AreaGrid); + } + else if (Item == mLightAreaGridYItem) + { + lcVector2i AreaGrid = Light->GetAreaGrid(); + AreaGrid.y = Editor->text().toInt(); + + Model->SetLightAreaGrid(Light, AreaGrid); + } else if (Item == mLightSizeXItem) { lcVector2 Value = Light->GetSize(); @@ -954,7 +982,7 @@ void lcQPropertiesTree::slotSetValue(int Value) } else if (Item == mLightAreaShapeItem) { - Model->SetAreaLightShape(Light, static_cast(Value)); + Model->SetLightAreaShape(Light, static_cast(Value)); } else if (Item == lightFormat) { @@ -1100,6 +1128,8 @@ void lcQPropertiesTree::SetEmpty() mLightSpotPenumbraAngleItem = nullptr; mLightSpotTightnessItem = nullptr; mLightAreaShapeItem = nullptr; + mLightAreaGridXItem = nullptr; + mLightAreaGridYItem = nullptr; mLightSizeXItem = nullptr; mLightSizeYItem = nullptr; lightFormat = nullptr; @@ -1355,6 +1385,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) lcLightType LightType = lcLightType::Point; lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle; lcVector2 LightSize(0.0f, 0.0f); + lcVector2i AreaGrid(2, 2); float Power = 0.0f; int FormatIndex = 0; float Diffuse = 0.0f; @@ -1386,6 +1417,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) LightType = Light->GetLightType(); LightAreaShape = Light->GetAreaShape(); LightSize = Light->GetSize(); + AreaGrid = Light->GetAreaGrid(); switch (LightType) { @@ -1498,6 +1530,15 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) case lcLightAreaShape::Count: break; } + + mLightAreaGridXItem = addProperty(mLightAttributesItem, tr("Area Grid X"), PropertyInteger); + mLightAreaGridXItem->setToolTip(1, tr("Number of point sources along the X axis (POV-Ray only).")); + mLightAreaGridXItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX)); + + mLightAreaGridYItem = addProperty(mLightAttributesItem, tr("Area Grid Y"), PropertyInteger); + mLightAreaGridYItem->setToolTip(1, tr("Number of point sources along the Y axis (POV-Ray only).")); + mLightAreaGridYItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX)); + break; case lcLightType::Count: @@ -1630,6 +1671,12 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) case lcLightType::Area: mLightAreaShapeItem->setText(1, lcLight::GetAreaShapeString(LightAreaShape)); mLightAreaShapeItem->setData(0, PropertyValueRole, static_cast(LightAreaShape)); + + mLightAreaGridXItem->setText(1, QString::number(AreaGrid.x)); + mLightAreaGridXItem->setData(0, PropertyValueRole, AreaGrid.x); + + mLightAreaGridYItem->setText(1, QString::number(AreaGrid.y)); + mLightAreaGridYItem->setData(0, PropertyValueRole, AreaGrid.y); break; case lcLightType::Count: diff --git a/qt/lc_qpropertiestree.h b/qt/lc_qpropertiestree.h index d6d1e8f2..148d3244 100644 --- a/qt/lc_qpropertiestree.h +++ b/qt/lc_qpropertiestree.h @@ -45,6 +45,7 @@ public: PropertyGroup, PropertyBool, PropertyFloat, + PropertyInteger, PropertyStep, PropertyString, PropertyStringList, @@ -128,6 +129,8 @@ protected: QTreeWidgetItem* mLightSpotPenumbraAngleItem; QTreeWidgetItem* mLightSpotTightnessItem; QTreeWidgetItem* mLightAreaShapeItem; + QTreeWidgetItem* mLightAreaGridXItem; + QTreeWidgetItem* mLightAreaGridYItem; QTreeWidgetItem* mLightSizeXItem; QTreeWidgetItem* mLightSizeYItem; QTreeWidgetItem* mLightNameItem;