diff --git a/common/lc_global.h b/common/lc_global.h index 48a3b33e..53335edb 100644 --- a/common/lc_global.h +++ b/common/lc_global.h @@ -76,6 +76,7 @@ class lcPiece; class lcCamera; class lcLight; enum class lcLightType; +enum class lcLightAreaShape; class lcGroup; class PieceInfo; typedef std::map> lcPartsList; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 1085028d..f9710522 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -3163,7 +3163,9 @@ void lcModel::SetCameraName(lcCamera* Camera, const QString& Name) void lcModel::SetLightType(lcLight* Light, lcLightType LightType) { - Light->SetLightType(LightType); + if (!Light->SetLightType(LightType)) + return; + Light->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Changing Light Type")); @@ -3173,9 +3175,6 @@ void lcModel::SetLightType(lcLight* Light, lcLightType LightType) void lcModel::SetLightColor(lcLight* Light, const lcVector3& Color) { - if (Light->GetColor() == Color) - return; - Light->SetColor(Color, mCurrentStep, gMainWindow->GetAddKeys()); Light->UpdatePosition(mCurrentStep); @@ -3186,9 +3185,6 @@ void lcModel::SetLightColor(lcLight* Light, const lcVector3& Color) void lcModel::SetSpotLightConeAngle(lcLight* Light, float Angle) { - if (Light->GetSpotConeAngle() == Angle) - return; - Light->SetSpotConeAngle(Angle, mCurrentStep, gMainWindow->GetAddKeys()); Light->UpdatePosition(mCurrentStep); @@ -3199,9 +3195,6 @@ void lcModel::SetSpotLightConeAngle(lcLight* Light, float Angle) void lcModel::SetSpotLightPenumbraAngle(lcLight* Light, float Angle) { - if (Light->GetSpotPenumbraAngle() == Angle) - return; - Light->SetSpotPenumbraAngle(Angle, mCurrentStep, gMainWindow->GetAddKeys()); Light->UpdatePosition(mCurrentStep); @@ -3212,9 +3205,6 @@ void lcModel::SetSpotLightPenumbraAngle(lcLight* Light, float Angle) void lcModel::SetSpotLightTightness(lcLight* Light, float Tightness) { - if (Light->GetSpotTightness() == Tightness) - return; - Light->SetSpotTightness(Tightness, mCurrentStep, gMainWindow->GetAddKeys()); Light->UpdatePosition(mCurrentStep); @@ -3223,12 +3213,33 @@ void lcModel::SetSpotLightTightness(lcLight* Light, float Tightness) UpdateAllViews(); } -void lcModel::SetLightCastShadow(lcLight* Light, bool CastShadow) +void lcModel::SetAreaLightShape(lcLight* Light, lcLightAreaShape LightAreaShape) { - if (Light->GetCastShadow() == CastShadow) + if (!Light->SetAreaShape(LightAreaShape)) + return; + + Light->UpdatePosition(mCurrentStep); + + SaveCheckpoint(tr("Changing Area Light Shape")); + gMainWindow->UpdateSelectedObjects(false); + UpdateAllViews(); +} + +void lcModel::SetAreaLightSize(lcLight* Light, lcVector2 LightAreaSize) +{ + Light->SetAreaSize(LightAreaSize, mCurrentStep, gMainWindow->GetAddKeys()); + Light->UpdatePosition(mCurrentStep); + + SaveCheckpoint(tr("Changing Area Light Size")); + gMainWindow->UpdateSelectedObjects(false); + UpdateAllViews(); +} + +void lcModel::SetLightCastShadow(lcLight* Light, bool CastShadow) +{ + if (!Light->SetCastShadow(CastShadow)) return; - Light->SetCastShadow(CastShadow); Light->UpdatePosition(mCurrentStep); SaveCheckpoint(tr("Changing Light Shadow")); diff --git a/common/lc_model.h b/common/lc_model.h index 0adcc909..32ae4869 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -373,6 +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 SetAreaLightSize(lcLight* Light, lcVector2 LightAreaSize); void SetLightCastShadow(lcLight* Light, bool CastShadow); void SetLightName(lcLight* Light, const QString& Name); void UpdateLight(lcLight* Light, const lcLightProperties Props, int Property); diff --git a/common/light.cpp b/common/light.cpp index 334e0bbb..9f24777d 100644 --- a/common/light.cpp +++ b/common/light.cpp @@ -18,6 +18,7 @@ #define LC_LIGHT_POSITION_EDGE 7.5f static const std::array(lcLightType::Count)> gLightTypes = { QLatin1String("POINT"), QLatin1String("SPOT"), QLatin1String("DIRECTIONAL"), QLatin1String("AREA") }; +static const std::array(lcLightAreaShape::Count)> gLightAreaShapes = { QLatin1String("RECTANGLE"), QLatin1String("SQUARE"), QLatin1String("DISK"), QLatin1String("ELLIPSE") }; lcLight::lcLight(const lcVector3& Position, lcLightType LightType) : lcObject(lcObjectType::Light), mLightType(LightType) @@ -35,15 +36,14 @@ lcLight::lcLight(const lcVector3& Position, lcLightType LightType) mPOVRayExponent = 1.0f; mSpotCutoff = LightType != lcLightType::Directional ? 40.0f : 0.0f; mAreaGrid = lcVector2(10.0f, 10.0f); - mAreaSize = lcVector2(200.0f, 200.0f); - mLightShape = LC_LIGHT_SHAPE_SQUARE; - + mPositionKeys.ChangeKey(mWorldMatrix.GetTranslation(), 1, true); mRotationKeys.ChangeKey(lcMatrix33(mWorldMatrix), 1, true); mColorKeys.ChangeKey(mColor, 1, true); mSpotConeAngleKeys.ChangeKey(mSpotConeAngle, 1, true); mSpotPenumbraAngleKeys.ChangeKey(mSpotPenumbraAngle, 1, true); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); + mAreaSizeKeys.ChangeKey(mAreaSize, 1, true); mAttenuationKeys.ChangeKey(mAttenuation, 1, true); mLightFactorKeys.ChangeKey(mLightFactor, 1, true); @@ -56,7 +56,7 @@ lcLight::lcLight(const lcVector3& Position, lcLightType LightType) UpdatePosition(1); } -QString lcLight::GetLightTypeString(lcLightType LightType) +QString lcLight::GetTypeString(lcLightType LightType) { switch (LightType) { @@ -79,6 +79,29 @@ QString lcLight::GetLightTypeString(lcLightType LightType) return QString(); } +QString lcLight::GetAreaShapeString(lcLightAreaShape LightAreaShape) +{ + switch (LightAreaShape) + { + case lcLightAreaShape::Rectangle: + return QT_TRANSLATE_NOOP("Light Shapes", "Rectangle"); + + case lcLightAreaShape::Square: + return QT_TRANSLATE_NOOP("Light Shapes", "Square"); + + case lcLightAreaShape::Disk: + return QT_TRANSLATE_NOOP("Light Shapes", "Disk"); + + case lcLightAreaShape::Ellipse: + return QT_TRANSLATE_NOOP("Light Shapes", "Ellipse"); + + case lcLightAreaShape::Count: + break; + } + + return QString(); +} + void lcLight::SaveLDraw(QTextStream& Stream) const { const QLatin1String LineEnding("\r\n"); @@ -167,10 +190,7 @@ void lcLight::SaveLDraw(QTextStream& Stream) const else Stream << QLatin1String("0 !LEOCAD LIGHT SPOT_TIGHTNESS ") << mSpotTightness << LineEnding; - if (mPOVRayLight) - { - } - else + if (!mPOVRayLight) { if (mLightFactorKeys.GetSize() > 1) mLightFactorKeys.SaveKeysLDraw(Stream, "LIGHT RADIUS_AND_SPOT_BLEND_KEY "); @@ -202,44 +222,13 @@ void lcLight::SaveLDraw(QTextStream& Stream) const else Stream << QLatin1String("0 !LEOCAD LIGHT AREA_ROWS ") << mAreaGrid[0] << QLatin1String(" AREA_COLUMNS ") << mAreaGrid[1] << LineEnding; } - if (mLightFactorKeys.GetSize() > 1) - mLightFactorKeys.SaveKeysLDraw(Stream, "LIGHT SIZE_KEY "); + + Stream << QLatin1String("0 !LEOCAD LIGHT SHAPE ") << gLightAreaShapes[static_cast(mAreaShape)] << LineEnding; + + if (mAreaSizeKeys.GetSize() > 1) + mAreaSizeKeys.SaveKeysLDraw(Stream, "LIGHT AREA_SIZE_KEY "); else - { - if (mPOVRayLight) - { - Stream << QLatin1String("0 !LEOCAD LIGHT WIDTH ") << mAreaSize[0] << QLatin1String(" HEIGHT ") << mAreaSize[1] << LineEnding; - } - else - { - if (mLightShape == LC_LIGHT_SHAPE_RECTANGLE || mLightShape == LC_LIGHT_SHAPE_ELLIPSE || mLightFactor[1] > 0) - Stream << QLatin1String("0 !LEOCAD LIGHT WIDTH ") << mLightFactor[0] << QLatin1String(" HEIGHT ") << mLightFactor[1] << LineEnding; - else - Stream << QLatin1String("0 !LEOCAD LIGHT SIZE ") << mLightFactor[0] << LineEnding; - } - } - - Stream << QLatin1String("0 !LEOCAD LIGHT SHAPE "); - - QString Shape = QLatin1String("UNDEFINED "); - - switch (mLightShape) - { - case LC_LIGHT_SHAPE_SQUARE: - Shape = QLatin1String("SQUARE "); - break; - case LC_LIGHT_SHAPE_DISK: - Shape = QLatin1String("DISK "); - break; - case LC_LIGHT_SHAPE_RECTANGLE: - Shape = QLatin1String("RECTANGLE "); - break; - case LC_LIGHT_SHAPE_ELLIPSE: - Shape = QLatin1String("ELLIPSE "); - break; - } - - Stream << QLatin1String("0 !LEOCAD LIGHT SHAPE ") << Shape << LineEnding; + Stream << QLatin1String("0 !LEOCAD LIGHT AREA_SIZE ") << mAreaSize[0] << mAreaSize[1] << LineEnding; break; } @@ -379,6 +368,28 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream) } else if (Token == QLatin1String("SPOT_TIGHTNESS_KEY")) mSpotTightnessKeys.LoadKeysLDraw(Stream); + else if (Token == QLatin1String("SHAPE")) + { + QString AreaShape; + Stream >> AreaShape; + + for (size_t ShapeIndex = 0; ShapeIndex < gLightAreaShapes.size(); ShapeIndex++) + { + if (AreaShape == gLightAreaShapes[ShapeIndex]) + { + mAreaShape = static_cast(ShapeIndex); + break; + } + } + } + else if (Token == QLatin1String("AREA_SIZE")) + { + Stream >> mAreaSize[0] >> mAreaSize[1]; + mAreaSizeKeys.ChangeKey(mAreaSize, 1, true); + } + else if (Token == QLatin1String("AREA_SIZE_KEY")) + mAreaSizeKeys.LoadKeysLDraw(Stream); + else if (Token == QLatin1String("POWER") || Token == QLatin1String("STRENGTH")) { if (mPOVRayLight) @@ -392,25 +403,6 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream) mSpotExponentKeys.ChangeKey(mSpotExponent, 1, true); } } - else if (Token == QLatin1String("RADIUS") || Token == QLatin1String("SIZE") || Token == QLatin1String("WIDTH") || (mHeightSet = Token == QLatin1String("HEIGHT")) || (mSpotBlendSet = Token == QLatin1String("SPOT_BLEND")) || (mAngleSet = Token == QLatin1String("ANGLE"))) - { - if (mPOVRayLight) - { - if (Token == QLatin1String("WIDTH")) - Stream >> mAreaSize[0]; - else if (Token == QLatin1String("HEIGHT")) - Stream >> mAreaSize[1]; - mLightFactorKeys.ChangeKey(mAreaSize, 1, true); - } - else - { - if(Token == QLatin1String("HEIGHT") || Token == QLatin1String("SPOT_BLEND")) - Stream >> mLightFactor[1]; - else - Stream >> mLightFactor[0]; - mLightFactorKeys.ChangeKey(mLightFactor, 1, true); - } - } else if (Token == QLatin1String("AREA_ROWS")) { mPOVRayLight = true; @@ -423,21 +415,6 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream) Stream >> mAreaGrid[1]; mAreaGridKeys.ChangeKey(mAreaGrid, 1, true); } - else if (Token == QLatin1String("SHAPE")) - { - QString Shape; - Stream >> Shape; - Shape.replace("\"", ""); - - if (Shape == QLatin1String("SQUARE")) - mLightShape = LC_LIGHT_SHAPE_SQUARE; - else if (Shape == QLatin1String("DISK") || Shape == QLatin1String("CIRCLE")) - mLightShape = LC_LIGHT_SHAPE_DISK; - else if (Shape == QLatin1String("RECTANGLE")) - mLightShape = LC_LIGHT_SHAPE_RECTANGLE; - else if (Shape == QLatin1String("ELLIPSE")) - mLightShape = LC_LIGHT_SHAPE_ELLIPSE; - } else if (Token == QLatin1String("DIFFUSE")) { Stream >>mLightDiffuse; @@ -522,14 +499,6 @@ bool lcLight::ParseLDrawLine(QTextStream& Stream) break; case lcLightType::Area: - if (mLightShape == LC_LIGHT_SHAPE_RECTANGLE || mLightShape == LC_LIGHT_SHAPE_ELLIPSE) - { - if (!mHeightSet) - { - mLightFactor[1] = 0.25f; - mLightFactorKeys.ChangeKey(mLightFactor, 1, true); - } - } break; case lcLightType::Count: @@ -557,9 +526,6 @@ void lcLight::UpdateLight(lcStep Step, lcLightProperties Props, int Property) { switch(Property) { - case LC_LIGHT_SHAPE: - mLightShape = Props.mLightShape; - break; case LC_LIGHT_FACTOR: if (Props.mPOVRayLight && mLightType == lcLightType::Area) { @@ -755,12 +721,18 @@ void lcLight::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, SetRotation(NewLocalToWorldMatrix, Step, AddKey); } -void lcLight::SetLightType(lcLightType LightType) +bool lcLight::SetLightType(lcLightType LightType) { if (static_cast(LightType) < 0 || LightType >= lcLightType::Count) - return; + return false; - mLightType = LightType; + if (mLightType != LightType) + { + mLightType = LightType; + return true; + } + + return false; } void lcLight::SetColor(const lcVector3& Color, lcStep Step, bool AddKey) @@ -783,9 +755,37 @@ void lcLight::SetSpotTightness(float Tightness, lcStep Step, bool AddKey) mSpotTightnessKeys.ChangeKey(Tightness, Step, AddKey); } -void lcLight::SetCastShadow(bool CastShadow) +bool lcLight::SetAreaShape(lcLightAreaShape AreaShape) { - mCastShadow = CastShadow; + if (static_cast(AreaShape) < 0 || AreaShape >= lcLightAreaShape::Count) + return false; + + if (mAreaShape != AreaShape) + { + mAreaShape = AreaShape; + return true; + } + + return false; +} + +void lcLight::SetAreaSize(lcVector2 AreaSize, lcStep Step, bool AddKey) +{ + if (mAreaShape == lcLightAreaShape::Square || mAreaShape == lcLightAreaShape::Disk) + AreaSize[1] = AreaSize[0]; + + mAreaSizeKeys.ChangeKey(AreaSize, Step, AddKey); +} + +bool lcLight::SetCastShadow(bool CastShadow) +{ + if (mCastShadow != CastShadow) + { + mCastShadow = CastShadow; + return true; + } + + return false; } void lcLight::InsertTime(lcStep Start, lcStep Time) @@ -796,6 +796,7 @@ void lcLight::InsertTime(lcStep Start, lcStep Time) mSpotConeAngleKeys.InsertTime(Start, Time); mSpotPenumbraAngleKeys.InsertTime(Start, Time); mSpotTightnessKeys.InsertTime(Start, Time); + mAreaSizeKeys.InsertTime(Start, Time); mAttenuationKeys.InsertTime(Start, Time); mLightFactorKeys.InsertTime(Start, Time); @@ -814,6 +815,7 @@ void lcLight::RemoveTime(lcStep Start, lcStep Time) mSpotConeAngleKeys.RemoveTime(Start, Time); mSpotPenumbraAngleKeys.RemoveTime(Start, Time); mSpotTightnessKeys.RemoveTime(Start, Time); + mAreaSizeKeys.RemoveTime(Start, Time); mAttenuationKeys.RemoveTime(Start, Time); mLightFactorKeys.RemoveTime(Start, Time); @@ -843,6 +845,7 @@ void lcLight::UpdatePosition(lcStep Step) mSpotConeAngle = mSpotConeAngleKeys.CalculateKey(Step); mSpotPenumbraAngle = mSpotPenumbraAngleKeys.CalculateKey(Step); mSpotTightness = mSpotTightnessKeys.CalculateKey(Step); + mAreaSize = mAreaSizeKeys.CalculateKey(Step); mAttenuation = mAttenuationKeys.CalculateKey(Step); mLightFactor = mLightFactorKeys.CalculateKey(Step); @@ -946,7 +949,7 @@ void lcLight::DrawAreaLight(lcContext* Context) const { SetupLightMatrix(Context); - if (mLightShape == LC_LIGHT_SHAPE_SQUARE || mLightShape == LC_LIGHT_SHAPE_RECTANGLE) + if (mAreaShape == lcLightAreaShape::Square || mAreaShape == lcLightAreaShape::Rectangle) { float Verts[4 * 3]; float* CurVert = Verts; @@ -1271,6 +1274,9 @@ void lcLight::RemoveKeyFrames() mSpotTightnessKeys.RemoveAll(); mSpotTightnessKeys.ChangeKey(mSpotTightness, 1, true); + mAreaSizeKeys.RemoveAll(); + mAreaSizeKeys.ChangeKey(mAreaSize, 1, true); + mAttenuationKeys.RemoveAll(); mAttenuationKeys.ChangeKey(mAttenuation, 1, true); diff --git a/common/light.h b/common/light.h index eeb67feb..93ce91af 100644 --- a/common/light.h +++ b/common/light.h @@ -25,20 +25,17 @@ enum class lcLightType Count }; -enum lcLightShape +enum class lcLightAreaShape { - LC_LIGHT_SHAPE_UNDEFINED = -1, - LC_LIGHT_SHAPE_SQUARE, - LC_LIGHT_SHAPE_DISK, - LC_LIGHT_SHAPE_RECTANGLE, - LC_LIGHT_SHAPE_ELLIPSE + Rectangle, + Square, + Disk, + Ellipse, + Count }; enum lcLightProperty { - LC_LIGHT_NONE, - LC_LIGHT_SHAPE, - LC_LIGHT_TYPE, LC_LIGHT_FACTOR, LC_LIGHT_DIFFUSE, LC_LIGHT_SPECULAR, @@ -59,7 +56,6 @@ struct lcLightProperties float mSpotCutoff; bool mEnableCutoff; bool mPOVRayLight; - int mLightShape; }; class lcLight : public lcObject @@ -73,7 +69,8 @@ public: lcLight& operator=(const lcLight&) = delete; lcLight& operator=(lcLight&&) = delete; - static QString GetLightTypeString(lcLightType LightType); + static QString GetTypeString(lcLightType LightType); + static QString GetAreaShapeString(lcLightAreaShape LightAreaShape); bool IsPointLight() const { @@ -100,11 +97,11 @@ public: return mLightType; } - void SetLightType(lcLightType LightType); + bool SetLightType(lcLightType LightType); - int GetLightShape() const + lcLightAreaShape GetLightShape() const { - return mLightShape; + return mAreaShape; } bool IsSelected() const override @@ -282,7 +279,21 @@ public: return mSpotTightness; } - void SetCastShadow(bool CastShadow); + bool SetAreaShape(lcLightAreaShape LightAreaShape); + + lcLightAreaShape GetAreaShape() const + { + return mAreaShape; + } + + void SetAreaSize(lcVector2 AreaSize, lcStep Step, bool AddKey); + + lcVector2 GetAreaSize() const + { + return mAreaSize; + } + + bool SetCastShadow(bool CastShadow); bool GetCastShadow() const { @@ -306,6 +317,7 @@ public: bool Setup(int LightIndex); void CreateName(const lcArray& Lights); void UpdateLight(lcStep Step, lcLightProperties Props, int Property); + lcLightProperties GetLightProperties() const { lcLightProperties props; @@ -317,7 +329,6 @@ public: props.mPOVRayLight = mPOVRayLight; props.mEnableCutoff = mEnableCutoff; props.mAreaGrid = mAreaGrid; - props.mLightShape = mLightShape; return props; } @@ -326,11 +337,9 @@ public: lcVector3 mAttenuation; lcVector2 mLightFactor; lcVector2 mAreaGrid; - lcVector2 mAreaSize; bool mAngleSet; bool mSpotBlendSet; bool mSpotCutoffSet; - bool mHeightSet; bool mEnableCutoff; bool mPOVRayLight; float mLightDiffuse; @@ -353,20 +362,22 @@ protected: void DrawCone(lcContext* Context, float TargetDistance) const; quint32 mState = 0; - lcLightType mLightType; + lcLightType mLightType = lcLightType::Point; bool mCastShadow = true; lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f); float mSpotConeAngle = 80.0f; float mSpotPenumbraAngle = 0.0f; float mSpotTightness = 0.0f; + lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle; + lcVector2 mAreaSize = lcVector2(200.0f, 200.0f); - int mLightShape; lcObjectKeyArray mPositionKeys; lcObjectKeyArray mRotationKeys; lcObjectKeyArray mColorKeys; lcObjectKeyArray mSpotConeAngleKeys; lcObjectKeyArray mSpotPenumbraAngleKeys; lcObjectKeyArray mSpotTightnessKeys; + lcObjectKeyArray mAreaSizeKeys; lcObjectKeyArray mAttenuationKeys; lcObjectKeyArray mLightFactorKeys; diff --git a/common/project.cpp b/common/project.cpp index 67ed8583..c67713db 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -2177,23 +2177,31 @@ bool Project::ExportPOVRay(const QString& FileName) const lcVector3 LightPosition = Light->GetPosition(); const lcVector3 LightTarget = LightPosition + Light->GetDirection(); const lcVector3 LightColor = Light->GetColor(); - const QString LightName = QString(Light->mName).replace(" ","_"); + const QString LightName = QString(Light->mName).replace(" ", "_"); LightType = Light->GetLightType(); Shadowless = Light->GetCastShadow() ? 0 : 1; Power = Light->mPOVRayExponent; - switch(LightType) + switch (LightType) { + case lcLightType::Point: + break; + case lcLightType::Spot: SpotFalloff = Light->GetSpotConeAngle() / 2.0f; SpotRadius = SpotFalloff - Light->GetSpotPenumbraAngle(); break; + + case lcLightType::Directional: + break; + case lcLightType::Area: - AreaCircle = Light->GetLightShape() == LC_LIGHT_SHAPE_DISK ? 1 : 0; - AreaSize = Light->mAreaSize; + AreaCircle = (Light->GetLightShape() == lcLightAreaShape::Disk || Light->GetLightShape() == lcLightAreaShape::Ellipse) ? 1 : 0; + AreaSize = Light->GetAreaSize(); AreaGrid = Light->mAreaGrid; break; - default: + + case lcLightType::Count: break; } diff --git a/qt/lc_qpropertiestree.cpp b/qt/lc_qpropertiestree.cpp index 4d248702..5f13f0cf 100644 --- a/qt/lc_qpropertiestree.cpp +++ b/qt/lc_qpropertiestree.cpp @@ -499,7 +499,12 @@ QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item) else if (Item == mLightTypeItem) { for (int LightTypeIndex = 0; LightTypeIndex < static_cast(lcLightType::Count); LightTypeIndex++) - editor->addItem(lcLight::GetLightTypeString(static_cast(LightTypeIndex))); + editor->addItem(lcLight::GetTypeString(static_cast(LightTypeIndex))); + } + else if (Item == mLightAreaShapeItem) + { + for (int LightAreaShapeIndex = 0; LightAreaShapeIndex < static_cast(lcLightAreaShape::Count); LightAreaShapeIndex++) + editor->addItem(lcLight::GetAreaShapeString(static_cast(LightAreaShapeIndex))); } int value = Item->data(0, PropertyValueRole).toInt(); @@ -529,25 +534,6 @@ QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item) return editor; } - case PropertyLightShape: - { - QComboBox *editor = new QComboBox(Parent); - - editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); - editor->setMinimumContentsLength(1); - - QStringList shapes = { tr("Square"), tr("Disk"), tr("Rectangle"), tr("Ellipse") }; - for (int i = 0; i < shapes.size(); i++) - editor->addItem(shapes.at(i), QVariant::fromValue(i)); - - int value = Item->data(0, PropertyValueRole).toInt(); - editor->setCurrentIndex(value); - - connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); - - return editor; - } - case PropertyColor: { QPushButton *Editor = new QPushButton(Parent); @@ -893,13 +879,25 @@ void lcQPropertiesTree::slotReturnPressed() Model->SetSpotLightTightness(Light, Value); } - else if (Item == lightFactorA || Item == lightFactorB) + else if (Item == mLightAreaSizeXItem) + { + lcVector2 Value = Light->GetAreaSize(); + Value[0] = lcParseValueLocalized(Editor->text()); + + Model->SetAreaLightSize(Light, Value); + } + else if (Item == mLightAreaSizeYItem) + { + lcVector2 Value = Light->GetAreaSize(); + Value[1] = lcParseValueLocalized(Editor->text()); + + Model->SetAreaLightSize(Light, Value); + } + else if (Item == lightFactorA) { float Value = lcParseValueLocalized(Editor->text()); if (Item == lightFactorA) Props.mLightFactor[0] = Value; - else if (Item == lightFactorB) - Props.mLightFactor[1] = Value; Model->UpdateLight(Light, Props, LC_LIGHT_FACTOR); } @@ -937,7 +935,6 @@ void lcQPropertiesTree::slotReturnPressed() Model->UpdateLight(Light, Props, LC_LIGHT_AREA_GRID); } - else if (Item == mLightNameItem) { QString Value = Editor->text(); @@ -1004,10 +1001,9 @@ void lcQPropertiesTree::slotSetValue(int Value) { Model->SetLightType(Light, static_cast(Value)); } - else if (Item == lightShape) + else if (Item == mLightAreaShapeItem) { - Props.mLightShape = static_cast(Value); - Model->UpdateLight(Light, Props, LC_LIGHT_SHAPE); + Model->SetAreaLightShape(Light, static_cast(Value)); } else if (Item == lightFormat) { @@ -1167,12 +1163,13 @@ void lcQPropertiesTree::SetEmpty() lightExponent = nullptr; mLightTypeItem = nullptr; lightFactorA = nullptr; - lightFactorB = nullptr; mLightNameItem = nullptr; mLightSpotConeAngleItem = nullptr; mLightSpotPenumbraAngleItem = nullptr; mLightSpotTightnessItem = nullptr; - lightShape = nullptr; + mLightAreaShapeItem = nullptr; + mLightAreaSizeXItem = nullptr; + mLightAreaSizeYItem = nullptr; lightFormat = nullptr; mLightCastShadowItem = nullptr; lightAreaGridRows = nullptr; @@ -1411,9 +1408,10 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) QString Name = tr("Light"); QString ExponentLabel = tr("Exponent"); QString FactorALabel = QLatin1String("FactorA"); - QString Format, Shape, ExponentToolTip, FactorAToolTip, FactorBToolTip; + QString Format, ExponentToolTip, FactorAToolTip, FactorBToolTip; lcLightType LightType = lcLightType::Point; - lcLightShape ShapeIndex = LC_LIGHT_SHAPE_UNDEFINED; + lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle; + lcVector2 LightAreaSize(0.0f, 0.0f); int FormatIndex = 0; float Diffuse = 0.0f; float Specular = 0.0f; @@ -1447,14 +1445,17 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) Factor = Light->mLightFactor; LightType = Light->GetLightType(); + LightAreaShape = Light->GetAreaShape(); + LightAreaSize = Light->GetAreaSize(); - switch(LightType) + switch (LightType) { case lcLightType::Point: FactorALabel = tr("Radius (m)"); FactorAToolTip = tr("The light size for shadow sampling in metres."); ExponentLabel = tr("Exponent"); break; + case lcLightType::Spot: FactorBToolTip = tr("The softness of the spotlight edge."); ExponentLabel = tr("Power"); @@ -1470,51 +1471,20 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) FactorAToolTip = tr("Shadow soft size - Light size in metres for shadow sampling."); } break; + case lcLightType::Directional: FactorALabel = tr("Angle (°)"); FactorAToolTip = tr("Angular diamater of the sun as seen from the Earth."); ExponentLabel = tr("Strength"); break; + case lcLightType::Area: ExponentLabel = tr("Power"); - - if (POVRayLight) - { - Factor = Light->mAreaSize; - FactorALabel = tr("Width"); - FactorAToolTip = tr("The width (X direction) of the area light."); - FactorBToolTip = tr("The height (Y direction) of the area light."); - } - else - { - FactorALabel = tr("Width"); - FactorAToolTip = tr("The width (X direction) of the area light."); - FactorBToolTip = tr("The height (Y direction) of the area light."); - } break; default: break; } - ShapeIndex = static_cast(Light->GetLightType()); - - switch(ShapeIndex) - { - case LC_LIGHT_SHAPE_SQUARE: - Shape = tr("Square"); - break; - case LC_LIGHT_SHAPE_DISK: - Shape = POVRayLight ? tr("Circle") : tr("Disk"); - break; - case LC_LIGHT_SHAPE_RECTANGLE: - Shape = tr("Rectangle"); - break; - case LC_LIGHT_SHAPE_ELLIPSE: - Shape = tr("Ellipse"); - break; - default: - break; - } Diffuse = Light->mLightDiffuse; Specular = Light->mLightSpecular; @@ -1538,7 +1508,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) AreaGrid = Light->mAreaGrid; } - if (mWidgetMode != LC_PROPERTY_WIDGET_LIGHT || mLightType != LightType || mLightShape != ShapeIndex || mPOVRayLight != POVRayLight) + if (mWidgetMode != LC_PROPERTY_WIDGET_LIGHT || mLightType != LightType || mLightAreaShape != LightAreaShape || mPOVRayLight != POVRayLight) { SetEmpty(); @@ -1549,16 +1519,65 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) mLightColorItem = addProperty(mLightAttributesItem, tr("Color"), PropertyColor); mLightCastShadowItem = addProperty(mLightAttributesItem, tr("Cast Shadows"), PropertyBool); - if (LightType == lcLightType::Spot) + switch (LightType) { - mLightSpotConeAngleItem = addProperty(mLightAttributesItem, tr("Spot Cone Angle"), PropertyFloat); - mLightSpotConeAngleItem->setToolTip(1, tr("The angle (in degrees) of the spot light's beam.")); + case lcLightType::Point: + break; - mLightSpotPenumbraAngleItem = addProperty(mLightAttributesItem, tr("Spot Penumbra Angle"), PropertyFloat); - mLightSpotPenumbraAngleItem->setToolTip(1, tr("The angle (in degrees) over which the intensity of the spot light falls off to zero.")); + case lcLightType::Spot: + { + mLightSpotConeAngleItem = addProperty(mLightAttributesItem, tr("Spot Cone Angle"), PropertyFloat); + mLightSpotConeAngleItem->setToolTip(1, tr("The angle (in degrees) of the spot light's beam.")); - mLightSpotTightnessItem = addProperty(mLightAttributesItem, tr("Spot Tightness"), PropertyFloat); - mLightSpotTightnessItem->setToolTip(1, tr("Additional exponential spotlight edge softening (POV-Ray only).")); + mLightSpotPenumbraAngleItem = addProperty(mLightAttributesItem, tr("Spot Penumbra Angle"), PropertyFloat); + mLightSpotPenumbraAngleItem->setToolTip(1, tr("The angle (in degrees) over which the intensity of the spot light falls off to zero.")); + + mLightSpotTightnessItem = addProperty(mLightAttributesItem, tr("Spot Tightness"), PropertyFloat); + mLightSpotTightnessItem->setToolTip(1, tr("Additional exponential spot light edge softening (POV-Ray only).")); + } + break; + + case lcLightType::Directional: + break; + + case lcLightType::Area: + { + mLightAreaShapeItem = addProperty(mLightAttributesItem, tr("Area Shape"), PropertyStringList); + mLightAreaShapeItem->setToolTip(1, tr("The shape of the area light.")); + + switch (LightAreaShape) + { + case lcLightAreaShape::Rectangle: + case lcLightAreaShape::Ellipse: + mLightAreaSizeXItem = addProperty(mLightAttributesItem, tr("Area Width"), PropertyFloat); + mLightAreaSizeXItem->setToolTip(1, tr("The width (X direction) of the area light.")); + + mLightAreaSizeYItem = addProperty(mLightAttributesItem, tr("Area Height"), PropertyFloat); + mLightAreaSizeYItem->setToolTip(1, tr("The height (Y direction) of the area light.")); + break; + + case lcLightAreaShape::Square: + case lcLightAreaShape::Disk: + mLightAreaSizeXItem = addProperty(mLightAttributesItem, tr("Area Size"), PropertyFloat); + mLightAreaSizeXItem->setToolTip(1, tr("The size of the area light.")); + + mLightAreaSizeYItem = nullptr; + break; + + case lcLightAreaShape::Count: + break; + } + + if (POVRayLight) + { + lightAreaGridRows = addProperty(mLightAttributesItem, tr("Grid Rows"), PropertyFloat); + lightAreaGridColumns = addProperty(mLightAttributesItem, tr("Grid Columns"), PropertyFloat); + } + } + break; + + case lcLightType::Count: + break; } lightExponent = addProperty(mLightAttributesItem, ExponentLabel, PropertyFloat); @@ -1566,23 +1585,6 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) if ((LightType == lcLightType::Point || LightType == lcLightType::Directional) && !POVRayLight) lightFactorA = addProperty(mLightAttributesItem, FactorALabel, PropertyFloat); - if (LightType == lcLightType::Area) - { - lightShape = addProperty(mLightAttributesItem, tr("Shape"), PropertyLightShape); - lightFactorA = addProperty(mLightAttributesItem, FactorALabel, PropertyFloat); - - if (ShapeIndex == LC_LIGHT_SHAPE_RECTANGLE || ShapeIndex == LC_LIGHT_SHAPE_ELLIPSE || POVRayLight) - lightFactorB = addProperty(mLightAttributesItem, tr("Height"), PropertyFloat); - else - FactorAToolTip = tr("The size of the area light grid."); - - if (POVRayLight) - { - lightAreaGridRows = addProperty(mLightAttributesItem, tr("Grid Rows"), PropertyFloat); - lightAreaGridColumns = addProperty(mLightAttributesItem, tr("Grid Columns"), PropertyFloat); - } - } - if (!POVRayLight) { if (LightType != lcLightType::Directional) @@ -1616,7 +1618,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) mWidgetMode = LC_PROPERTY_WIDGET_LIGHT; mLightType = LightType; - mLightShape = ShapeIndex; + mLightAreaShape = LightAreaShape; mPOVRayLight = POVRayLight; } @@ -1656,7 +1658,7 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) lightFormat->setText(1, Format); lightFormat->setData(0, PropertyValueRole, FormatIndex); - mLightTypeItem->setText(1, lcLight::GetLightTypeString(LightType)); + mLightTypeItem->setText(1, lcLight::GetTypeString(LightType)); mLightTypeItem->setData(0, PropertyValueRole, static_cast(LightType)); mLightCastShadowItem->setCheckState(1, CastShadow ? Qt::Checked : Qt::Unchecked); @@ -1674,19 +1676,16 @@ void lcQPropertiesTree::SetLight(lcObject* Focus) } else if (LightType == lcLightType::Area) { - lightShape->setText(1, Shape); - lightShape->setData(0, PropertyValueRole, ShapeIndex); - lightShape->setToolTip(1, tr("Suggested shape of the arealight.")); + mLightAreaShapeItem->setText(1, lcLight::GetAreaShapeString(LightAreaShape)); + mLightAreaShapeItem->setData(0, PropertyValueRole, static_cast(LightAreaShape)); - lightFactorA->setText(1, lcFormatValueLocalized(Factor[0])); - lightFactorA->setData(0, PropertyValueRole, Factor[0]); - lightFactorA->setToolTip(1, FactorAToolTip); + mLightAreaSizeXItem->setText(1, lcFormatValueLocalized(LightAreaSize[0])); + mLightAreaSizeXItem->setData(0, PropertyValueRole, LightAreaSize[0]); - if (ShapeIndex == LC_LIGHT_SHAPE_RECTANGLE || ShapeIndex == LC_LIGHT_SHAPE_ELLIPSE || POVRayLight) + if (mLightAreaSizeYItem) { - lightFactorB->setText(1, lcFormatValueLocalized(Factor[1])); - lightFactorB->setData(0, PropertyValueRole, Factor[1]); - lightFactorB->setToolTip(1, FactorBToolTip); + mLightAreaSizeYItem->setText(1, lcFormatValueLocalized(LightAreaSize[1])); + mLightAreaSizeYItem->setData(0, PropertyValueRole, LightAreaSize[1]); } if (POVRayLight) diff --git a/qt/lc_qpropertiestree.h b/qt/lc_qpropertiestree.h index be8242bb..f4910b73 100644 --- a/qt/lc_qpropertiestree.h +++ b/qt/lc_qpropertiestree.h @@ -50,7 +50,6 @@ public: PropertyString, PropertyStringList, PropertyLightFormat, - PropertyLightShape, PropertyColor, PropertyPieceColor, PropertyPart @@ -79,7 +78,7 @@ protected: void SetMultiple(); lcLightType mLightType; - int mLightShape; + lcLightAreaShape mLightAreaShape; bool mPOVRayLight; lcPropertyWidgetMode mWidgetMode; @@ -145,7 +144,9 @@ protected: QTreeWidgetItem* mLightSpotConeAngleItem; QTreeWidgetItem* mLightSpotPenumbraAngleItem; QTreeWidgetItem* mLightSpotTightnessItem; - QTreeWidgetItem* lightShape; + QTreeWidgetItem* mLightAreaShapeItem; + QTreeWidgetItem* mLightAreaSizeXItem; + QTreeWidgetItem* mLightAreaSizeYItem; QTreeWidgetItem* lightFactorA; QTreeWidgetItem* lightFactorB; QTreeWidgetItem* mLightNameItem;