diff --git a/.gitignore b/.gitignore index f51005d..05ed939 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ src/Python/uLib/*.pyd src/Python/uLib/*.pyc src/Python/uLib/__pycache__ src/Python/uLib/.nfs* +test_props.xml +test_props2.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index 59eb58f..3b61e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ endif() # The version number. set(PROJECT_VERSION_MAJOR 0) -set(PROJECT_VERSION_MINOR 6) +set(PROJECT_VERSION_MINOR 7) set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") set(PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") diff --git a/docs/update_properties.md b/docs/update_properties.md index 15c1790..219a420 100644 --- a/docs/update_properties.md +++ b/docs/update_properties.md @@ -19,3 +19,76 @@ The vtkHandlerWidget should handle the transformation of the puppet internal Con + + + +## ACTIVATE PROPERTIES + +ULIB_ACTIVATE_PROPERTIES must run after all member initialization, with the vtable pointing to the most-derived type. This is why it has to be in each constructor — in C++, virtual dispatch only works correctly after a class's vtable is installed, which happens at the start of each level's constructor body. + +### Option 1 — End-of-class macro (no constructor boilerplate) +Declare a private member activator as the last member of the class. Its constructor runs after all other members, and at that point the vtable is already Derived's: + + +// In Property.h, add alongside ULIB_ACTIVATE_PROPERTIES: +#define ULIB_DECLARE_PROPERTIES(SelfType) \ +private: \ + struct _PropActivator { \ + _PropActivator(SelfType* self) { \ + uLib::Archive::property_register_archive ar(self); \ + ar & *self; \ + } \ + } _prop_activator{this}; +Usage in ContainerBox.h — place it just before the closing brace: + + +class ContainerBox : public TRS { +public: + // ... all constructors, no more ULIB_ACTIVATE_PROPERTIES(*this) + + ULIB_DECLARE_PROPERTIES(ContainerBox) // ← replaces all 3 constructor calls +}; +Tradeoff: Works perfectly for single-level classes. For hierarchies where multiple levels use the macro, RegisterDynamicProperty must deduplicate by name (skip if already registered). Requires one line per class in the class body, but zero lines in constructors. + +### Option 2 — Lazy init via virtual InitProperties() in Object +Modify Object to call a virtual hook on first GetProperties(): + + +// In Object.h: +class Object { +protected: + virtual void InitProperties() {} // override in derived +public: + const std::vector& GetProperties() const { + if (!m_propertiesInitialized) { + const_cast(this)->m_propertiesInitialized = true; + const_cast(this)->InitProperties(); + } + return m_properties; + } +}; +Then a CRTP base handles the rest without any macro: + + +template +class PropertyObject : public Object { +protected: + void InitProperties() override { + uLib::Archive::property_register_archive ar(this); + ar & *static_cast(this); + } +}; +Usage — just change the base class: + + +class ContainerBox : public PropertyObject, public TRS { ... }; +// Nothing else needed — properties activated on first GetProperties() call +Tradeoff: Most "automatic" — pure inheritance, no constructor or class-body macros. But requires modifying Object (adding m_propertiesInitialized flag + virtual hook), and lazy init means properties aren't available until first access. Also doesn't work well with multiple inheritance (which TRS likely involves). + +Option 3 — CRTP doesn't work from the base constructor +Just to be explicit: a CRTP base that calls ULIB_ACTIVATE_PROPERTIES in its own constructor won't work, because when PropertyObject's constructor runs, the vtable is PropertyObject's — Derived::serialize() hasn't been installed yet. So ar & *self calls Object::serialize() (a no-op). + +Recommendation +Option 1 is the least invasive and safest. Add deduplication to RegisterDynamicProperty in Object.cpp to guard against re-registration when hierarchies stack activators, then replace every ULIB_ACTIVATE_PROPERTIES(*this) in constructors with a single ULIB_DECLARE_PROPERTIES(ClassName) at the end of the class body. + +Option 2 is cleaner to use but requires changing the Object interface and has the lazy-init semantic change — only worth it if you want zero-touch activation across the entire framework. \ No newline at end of file diff --git a/src/Core/Archives.h b/src/Core/Archives.h index d2bb76b..5a6348a 100644 --- a/src/Core/Archives.h +++ b/src/Core/Archives.h @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -309,18 +311,32 @@ namespace Archive { //////////////////////////////////////////////////////////////////////////////// // XML // +// ULIB_SERIALIZATION_VERSION should be get from the build system +#ifndef ULIB_SERIALIZATION_VERSION +#define ULIB_SERIALIZATION_VERSION "0.0" +#endif + class xml_iarchive : public boost::archive::xml_iarchive_impl { typedef xml_iarchive Archive; typedef boost::archive::xml_iarchive_impl base; + unsigned int m_flags; + // give serialization implementation access to this class friend class boost::archive::detail::interface_iarchive; friend class boost::archive::basic_xml_iarchive; friend class boost::archive::load_access; - public: xml_iarchive(std::istream &is, unsigned int flags = 0) - : xml_iarchive_impl(is, flags) {} + : boost::archive::xml_iarchive_impl( + is, flags | boost::archive::no_header), m_flags(flags) { + if (0 == (flags & boost::archive::no_header)) { + std::string line; + std::getline(is, line); // + std::getline(is, line); // + std::getline(is, line); // + } + } using basic_xml_iarchive::load_override; @@ -368,14 +384,31 @@ class xml_oarchive : public boost::archive::xml_oarchive_impl { typedef xml_oarchive Archive; typedef boost::archive::xml_oarchive_impl base; + unsigned int m_flags; + // give serialization implementation access to this class friend class boost::archive::detail::interface_oarchive; friend class boost::archive::basic_xml_oarchive; friend class boost::archive::save_access; - public: xml_oarchive(std::ostream &os, unsigned int flags = 0) - : boost::archive::xml_oarchive_impl(os, flags) {} + : boost::archive::xml_oarchive_impl( + os, flags | boost::archive::no_header), m_flags(flags) { + if (0 == (flags & boost::archive::no_header)) { + this->This()->put( + "\n"); + this->This()->put("\n"); + this->This()->put("write_attribute("version", (const char *)ULIB_SERIALIZATION_VERSION); + this->This()->put(">\n"); + } + } + + virtual ~xml_oarchive() { + if (0 == (m_flags & boost::archive::no_header)) { + this->This()->put("\n"); + } + } using basic_xml_oarchive::save_override; @@ -397,8 +430,6 @@ public: // Do not save any human decoration string // // basic_text_oprimitive::save(str); } - - virtual ~xml_oarchive() {} }; // typedef boost::archive::detail::polymorphic_oarchive_route< diff --git a/src/Core/CMakeLists.txt b/src/Core/CMakeLists.txt index e64459f..ed80177 100644 --- a/src/Core/CMakeLists.txt +++ b/src/Core/CMakeLists.txt @@ -58,6 +58,7 @@ if(USE_CUDA) endif() target_link_libraries(${libname} ${LIBRARIES}) +target_compile_definitions(${libname} PUBLIC ULIB_SERIALIZATION_VERSION="${PROJECT_VERSION}") install(TARGETS ${libname} EXPORT "uLibTargets" diff --git a/src/Core/Object.cpp b/src/Core/Object.cpp index cdc4837..e75e779 100644 --- a/src/Core/Object.cpp +++ b/src/Core/Object.cpp @@ -79,6 +79,7 @@ void Object::RegisterDynamicProperty(PropertyBase* prop) { if (prop) { for (auto* existing : d->m_DynamicProperties) { if (existing == prop) return; + if (existing->GetQualifiedName() == prop->GetQualifiedName()) return; } d->m_DynamicProperties.push_back(prop); } diff --git a/src/Core/Object.h b/src/Core/Object.h index 40613ec..99bd91b 100644 --- a/src/Core/Object.h +++ b/src/Core/Object.h @@ -78,7 +78,8 @@ public: Object(const Object ©); virtual ~Object(); - virtual const char * GetClassName() const { return "Object"; } + virtual const char * GetClassName() const { return type_name(); } + virtual const char * type_name() const { return "Object"; } const std::string& GetInstanceName() const; void SetInstanceName(const std::string& name); diff --git a/src/Core/ObjectsContext.h b/src/Core/ObjectsContext.h index 57b213a..af82f59 100644 --- a/src/Core/ObjectsContext.h +++ b/src/Core/ObjectsContext.h @@ -14,7 +14,7 @@ public: ObjectsContext(); virtual ~ObjectsContext(); - virtual const char * GetClassName() const { return "ObjectsContext"; } + uLibTypeMacro(ObjectsContext, Object) virtual ObjectsContext* GetChildren() override { return this; } /** diff --git a/src/Core/Property.h b/src/Core/Property.h index e932a0b..70e08e6 100644 --- a/src/Core/Property.h +++ b/src/Core/Property.h @@ -54,13 +54,13 @@ public: virtual void Updated() override { ULIB_SIGNAL_EMIT(PropertyBase::Updated); } // Serialization support for different uLib archives - virtual void serialize(Archive::xml_oarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::xml_iarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::text_oarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::text_iarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::hrt_oarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::hrt_iarchive & ar, const unsigned int version) = 0; - virtual void serialize(Archive::log_archive & ar, const unsigned int version) = 0; + virtual void serialize(Archive::xml_oarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::xml_iarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::text_oarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::text_iarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::hrt_oarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::hrt_iarchive & ar, const unsigned int version) override = 0; + virtual void serialize(Archive::log_archive & ar, const unsigned int version) override = 0; }; @@ -407,12 +407,32 @@ private: /** - * @brief Convenience macro to automatically activate and register all HRP members + * @brief Convenience macro to automatically activate and register all HRP members * as uLib properties. Usage: ULIB_ACTIVATE_PROPERTIES(obj) */ #define ULIB_ACTIVATE_PROPERTIES(obj) \ { uLib::Archive::property_register_archive _ar_tmp(&(obj)); _ar_tmp & (obj); } +/** + * @brief Declares a private member that automatically calls ULIB_ACTIVATE_PROPERTIES + * in every constructor of the class. Place this macro as the last declaration + * inside the class body (before the closing brace). + * + * Usage: ULIB_DECLARE_PROPERTIES(ClassName) + * + * This replaces per-constructor ULIB_ACTIVATE_PROPERTIES(*this) calls. + * RegisterDynamicProperty deduplicates by qualified name, so re-registration + * from inherited activators in a hierarchy is safe. + */ +#define ULIB_DECLARE_PROPERTIES(SelfType) \ +private: \ + struct _PropActivator { \ + _PropActivator(SelfType* self) { \ + uLib::Archive::property_register_archive _ar(self); \ + _ar & *self; \ + } \ + } _prop_activator{this}; + } // namespace Archive } // namespace uLib diff --git a/src/Core/Serializable.h b/src/Core/Serializable.h index ec5996e..ee14e20 100644 --- a/src/Core/Serializable.h +++ b/src/Core/Serializable.h @@ -309,6 +309,8 @@ namespace uLib { #define HRP5(name, data, units, min, max) boost::serialization::make_hrp(name, data, units).range(min, max) #define HRP6(name, data, units, default, min, max) boost::serialization::make_hrp(name, data, units).set_default(default).range(min, max) +#define HRPE(name, data, labels) boost::serialization::make_hrp_enum(name, data, labels) + // LEFT FOR BACKWARD COMPATIBILITY #define HRPU(name, units) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name, units) @@ -349,7 +351,7 @@ using boost::serialization::make_hrp_enum; #define ULIB_SERIALIZE_OBJECT(_Ob, ...) \ _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob, __VA_ARGS__) #define AR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name) -#define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name) +#define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_HR_(_name) #endif #define ULIB_SERIALIZE_ACCESS \ @@ -362,14 +364,14 @@ using boost::serialization::make_hrp_enum; #define ULIB_CLASS_EXPORT_OBJECT_KEY(_FullNamespaceClass) \ BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass) -#define _SERIALIZE_IMPL_SEQ \ - (uLib::Archive::text_iarchive)(uLib::Archive::text_oarchive)( \ - uLib::Archive:: \ - hrt_iarchive)(uLib::Archive:: \ - hrt_oarchive)(uLib::Archive:: \ - xml_iarchive)(uLib::Archive:: \ - xml_oarchive)(uLib::Archive:: \ - log_archive) +#define _SERIALIZE_IMPL_SEQ \ + (uLib::Archive::text_iarchive) \ + (uLib::Archive::text_oarchive) \ + (uLib::Archive::hrt_iarchive) \ + (uLib::Archive::hrt_oarchive) \ + (uLib::Archive::xml_iarchive) \ + (uLib::Archive::xml_oarchive) \ + (uLib::Archive::log_archive) /** Solving virtual class check problem */ #define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(_Base, _Derived) \ @@ -549,7 +551,8 @@ using boost::serialization::make_hrp_enum; void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \ /* PP serialize */ BOOST_PP_SEQ_FOR_EACH( \ _UNAR_OP, ob, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); \ - /* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList>(uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ } \ + /* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList> \ + (uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ }\ template \ inline void load_construct_data(ArchiveT &ar, _Ob *ob, \ const unsigned int file_version) { \ @@ -572,10 +575,18 @@ using boost::serialization::make_hrp_enum; _SERIALIZE_IMPL_SEQ) \ template \ void boost::serialization::access2<_Ob>::save_override( \ - ArchiveT &ar, _Ob &ob, const unsigned int version) + ArchiveT &ar, _Ob &ob, const unsigned int version) + #define _ULIB_DETAIL_UNINTRUSIVE_AR_(name) \ boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), ob.name) +#define _ULIB_DETAIL_UNINTRUSIVE_HR_(name) \ + boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), ob.name) + + + + + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Core/testing/PropertiesTest.cpp b/src/Core/testing/PropertiesTest.cpp index 9b1bdb7..7d740c7 100644 --- a/src/Core/testing/PropertiesTest.cpp +++ b/src/Core/testing/PropertiesTest.cpp @@ -76,8 +76,9 @@ public: ULIB_SERIALIZABLE_OBJECT(TestObject2) ULIB_SERIALIZE_OBJECT(TestObject2, TestObject) { - // std::cout << "Serializing TestObject2" << std::endl; - ar & boost::serialization::make_hrp("value2", ob.m_Value2, "mm").set_default(1.); + std::cout << "Serializing TestObject2" << std::endl; + // ar & boost::serialization::make_hrp("value2", ob.m_Value2, "mm").set_default(1.); + ar & HRP("value2", ob.m_Value2, "mm").set_default(1.); } diff --git a/src/Core/testing/PropertySystemTest.cpp b/src/Core/testing/PropertySystemTest.cpp index 092f9f8..03d1610 100644 --- a/src/Core/testing/PropertySystemTest.cpp +++ b/src/Core/testing/PropertySystemTest.cpp @@ -8,13 +8,12 @@ using namespace uLib; class TestObject : public Object { public: + uLibTypeMacro(TestObject, Object) TestObject() : Object(), IntProp(this, "IntProp", 10), StringProp(this, "StringProp", "Initial") {} - virtual const char* GetClassName() const override { return "TestObject"; } - Property IntProp; Property StringProp; }; diff --git a/src/Core/testing/PropertyTypesTest.cpp b/src/Core/testing/PropertyTypesTest.cpp index 2eeca71..e54d631 100644 --- a/src/Core/testing/PropertyTypesTest.cpp +++ b/src/Core/testing/PropertyTypesTest.cpp @@ -9,10 +9,9 @@ using namespace uLib; class TestObject : public Object { public: + uLibTypeMacro(TestObject, Object) TestObject() : Object() {} - virtual const char* GetClassName() const override { return "TestObject"; } - // Use new typedefs StringProperty StringProp = StringProperty(this, "StringProp", "Initial"); IntProperty IntProp = IntProperty(this, "IntProp", 42); diff --git a/src/HEP/Detectors/DetectorChamber.h b/src/HEP/Detectors/DetectorChamber.h index 3878f08..de135c0 100644 --- a/src/HEP/Detectors/DetectorChamber.h +++ b/src/HEP/Detectors/DetectorChamber.h @@ -39,13 +39,11 @@ namespace uLib { class DetectorChamber : public ContainerBox { - - typedef ContainerBox BaseClass; - public: + uLibTypeMacro(DetectorChamber, ContainerBox) - virtual const char * GetClassName() const { return "DetectorChamber"; } + DetectorChamber() : BaseClass() { m_ProjectionPlane.origin = HPoint3f(0, 0, 0); diff --git a/src/HEP/Geant/EmitterPrimary.hh b/src/HEP/Geant/EmitterPrimary.hh index 8c81d28..f9fd9ef 100644 --- a/src/HEP/Geant/EmitterPrimary.hh +++ b/src/HEP/Geant/EmitterPrimary.hh @@ -26,8 +26,7 @@ namespace Geant { class EmitterPrimary : public G4VUserPrimaryGeneratorAction, public AffineTransform { public: - - virtual const char* GetClassName() const override { return "Geant.EmitterPrimary"; } + uLibTypeMacro(EmitterPrimary, Object) EmitterPrimary(); virtual ~EmitterPrimary(); @@ -47,8 +46,7 @@ class EmitterPrimary : public G4VUserPrimaryGeneratorAction, public AffineTransf class SkyPlaneEmitterPrimary : public EmitterPrimary { public: - - virtual const char* GetClassName() const override { return "Geant.SkyPlaneEmitterPrimary"; } + uLibTypeMacro(SkyPlaneEmitterPrimary, EmitterPrimary) SkyPlaneEmitterPrimary(); virtual ~SkyPlaneEmitterPrimary(); @@ -69,8 +67,7 @@ class SkyPlaneEmitterPrimary : public EmitterPrimary class CylinderEmitterPrimary : public EmitterPrimary { public: - - virtual const char* GetClassName() const override { return "Geant.CylinderEmitterPrimary"; } + uLibTypeMacro(CylinderEmitterPrimary, EmitterPrimary) CylinderEmitterPrimary(); virtual ~CylinderEmitterPrimary(); @@ -98,8 +95,7 @@ class CylinderEmitterPrimary : public EmitterPrimary class QuadMeshEmitterPrimary : public EmitterPrimary { public: - - virtual const char* GetClassName() const override { return "Geant.QuadMeshEmitterPrimary"; } + uLibTypeMacro(QuadMeshEmitterPrimary, EmitterPrimary) QuadMeshEmitterPrimary(); virtual ~QuadMeshEmitterPrimary(); diff --git a/src/HEP/Geant/GeantEvent.h b/src/HEP/Geant/GeantEvent.h index b0e6dec..ca1e37c 100644 --- a/src/HEP/Geant/GeantEvent.h +++ b/src/HEP/Geant/GeantEvent.h @@ -50,8 +50,7 @@ class SteppingAction; class GeantEvent : public Object { public: - - virtual const char* GetClassName() const override { return "Geant.GeantEvent"; } + uLibTypeMacro(GeantEvent, Object) /// A single interaction step along the muon path. struct Delta { diff --git a/src/HEP/Geant/Matter.h b/src/HEP/Geant/Matter.h index 1df6573..d5eafb9 100644 --- a/src/HEP/Geant/Matter.h +++ b/src/HEP/Geant/Matter.h @@ -60,6 +60,7 @@ private: class Material : public Object { public: + uLibTypeMacro(Material, Object) enum State { Undefined = 0, @@ -68,8 +69,6 @@ public: Gas }; - virtual const char* GetClassName() const override { return "Geant.Material"; } - Material(); Material(const char *name); ~Material(); diff --git a/src/HEP/Geant/Scene.h b/src/HEP/Geant/Scene.h index 504a56e..f2fa6d4 100644 --- a/src/HEP/Geant/Scene.h +++ b/src/HEP/Geant/Scene.h @@ -43,8 +43,7 @@ class EmitterPrimary; class Scene : public Object { public: - - virtual const char* GetClassName() const override { return "Geant.Scene"; } + uLibTypeMacro(Scene, Object) Scene(); ~Scene(); diff --git a/src/HEP/Geant/Solid.h b/src/HEP/Geant/Solid.h index 82fac46..1e81fc4 100644 --- a/src/HEP/Geant/Solid.h +++ b/src/HEP/Geant/Solid.h @@ -43,8 +43,7 @@ namespace Geant { class Solid : public Object { public: - - virtual const char* GetClassName() const override { return "Geant.Solid"; } + uLibTypeMacro(Solid, Object) Solid(); Solid(const char *name); @@ -93,10 +92,8 @@ protected: class TessellatedSolid : public Solid { - typedef Solid BaseClass; public: - - virtual const char* GetClassName() const override { return "Geant.TessellatedSolid"; } + uLibTypeMacro(TessellatedSolid, Solid) TessellatedSolid(); TessellatedSolid(const char *name); @@ -120,11 +117,9 @@ private : class BoxSolid : public Solid { - typedef Solid BaseClass; - + public: - - virtual const char* GetClassName() const override { return "Geant.BoxSolid"; } + uLibTypeMacro(BoxSolid, Solid) BoxSolid(const char *name = ""); BoxSolid(const char *name, ContainerBox *box); diff --git a/src/Math/Assembly.cpp b/src/Math/Assembly.cpp index e232e3e..3a9d816 100644 --- a/src/Math/Assembly.cpp +++ b/src/Math/Assembly.cpp @@ -26,7 +26,6 @@ Assembly::Assembly() m_BBoxMax(Vector3f::Zero()), m_ShowBoundingBox(false), m_GroupSelection(true) { - ULIB_ACTIVATE_PROPERTIES(*this); } Assembly::Assembly(const Assembly ©) diff --git a/src/Math/Assembly.h b/src/Math/Assembly.h index 64246d4..88a9df4 100644 --- a/src/Math/Assembly.h +++ b/src/Math/Assembly.h @@ -46,7 +46,7 @@ namespace uLib { class Assembly : public ObjectsContext, public TRS { public: uLibTypeMacro(Assembly, ObjectsContext, TRS) - virtual const char *GetClassName() const override { return "Assembly"; } + Assembly(); Assembly(const Assembly ©); @@ -113,6 +113,8 @@ private: bool m_GroupSelection; bool m_InUpdated = false; std::map m_ChildConnections; + + ULIB_DECLARE_PROPERTIES(Assembly) }; } // namespace uLib diff --git a/src/Math/ContainerBox.h b/src/Math/ContainerBox.h index 674e571..dcdf57e 100644 --- a/src/Math/ContainerBox.h +++ b/src/Math/ContainerBox.h @@ -29,6 +29,7 @@ #include "Geometry.h" #include "Core/Object.h" #include "Core/Property.h" +#include "Core/Serializable.h" #include "Math/Dense.h" #include "Math/Transform.h" #include @@ -48,16 +49,11 @@ namespace uLib { */ class ContainerBox : public TRS { -public: uLibTypeMacro(ContainerBox, TRS) + ULIB_SERIALIZE_ACCESS + ULIB_DECLARE_PROPERTIES(ContainerBox) - virtual const char * GetClassName() const override { return "ContainerBox"; } - - //////////////////////////////////////////////////////////////////////////// - // PROPERTIES // - - Vector3f Size; - Vector3f Origin; +public: /** * @brief Default constructor. @@ -67,7 +63,6 @@ public: : m_LocalT(this), // BaseClass is Parent of m_LocalTransform Size(1.0f, 1.0f, 1.0f), Origin(0.0f, 0.0f, 0.0f) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } @@ -79,7 +74,6 @@ public: : m_LocalT(this), Size(size), Origin(0.0f, 0.0f, 0.0f) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } @@ -92,13 +86,12 @@ public: TRS(copy), Size(copy.Size), Origin(copy.Origin) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } - /** - * @brief Serialization template for property registration and persistence. - */ + // /** + // * @brief Serialization template for property registration and persistence. + // */ template void serialize(ArchiveT & ar, const unsigned int version) { ar & HRP(Size); @@ -236,9 +229,13 @@ private: private: + Vector3f Size; + Vector3f Origin; AffineTransform m_LocalT; + }; } // namespace uLib + #endif // CONTAINERBOX_H diff --git a/src/Math/Cylinder.h b/src/Math/Cylinder.h index 688149c..921d52a 100644 --- a/src/Math/Cylinder.h +++ b/src/Math/Cylinder.h @@ -41,8 +41,10 @@ namespace uLib { */ class Cylinder : public TRS { -public: uLibTypeMacro(Cylinder, TRS) + ULIB_DECLARE_PROPERTIES(Cylinder) + +public: /** * @brief PROPERTIES @@ -51,22 +53,20 @@ public: float Height; int Axis; - virtual const char * GetClassName() const override { return "Cylinder"; } + /** * @brief Default constructor. Aligns with Y by default. */ Cylinder() : m_LocalT(this), Radius(1.0), Height(1.0), Axis(1) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } /** * @brief Constructor with radius and height. */ - Cylinder(float radius, float height, int axis = 1) + Cylinder(float radius, float height, int axis = 1) : m_LocalT(this), Radius(radius), Height(height), Axis(axis) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } @@ -75,7 +75,6 @@ public: */ Cylinder(const Cylinder ©) : m_LocalT(this), TRS(copy), Radius(copy.Radius), Height(copy.Height), Axis(copy.Axis) { - ULIB_ACTIVATE_PROPERTIES(*this); this->Sync(); } @@ -84,10 +83,10 @@ public: */ template void serialize(ArchiveT & ar, const unsigned int version) { - ar & boost::serialization::make_nvp("TRS", boost::serialization::base_object(*this)); ar & HRP(Radius); ar & HRP(Height); - ar & HRP(Axis); + ar & boost::serialization::make_hrp_enum("Axis", Axis, {"X", "Y", "Z"}); + ar & HRP("TRS", boost::serialization::base_object(*this)); } /** Sets the radius of the cylinder */ diff --git a/src/Math/Geometry.h b/src/Math/Geometry.h index 7d29ec7..139bfbf 100644 --- a/src/Math/Geometry.h +++ b/src/Math/Geometry.h @@ -43,7 +43,7 @@ protected: public: uLibTypeMacro(Geometry, Object) - virtual const char * GetClassName() const override { return "Geometry"; } + virtual void SetParent(Geometry* p) { m_Parent = p; } virtual Geometry* GetParent() const { return m_Parent; } @@ -93,7 +93,7 @@ protected: public: uLibTypeMacro(LinearGeometry, Geometry) - virtual const char * GetClassName() const override { return "LinearGeometry"; } + virtual bool IsLinear() const override { return true; } virtual bool IsPure() const override { return true; } @@ -162,7 +162,7 @@ public: uLibTypeMacro(CylindricalGeometry, LinearGeometry) CylindricalGeometry() {} - virtual const char * GetClassName() const override { return "CylindricalGeometry"; } + virtual bool IsPure() const override { return false; } @@ -185,7 +185,7 @@ public: uLibTypeMacro(SphericalGeometry, LinearGeometry) SphericalGeometry() {} - virtual const char * GetClassName() const override { return "SphericalGeometry"; } + virtual bool IsPure() const override { return false; } @@ -212,7 +212,7 @@ public: uLibTypeMacro(ToroidalGeometry, LinearGeometry) ToroidalGeometry(float Rtor) : m_Rtor(Rtor) {} - virtual const char * GetClassName() const override { return "ToroidalGeometry"; } + virtual bool IsPure() const override { return false; } diff --git a/src/Math/Polydata.h b/src/Math/Polydata.h index a28cd77..cdfe3d4 100644 --- a/src/Math/Polydata.h +++ b/src/Math/Polydata.h @@ -36,7 +36,7 @@ class Polydata : public Object { public: - virtual const char * GetClassName() const { return "Polydata"; } + diff --git a/src/Math/QuadMesh.h b/src/Math/QuadMesh.h index 8361f70..b1f25dd 100644 --- a/src/Math/QuadMesh.h +++ b/src/Math/QuadMesh.h @@ -39,7 +39,7 @@ class QuadMesh : public TRS public: uLibTypeMacro(QuadMesh, TRS) - virtual const char * GetClassName() const override { return "QuadMesh"; } + void PrintSelf(std::ostream &o); diff --git a/src/Math/Transform.h b/src/Math/Transform.h index 63d0c5d..becad34 100644 --- a/src/Math/Transform.h +++ b/src/Math/Transform.h @@ -188,9 +188,12 @@ public: typedef Eigen::Affine3f AffineMatrix; class TRS : public AffineTransform { - -public: + uLibTypeMacro(TRS, AffineTransform) + ULIB_SERIALIZE_ACCESS + // ULIB_DECLARE_PROPERTIES(TRS) + +public: Vector3f position = Vector3f::Zero(); Vector3f rotation = Vector3f::Zero(); @@ -259,6 +262,7 @@ public: ar & HRPU(rotation, "rad"); ar & HRP(scaling); } + AffineMatrix GetAffineMatrix() const { AffineMatrix m = AffineMatrix::Identity(); @@ -273,6 +277,10 @@ public: Matrix4f GetMatrix() const { return this->GetAffineMatrix().matrix(); } + + + + }; diff --git a/src/Math/TriangleMesh.h b/src/Math/TriangleMesh.h index 590fdf3..157d9ef 100644 --- a/src/Math/TriangleMesh.h +++ b/src/Math/TriangleMesh.h @@ -42,7 +42,7 @@ class TriangleMesh : public TRS public: uLibTypeMacro(TriangleMesh, TRS) - virtual const char * GetClassName() const override { return "TriangleMesh"; } + void PrintSelf(std::ostream &o); diff --git a/src/Math/VoxImage.h b/src/Math/VoxImage.h index 4dfb8c4..b50f5a1 100644 --- a/src/Math/VoxImage.h +++ b/src/Math/VoxImage.h @@ -47,7 +47,7 @@ namespace Abstract { class VoxImage : public uLib::StructuredGrid { public: - virtual const char * GetClassName() const { return "VoxImage"; } + typedef uLib::StructuredGrid BaseClass; diff --git a/src/Math/VoxImageFilter.h b/src/Math/VoxImageFilter.h index e66778a..676310f 100644 --- a/src/Math/VoxImageFilter.h +++ b/src/Math/VoxImageFilter.h @@ -61,7 +61,7 @@ class VoxImageFilter : public Abstract::VoxImageFilter, public Object { public: - virtual const char * GetClassName() const { return "VoxImageFilter"; } + VoxImageFilter(const Vector3i &size); diff --git a/src/Vtk/Math/vtkAssembly.h b/src/Vtk/Math/vtkAssembly.h index f63c8d7..69ce2dc 100644 --- a/src/Vtk/Math/vtkAssembly.h +++ b/src/Vtk/Math/vtkAssembly.h @@ -36,7 +36,7 @@ class vtkObjectsContext; // forward */ class Assembly : public Puppet { public: - virtual const char *GetClassName() const override { return "Vtk.Assembly"; } + uLibTypeMacro(Assembly, Puppet) Assembly(uLib::Assembly *content); virtual ~Assembly(); diff --git a/src/Vtk/vtkObjectsContext.h b/src/Vtk/vtkObjectsContext.h index 3299de3..bc54917 100644 --- a/src/Vtk/vtkObjectsContext.h +++ b/src/Vtk/vtkObjectsContext.h @@ -15,7 +15,7 @@ namespace Vtk { */ class vtkObjectsContext : public Puppet { public: - virtual const char* GetClassName() const override { return "vtkObjectsContext"; } + uLibTypeMacro(vtkObjectsContext, Puppet) vtkObjectsContext(uLib::ObjectsContext *context); virtual ~vtkObjectsContext();