Files
leocad/common/object.h
T
Leonardo Zide baae697960 Fix in-place submodel editing context and navigation
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.
2026-10-24 12:39:25 -07:00

164 lines
3.7 KiB
C++

#pragma once
#include "lc_math.h"
#include "lc_objectproperty.h"
enum class lcObjectType
{
Piece,
Camera,
Light
};
enum class lcObjectId : uint32_t;
struct lcObjectSection
{
lcObject* Object = nullptr;
quint32 Section = 0;
};
struct lcPieceRayTest
{
const lcPieceData* PieceData = nullptr;
lcMatrix44 Transform;
lcVector3 Plane;
};
struct lcObjectRayTest
{
lcCamera* ViewCamera;
bool PiecesOnly;
bool IgnoreSelected;
lcVector3 Start;
lcVector3 End;
float Distance = FLT_MAX;
lcObjectSection ObjectSection;
lcPieceRayTest PieceRayTest;
};
struct lcObjectBoxTest
{
lcCamera* ViewCamera;
lcVector4 Planes[6];
std::vector<lcObject*> Objects;
};
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
#define LC_OBJECT_TRANSFORM_MOVE_XYZ (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
#define LC_OBJECT_TRANSFORM_ROTATE_XYZ (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)
#define LC_OBJECT_TRANSFORM_SCALE_X 0x100
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400
#define LC_OBJECT_TRANSFORM_SCALE_XYZ (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z)
#define LC_OBJECT_SECTION_INVALID 0xffffffff
class lcObject
{
public:
lcObject(lcObjectType ObjectType);
virtual ~lcObject();
lcObject(const lcObject&) = delete;
lcObject(lcObject&&) = delete;
lcObject& operator=(const lcObject&) = delete;
lcObject& operator=(lcObject&&) = delete;
public:
bool IsPiece() const
{
return mObjectType == lcObjectType::Piece;
}
bool IsCamera() const
{
return mObjectType == lcObjectType::Camera;
}
bool IsLight() const
{
return mObjectType == lcObjectType::Light;
}
lcObjectType GetType() const
{
return mObjectType;
}
lcObjectId GetId() const
{
return mId;
}
bool IsSelected() const
{
return mSelected;
}
void SetSelected(bool Selected)
{
mSelected = Selected;
if (!Selected)
mFocusedSection = LC_OBJECT_SECTION_INVALID;
}
bool IsFocused() const
{
return mFocusedSection != LC_OBJECT_SECTION_INVALID;
}
bool IsFocused(quint32 Section) const
{
return mFocusedSection == Section;
}
void SetFocused(quint32 Section, bool Focused)
{
if (Focused)
{
mFocusedSection = Section;
mSelected = true;
}
else
mFocusedSection = LC_OBJECT_SECTION_INVALID;
}
quint32 GetFocusSection() const
{
return mFocusedSection;
}
virtual void UpdatePosition(lcStep Step) = 0;
virtual quint32 GetAllowedTransforms() const = 0;
virtual lcVector3 GetSectionPosition(quint32 Section) const = 0;
virtual void RayTest(lcObjectRayTest& ObjectRayTest) const = 0;
virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const = 0;
virtual void DrawInterface(lcContext* Context, const lcScene& Scene) const = 0;
virtual QVariant GetPropertyValue(lcObjectPropertyId PropertyId) const = 0;
virtual bool SetPropertyValue(lcObjectPropertyId PropertyId, lcStep Step, bool AddKey, QVariant Value) = 0;
virtual bool HasKeyFrame(lcObjectPropertyId PropertyId, lcStep Time) const = 0;
virtual lcStep GetLastStep() const = 0;
virtual bool SetKeyFrame(lcObjectPropertyId PropertyId, lcStep Time, bool KeyFrame) = 0;
virtual void RemoveKeyFrames() = 0;
virtual QString GetName() const = 0;
static QString GetCheckpointString(lcObjectPropertyId PropertyId);
private:
lcObjectType mObjectType;
protected:
bool mHidden = false;
bool mSelected = false;
quint32 mFocusedSection = LC_OBJECT_SECTION_INVALID;
lcObjectId mId = static_cast<lcObjectId>(0);
static lcObjectId mNextId;
};