refactor: extend Object property system and implement recursive property discovery in Vtk::Puppet archive

This commit is contained in:
AndreaRigoni
2026-04-03 08:54:37 +00:00
parent 6396bdfebf
commit a6a1539663
12 changed files with 459 additions and 272 deletions

View File

@@ -35,6 +35,8 @@
#include <iomanip>
#include <ostream>
#include <vector>
#include <set>
#include <boost/type_traits/is_base_of.hpp>
// vtk classes forward declaration //
class vtkProp;
@@ -106,7 +108,7 @@ uLibTypeMacro(Puppet, uLib::Object)
* This method should be called when the VTK representation has been modified
* (e.g., via a gizmo) and the changes need to be pushed back to the model.
*/
virtual void SyncFromVtk() {}
virtual void SyncFromVtk();
enum Representation {
Points = 0,
@@ -149,6 +151,7 @@ protected:
void ApplyAppearance(vtkProp *prop);
void ApplyTransform(vtkProp3D *p3d);
void ApplyPuppetTransform(vtkProp3D *p3d);
std::vector<uLib::PropertyBase *> m_DisplayProperties;
mutable uLib::RecursiveMutex m_UpdateMutex;
@@ -179,10 +182,17 @@ class display_properties_archive
: public boost::archive::detail::common_oarchive<
display_properties_archive> {
public:
display_properties_archive(Vtk::Puppet *puppet)
friend class boost::archive::detail::interface_oarchive<display_properties_archive>;
friend class boost::archive::save_access;
using boost::archive::detail::common_oarchive<display_properties_archive>::save_override;
display_properties_archive(Vtk::Puppet *p)
: boost::archive::detail::common_oarchive<display_properties_archive>(
boost::archive::no_header),
m_Puppet(puppet) {}
m_Puppet(p) {
if (p)
m_Visited.insert(dynamic_cast<const void *>(p));
}
std::string GetCurrentGroup() const {
std::string group;
@@ -234,6 +244,24 @@ public:
m_GroupStack.pop_back();
}
// Follow pointers to discover properties in child objects
template<class T>
void save_override(T * const & t) {
if (!t) return;
this->save_pointer_helper(t, typename boost::is_base_of<uLib::Object, T>::type());
}
template<class T>
void save_pointer_helper(T* t, boost::mpl::true_) {
const void* ptr = dynamic_cast<const void*>(t);
if (m_Visited.find(ptr) != m_Visited.end()) return;
m_Visited.insert(ptr);
this->save_override(*t);
}
template<class T>
void save_pointer_helper(T* t, boost::mpl::false_) {}
// Recursion for nested classes, ignore primitives
template <class T> void save_override(const T &t) {
this->save_helper(t, typename boost::is_class<T>::type());
@@ -243,6 +271,8 @@ public:
boost::serialization::serialize_adl(*this, const_cast<T &>(t), 0);
}
void save_helper(const std::string &t, boost::mpl::true_) {}
template <class T> void save_helper(const T &t, boost::mpl::false_) {}
void save_override(const boost::archive::object_id_type &t) {}
@@ -257,6 +287,7 @@ public:
private:
Vtk::Puppet *m_Puppet;
std::vector<std::string> m_GroupStack;
std::set<const void *> m_Visited;
};
} // namespace Archive