# Skill: VTK Visualization Pipeline This skill defines how to bridge domain objects with the VTK 3D visualization layer. ## Context - **Wrapper**: `Prop3D` (wraps a `vtkProp`). - **Mapping**: `Viewport` maintains `m_ObjectToProp3D` for synchronization. - **GUI Integration**: `QViewport` handles Qt events and selection signals. ## Implementation Patterns ### 1. Creating a Prop3D A `Prop3D` should wrap a domain object and update its visual state when the object changes. ```cpp class MyProp3D : public Prop3D { public: MyProp3D(MyObject* obj) : Prop3D(obj) { // Connect domain updates to visual refreshes uLib::Object::connect(obj, &Object::Updated, [this]() { this->SyncFromObject(); }); // Expose properties to the VTK side-panel ULIB_ACTIVATE_DISPLAY_PROPERTIES(*this) } void SyncFromObject() { // Update VTK actors/mappers from MyObject's properties } }; ``` ### 2. Display Properties Use `serialize_display` to choose which properties of the domain object or the `Prop3D` itself are visible in the sliding "Display Properties" panel in `gcompose`. ```cpp void serialize_display(Archive::display_properties_archive &ar) { ar & boost::serialization::make_hrp("Opacity", m_Opacity); ar & boost::serialization::make_hrp("Wireframe", m_Wireframe); } ``` ### 3. Transformation Sync (TRS) Always synchronize the object's `trs` (Translate, Rotate, Scale) with the VTK actor's user transform. ```cpp void UpdateTransform() { auto matrix = GetContent()->GetTransform().GetMatrix(); m_Actor->SetUserMatrix(uLib::ToVtkMatrix(matrix)); } ``` ## Checklist - [ ] Does the `Prop3D` connect to the object's `Updated()` signal? - [ ] Are `ULIB_ACTIVATE_DISPLAY_PROPERTIES` and `serialize_display` implemented? - [ ] Is the transformation (TRS) correctly mapped to the VTK actor?