mirror of
https://github.com/leozide/leocad.git
synced 2026-10-26 22:10:32 +00:00
In-place editing could use the tab model's step and focus, lose its active state after switching tabs, or resolve a nested instance through the wrong parent. Entering before the final animation key also moved geometry when drilling into a child. Use the edited model for step controls, step edits, visibility, and focus coordinates. Restore that editing target when returning to its tab, include animation keys and finite hide steps in the last step, and retain the selected instance path and transforms during nested editing. Show the editing path only during in-place edits, with links to ancestors and a close control to return to the tab model. Stack Find/Replace beneath it and preserve full names in accessible text and tooltips. Add translated source entries without changing existing translations. Add a regression test for final-key tracking through time and key edits. Validated with the macOS Qt 6 application build, all 8 Qt Test cases, and 51 focused checks against the compiled application for steps, tab switching, focus status, breadcrumbs, and Find/Replace layout. Visually checked the viewport overlay and its placement during nested editing.
375 lines
10 KiB
C++
375 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "object.h"
|
|
#include "lc_math.h"
|
|
|
|
enum lcLightSection : quint32
|
|
{
|
|
LC_LIGHT_SECTION_INVALID = LC_OBJECT_SECTION_INVALID,
|
|
LC_LIGHT_SECTION_POSITION = 0,
|
|
LC_LIGHT_SECTION_TARGET
|
|
};
|
|
|
|
enum class lcLightType
|
|
{
|
|
Point,
|
|
Spot,
|
|
Directional,
|
|
Area,
|
|
Count
|
|
};
|
|
|
|
enum class lcLightAreaShape
|
|
{
|
|
Rectangle,
|
|
Square,
|
|
Disk,
|
|
Ellipse,
|
|
Count
|
|
};
|
|
|
|
struct lcLightHistoryState
|
|
{
|
|
lcObjectId Id;
|
|
bool Hidden;
|
|
QString Name;
|
|
lcLightType LightType;
|
|
bool CastShadow;
|
|
lcObjectProperty<lcVector3> Position;
|
|
lcObjectProperty<lcMatrix33> Rotation;
|
|
lcObjectProperty<lcVector3> Color;
|
|
lcObjectProperty<float> BlenderPower;
|
|
lcObjectProperty<float> BlenderRadius;
|
|
lcObjectProperty<float> BlenderAngle;
|
|
lcObjectProperty<float> POVRayPower;
|
|
lcObjectProperty<float> POVRayFadeDistance;
|
|
lcObjectProperty<float> POVRayFadePower;
|
|
lcObjectProperty<float> SpotConeAngle;
|
|
lcObjectProperty<float> SpotPenumbraAngle;
|
|
lcObjectProperty<float> POVRaySpotTightness;
|
|
lcLightAreaShape AreaShape;
|
|
lcObjectProperty<float> AreaSizeX;
|
|
lcObjectProperty<float> AreaSizeY;
|
|
lcObjectProperty<int> POVRayAreaGridX;
|
|
lcObjectProperty<int> POVRayAreaGridY;
|
|
|
|
bool operator==(const lcLightHistoryState& Other) const
|
|
{
|
|
return Id == Other.Id && Hidden == Other.Hidden && Name == Other.Name && LightType == Other.LightType &&
|
|
CastShadow == Other.CastShadow && Position == Other.Position && Rotation == Other.Rotation && Color == Other.Color &&
|
|
BlenderPower == Other.BlenderPower && BlenderRadius == Other.BlenderRadius && BlenderAngle == Other.BlenderAngle &&
|
|
POVRayPower == Other.POVRayPower && POVRayFadeDistance == Other.POVRayFadeDistance && POVRayFadePower == Other.POVRayFadePower &&
|
|
SpotConeAngle == Other.SpotConeAngle && SpotPenumbraAngle == Other.SpotPenumbraAngle &&
|
|
POVRaySpotTightness == Other.POVRaySpotTightness && AreaShape == Other.AreaShape && AreaSizeX == Other.AreaSizeX &&
|
|
AreaSizeY == Other.AreaSizeY && POVRayAreaGridX == Other.POVRayAreaGridX && POVRayAreaGridY == Other.POVRayAreaGridY;
|
|
}
|
|
};
|
|
|
|
class lcLight : public lcObject
|
|
{
|
|
public:
|
|
lcLight();
|
|
lcLight(const lcVector3& Position, lcLightType LightType);
|
|
virtual ~lcLight() = default;
|
|
|
|
lcLight(const lcLight&) = delete;
|
|
lcLight(lcLight&&) = delete;
|
|
lcLight& operator=(const lcLight&) = delete;
|
|
lcLight& operator=(lcLight&&) = delete;
|
|
|
|
static QString GetLightTypeString(lcLightType LightType);
|
|
static QStringList GetLightTypeStrings();
|
|
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
|
|
static QStringList GetAreaShapeStrings();
|
|
|
|
bool IsPointLight() const
|
|
{
|
|
return mLightType == lcLightType::Point;
|
|
}
|
|
|
|
bool IsSpotLight() const
|
|
{
|
|
return mLightType == lcLightType::Spot;
|
|
}
|
|
|
|
bool IsDirectionalLight() const
|
|
{
|
|
return mLightType == lcLightType::Directional;
|
|
}
|
|
|
|
bool IsAreaLight() const
|
|
{
|
|
return mLightType == lcLightType::Area;
|
|
}
|
|
|
|
lcLightType GetLightType() const
|
|
{
|
|
return mLightType;
|
|
}
|
|
|
|
bool SetLightType(lcLightType LightType);
|
|
|
|
quint32 GetAllowedTransforms() const override
|
|
{
|
|
if (IsPointLight())
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
|
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
|
|
|
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
|
|
|
return 0;
|
|
}
|
|
|
|
lcMatrix33 GetRelativeRotation() const
|
|
{
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
|
return lcMatrix33(mWorldMatrix);
|
|
else
|
|
return lcMatrix33Identity();
|
|
}
|
|
|
|
lcVector3 GetSectionPosition(quint32 Section) const override
|
|
{
|
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
|
return mWorldMatrix.GetTranslation();
|
|
|
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
|
|
|
return lcVector3(0.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
|
|
{
|
|
mPosition.ChangeKey(Position, Step, AddKey);
|
|
}
|
|
|
|
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
|
|
{
|
|
mRotation.ChangeKey(Rotation, Step, AddKey);
|
|
}
|
|
|
|
lcVector3 GetRotationCenter() const
|
|
{
|
|
const quint32 Section = GetFocusSection();
|
|
|
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
|
{
|
|
return mWorldMatrix.GetTranslation();
|
|
}
|
|
else
|
|
{
|
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
|
}
|
|
}
|
|
|
|
lcVector3 GetPosition() const
|
|
{
|
|
return mWorldMatrix.GetTranslation();
|
|
}
|
|
|
|
lcVector3 GetDirection() const
|
|
{
|
|
return -lcVector3(mWorldMatrix[2]);
|
|
}
|
|
|
|
const lcMatrix44& GetWorldMatrix() const
|
|
{
|
|
return mWorldMatrix;
|
|
}
|
|
|
|
void SaveLDraw(QTextStream& Stream) const;
|
|
bool ParseLDrawLine(QTextStream& Stream);
|
|
|
|
public:
|
|
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
|
|
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const override;
|
|
void DrawInterface(lcContext* Context, const lcScene& Scene) const override;
|
|
QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const override;
|
|
bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) override;
|
|
bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const override;
|
|
lcStep GetLastStep() const override;
|
|
bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) override;
|
|
void RemoveKeyFrames() override;
|
|
lcLightHistoryState GetHistoryState() const;
|
|
void SetHistoryState(const lcLightHistoryState& State);
|
|
|
|
void InsertTime(lcStep Start, lcStep Time);
|
|
void RemoveTime(lcStep Start, lcStep Time);
|
|
|
|
bool IsVisible() const
|
|
{
|
|
return !mHidden;
|
|
}
|
|
|
|
bool SetColor(const lcVector3& Color, lcStep Step, bool AddKey);
|
|
|
|
lcVector3 GetColor() const
|
|
{
|
|
return mColor;
|
|
}
|
|
|
|
bool SetPOVRayFadeDistance(float Distance, lcStep Step, bool AddKey);
|
|
|
|
float GetPOVRayFadeDistance() const
|
|
{
|
|
return mPOVRayFadeDistance;
|
|
}
|
|
|
|
bool SetPOVRayFadePower(float Power, lcStep Step, bool AddKey);
|
|
|
|
float GetPOVRayFadePower() const
|
|
{
|
|
return mPOVRayFadePower;
|
|
}
|
|
|
|
bool SetSpotConeAngle(float Angle, lcStep Step, bool AddKey);
|
|
|
|
float GetSpotConeAngle() const
|
|
{
|
|
return mSpotConeAngle;
|
|
}
|
|
|
|
bool SetSpotPenumbraAngle(float Angle, lcStep Step, bool AddKey);
|
|
|
|
float GetSpotPenumbraAngle() const
|
|
{
|
|
return mSpotPenumbraAngle;
|
|
}
|
|
|
|
bool SetSpotPOVRayTightness(float Angle, lcStep Step, bool AddKey);
|
|
|
|
float GetSpotPOVRayTightness() const
|
|
{
|
|
return mPOVRaySpotTightness;
|
|
}
|
|
|
|
bool SetAreaShape(lcLightAreaShape LightAreaShape);
|
|
|
|
lcLightAreaShape GetAreaShape() const
|
|
{
|
|
return mAreaShape;
|
|
}
|
|
|
|
bool SetAreaPOVRayGridX(int AreaGrid, lcStep Step, bool AddKey);
|
|
|
|
int GetAreaPOVRayGridX() const
|
|
{
|
|
return mPOVRayAreaGridX;
|
|
}
|
|
|
|
bool SetAreaPOVRayGridY(int AreaGrid, lcStep Step, bool AddKey);
|
|
|
|
int GetAreaPOVRayGridY() const
|
|
{
|
|
return mPOVRayAreaGridY;
|
|
}
|
|
|
|
bool SetBlenderRadius(float Radius, lcStep Step, bool AddKey);
|
|
|
|
float GetBlenderRadius() const
|
|
{
|
|
return mBlenderRadius;
|
|
}
|
|
|
|
bool SetBlenderAngle(float Angle, lcStep Step, bool AddKey);
|
|
|
|
float GetBlenderAngle() const
|
|
{
|
|
return mBlenderAngle * LC_RTOD;
|
|
}
|
|
|
|
bool SetAreaSizeX(float Size, lcStep Step, bool AddKey);
|
|
|
|
float GetAreaSizeX() const
|
|
{
|
|
return mAreaSizeX;
|
|
}
|
|
|
|
bool SetAreaSizeY(float Size, lcStep Step, bool AddKey);
|
|
|
|
float GetAreaSizeY() const
|
|
{
|
|
return mAreaSizeY;
|
|
}
|
|
|
|
bool SetBlenderPower(float Power, lcStep Step, bool AddKey);
|
|
|
|
float GetBlenderPower() const
|
|
{
|
|
return mBlenderPower;
|
|
}
|
|
|
|
bool SetPOVRayPower(float Power, lcStep Step, bool AddKey);
|
|
|
|
float GetPOVRayPower() const
|
|
{
|
|
return mPOVRayPower;
|
|
}
|
|
|
|
bool SetCastShadow(bool CastShadow);
|
|
|
|
bool GetCastShadow() const
|
|
{
|
|
return mCastShadow;
|
|
}
|
|
|
|
bool SetName(const QString& Name);
|
|
|
|
QString GetName() const override
|
|
{
|
|
return mName;
|
|
}
|
|
|
|
void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
|
|
void UpdatePosition(lcStep Step) override;
|
|
void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance, bool FirstMove);
|
|
void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame);
|
|
void CreateName(const std::vector<std::unique_ptr<lcLight>>& Lights);
|
|
|
|
protected:
|
|
void DrawPointLight(lcContext* Context) const;
|
|
void DrawSpotLight(lcContext* Context) const;
|
|
void DrawDirectionalLight(lcContext* Context) const;
|
|
void DrawAreaLight(lcContext* Context) const;
|
|
|
|
void SetupLightMatrix(lcContext* Context) const;
|
|
void DrawSphere(lcContext* Context, const lcVector3& Center, float Radius) const;
|
|
void DrawCylinder(lcContext* Context, float Radius, float Height) const;
|
|
void DrawTarget(lcContext* Context) const;
|
|
void DrawCone(lcContext* Context, float TargetDistance) const;
|
|
|
|
QString mName;
|
|
lcLightType mLightType = lcLightType::Point;
|
|
bool mCastShadow = true;
|
|
lcObjectProperty<lcVector3> mPosition = lcObjectProperty<lcVector3>(lcVector3(0.0f, 0.0f, 0.0f));
|
|
lcObjectProperty<lcMatrix33> mRotation = lcObjectProperty<lcMatrix33>(lcMatrix33Identity());
|
|
lcObjectProperty<lcVector3> mColor = lcObjectProperty<lcVector3>(lcVector3(1.0f, 1.0f, 1.0f));
|
|
lcObjectProperty<float> mBlenderPower = lcObjectProperty<float>(10.0f);
|
|
lcObjectProperty<float> mBlenderRadius = lcObjectProperty<float>(0.0f);
|
|
lcObjectProperty<float> mBlenderAngle = lcObjectProperty<float>(0.526f * LC_DTOR);
|
|
lcObjectProperty<float> mPOVRayPower = lcObjectProperty<float>(1.0f);
|
|
lcObjectProperty<float> mPOVRayFadeDistance = lcObjectProperty<float>(0.0f);
|
|
lcObjectProperty<float> mPOVRayFadePower = lcObjectProperty<float>(0.0f);
|
|
lcObjectProperty<float> mSpotConeAngle = lcObjectProperty<float>(80.0f);
|
|
lcObjectProperty<float> mSpotPenumbraAngle = lcObjectProperty<float>(0.0f);
|
|
lcObjectProperty<float> mPOVRaySpotTightness = lcObjectProperty<float>(0.0f);
|
|
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
|
|
lcObjectProperty<float> mAreaSizeX = lcObjectProperty<float>(250.0f);
|
|
lcObjectProperty<float> mAreaSizeY = lcObjectProperty<float>(250.0f);
|
|
lcObjectProperty<int> mPOVRayAreaGridX = lcObjectProperty<int>(2);
|
|
lcObjectProperty<int> mPOVRayAreaGridY = lcObjectProperty<int>(2);
|
|
|
|
lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f);
|
|
lcMatrix44 mWorldMatrix;
|
|
|
|
static constexpr float mTargetDistance = 50.0f;
|
|
};
|