#pragma once #include "../CommandHistory.h" #include #include #include #include #include #include #include #include namespace UsdLayerManager { /// Reverses a complete TRS edit on a single prim (from gizmo drag or /// Property panel field commit). Stores the prim path, edit-target layer, /// and pre/post translate/rotate/scale triples. /// /// When timeCode is not Default() the edit is a keyframe: values are written /// as time samples at that frame. Undo removes samples this command created /// on ops that had no sample at that frame before the edit. class TransformCommand : public ICommand { public: /// Whether each common op had an authored sample at the edit time. /// Must be queried BEFORE the first live write of an interactive edit /// (live writes author the sample, so querying later always finds one). struct SamplePresence { bool translate = false; bool rotate = false; bool scale = false; }; static SamplePresence QuerySamplePresence( pxr::UsdStageRefPtr stage, const pxr::SdfPath& primPath, pxr::UsdGeomXformCommonAPI::RotationOrder rotOrder, pxr::UsdTimeCode timeCode); TransformCommand(pxr::UsdStageRefPtr stage, const pxr::SdfPath& primPath, pxr::SdfLayerHandle editLayer, const pxr::GfVec3d& oldTranslate, const pxr::GfVec3f& oldRotate, const pxr::GfVec3f& oldScale, const pxr::GfVec3d& newTranslate, const pxr::GfVec3f& newRotate, const pxr::GfVec3f& newScale, pxr::UsdGeomXformCommonAPI::RotationOrder rotOrder, pxr::UsdTimeCode timeCode, SamplePresence preEditSamples, std::string description = "Transform"); void Execute() override; void Undo() override; std::string GetDescription() const override { return m_description; } private: void Apply(const pxr::GfVec3d& t, const pxr::GfVec3f& r, const pxr::GfVec3f& s); /// Remove the time samples Execute created on ops that previously had /// no sample at m_timeCode (no-op when m_timeCode is Default). void ClearCreatedSamples(); pxr::UsdStageRefPtr m_stage; pxr::SdfPath m_primPath; pxr::SdfLayerHandle m_editLayer; pxr::GfVec3d m_oldTranslate; pxr::GfVec3f m_oldRotate; pxr::GfVec3f m_oldScale; pxr::GfVec3d m_newTranslate; pxr::GfVec3f m_newRotate; pxr::GfVec3f m_newScale; pxr::UsdGeomXformCommonAPI::RotationOrder m_rotOrder; pxr::UsdTimeCode m_timeCode; std::string m_description; // Whether each op already had a sample at m_timeCode before the edit // (only meaningful when m_timeCode is not Default). SamplePresence m_preEditSamples; }; } // namespace UsdLayerManager