refactor: rename Puppet class to Prop3D across the codebase
This commit is contained in:
@@ -6,4 +6,4 @@ When this rule is active, restrict the operational context to libraries excludin
|
||||
- **Exclude Path**: `src/Vtk`
|
||||
- **Include Paths**: `src/Core`, `src/Math`, `src/HEP`, `src/Root`, `src/Python`, `src/utils`
|
||||
- **Focus**: Tomographic reconstruction algorithms, data structures in `Core`, and physical modeling in `HEP`.
|
||||
- **Constraint**: Avoid referencing `Puppet`, `Viewport`, or any VTK-specific headers unless the user overrides this restriction.
|
||||
- **Constraint**: Avoid referencing `Prop3D`, `Viewport`, or any VTK-specific headers unless the user overrides this restriction.
|
||||
|
||||
@@ -4,6 +4,6 @@ trigger: always_on
|
||||
# Context Inclusion: VTK
|
||||
When this rule is active, include the VTK visualization layer in the operational context.
|
||||
- **Priority Path**: `src/Vtk`
|
||||
- **Focus**: `Puppet` hierarchy, `Viewport` management, and the synchronization between domain objects and VTK props.
|
||||
- **Focus**: `Prop3D` hierarchy, `Viewport` management, and the synchronization between domain objects and VTK props.
|
||||
- **Key Classes**: `vtkViewport`, `vtkQViewport`, `vtkObjectsContext`, and all classes in `src/Vtk/HEP/Geant`.
|
||||
- **Logic**: Ensure transformations (TRS) applied to domain objects are correctly mirrored in the visualization layer and vice versa.
|
||||
|
||||
24
CLAUDE.md
24
CLAUDE.md
@@ -71,32 +71,32 @@ mutomCore → mutomMath → mutomDetectors → mutomGeant
|
||||
- `ObjectsContext` is a container owning a list of `Object*` pointers; signals `ObjectAdded`/`ObjectRemoved`
|
||||
|
||||
### VTK Layer (`src/Vtk/`)
|
||||
- `Puppet` (inherits `uLib::Object`): wraps a VTK `vtkProp` for rendering. Has `GetContent()` returning the underlying domain object. Display-only properties are registered via `ULIB_ACTIVATE_DISPLAY_PROPERTIES` macro.
|
||||
- `Viewport`: base class managing the VTK renderer, picking, selection logic. Maintains `m_Puppets` vector and `m_ObjectToPuppet` map.
|
||||
- `QViewport` (inherits `QWidget` + `Viewport`): Qt-embedded VTK widget. Emits Qt signal `puppetSelected(Puppet*)` on click-selection via `OnSelectionChanged`.
|
||||
- `vtkObjectsContext`: wraps `ObjectsContext`, creating/destroying `Puppet`s as objects come/go. Emits `PuppetAdded`/`PuppetRemoved`.
|
||||
- Display properties: `serialize_display()` + `display_properties_archive` registers selected `hrp<T>` fields as `PropertyBase*` in the puppet's `m_DisplayProperties`. `PropertyEditor::setObject(obj, displayOnly=true)` shows only those.
|
||||
- `Prop3D` (inherits `uLib::Object`): wraps a VTK `vtkProp` for rendering. Has `GetContent()` returning the underlying domain object. Display-only properties are registered via `ULIB_ACTIVATE_DISPLAY_PROPERTIES` macro.
|
||||
- `Viewport`: base class managing the VTK renderer, picking, selection logic. Maintains `m_Prop3Ds` vector and `m_ObjectToProp3D` map.
|
||||
- `QViewport` (inherits `QWidget` + `Viewport`): Qt-embedded VTK widget. Emits Qt signal `prop3dSelected(Prop3D*)` on click-selection via `OnSelectionChanged`.
|
||||
- `vtkObjectsContext`: wraps `ObjectsContext`, creating/destroying `Prop3D`s as objects come/go. Emits `Prop3DAdded`/`Prop3DRemoved`.
|
||||
- Display properties: `serialize_display()` + `display_properties_archive` registers selected `hrp<T>` fields as `PropertyBase*` in the prop3d's `m_DisplayProperties`. `PropertyEditor::setObject(obj, displayOnly=true)` shows only those.
|
||||
|
||||
### gcompose GUI App (`app/gcompose/src/`)
|
||||
- `MainPanel`: top-level widget. Owns `ContextPanel` (left) and `ViewportPane` (right). Wires together viewport↔context selection via signals.
|
||||
- `ContextPanel`: tree view of `ObjectsContext`. Emits `objectSelected(Object*)`. Contains an embedded `PropertiesPanel`.
|
||||
- `PropertiesPanel`: shows `uLib::Object` properties via `PropertyEditor`.
|
||||
- `ViewportPane`: embeds `QViewport` + a slide-out "Display Properties" panel (`PropertyEditor` in display-only mode).
|
||||
- `PropertyEditor`: populates widgets from `Object::GetProperties()` (all) or `Puppet::GetDisplayProperties()` (display-only mode).
|
||||
- `PropertyEditor`: populates widgets from `Object::GetProperties()` (all) or `Prop3D::GetDisplayProperties()` (display-only mode).
|
||||
|
||||
### Selection Sync Flow
|
||||
```
|
||||
Viewport click → Viewport::SelectPuppet() → QViewport::OnSelectionChanged()
|
||||
→ emit puppetSelected(p)
|
||||
Viewport click → Viewport::SelectProp3D() → QViewport::OnSelectionChanged()
|
||||
→ emit prop3dSelected(p)
|
||||
→ MainPanel: contextPanel->selectObject(p->GetContent()) [updates tree + PropertiesPanel]
|
||||
→ MainPanel: firstPane->setObject(p) [updates Display Properties panel]
|
||||
|
||||
ContextPanel tree click → emit objectSelected(obj)
|
||||
→ MainPanel: viewport->SelectPuppet(puppet) [visual selection in VTK]
|
||||
→ MainPanel: firstPane->setObject(puppet) [updates Display Properties panel]
|
||||
→ MainPanel: viewport->SelectProp3D(prop3d) [visual selection in VTK]
|
||||
→ MainPanel: firstPane->setObject(prop3d) [updates Display Properties panel]
|
||||
```
|
||||
|
||||
### Key Patterns
|
||||
- **Two signal systems coexist**: Qt signals (`Q_OBJECT`, `connect(...)`) for GUI; `uLib::Object::connect(...)` for domain signals.
|
||||
- **Display properties** flow: `Puppet::serialize_display()` → `display_properties_archive` → `RegisterDisplayProperty()` → `PropertyEditor(displayOnly=true)`. Must call `ULIB_ACTIVATE_DISPLAY_PROPERTIES` in the puppet constructor.
|
||||
- **Puppet ↔ Object map**: `Viewport::m_ObjectToPuppet` allows lookup by domain object; `vtkObjectsContext::GetPuppet(obj)` does the same.
|
||||
- **Display properties** flow: `Prop3D::serialize_display()` → `display_properties_archive` → `RegisterDisplayProperty()` → `PropertyEditor(displayOnly=true)`. Must call `ULIB_ACTIVATE_DISPLAY_PROPERTIES` in the prop3d constructor.
|
||||
- **Prop3D ↔ Object map**: `Viewport::m_ObjectToProp3D` allows lookup by domain object; `vtkObjectsContext::GetProp3D(obj)` does the same.
|
||||
|
||||
@@ -90,13 +90,13 @@ MainPanel::MainPanel(QWidget* parent) : QWidget(parent), m_context(nullptr), m_m
|
||||
|
||||
connect(m_contextPanel, &ContextPanel::objectSelected, [this](uLib::Object* obj) {
|
||||
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
||||
uLib::Vtk::Puppet* puppet = nullptr;
|
||||
uLib::Vtk::Prop3D* prop3d = nullptr;
|
||||
if (m_mainVtkContext) {
|
||||
puppet = m_mainVtkContext->GetPuppet(obj);
|
||||
prop3d = m_mainVtkContext->GetProp3D(obj);
|
||||
}
|
||||
viewport->SelectPuppet(puppet);
|
||||
// Update the display properties in the viewport pane itself - use the puppet proxy if possible
|
||||
m_firstPane->setObject(puppet ? (uLib::Object*)puppet : obj);
|
||||
viewport->SelectProp3D(prop3d);
|
||||
// Update the display properties in the viewport pane itself - use the prop3d proxy if possible
|
||||
m_firstPane->setObject(prop3d ? (uLib::Object*)prop3d : obj);
|
||||
} else {
|
||||
m_firstPane->setObject(obj);
|
||||
}
|
||||
@@ -116,7 +116,7 @@ void MainPanel::setContext(uLib::ObjectsContext* context) {
|
||||
|
||||
if (m_mainVtkContext) {
|
||||
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
||||
viewport->RemovePuppet(*m_mainVtkContext);
|
||||
viewport->RemoveProp3D(*m_mainVtkContext);
|
||||
}
|
||||
delete m_mainVtkContext;
|
||||
m_mainVtkContext = nullptr;
|
||||
@@ -125,9 +125,9 @@ void MainPanel::setContext(uLib::ObjectsContext* context) {
|
||||
if (context) {
|
||||
if (auto* viewport = qobject_cast<uLib::Vtk::QViewport*>(m_firstPane->currentViewport())) {
|
||||
m_mainVtkContext = new uLib::Vtk::ObjectsContext(context);
|
||||
// viewport->AddPuppet(*m_mainVtkContext); // redundant
|
||||
// viewport->AddProp3D(*m_mainVtkContext); // redundant
|
||||
|
||||
auto syncSelection = [this](uLib::Vtk::Puppet* p) {
|
||||
auto syncSelection = [this](uLib::Vtk::Prop3D* p) {
|
||||
if (!p) {
|
||||
m_contextPanel->clearSelection();
|
||||
m_firstPane->setObject(nullptr);
|
||||
@@ -136,14 +136,14 @@ void MainPanel::setContext(uLib::ObjectsContext* context) {
|
||||
m_firstPane->setObject(p);
|
||||
}
|
||||
};
|
||||
connect(viewport, &uLib::Vtk::QViewport::puppetSelected, syncSelection);
|
||||
connect(viewport, &uLib::Vtk::QViewport::prop3dSelected, syncSelection);
|
||||
|
||||
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::PuppetAdded, [this](uLib::Vtk::Puppet* p) {
|
||||
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::Prop3DAdded, [this](uLib::Vtk::Prop3D* p) {
|
||||
if (p) {
|
||||
auto panes = this->findChildren<ViewportPane*>();
|
||||
for (auto* pane : panes) {
|
||||
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
||||
vp->AddPuppet(*p);
|
||||
vp->AddProp3D(*p);
|
||||
vp->ZoomAuto();
|
||||
vp->Render();
|
||||
}
|
||||
@@ -151,25 +151,25 @@ void MainPanel::setContext(uLib::ObjectsContext* context) {
|
||||
}
|
||||
});
|
||||
|
||||
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::PuppetRemoved, [this](uLib::Vtk::Puppet* p) {
|
||||
uLib::Object::connect(m_mainVtkContext, &uLib::Vtk::ObjectsContext::Prop3DRemoved, [this](uLib::Vtk::Prop3D* p) {
|
||||
if (p) {
|
||||
auto panes = this->findChildren<ViewportPane*>();
|
||||
for (auto* pane : panes) {
|
||||
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
||||
vp->RemovePuppet(*p);
|
||||
vp->RemoveProp3D(*p);
|
||||
vp->Render();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add any puppets that were created during m_mainVtkContext's construction to all panes
|
||||
// Add any prop3ds that were created during m_mainVtkContext's construction to all panes
|
||||
auto panes = this->findChildren<ViewportPane*>();
|
||||
for (auto* obj : context->GetObjects()) {
|
||||
if (auto* p = m_mainVtkContext->GetPuppet(obj)) {
|
||||
if (auto* p = m_mainVtkContext->GetProp3D(obj)) {
|
||||
for (auto* pane : panes) {
|
||||
if (auto* vp = qobject_cast<uLib::Vtk::QViewport*>(pane->currentViewport())) {
|
||||
vp->AddPuppet(*p);
|
||||
vp->AddProp3D(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,10 +403,10 @@ void PropertyEditor::setObject(::uLib::Object* obj, bool displayOnly) {
|
||||
const std::vector<::uLib::PropertyBase*>* props = &obj->GetProperties();
|
||||
|
||||
if (displayOnly) {
|
||||
if (auto* puppet = dynamic_cast<::uLib::Vtk::Puppet*>(obj)) {
|
||||
props = &puppet->GetDisplayProperties();
|
||||
if (auto* prop3d = dynamic_cast<::uLib::Vtk::Prop3D*>(obj)) {
|
||||
props = &prop3d->GetDisplayProperties();
|
||||
} else {
|
||||
// If it's not a puppet but displayOnly is requested, showing nothing or fallback?
|
||||
// If it's not a prop3d but displayOnly is requested, showing nothing or fallback?
|
||||
// Fallback: core properties.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ void QViewportPane::toggleDisplayPanel() {
|
||||
|
||||
void QViewportPane::setObject(uLib::Object* obj) {
|
||||
m_displayEditor->setObject(obj, true);
|
||||
// Auto-show panel if it's a puppet and we want to highlight this feature?
|
||||
// Auto-show panel if it's a prop3d and we want to highlight this feature?
|
||||
// User asked for "hiding panel", so maybe we don't auto-show.
|
||||
}
|
||||
|
||||
@@ -179,9 +179,9 @@ void QViewportPane::AttemptSplit(Qt::Orientation orientation) {
|
||||
if (currentVtk) {
|
||||
auto* newVtk = qobject_cast<uLib::Vtk::QViewport*>(newPane->currentViewport());
|
||||
if (newVtk) {
|
||||
// Copy puppets
|
||||
for (auto* puppet : currentVtk->getPuppets()) {
|
||||
newVtk->AddPuppet(*puppet);
|
||||
// Copy prop3ds
|
||||
for (auto* prop3d : currentVtk->getProp3Ds()) {
|
||||
newVtk->AddProp3D(*prop3d);
|
||||
}
|
||||
// Copy camera
|
||||
if (currentVtk->GetRenderer() && newVtk->GetRenderer()) {
|
||||
|
||||
@@ -99,15 +99,15 @@ void ViewportPane::toggleDisplayPanel() {
|
||||
void ViewportPane::setObject(uLib::Object* obj) {
|
||||
m_displayEditor->setObject(obj, true);
|
||||
|
||||
// Check if the object is a Puppet (meaning it has display properties)
|
||||
bool isPuppet = (dynamic_cast<::uLib::Vtk::Puppet*>(obj) != nullptr);
|
||||
// Check if the object is a Prop3D (meaning it has display properties)
|
||||
bool isProp3D = (dynamic_cast<::uLib::Vtk::Prop3D*>(obj) != nullptr);
|
||||
|
||||
// Only show the "Display" toggle button if it's a puppet
|
||||
m_toggleBtn->setVisible(isPuppet);
|
||||
// Only show the "Display" toggle button if it's a prop3d
|
||||
m_toggleBtn->setVisible(isProp3D);
|
||||
|
||||
// If it's a puppet, we might want to keep the panel state if it was already open,
|
||||
// or if it's NOT a puppet, definitely hide the toggle and panel.
|
||||
if (!isPuppet) {
|
||||
// If it's a prop3d, we might want to keep the panel state if it was already open,
|
||||
// or if it's NOT a prop3d, definitely hide the toggle and panel.
|
||||
if (!isProp3D) {
|
||||
m_toggleBtn->setChecked(false);
|
||||
m_displayPanel->hide();
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
|
||||
# Properties and the vtk-gui representation
|
||||
|
||||
This is the rationale behind the connection between TRS properties and Puppet Transformation.
|
||||
This is the rationale behind the connection between TRS properties and Prop3D Transformation.
|
||||
|
||||
The properties from model get propoagated via Object signalling system (the Update signal) to the vtkRepresentation and to the Qt widgets so that the overall transformation of the model reflects into a modification of its representation in vtk and in the gui.
|
||||
|
||||
In addition the properties need to be adjusted also from vtk, for example if user uses handlerwidget to change the transformation this is eventually applied to Puppet and Puppet should propagate the transformation change to the vtk representation object (for instance vtkContainerBox) and the latter eventually propagates the change into the model.
|
||||
In addition the properties need to be adjusted also from vtk, for example if user uses handlerwidget to change the transformation this is eventually applied to Prop3D and Prop3D should propagate the transformation change to the vtk representation object (for instance vtkContainerBox) and the latter eventually propagates the change into the model.
|
||||
|
||||
the Puppet or the vtk representation wrapper ( vtkContainerBox for instance is the wrapper od ContainerBox ) should not directly show the transformation of the handlerwidget but it should show the transformation of the model once applied so we are always seeing the actual aspect of the model reflected to the vtk representation and not the other way around.
|
||||
the Prop3D or the vtk representation wrapper ( vtkContainerBox for instance is the wrapper od ContainerBox ) should not directly show the transformation of the handlerwidget but it should show the transformation of the model once applied so we are always seeing the actual aspect of the model reflected to the vtk representation and not the other way around.
|
||||
|
||||
So in syntesis the model is the master and the vtk representation and the gui are the slaves of any modification, but the vtkHandlerWidget is able to apply a transform that should be applied to the model and then the model should propagate the transformation change to the vtk representation and to the gui.
|
||||
|
||||
## The Puppet
|
||||
## The Prop3D
|
||||
|
||||
The puppet is the proxy of the spatial placement of objects in the scene. Puppets should have an internal ContainerBox that is shown in the scene around the content to be able to pick Puppet from vtkViewport using the handler widget. The HandlerWidget moves the Puppet ContainerBox (the red Highlight element whe selected) to reflect the handler current transformation, but the transformation is propagated to the derived Puppet classes like vtkContainerBox.
|
||||
The prop3d is the proxy of the spatial placement of objects in the scene. Prop3Ds should have an internal ContainerBox that is shown in the scene around the content to be able to pick Prop3D from vtkViewport using the handler widget. The HandlerWidget moves the Prop3D ContainerBox (the red Highlight element whe selected) to reflect the handler current transformation, but the transformation is propagated to the derived Prop3D classes like vtkContainerBox.
|
||||
|
||||
The vtkHandlerWidget should handle the transformation of the puppet internal ContainerBox. The changes of the ContainerBox will be propagated to the derived classes and eventually to the model.
|
||||
The vtkHandlerWidget should handle the transformation of the prop3d internal ContainerBox. The changes of the ContainerBox will be propagated to the derived classes and eventually to the model.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ EmitterPrimary::EmitterPrimary()
|
||||
// Initial position and direction through AffineTransform
|
||||
// 10m on Z axis, pointing towards origin
|
||||
this->SetPosition(Vector3f(0, 0, 10000.0));
|
||||
// Default orientation is identity (pointing along -Z if we rotate the puppet accordingly)
|
||||
// Default orientation is identity (pointing along -Z if we rotate the prop3d accordingly)
|
||||
// But fParticleGun defaults are set here and overridden in GeneratePrimaries
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace uLib {
|
||||
* transformation that is applied on top of each child's own transform.
|
||||
*
|
||||
* A bounding box is automatically computed from all contained objects and
|
||||
* can be queried or shown/hidden through the VTK puppet.
|
||||
* can be queried or shown/hidden through the VTK prop3d.
|
||||
*/
|
||||
class Assembly : public ObjectsContext, public TRS {
|
||||
public:
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Controls whether the bounding box wireframe should be shown
|
||||
* in the viewer (used by the VTK puppet).
|
||||
* in the viewer (used by the VTK prop3d).
|
||||
*/
|
||||
void SetShowBoundingBox(bool show);
|
||||
bool GetShowBoundingBox() const;
|
||||
|
||||
@@ -45,8 +45,8 @@ BOOST_AUTO_TEST_CASE(vtkDetectorChamberTest) {
|
||||
|
||||
Vtk::DetectorChamber v_d1(&d1);
|
||||
Vtk::DetectorChamber v_d2(&d2);
|
||||
v_d1.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_d2.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_d1.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
v_d2.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
|
||||
if (!v_d1.GetProp()) {
|
||||
BOOST_FAIL("DetectorChamber::GetProp() returned NULL");
|
||||
@@ -55,8 +55,8 @@ BOOST_AUTO_TEST_CASE(vtkDetectorChamberTest) {
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.SetGridAxis(Vtk::Viewport::Y);
|
||||
viewer.AddPuppet(v_d1);
|
||||
viewer.AddPuppet(v_d2);
|
||||
viewer.AddProp3D(v_d1);
|
||||
viewer.AddProp3D(v_d2);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
|
||||
using namespace uLib;
|
||||
|
||||
// A simple puppet class to represent an arrow indicative of a projected muon hit
|
||||
class vtkArrowPuppet : public Vtk::Puppet {
|
||||
// A simple prop3d class to represent an arrow indicative of a projected muon hit
|
||||
class vtkArrowProp3D : public Vtk::Prop3D {
|
||||
public:
|
||||
vtkArrowPuppet() : m_Actor(vtkActor::New()) {
|
||||
vtkArrowProp3D() : m_Actor(vtkActor::New()) {
|
||||
vtkNew<vtkArrowSource> arrow;
|
||||
vtkNew<vtkPolyDataMapper> mapper;
|
||||
mapper->SetInputConnection(arrow->GetOutputPort());
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
m_Actor->GetProperty()->SetColor(1, 1, 0); // Yellow color for visibility
|
||||
}
|
||||
|
||||
virtual ~vtkArrowPuppet() { m_Actor->Delete(); }
|
||||
virtual ~vtkArrowProp3D() { m_Actor->Delete(); }
|
||||
|
||||
void SetProjection(const HLine3f &line) {
|
||||
HPoint3f p = line.origin;
|
||||
@@ -131,24 +131,24 @@ BOOST_AUTO_TEST_CASE(vtkDetectorMuonProjectionTest) {
|
||||
v_event.AddPocaPoint(HPoint3f(0, 0, 0));
|
||||
v_event.SetColor(1, 0, 0); // Red muon event
|
||||
|
||||
v_d1.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_d1.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
v_d1.SetOpacity(0.3);
|
||||
v_d2.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_d2.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
v_d2.SetOpacity(0.3);
|
||||
|
||||
// 5. Add two arrows to mark where the projection is located on the chambers
|
||||
vtkArrowPuppet v_p1, v_p2;
|
||||
vtkArrowProp3D v_p1, v_p2;
|
||||
v_p1.SetProjection(mu_proj1.LineIn());
|
||||
v_p2.SetProjection(mu_proj2.LineIn());
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.SetGridAxis(Vtk::Viewport::Z);
|
||||
viewer.AddPuppet(v_d1);
|
||||
viewer.AddPuppet(v_d2);
|
||||
viewer.AddPuppet(v_event);
|
||||
viewer.AddPuppet(v_p1);
|
||||
viewer.AddPuppet(v_p2);
|
||||
viewer.AddProp3D(v_d1);
|
||||
viewer.AddProp3D(v_d2);
|
||||
viewer.AddProp3D(v_event);
|
||||
viewer.AddProp3D(v_p1);
|
||||
viewer.AddProp3D(v_p2);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(vtkMuonScatterTest) {
|
||||
// Vtk::Tie<Vtk::Viewer> vms;
|
||||
// vms.DoAction();
|
||||
|
||||
viewer.AddPuppet(v_event);
|
||||
viewer.AddProp3D(v_event);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class MuonEvent : public Puppet, public Polydata {
|
||||
class MuonEvent : public Prop3D, public Polydata {
|
||||
typedef MuonEventData Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -54,7 +54,7 @@ class vtkRenderWindowInteractor;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class MuonScatter : public Puppet, public Polydata {
|
||||
class MuonScatter : public Prop3D, public Polydata {
|
||||
typedef uLib::MuonScatter Content;
|
||||
|
||||
public:
|
||||
@@ -66,9 +66,9 @@ public:
|
||||
Content &GetModel();
|
||||
uLib::Object* GetContent() const override { return (uLib::Object*)m_Content; }
|
||||
|
||||
void PrintSelf(std::ostream &o) const;
|
||||
void PrintSelf(std::ostream &o) const override;
|
||||
|
||||
virtual vtkPolyData *GetPolyData() const;
|
||||
virtual vtkPolyData *GetPolyData() const override;
|
||||
|
||||
void AddPocaPoint(HPoint3f poca);
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
void vtkStartInteractive();
|
||||
|
||||
protected:
|
||||
void ConnectInteractor(vtkRenderWindowInteractor *interactor);
|
||||
void ConnectInteractor(vtkRenderWindowInteractor *interactor) override;
|
||||
|
||||
private:
|
||||
void InstallPipe();
|
||||
|
||||
@@ -59,7 +59,7 @@ void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void
|
||||
<< " with " << lastEvent->Path().size() << " steps." << std::endl;
|
||||
|
||||
Vtk::GeantEvent* vtkEvent = new Vtk::GeantEvent(lastEvent);
|
||||
state->viewer->AddPuppet(*vtkEvent);
|
||||
state->viewer->AddProp3D(*vtkEvent);
|
||||
|
||||
state->viewer->GetRenderer()->Render();
|
||||
state->viewer->GetRenderWindow()->Render();
|
||||
@@ -99,19 +99,19 @@ int main(int argc, char** argv) {
|
||||
|
||||
Vtk::ContainerBox* vtkWorld = new Vtk::ContainerBox(scene.GetWorldBox());
|
||||
vtkWorld->ShowScaleMeasures(true);
|
||||
vtkWorld->SetRepresentation(Vtk::Puppet::Wireframe);
|
||||
vtkWorld->SetRepresentation(Vtk::Prop3D::Wireframe);
|
||||
vtkWorld->SetSelectable(false);
|
||||
viewer.AddPuppet(*vtkWorld);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkIron);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// Use vtkCylinderEmitterPrimary
|
||||
Vtk::vtkCylinderEmitterPrimary* vtkEmitter = new Vtk::vtkCylinderEmitterPrimary(*emitter);
|
||||
vtkEmitter->SetSelectable(false);
|
||||
viewer.AddPuppet(*vtkEmitter);
|
||||
viewer.AddProp3D(*vtkEmitter);
|
||||
|
||||
// 3. Event Handling
|
||||
AppState state = { &scene, &viewer, {} };
|
||||
|
||||
@@ -52,7 +52,7 @@ void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void
|
||||
|
||||
// Wrap it for VTK
|
||||
Vtk::GeantEvent* vtkEvent = new Vtk::GeantEvent(lastEvent);
|
||||
state->viewer->AddPuppet(*vtkEvent);
|
||||
state->viewer->AddProp3D(*vtkEvent);
|
||||
|
||||
// Re-render
|
||||
state->viewer->GetRenderer()->Render();
|
||||
@@ -107,33 +107,33 @@ int main(int argc, char** argv) {
|
||||
// Visualize world box
|
||||
Vtk::ContainerBox* vtkWorld = new Vtk::ContainerBox(scene.GetWorldBox());
|
||||
vtkWorld->ShowScaleMeasures(true);
|
||||
vtkWorld->SetRepresentation(Vtk::Puppet::Wireframe);
|
||||
vtkWorld->SetRepresentation(Vtk::Prop3D::Wireframe);
|
||||
vtkWorld->SetSelectable(false);
|
||||
viewer.AddPuppet(*vtkWorld);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
// Visualize iron cube
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkIron);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// Visualize Top Chamber
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box);
|
||||
vtkTop->SetOpacity(0.5);
|
||||
vtkTop->SetColor(0.2, 0.8, 0.2);
|
||||
vtkTop->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkTop);
|
||||
vtkTop->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkTop);
|
||||
|
||||
// Visualize Bottom Chamber
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box);
|
||||
vtkBottom->SetOpacity(0.5);
|
||||
vtkBottom->SetColor(0.2, 0.8, 0.2);
|
||||
vtkBottom->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkBottom);
|
||||
vtkBottom->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkBottom);
|
||||
|
||||
// Visualize Emitter
|
||||
Vtk::EmitterPrimary* vtkEmitter = new Vtk::EmitterPrimary(*emitter);
|
||||
viewer.AddPuppet(*vtkEmitter);
|
||||
viewer.AddProp3D(*vtkEmitter);
|
||||
|
||||
// 3. Event Handling
|
||||
AppState state = { &scene, &viewer, {} };
|
||||
|
||||
@@ -83,7 +83,7 @@ void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void
|
||||
|
||||
// Wrap it for VTK
|
||||
Vtk::GeantEvent* vtkEvent = new Vtk::GeantEvent(lastEvent);
|
||||
state->viewer->AddPuppet(*vtkEvent);
|
||||
state->viewer->AddProp3D(*vtkEvent);
|
||||
|
||||
// Re-render
|
||||
state->viewer->GetRenderer()->Render();
|
||||
@@ -120,13 +120,13 @@ int main(int argc, char** argv) {
|
||||
Vtk::ContainerBox* vtkWorld = new Vtk::ContainerBox(scene.GetWorldBox());
|
||||
// vtkWorld->ShowBoundingBox(true);
|
||||
vtkWorld->ShowScaleMeasures(true);
|
||||
viewer.AddPuppet(*vtkWorld);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
// Visualize iron cube
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkIron);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// 3. Event Handling
|
||||
AppState state = { &scene, &viewer, {} };
|
||||
|
||||
@@ -50,7 +50,7 @@ void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void
|
||||
<< " with " << lastEvent->Path().size() << " steps." << std::endl;
|
||||
|
||||
Vtk::GeantEvent* vtkEvent = new Vtk::GeantEvent(lastEvent);
|
||||
state->viewer->AddPuppet(*vtkEvent);
|
||||
state->viewer->AddProp3D(*vtkEvent);
|
||||
|
||||
state->viewer->GetRenderer()->Render();
|
||||
state->viewer->GetRenderWindow()->Render();
|
||||
@@ -109,33 +109,33 @@ int main(int argc, char** argv) {
|
||||
|
||||
Vtk::ContainerBox* vtkWorld = new Vtk::ContainerBox(scene.GetWorldBox());
|
||||
vtkWorld->ShowScaleMeasures(true);
|
||||
vtkWorld->SetRepresentation(Vtk::Puppet::Wireframe);
|
||||
vtkWorld->SetRepresentation(Vtk::Prop3D::Wireframe);
|
||||
vtkWorld->SetSelectable(false);
|
||||
viewer.AddPuppet(*vtkWorld);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkIron);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// Visualize Top Chamber
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box);
|
||||
vtkTop->SetOpacity(0.5);
|
||||
vtkTop->SetColor(0.2, 0.8, 0.2);
|
||||
vtkTop->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkTop);
|
||||
vtkTop->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkTop);
|
||||
|
||||
// Visualize Bottom Chamber
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box);
|
||||
vtkBottom->SetOpacity(0.5);
|
||||
vtkBottom->SetColor(0.2, 0.8, 0.2);
|
||||
vtkBottom->SetRepresentation(Vtk::Puppet::Surface);
|
||||
viewer.AddPuppet(*vtkBottom);
|
||||
vtkBottom->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkBottom);
|
||||
|
||||
// Use vtkSkyPlaneEmitterPrimary instead of EmitterPrimary
|
||||
Vtk::vtkSkyPlaneEmitterPrimary* vtkEmitter = new Vtk::vtkSkyPlaneEmitterPrimary(*emitter);
|
||||
vtkEmitter->SetSelectable(false);
|
||||
viewer.AddPuppet(*vtkEmitter);
|
||||
viewer.AddProp3D(*vtkEmitter);
|
||||
|
||||
// 3. Event Handling
|
||||
AppState state = { &scene, &viewer, {} };
|
||||
|
||||
@@ -41,12 +41,12 @@ BoxSolid::~BoxSolid() {
|
||||
void BoxSolid::Update() {
|
||||
ConnectionBlock blocker(m_UpdateConnection);
|
||||
this->UpdateGeometry();
|
||||
// Ensure base Puppet properties (color, opacity, etc) and transform are applied
|
||||
this->Puppet::Update();
|
||||
// Ensure base Prop3D properties (color, opacity, etc) and transform are applied
|
||||
this->Prop3D::Update();
|
||||
}
|
||||
|
||||
void BoxSolid::SyncFromVtk() {
|
||||
this->Puppet::SyncFromVtk();
|
||||
this->Prop3D::SyncFromVtk();
|
||||
if (auto* proxy = vtkProp3D::SafeDownCast(this->GetProxyProp())) {
|
||||
if (vtkMatrix4x4* mat = proxy->GetUserMatrix()) {
|
||||
m_BoxContent->SetTransform(VtkToMatrix4f(mat));
|
||||
@@ -60,14 +60,14 @@ void BoxSolid::UpdateGeometry() {
|
||||
}
|
||||
|
||||
void BoxSolid::UpdateTransform() {
|
||||
// Take transform from Puppet base (which uses GetContent() -> ContainerBox TRS)
|
||||
this->Puppet::Update();
|
||||
// Take transform from Prop3D base (which uses GetContent() -> ContainerBox TRS)
|
||||
this->Prop3D::Update();
|
||||
}
|
||||
|
||||
void BoxSolid::serialize_display(uLib::Archive::display_properties_archive &ar,
|
||||
const unsigned int version) {
|
||||
// Expose Geant solid properties and underlying Box/TRS properties
|
||||
this->Puppet::serialize_display(ar, version);
|
||||
this->Prop3D::serialize_display(ar, version);
|
||||
if (m_BoxContent) {
|
||||
ar & NVP("Box", *m_BoxContent);
|
||||
if (m_BoxContent->GetObject()) {
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* @brief VTK Puppet for visualizing a Geant::BoxSolid.
|
||||
* @brief VTK Prop3D for visualizing a Geant::BoxSolid.
|
||||
*/
|
||||
class BoxSolid : public GeantSolid {
|
||||
uLibTypeMacro(BoxSolid, uLib::Vtk::GeantSolid)
|
||||
|
||||
@@ -63,7 +63,7 @@ void EmitterPrimary::contentUpdate() {
|
||||
Matrix4f transform = m_emitter.GetWorldMatrix();
|
||||
Matrix4fToVtk(transform, vmat);
|
||||
|
||||
Puppet::Update();
|
||||
Prop3D::Update();
|
||||
}
|
||||
|
||||
void EmitterPrimary::Update() {
|
||||
|
||||
@@ -14,7 +14,7 @@ class vtkCylinderSource;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class EmitterPrimary : public Puppet {
|
||||
class EmitterPrimary : public Prop3D {
|
||||
public:
|
||||
EmitterPrimary(Geant::EmitterPrimary &emitter);
|
||||
virtual ~EmitterPrimary();
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class GeantEvent : public Puppet, public Polydata {
|
||||
class GeantEvent : public Prop3D, public Polydata {
|
||||
typedef Geant::GeantEvent Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -33,19 +33,19 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
GeantScene::GeantScene(Geant::Scene *scene)
|
||||
: m_Scene(scene), m_WorldPuppet(nullptr) {
|
||||
: m_Scene(scene), m_WorldProp3D(nullptr) {
|
||||
if (!m_Scene)
|
||||
return;
|
||||
|
||||
// 1. Create the world box wireframe puppet
|
||||
// 1. Create the world box wireframe prop3d
|
||||
uLib::ContainerBox *worldBox = m_Scene->GetWorldBox();
|
||||
if (worldBox) {
|
||||
m_WorldPuppet = new ContainerBox(worldBox);
|
||||
m_WorldPuppet->SetRepresentation(Puppet::Wireframe);
|
||||
m_WorldPuppet->ShowScaleMeasures(true);
|
||||
m_WorldProp3D = new ContainerBox(worldBox);
|
||||
m_WorldProp3D->SetRepresentation(Prop3D::Wireframe);
|
||||
m_WorldProp3D->ShowScaleMeasures(true);
|
||||
}
|
||||
|
||||
// 2. Create puppets for each non-world solid
|
||||
// 2. Create prop3ds for each non-world solid
|
||||
const Geant::Solid *world = m_Scene->GetWorld();
|
||||
const Vector<Geant::Solid *> &solids = m_Scene->GetSolids();
|
||||
|
||||
@@ -54,7 +54,7 @@ GeantScene::GeantScene(Geant::Scene *scene)
|
||||
if (solid == world)
|
||||
continue;
|
||||
|
||||
// Only create a puppet if the solid has a valid G4VSolid
|
||||
// Only create a prop3d if the solid has a valid G4VSolid
|
||||
if (solid->GetG4Solid()) {
|
||||
GeantSolid *vtkSolid = nullptr;
|
||||
if (auto *box = dynamic_cast<Geant::BoxSolid *>(solid)) {
|
||||
@@ -67,34 +67,34 @@ GeantScene::GeantScene(Geant::Scene *scene)
|
||||
}
|
||||
|
||||
if (vtkSolid) {
|
||||
m_SolidPuppets.push_back(vtkSolid);
|
||||
m_SolidProp3Ds.push_back(vtkSolid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeantScene::~GeantScene() {
|
||||
delete m_WorldPuppet;
|
||||
for (auto *p : m_SolidPuppets) {
|
||||
delete m_WorldProp3D;
|
||||
for (auto *p : m_SolidProp3Ds) {
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
void GeantScene::AddToViewer(Viewport &viewer) {
|
||||
if (m_WorldPuppet) {
|
||||
viewer.AddPuppet(*m_WorldPuppet);
|
||||
if (m_WorldProp3D) {
|
||||
viewer.AddProp3D(*m_WorldProp3D);
|
||||
}
|
||||
for (auto *p : m_SolidPuppets) {
|
||||
viewer.AddPuppet(*p);
|
||||
for (auto *p : m_SolidProp3Ds) {
|
||||
viewer.AddProp3D(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void GeantScene::RemoveFromViewer(Viewport &viewer) {
|
||||
if (m_WorldPuppet) {
|
||||
viewer.RemovePuppet(*m_WorldPuppet);
|
||||
if (m_WorldProp3D) {
|
||||
viewer.RemoveProp3D(*m_WorldProp3D);
|
||||
}
|
||||
for (auto *p : m_SolidPuppets) {
|
||||
viewer.RemovePuppet(*p);
|
||||
for (auto *p : m_SolidProp3Ds) {
|
||||
viewer.RemoveProp3D(*p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace Vtk {
|
||||
class GeantSolid;
|
||||
|
||||
/**
|
||||
* @brief VTK Puppet representing the entire Geant::Scene.
|
||||
* @brief VTK Prop3D representing the entire Geant::Scene.
|
||||
*
|
||||
* When constructed, it creates child puppets for the world box (as a
|
||||
* When constructed, it creates child prop3ds for the world box (as a
|
||||
* ContainerBox wireframe) and for each non-world Solid in the scene
|
||||
* (as GeantSolid surfaces).
|
||||
*
|
||||
@@ -63,22 +63,22 @@ public:
|
||||
GeantScene(Geant::Scene *scene);
|
||||
~GeantScene();
|
||||
|
||||
/// Add all puppets (world box + solids) to a viewer.
|
||||
/// Add all prop3ds (world box + solids) to a viewer.
|
||||
void AddToViewer(class Viewport &viewer);
|
||||
|
||||
/// Remove all puppets from viewport.
|
||||
/// Remove all prop3ds from viewport.
|
||||
void RemoveFromViewer(class Viewport &viewer);
|
||||
|
||||
/// Get the world box puppet
|
||||
ContainerBox* GetWorldPuppet() const { return m_WorldPuppet; }
|
||||
/// Get the world box prop3d
|
||||
ContainerBox* GetWorldProp3D() const { return m_WorldProp3D; }
|
||||
|
||||
/// Get the solid puppets
|
||||
const std::vector<GeantSolid*>& GetSolidPuppets() const { return m_SolidPuppets; }
|
||||
/// Get the solid prop3ds
|
||||
const std::vector<GeantSolid*>& GetSolidProp3Ds() const { return m_SolidProp3Ds; }
|
||||
|
||||
private:
|
||||
Geant::Scene *m_Scene;
|
||||
ContainerBox *m_WorldPuppet;
|
||||
std::vector<GeantSolid*> m_SolidPuppets;
|
||||
ContainerBox *m_WorldProp3D;
|
||||
std::vector<GeantSolid*> m_SolidProp3Ds;
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
@@ -36,13 +36,13 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* @brief VTK Puppet for visualizing a Geant::Solid.
|
||||
* @brief VTK Prop3D for visualizing a Geant::Solid.
|
||||
*
|
||||
* Renders the G4VSolid geometry as a tessellated polydata surface.
|
||||
* Works with BoxSolid, TessellatedSolid, or any Solid that provides
|
||||
* a valid G4VSolid via GetG4Solid().
|
||||
*/
|
||||
class GeantSolid : public Puppet, public Polydata {
|
||||
class GeantSolid : public Prop3D, public Polydata {
|
||||
typedef Geant::Solid Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* @brief VTK Puppet for visualizing a Geant::TessellatedSolid.
|
||||
* @brief VTK Prop3D for visualizing a Geant::TessellatedSolid.
|
||||
*/
|
||||
class TessellatedSolid : public GeantSolid {
|
||||
public:
|
||||
|
||||
@@ -110,12 +110,12 @@ BOOST_AUTO_TEST_CASE(vtkVoxRaytracerRepresentationTest) {
|
||||
// renderer //
|
||||
Vtk::Viewer viewer;
|
||||
|
||||
viewer.AddPuppet(v_grid);
|
||||
viewer.AddPuppet(v_rt);
|
||||
viewer.AddPuppet(v_muon);
|
||||
viewer.AddProp3D(v_grid);
|
||||
viewer.AddProp3D(v_rt);
|
||||
viewer.AddProp3D(v_muon);
|
||||
|
||||
// Select grid to show handler widget
|
||||
viewer.SelectPuppet(&v_grid);
|
||||
viewer.SelectProp3D(&v_grid);
|
||||
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class vtkActor;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class VoxRaytracerRepresentation : public Puppet {
|
||||
class VoxRaytracerRepresentation : public Prop3D {
|
||||
typedef VoxRaytracer Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -50,18 +50,18 @@ int main(int argc, char **argv) {
|
||||
// ---- 3. Apply a group transform ----
|
||||
assembly.SetPosition(Vector3f(1_m, 1_m, 0));
|
||||
|
||||
// ---- 5. Visualize (create puppets to set properties) ----
|
||||
// ---- 5. Visualize (create prop3ds to set properties) ----
|
||||
Vtk::Assembly vtkAsm(&assembly);
|
||||
|
||||
Vtk::Viewer viewer;
|
||||
vtkAsm.AddToViewer(viewer); // This triggers puppet creation via ConnectRenderer which eventually calls Puppet::GetProp
|
||||
vtkAsm.AddToViewer(viewer); // This triggers prop3d creation via ConnectRenderer which eventually calls Prop3D::GetProp
|
||||
|
||||
// Explicitly update to ensure puppets exist and are added to assemblies
|
||||
// Explicitly update to ensure prop3ds exist and are added to assemblies
|
||||
vtkAsm.Update();
|
||||
|
||||
// Use the child context to find child puppets and set colors
|
||||
// Use the child context to find child prop3ds and set colors
|
||||
if (auto* childCtx = vtkAsm.GetChildrenContext()) {
|
||||
auto setProps = [](Vtk::Puppet* p, float r, float g, float b) {
|
||||
auto setProps = [](Vtk::Prop3D* p, float r, float g, float b) {
|
||||
if (!p) return;
|
||||
vtkPropCollection* props = p->GetProps();
|
||||
props->InitTraversal();
|
||||
@@ -74,12 +74,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
};
|
||||
|
||||
setProps(childCtx->GetPuppet(&box1), 1.0, 0.0, 0.0); // Red
|
||||
setProps(childCtx->GetPuppet(&box2), 0.0, 1.0, 0.0); // Green
|
||||
setProps(childCtx->GetPuppet(&cyl), 0.0, 0.0, 1.0); // Blue
|
||||
setProps(childCtx->GetProp3D(&box1), 1.0, 0.0, 0.0); // Red
|
||||
setProps(childCtx->GetProp3D(&box2), 0.0, 1.0, 0.0); // Green
|
||||
setProps(childCtx->GetProp3D(&cyl), 0.0, 0.0, 1.0); // Blue
|
||||
}
|
||||
|
||||
std::cout << "Puppets in viewport: " << viewer.getPuppets().size() << " (Expected 4: 1 assembly + 3 children)" << std::endl;
|
||||
std::cout << "Prop3Ds in viewport: " << viewer.getProp3Ds().size() << " (Expected 4: 1 assembly + 3 children)" << std::endl;
|
||||
|
||||
// ---- 4. Query the bounding box for terminal output ----
|
||||
Vector3f bbMin, bbMax;
|
||||
|
||||
@@ -43,7 +43,7 @@ int main() {
|
||||
Vtk::ContainerBox v_box(&box);
|
||||
v_box.Update();
|
||||
|
||||
// v_box.SetRepresentation(Vtk::Puppet::Surface);
|
||||
// v_box.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
// v_box.SetOpacity(0.5);
|
||||
// v_box.SetSelectable(true);
|
||||
|
||||
@@ -53,7 +53,7 @@ int main() {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer v_viewer;
|
||||
v_viewer.AddPuppet(v_box);
|
||||
v_viewer.AddProp3D(v_box);
|
||||
v_viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ int main() {
|
||||
|
||||
std::cout << "Creating VTK representation..." << std::endl;
|
||||
Vtk::ContainerBox v_box(&box);
|
||||
v_box.SetRepresentation(Vtk::Puppet::Wireframe);
|
||||
v_box.SetRepresentation(Vtk::Prop3D::Wireframe);
|
||||
v_box.SetColor(1.0, 0.0, 0.0); // Red
|
||||
|
||||
// // 1. Initial Visualization setup (handled by Viewer)
|
||||
@@ -38,7 +38,7 @@ int main() {
|
||||
|
||||
std::cout << "Starting viewer (close window to exit)..." << std::endl;
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(v_box);
|
||||
viewer.AddProp3D(v_box);
|
||||
viewer.Start();
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(vtkQuadMeshConstruction) {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(v_mesh);
|
||||
viewer.AddProp3D(v_mesh);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(vtkStructuredGridTest) {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(grid_viewer);
|
||||
viewer.AddProp3D(grid_viewer);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(vtkTriangleMeshConstruction) {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(v_mesh);
|
||||
viewer.AddProp3D(v_mesh);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(vtkTriangleMeshConstruction2) {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(v_mesh);
|
||||
viewer.AddProp3D(v_mesh);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,12 @@ void KeyPressCallbackFunction(vtkObject* caller, long unsigned int eventId, void
|
||||
std::string key = interactor->GetKeySym();
|
||||
if (key == "w") {
|
||||
std::cout << "--> Switching all images to Wireframe Box" << std::endl;
|
||||
for (auto* img : state->images) img->SetRepresentation(Vtk::Puppet::Wireframe);
|
||||
for (auto* img : state->images) img->SetRepresentation(Vtk::Prop3D::Wireframe);
|
||||
state->viewer->GetRenderWindow()->Render();
|
||||
}
|
||||
else if (key == "s") {
|
||||
std::cout << "--> Switching all images to Surface (Volume Rendering)" << std::endl;
|
||||
for (auto* img : state->images) img->SetRepresentation(Vtk::Puppet::Surface);
|
||||
for (auto* img : state->images) img->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
state->viewer->GetRenderWindow()->Render();
|
||||
}
|
||||
else if (key >= "0" && key <= "5") {
|
||||
@@ -104,8 +104,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
Vtk::Viewer viewer;
|
||||
viewer.GetRenderer()->SetBackground(0.05, 0.05, 0.1);
|
||||
viewer.AddPuppet(vtk_img1);
|
||||
viewer.AddPuppet(vtk_img2);
|
||||
viewer.AddProp3D(vtk_img1);
|
||||
viewer.AddProp3D(vtk_img2);
|
||||
|
||||
// Setup KeyPress Callback
|
||||
AppState state;
|
||||
|
||||
@@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(vtkVoxImageConstruction) {
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer viewer;
|
||||
viewer.AddPuppet(vtk_img);
|
||||
viewer.AddProp3D(vtk_img);
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ void Assembly::InstallPipe() {
|
||||
|
||||
m_VtkAsm->AddPart(m_BBoxActor);
|
||||
|
||||
// 3. Build a child-objects context (auto-creates puppets for each child)
|
||||
// 3. Build a child-objects context (auto-creates prop3ds for each child)
|
||||
if (m_Content) {
|
||||
m_ChildContext = new ObjectsContext(m_Content);
|
||||
// Link the children context's assembly into our group assembly
|
||||
@@ -101,7 +101,7 @@ void Assembly::Update() {
|
||||
m_VtkAsm->Modified();
|
||||
}
|
||||
|
||||
this->Puppet::Update();
|
||||
this->Prop3D::Update();
|
||||
this->UpdateBoundingBox();
|
||||
if (m_ChildContext)
|
||||
m_ChildContext->Update();
|
||||
|
||||
@@ -24,19 +24,19 @@ namespace Vtk {
|
||||
class ObjectsContext; // forward
|
||||
|
||||
/**
|
||||
* @brief VTK Puppet for visualizing uLib::Assembly.
|
||||
* @brief VTK Prop3D for visualizing uLib::Assembly.
|
||||
*
|
||||
* Manages a VTK assembly (vtkAssembly from the VTK library) that groups
|
||||
* all child puppets and applies the Assembly's AffineTransform. It also
|
||||
* all child prop3ds and applies the Assembly's AffineTransform. It also
|
||||
* renders an optional bounding box wireframe computed from the Assembly's AABB.
|
||||
*
|
||||
* @note This class is uLib::Vtk::Assembly. It internally uses
|
||||
* the VTK library class vtkAssembly for grouping, but the two
|
||||
* are distinct.
|
||||
*/
|
||||
class Assembly : public Puppet {
|
||||
class Assembly : public Prop3D {
|
||||
public:
|
||||
uLibTypeMacro(Assembly, Puppet)
|
||||
uLibTypeMacro(Assembly, Prop3D)
|
||||
|
||||
Assembly(uLib::Assembly *content);
|
||||
virtual ~Assembly();
|
||||
@@ -51,10 +51,10 @@ public:
|
||||
virtual uLib::ObjectsContext* GetChildren() override { return (uLib::ObjectsContext*)m_Content; }
|
||||
|
||||
/**
|
||||
* @brief Returns the puppet managing child objects.
|
||||
* @brief Returns the prop3d managing child objects.
|
||||
*/
|
||||
|
||||
/** @brief Returns the puppet managing child objects. */
|
||||
/** @brief Returns the prop3d managing child objects. */
|
||||
ObjectsContext *GetChildrenContext() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -96,7 +96,7 @@ void ContainerBox::Update() {
|
||||
|
||||
// Delegate rest of update (appearance, render, etc)
|
||||
ConnectionBlock blocker(d->m_UpdateSignal);
|
||||
this->Puppet::Update();
|
||||
this->Prop3D::Update();
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ void ContainerBox::InstallPipe() {
|
||||
|
||||
// vtkProp3D* root = d->m_VtkAsm;
|
||||
// if (root) {
|
||||
// this->ApplyPuppetTransform(root);
|
||||
// this->ApplyProp3DTransform(root);
|
||||
// }
|
||||
this->Update();
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ namespace Vtk {
|
||||
|
||||
struct ContainerBoxData;
|
||||
|
||||
class ContainerBox : public Puppet, public Polydata {
|
||||
class ContainerBox : public Prop3D, public Polydata {
|
||||
|
||||
uLibTypeMacro(ContainerBox, Puppet, Polydata)
|
||||
uLibTypeMacro(ContainerBox, Prop3D, Polydata)
|
||||
typedef uLib::ContainerBox Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -82,7 +82,7 @@ void Cylinder::Update() {
|
||||
|
||||
// Delegate rest of update (appearance, render, etc)
|
||||
ConnectionBlock blocker(m_UpdateSignal);
|
||||
this->Puppet::Update();
|
||||
this->Prop3D::Update();
|
||||
}
|
||||
|
||||
void Cylinder::SyncFromVtk() {
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Vtk {
|
||||
* mathematical state of a Cylinder object. It manages the alignment
|
||||
* between VTK's Y-centered cylinder and uLib's Z-based coordinate system.
|
||||
*/
|
||||
class Cylinder : public Puppet {
|
||||
class Cylinder : public Prop3D {
|
||||
typedef uLib::Cylinder Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -125,7 +125,7 @@ void QuadMesh::contentUpdate() {
|
||||
|
||||
m_Poly->Modified();
|
||||
m_Actor->GetMapper()->Update();
|
||||
Puppet::Update();
|
||||
Prop3D::Update();
|
||||
}
|
||||
|
||||
void QuadMesh::Update() {
|
||||
|
||||
@@ -36,7 +36,7 @@ class vtkActor;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class QuadMesh : public Puppet, public Polydata {
|
||||
class QuadMesh : public Prop3D, public Polydata {
|
||||
typedef uLib::QuadMesh Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class StructuredGrid : public Puppet {
|
||||
class StructuredGrid : public Prop3D {
|
||||
typedef uLib::StructuredGrid Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -120,7 +120,7 @@ void TriangleMesh::contentUpdate() {
|
||||
|
||||
m_Poly->Modified();
|
||||
m_Actor->GetMapper()->Update();
|
||||
Puppet::Update();
|
||||
Prop3D::Update();
|
||||
}
|
||||
|
||||
void TriangleMesh::Update() {
|
||||
|
||||
@@ -36,7 +36,7 @@ class vtkActor;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class TriangleMesh : public Puppet, public Polydata {
|
||||
class TriangleMesh : public Prop3D, public Polydata {
|
||||
typedef uLib::TriangleMesh Content;
|
||||
|
||||
public:
|
||||
|
||||
@@ -281,7 +281,7 @@ void VoxImage::RescaleShaderRange() {
|
||||
}
|
||||
|
||||
void VoxImage::SetRepresentation(Representation mode) {
|
||||
Puppet::SetRepresentation(mode); // Ensure base class data state is updated
|
||||
Prop3D::SetRepresentation(mode); // Ensure base class data state is updated
|
||||
|
||||
if (mode == Wireframe) {
|
||||
m_Actor->SetVisibility(0);
|
||||
@@ -292,14 +292,14 @@ void VoxImage::SetRepresentation(Representation mode) {
|
||||
m_OutlineActor->SetVisibility(1);
|
||||
m_OutlineActor->GetProperty()->SetRepresentationToWireframe();
|
||||
} else {
|
||||
// Other representations (Points, Surface, etc) are handled by basic Puppet
|
||||
// Other representations (Points, Surface, etc) are handled by basic Prop3D
|
||||
// behavior which affects the m_Asm parts.
|
||||
}
|
||||
}
|
||||
|
||||
void VoxImage::serialize_display(uLib::Archive::display_properties_archive & ar, const unsigned int version) {
|
||||
// Call base class to show Transform and Appearance properties
|
||||
// Puppet::serialize_display(ar, version);
|
||||
// Prop3D::serialize_display(ar, version);
|
||||
|
||||
// Use the member variables for volume rendering parameters
|
||||
ar & boost::serialization::make_hrp("Window", m_Window);
|
||||
@@ -335,7 +335,7 @@ void VoxImage::Update() {
|
||||
m_Outline->Update();
|
||||
|
||||
ConnectionBlock blocker(m_UpdateConnection);
|
||||
this->Puppet::Update();
|
||||
this->Prop3D::Update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class vtkPiecewiseFunction;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class VoxImage : public Puppet {
|
||||
class VoxImage : public Prop3D {
|
||||
public:
|
||||
typedef Abstract::VoxImage Content;
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
set(TESTS
|
||||
vtkViewerTest
|
||||
vtkHandlerWidget
|
||||
PuppetPropertyTest
|
||||
PuppetParentingTest
|
||||
Prop3DPropertyTest
|
||||
Prop3DParentingTest
|
||||
vtkQViewportTest
|
||||
# vtkVoxImageTest
|
||||
# vtkTriangleMeshTest
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
using namespace uLib;
|
||||
|
||||
int main() {
|
||||
BEGIN_TESTING(Puppet Parenting Test);
|
||||
BEGIN_TESTING(Prop3D Parenting Test);
|
||||
|
||||
ObjectsContext globalContext;
|
||||
Vtk::Viewer viewer;
|
||||
|
||||
// Create the display context, linked to the model context.
|
||||
// It will automatically create visual puppets for each model object.
|
||||
// It will automatically create visual prop3ds for each model object.
|
||||
Vtk::ObjectsContext viewerContext(&globalContext);
|
||||
viewerContext.ConnectRenderer(viewer.GetRenderer());
|
||||
|
||||
@@ -41,12 +41,12 @@ int main() {
|
||||
assembly->SetInstanceName("ParentAssembly");
|
||||
globalContext.AddObject(assembly);
|
||||
|
||||
// Verify assembly puppet exists in the viewer context
|
||||
Vtk::Puppet* assemblyPuppet = viewerContext.GetPuppet(assembly);
|
||||
ASSERT_NOT_NULL(assemblyPuppet);
|
||||
// Verify assembly prop3d exists in the viewer context
|
||||
Vtk::Prop3D* assemblyProp3D = viewerContext.GetProp3D(assembly);
|
||||
ASSERT_NOT_NULL(assemblyProp3D);
|
||||
|
||||
// cast to Vtk::Assembly to access child context
|
||||
auto* vtkAss = dynamic_cast<Vtk::Assembly*>(assemblyPuppet);
|
||||
auto* vtkAss = dynamic_cast<Vtk::Assembly*>(assemblyProp3D);
|
||||
ASSERT_NOT_NULL(vtkAss);
|
||||
|
||||
// 2. Create a child Box and add it to the Assembly
|
||||
@@ -55,25 +55,25 @@ int main() {
|
||||
box1->SetPosition(Vector3f(20, 0, 0));
|
||||
assembly->AddObject(box1);
|
||||
|
||||
// Verify child puppet was created in the assembly's child context
|
||||
// Verify child prop3d was created in the assembly's child context
|
||||
Vtk::ObjectsContext* childVtkCtx = vtkAss->GetChildrenContext();
|
||||
ASSERT_NOT_NULL(childVtkCtx);
|
||||
|
||||
Vtk::Puppet* box1Puppet = childVtkCtx->GetPuppet(box1);
|
||||
ASSERT_NOT_NULL(box1Puppet);
|
||||
Vtk::Prop3D* box1Prop3D = childVtkCtx->GetProp3D(box1);
|
||||
ASSERT_NOT_NULL(box1Prop3D);
|
||||
|
||||
// 3. Move the parent and verify the child follows
|
||||
assembly->SetPosition(Vector3f(100, 0, 0));
|
||||
assembly->Updated();
|
||||
|
||||
// In VTK assemblies, the child's absolute matrix should reflect the parent's transform
|
||||
vtkProp3D* box1Prop = vtkProp3D::SafeDownCast(box1Puppet->GetProp());
|
||||
vtkProp3D* box1Prop = vtkProp3D::SafeDownCast(box1Prop3D->GetProp());
|
||||
ASSERT_NOT_NULL(box1Prop);
|
||||
|
||||
vtkMatrix4x4* boxMatrix = box1Prop->GetMatrix();
|
||||
// Origin (0,0,0) + local(20,0,0) + assembly(100,0,0) = world(120,0,0) ?
|
||||
// Actually, box1->GetPosition() is (20,0,0).
|
||||
// The puppet ApplyTransform sets the prop orientation and position.
|
||||
// The prop3d ApplyTransform sets the prop orientation and position.
|
||||
|
||||
std::cout << "Checking transformation chain..." << std::endl;
|
||||
// std::cout << *boxMatrix << std::endl;
|
||||
@@ -93,8 +93,8 @@ int main() {
|
||||
box2->SetPosition(Vector3f(-20, 0, 0));
|
||||
assembly->AddObject(box2);
|
||||
|
||||
Vtk::Puppet* box2Puppet = childVtkCtx->GetPuppet(box2);
|
||||
ASSERT_NOT_NULL(box2Puppet);
|
||||
Vtk::Prop3D* box2Prop3D = childVtkCtx->GetProp3D(box2);
|
||||
ASSERT_NOT_NULL(box2Prop3D);
|
||||
|
||||
// Render if not in batch environment
|
||||
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||
@@ -19,13 +19,13 @@ using namespace uLib;
|
||||
using namespace Vtk;
|
||||
|
||||
int main() {
|
||||
BEGIN_TESTING(Puppet Property Registration Test);
|
||||
BEGIN_TESTING(Prop3D Property Registration Test);
|
||||
|
||||
std::cout << "Creating Puppet object..." << std::endl;
|
||||
Puppet p;
|
||||
std::cout << "Creating Prop3D object..." << std::endl;
|
||||
Prop3D p;
|
||||
|
||||
// At this point, the Puppet constructor has called ULIB_ACTIVATE_PROPERTIES.
|
||||
// This should have discovered the members used in Puppet::serialize()
|
||||
// At this point, the Prop3D constructor has called ULIB_ACTIVATE_PROPERTIES.
|
||||
// This should have discovered the members used in Prop3D::serialize()
|
||||
// and registered them as uLib properties.
|
||||
|
||||
const auto& props = p.GetProperties();
|
||||
@@ -62,7 +62,7 @@ int main() {
|
||||
*colorRProp = 0.9;
|
||||
assert(colorRProp->Get() == 0.9);
|
||||
|
||||
std::cout << "All Puppet Property Registration Tests PASSED!" << std::endl;
|
||||
std::cout << "All Prop3D Property Registration Tests PASSED!" << std::endl;
|
||||
|
||||
END_TESTING;
|
||||
}
|
||||
@@ -49,12 +49,12 @@ int main() {
|
||||
// 3. Setup the Viewer
|
||||
Vtk::Viewer viewer;
|
||||
|
||||
// 2. Wrap it in a Vtk::ContainerBox (Vtk Puppet)
|
||||
// 2. Wrap it in a Vtk::ContainerBox (Vtk Prop3D)
|
||||
Vtk::ContainerBox v_box(&box);
|
||||
v_box.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_box.SetRepresentation(Vtk::Prop3D::Surface);
|
||||
v_box.SetOpacity(0.5);
|
||||
|
||||
viewer.AddPuppet(v_box);
|
||||
viewer.AddProp3D(v_box);
|
||||
|
||||
// 4. Create and setup the HandlerWidget
|
||||
vtkSmartPointer<Vtk::HandlerWidget> handler =
|
||||
@@ -62,7 +62,7 @@ int main() {
|
||||
|
||||
handler->SetInteractor(viewer.GetInteractor());
|
||||
|
||||
// Get the prop from the puppet and cast it to vtkProp3D
|
||||
// Get the prop from the prop3d and cast it to vtkProp3D
|
||||
vtkProp *v_prop = v_box.GetProp();
|
||||
vtkProp3D *prop = vtkProp3D::SafeDownCast(v_prop);
|
||||
if (!prop) {
|
||||
|
||||
@@ -80,15 +80,15 @@ namespace Vtk {
|
||||
|
||||
// PIMPL -------------------------------------------------------------------- //
|
||||
|
||||
class PuppetData {
|
||||
class Prop3DData {
|
||||
public:
|
||||
PuppetData(Puppet* owner) :
|
||||
m_Puppet(owner),
|
||||
Prop3DData(Prop3D* owner) :
|
||||
m_Prop3D(owner),
|
||||
m_Renderers(vtkSmartPointer<vtkRendererCollection>::New()),
|
||||
m_Prop(nullptr),
|
||||
m_ShowBoundingBox(false),
|
||||
m_ShowScaleMeasures(false),
|
||||
m_Representation(Puppet::Surface),
|
||||
m_Representation(Prop3D::Surface),
|
||||
m_Opacity(1.0),
|
||||
m_Selectable(true),
|
||||
m_Selected(false),
|
||||
@@ -98,12 +98,12 @@ public:
|
||||
m_Color = Vector3d(-1, -1, -1);
|
||||
}
|
||||
|
||||
~PuppetData() {
|
||||
~Prop3DData() {
|
||||
// No manual Delete needed for smart pointers
|
||||
|
||||
}
|
||||
|
||||
Puppet *m_Puppet;
|
||||
Prop3D *m_Prop3D;
|
||||
// members //
|
||||
vtkSmartPointer<vtkRendererCollection> m_Renderers;
|
||||
vtkSmartPointer<vtkProp3D> m_Prop;
|
||||
@@ -136,11 +136,11 @@ public:
|
||||
|
||||
vtkActor *actor = vtkActor::SafeDownCast(p);
|
||||
if (actor) {
|
||||
if (m_Representation != -1 && m_Representation != Puppet::Volume) {
|
||||
if (m_Representation == Puppet::SurfaceWithEdges) {
|
||||
if (m_Representation != -1 && m_Representation != Prop3D::Volume) {
|
||||
if (m_Representation == Prop3D::SurfaceWithEdges) {
|
||||
actor->GetProperty()->SetRepresentation(VTK_SURFACE);
|
||||
actor->GetProperty()->SetEdgeVisibility(1);
|
||||
} else if (m_Representation != Puppet::Outline && m_Representation != Puppet::Slice) {
|
||||
} else if (m_Representation != Prop3D::Outline && m_Representation != Prop3D::Slice) {
|
||||
actor->GetProperty()->SetRepresentation(m_Representation);
|
||||
actor->GetProperty()->SetEdgeVisibility(0);
|
||||
}
|
||||
@@ -248,8 +248,8 @@ public:
|
||||
}
|
||||
|
||||
// Update highlight matrix from the model world matrix
|
||||
if (m_Puppet) {
|
||||
if (auto* content = m_Puppet->GetContent()) {
|
||||
if (m_Prop3D) {
|
||||
if (auto* content = m_Prop3D->GetContent()) {
|
||||
if (auto* tr = dynamic_cast<uLib::TRS*>(content)) {
|
||||
vtkNew<vtkMatrix4x4> vwm;
|
||||
Matrix4fToVtk(tr->GetWorldMatrix(), vwm);
|
||||
@@ -288,24 +288,24 @@ public:
|
||||
|
||||
|
||||
|
||||
Puppet::Puppet() : Object(), pd(new PuppetData(this)) {
|
||||
Prop3D::Prop3D() : Object(), pd(new Prop3DData(this)) {
|
||||
ULIB_ACTIVATE_DISPLAY_PROPERTIES;
|
||||
for (auto* p : this->GetDisplayProperties()) {
|
||||
uLib::Object::connect(p, &uLib::PropertyBase::Updated, this, &Puppet::Update);
|
||||
uLib::Object::connect(p, &uLib::PropertyBase::Updated, this, &Prop3D::Update);
|
||||
}
|
||||
}
|
||||
|
||||
Puppet::~Puppet()
|
||||
Prop3D::~Prop3D()
|
||||
{
|
||||
delete pd;
|
||||
}
|
||||
|
||||
vtkProp *Puppet::GetProp()
|
||||
vtkProp *Prop3D::GetProp()
|
||||
{
|
||||
return pd->m_Prop;
|
||||
}
|
||||
|
||||
vtkProp3D *Puppet::GetProxyProp()
|
||||
vtkProp3D *Prop3D::GetProxyProp()
|
||||
{
|
||||
// The handler should manipulate the highlight actor if it exists
|
||||
if (pd->m_HighlightActor) {
|
||||
@@ -314,7 +314,7 @@ vtkProp3D *Puppet::GetProxyProp()
|
||||
return vtkProp3D::SafeDownCast(this->GetProp());
|
||||
}
|
||||
|
||||
void Puppet::SetProp(vtkProp *prop)
|
||||
void Prop3D::SetProp(vtkProp *prop)
|
||||
{
|
||||
if(prop) {
|
||||
prop->SetPickable(pd->m_Selectable);
|
||||
@@ -339,23 +339,23 @@ void Puppet::SetProp(vtkProp *prop)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::RemoveProp(vtkProp *prop)
|
||||
void Prop3D::RemoveProp(vtkProp *prop)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Puppet::ApplyAppearance(vtkProp* prop)
|
||||
void Prop3D::ApplyAppearance(vtkProp* prop)
|
||||
{
|
||||
pd->ApplyAppearance(prop);
|
||||
}
|
||||
|
||||
void Puppet::ApplyTransform(vtkProp3D* p3d)
|
||||
void Prop3D::ApplyTransform(vtkProp3D* p3d)
|
||||
{
|
||||
pd->ApplyTransform(p3d);
|
||||
}
|
||||
|
||||
|
||||
vtkPropCollection *Puppet::GetParts()
|
||||
vtkPropCollection *Prop3D::GetParts()
|
||||
{
|
||||
if (auto* asm_p = vtkAssembly::SafeDownCast(pd->m_Prop)) {
|
||||
return asm_p->GetParts();
|
||||
@@ -363,7 +363,7 @@ vtkPropCollection *Puppet::GetParts()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
vtkPropCollection *Puppet::GetProps()
|
||||
vtkPropCollection *Prop3D::GetProps()
|
||||
{
|
||||
if (auto* asm_p = vtkAssembly::SafeDownCast(pd->m_Prop)) {
|
||||
return asm_p->GetParts();
|
||||
@@ -371,7 +371,7 @@ vtkPropCollection *Puppet::GetProps()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
||||
void Prop3D::ConnectRenderer(vtkRenderer *renderer)
|
||||
{
|
||||
if(renderer) {
|
||||
this->GetRenderers()->AddItem(renderer);
|
||||
@@ -391,7 +391,7 @@ void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::DisconnectRenderer(vtkRenderer *renderer)
|
||||
void Prop3D::DisconnectRenderer(vtkRenderer *renderer)
|
||||
{
|
||||
if(renderer) {
|
||||
if(vtkProp* prop = this->GetProp())
|
||||
@@ -404,22 +404,22 @@ void Puppet::DisconnectRenderer(vtkRenderer *renderer)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::AddToViewer(Viewport &viewer)
|
||||
void Prop3D::AddToViewer(Viewport &viewer)
|
||||
{
|
||||
viewer.AddPuppet(*this);
|
||||
viewer.AddProp3D(*this);
|
||||
}
|
||||
|
||||
void Puppet::RemoveFromViewer(Viewport &viewer)
|
||||
void Prop3D::RemoveFromViewer(Viewport &viewer)
|
||||
{
|
||||
viewer.RemovePuppet(*this);
|
||||
viewer.RemoveProp3D(*this);
|
||||
}
|
||||
|
||||
vtkRendererCollection *Puppet::GetRenderers() const
|
||||
vtkRendererCollection *Prop3D::GetRenderers() const
|
||||
{
|
||||
return pd->m_Renderers;
|
||||
}
|
||||
|
||||
void Puppet::PrintSelf(std::ostream &o) const
|
||||
void Prop3D::PrintSelf(std::ostream &o) const
|
||||
{
|
||||
o << "Props Assembly: \n";
|
||||
if (pd->m_Prop)
|
||||
@@ -429,7 +429,7 @@ void Puppet::PrintSelf(std::ostream &o) const
|
||||
pd->m_Renderers->PrintSelf(o,vtkIndent(1));
|
||||
}
|
||||
|
||||
void Puppet::ShowBoundingBox(bool show)
|
||||
void Prop3D::ShowBoundingBox(bool show)
|
||||
{
|
||||
if (pd->m_ShowBoundingBox == show) return;
|
||||
pd->m_ShowBoundingBox = show;
|
||||
@@ -465,7 +465,7 @@ void Puppet::ShowBoundingBox(bool show)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::ShowScaleMeasures(bool show)
|
||||
void Prop3D::ShowScaleMeasures(bool show)
|
||||
{
|
||||
if (pd->m_ShowScaleMeasures == show) return;
|
||||
pd->m_ShowScaleMeasures = show;
|
||||
@@ -499,13 +499,13 @@ void Puppet::ShowScaleMeasures(bool show)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::SetRepresentation(Representation mode)
|
||||
void Prop3D::SetRepresentation(Representation mode)
|
||||
{
|
||||
pd->m_Representation = static_cast<int>(mode);
|
||||
pd->ApplyAppearance(pd->m_Prop);
|
||||
}
|
||||
|
||||
void Puppet::SetRepresentation(const char *mode)
|
||||
void Prop3D::SetRepresentation(const char *mode)
|
||||
{
|
||||
std::string s(mode);
|
||||
if (s == "points") SetRepresentation(Points);
|
||||
@@ -517,7 +517,7 @@ void Puppet::SetRepresentation(const char *mode)
|
||||
else if (s == "slice") SetRepresentation(Slice);
|
||||
}
|
||||
|
||||
void Puppet::SetColor(double r, double g, double b)
|
||||
void Prop3D::SetColor(double r, double g, double b)
|
||||
{
|
||||
pd->m_Color[0] = r;
|
||||
pd->m_Color[1] = g;
|
||||
@@ -525,7 +525,7 @@ void Puppet::SetColor(double r, double g, double b)
|
||||
pd->ApplyAppearance(pd->m_Prop);
|
||||
}
|
||||
|
||||
void Puppet::SetOpacity(double alpha)
|
||||
void Prop3D::SetOpacity(double alpha)
|
||||
{
|
||||
pd->m_Opacity = alpha;
|
||||
pd->ApplyAppearance(pd->m_Prop);
|
||||
@@ -537,18 +537,18 @@ void Puppet::SetOpacity(double alpha)
|
||||
|
||||
|
||||
|
||||
void Puppet::SetSelectable(bool selectable)
|
||||
void Prop3D::SetSelectable(bool selectable)
|
||||
{
|
||||
pd->m_Selectable = selectable;
|
||||
pd->ApplyAppearance(pd->m_Prop);
|
||||
}
|
||||
|
||||
bool Puppet::IsSelectable() const
|
||||
bool Prop3D::IsSelectable() const
|
||||
{
|
||||
return pd->m_Selectable;
|
||||
}
|
||||
|
||||
void Puppet::SetSelected(bool selected)
|
||||
void Prop3D::SetSelected(bool selected)
|
||||
{
|
||||
if (!pd->m_Selectable) return;
|
||||
if (pd->m_Selected == selected) return;
|
||||
@@ -556,12 +556,12 @@ void Puppet::SetSelected(bool selected)
|
||||
pd->UpdateHighlight();
|
||||
}
|
||||
|
||||
bool Puppet::IsSelected() const
|
||||
bool Prop3D::IsSelected() const
|
||||
{
|
||||
return pd->m_Selected;
|
||||
}
|
||||
|
||||
void Puppet::ApplyPuppetTransform(vtkProp3D* prop)
|
||||
void Prop3D::ApplyProp3DTransform(vtkProp3D* prop)
|
||||
{
|
||||
if (!prop) return;
|
||||
if (auto* content = this->GetContent()) {
|
||||
@@ -574,7 +574,7 @@ void Puppet::ApplyPuppetTransform(vtkProp3D* prop)
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::SyncFromVtk()
|
||||
void Prop3D::SyncFromVtk()
|
||||
{
|
||||
if (auto* content = this->GetContent()) {
|
||||
if (auto* tr = dynamic_cast<uLib::TRS*>(content)) {
|
||||
@@ -588,11 +588,11 @@ void Puppet::SyncFromVtk()
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::Update()
|
||||
void Prop3D::Update()
|
||||
{
|
||||
// Apply content transform via virtual GetProp() / ApplyPuppetTransform(),
|
||||
// Apply content transform via virtual GetProp() / ApplyProp3DTransform(),
|
||||
// so all derived classes benefit without duplicating the matrix code.
|
||||
this->ApplyPuppetTransform(vtkProp3D::SafeDownCast(this->GetProp()));
|
||||
this->ApplyProp3DTransform(vtkProp3D::SafeDownCast(this->GetProp()));
|
||||
|
||||
// Use virtual GetProp() for appearance so overriders (e.g. VoxImage)
|
||||
// that never call SetProp() are handled correctly.
|
||||
@@ -626,8 +626,7 @@ void Puppet::Update()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Puppet::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
||||
void Prop3D::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -639,7 +638,7 @@ void Puppet::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
||||
|
||||
|
||||
struct TransformProxy {
|
||||
PuppetData* pd;
|
||||
Prop3DData* pd;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version) {
|
||||
ar & boost::serialization::make_nvp("Transform", pd->m_Transform);
|
||||
@@ -647,7 +646,7 @@ struct TransformProxy {
|
||||
};
|
||||
|
||||
struct AppearanceProxy {
|
||||
PuppetData* pd;
|
||||
Prop3DData* pd;
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int version) {
|
||||
ar & boost::serialization::make_hrp("Color", pd->m_Color, "color");
|
||||
@@ -662,7 +661,7 @@ struct AppearanceProxy {
|
||||
}
|
||||
};
|
||||
|
||||
void Puppet::serialize_display(Archive::display_properties_archive & ar, const unsigned int version) {
|
||||
void Prop3D::serialize_display(Archive::display_properties_archive & ar, const unsigned int version) {
|
||||
AppearanceProxy appearance{pd};
|
||||
ar & boost::serialization::make_nvp("Appearance", appearance);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Archive {
|
||||
class display_properties_archive;
|
||||
}
|
||||
namespace Vtk {
|
||||
class Puppet;
|
||||
class Prop3D;
|
||||
class Viewer;
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
@@ -60,13 +60,13 @@ class Viewer;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class Puppet : public uLib::Object {
|
||||
class Prop3D : public uLib::Object {
|
||||
|
||||
uLibTypeMacro(Puppet, uLib::Object)
|
||||
uLibTypeMacro(Prop3D, uLib::Object)
|
||||
|
||||
public:
|
||||
Puppet();
|
||||
virtual ~Puppet();
|
||||
Prop3D();
|
||||
virtual ~Prop3D();
|
||||
|
||||
virtual vtkProp *GetProp();
|
||||
virtual vtkProp3D *GetProxyProp();
|
||||
@@ -152,17 +152,17 @@ protected:
|
||||
|
||||
virtual void ApplyAppearance(vtkProp *prop);
|
||||
virtual void ApplyTransform(vtkProp3D *p3d);
|
||||
virtual void ApplyPuppetTransform(vtkProp3D *p3d);
|
||||
virtual void ApplyProp3DTransform(vtkProp3D *p3d);
|
||||
|
||||
std::vector<uLib::PropertyBase *> m_DisplayProperties;
|
||||
mutable uLib::RecursiveMutex m_UpdateMutex;
|
||||
|
||||
private:
|
||||
Puppet(const Puppet &) = delete;
|
||||
Puppet &operator=(const Puppet &) = delete;
|
||||
Prop3D(const Prop3D &) = delete;
|
||||
Prop3D &operator=(const Prop3D &) = delete;
|
||||
|
||||
friend class PuppetData;
|
||||
class PuppetData *pd;
|
||||
friend class Prop3DData;
|
||||
class Prop3DData *pd;
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
@@ -181,7 +181,7 @@ namespace Archive {
|
||||
|
||||
/**
|
||||
* @brief Specialized archive for registering display-only properties in
|
||||
* Puppets.
|
||||
* Prop3Ds.
|
||||
*/
|
||||
class display_properties_archive
|
||||
: public boost::archive::detail::common_oarchive<
|
||||
@@ -191,10 +191,10 @@ public:
|
||||
friend class boost::archive::save_access;
|
||||
|
||||
using boost::archive::detail::common_oarchive<display_properties_archive>::save_override;
|
||||
display_properties_archive(Vtk::Puppet *p)
|
||||
display_properties_archive(Vtk::Prop3D *p)
|
||||
: boost::archive::detail::common_oarchive<display_properties_archive>(
|
||||
boost::archive::no_header),
|
||||
m_Puppet(p) {
|
||||
m_Prop3D(p) {
|
||||
if (p)
|
||||
m_Visited.insert(dynamic_cast<const void *>(p));
|
||||
}
|
||||
@@ -210,9 +210,9 @@ public:
|
||||
}
|
||||
|
||||
template <class T> void save_override(const boost::serialization::hrp<T> &t) {
|
||||
if (m_Puppet) {
|
||||
if (m_Prop3D) {
|
||||
uLib::Property<T> *p = new uLib::Property<T>(
|
||||
m_Puppet, t.name(),
|
||||
m_Prop3D, t.name(),
|
||||
&const_cast<boost::serialization::hrp<T> &>(t).value(),
|
||||
t.units() ? t.units() : "", GetCurrentGroup());
|
||||
if (t.has_range())
|
||||
@@ -220,24 +220,24 @@ public:
|
||||
if (t.has_default())
|
||||
p->SetDefault(t.default_val());
|
||||
|
||||
m_Puppet->RegisterDisplayProperty(p);
|
||||
Vtk::Puppet *puppet = m_Puppet;
|
||||
m_Prop3D->RegisterDisplayProperty(p);
|
||||
Vtk::Prop3D *prop3d = m_Prop3D;
|
||||
uLib::Object::connect(p, &uLib::PropertyBase::Updated,
|
||||
[puppet]() { puppet->Update(); });
|
||||
[prop3d]() { prop3d->Update(); });
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void save_override(const boost::serialization::hrp_enum<T> &t) {
|
||||
if (m_Puppet) {
|
||||
if (m_Prop3D) {
|
||||
uLib::EnumProperty *p = new uLib::EnumProperty(
|
||||
m_Puppet, t.name(),
|
||||
m_Prop3D, t.name(),
|
||||
(int *)&const_cast<boost::serialization::hrp_enum<T> &>(t).value(),
|
||||
t.labels(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||
m_Puppet->RegisterDisplayProperty(p);
|
||||
Vtk::Puppet *puppet = m_Puppet;
|
||||
m_Prop3D->RegisterDisplayProperty(p);
|
||||
Vtk::Prop3D *prop3d = m_Prop3D;
|
||||
uLib::Object::connect(p, &uLib::PropertyBase::Updated,
|
||||
[puppet]() { puppet->Update(); });
|
||||
[prop3d]() { prop3d->Update(); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,11 +292,11 @@ public:
|
||||
// Called by Property<T>::serialize() and EnumProperty::serialize() to
|
||||
// directly register an existing property object as a display property.
|
||||
void register_property(uLib::PropertyBase &p) {
|
||||
if (m_Puppet) {
|
||||
m_Puppet->RegisterDisplayProperty(&p);
|
||||
Vtk::Puppet *puppet = m_Puppet;
|
||||
if (m_Prop3D) {
|
||||
m_Prop3D->RegisterDisplayProperty(&p);
|
||||
Vtk::Prop3D *prop3d = m_Prop3D;
|
||||
uLib::Object::connect(&p, &uLib::PropertyBase::Updated,
|
||||
[puppet]() { puppet->Update(); });
|
||||
[prop3d]() { prop3d->Update(); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,14 +305,14 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Vtk::Puppet *m_Puppet;
|
||||
Vtk::Prop3D *m_Prop3D;
|
||||
std::vector<std::string> m_GroupStack;
|
||||
std::set<const void *> m_Visited;
|
||||
};
|
||||
|
||||
} // namespace Archive
|
||||
|
||||
// This macro MUST be defined after both Puppet and display_properties_archive
|
||||
// This macro MUST be defined after both Prop3D and display_properties_archive
|
||||
// are fully defined.
|
||||
#define ULIB_ACTIVATE_DISPLAY_PROPERTIES \
|
||||
{ \
|
||||
|
||||
@@ -34,8 +34,8 @@ ObjectsContext::ObjectsContext(uLib::ObjectsContext *context)
|
||||
}
|
||||
|
||||
ObjectsContext::~ObjectsContext() {
|
||||
for (auto const& [obj, puppet] : m_Puppets) {
|
||||
delete puppet;
|
||||
for (auto const& [obj, prop3d] : m_Prop3Ds) {
|
||||
delete prop3d;
|
||||
}
|
||||
m_Assembly->Delete();
|
||||
}
|
||||
@@ -48,31 +48,31 @@ void ObjectsContext::Synchronize() {
|
||||
std::map<uLib::Object*, bool> currentObjects;
|
||||
for (auto obj : objects) currentObjects[obj] = true;
|
||||
|
||||
// Remove puppets for objects no longer in context
|
||||
for (auto it = m_Puppets.begin(); it != m_Puppets.end(); ) {
|
||||
// Remove Prop3Ds for objects no longer in context
|
||||
for (auto it = m_Prop3Ds.begin(); it != m_Prop3Ds.end(); ) {
|
||||
if (currentObjects.find(it->first) == currentObjects.end()) {
|
||||
it->second->DisconnectRenderer(nullptr); // If we have a ref to a renderer we should disconnect but Puppet doesn't store it easily
|
||||
// Actually Puppet::DisconnectRenderer(vtkRenderer*) needs the renderer.
|
||||
it->second->DisconnectRenderer(nullptr); // If we have a ref to a renderer we should disconnect but Prop3D doesn't store it easily
|
||||
// Actually Prop3D::DisconnectRenderer(vtkRenderer*) needs the renderer.
|
||||
// For now we just remove from assembly
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(it->second->GetProp()))
|
||||
m_Assembly->RemovePart(p3d);
|
||||
this->PuppetRemoved(it->second);
|
||||
this->Prop3DRemoved(it->second);
|
||||
delete it->second;
|
||||
it = m_Puppets.erase(it);
|
||||
it = m_Prop3Ds.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// Add puppets for new objects
|
||||
// Add Prop3Ds for new objects
|
||||
for (auto obj : objects) {
|
||||
if (m_Puppets.find(obj) == m_Puppets.end()) {
|
||||
Puppet* puppet = this->CreatePuppet(obj);
|
||||
if (puppet) {
|
||||
m_Puppets[obj] = puppet;
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(puppet->GetProp()))
|
||||
if (m_Prop3Ds.find(obj) == m_Prop3Ds.end()) {
|
||||
Prop3D* prop3d = this->CreateProp3D(obj);
|
||||
if (prop3d) {
|
||||
m_Prop3Ds[obj] = prop3d;
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(prop3d->GetProp()))
|
||||
m_Assembly->AddPart(p3d);
|
||||
this->PuppetAdded(puppet);
|
||||
this->Prop3DAdded(prop3d);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,50 +80,50 @@ void ObjectsContext::Synchronize() {
|
||||
|
||||
void ObjectsContext::OnObjectAdded(uLib::Object* obj) {
|
||||
if (!obj) return;
|
||||
if (m_Puppets.find(obj) == m_Puppets.end()) {
|
||||
Puppet* puppet = this->CreatePuppet(obj);
|
||||
if (puppet) {
|
||||
m_Puppets[obj] = puppet;
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(puppet->GetProp()))
|
||||
if (m_Prop3Ds.find(obj) == m_Prop3Ds.end()) {
|
||||
Prop3D* prop3d = this->CreateProp3D(obj);
|
||||
if (prop3d) {
|
||||
m_Prop3Ds[obj] = prop3d;
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(prop3d->GetProp()))
|
||||
m_Assembly->AddPart(p3d);
|
||||
this->PuppetAdded(puppet);
|
||||
this->Prop3DAdded(prop3d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectsContext::OnObjectRemoved(uLib::Object* obj) {
|
||||
if (!obj) return;
|
||||
auto it = m_Puppets.find(obj);
|
||||
if (it != m_Puppets.end()) {
|
||||
auto it = m_Prop3Ds.find(obj);
|
||||
if (it != m_Prop3Ds.end()) {
|
||||
// For now we just remove from assembly.
|
||||
// Puppet::DisconnectRenderer(vtkRenderer*) needs the renderer, but we don't have it here easily.
|
||||
// Prop3D::DisconnectRenderer(vtkRenderer*) needs the renderer, but we don't have it here easily.
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(it->second->GetProp()))
|
||||
m_Assembly->RemovePart(p3d);
|
||||
this->PuppetRemoved(it->second);
|
||||
this->Prop3DRemoved(it->second);
|
||||
delete it->second;
|
||||
m_Puppets.erase(it);
|
||||
m_Prop3Ds.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
Puppet* ObjectsContext::GetPuppet(uLib::Object* obj) {
|
||||
auto it = m_Puppets.find(obj);
|
||||
if (it != m_Puppets.end()) return it->second;
|
||||
Prop3D* ObjectsContext::GetProp3D(uLib::Object* obj) {
|
||||
auto it = m_Prop3Ds.find(obj);
|
||||
if (it != m_Prop3Ds.end()) return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ObjectsContext::Update() {
|
||||
for (auto const& [obj, puppet] : m_Puppets) {
|
||||
puppet->Update();
|
||||
for (auto const& [obj, prop3d] : m_Prop3Ds) {
|
||||
prop3d->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectsContext::SyncFromVtk() {
|
||||
for (auto const& [obj, puppet] : m_Puppets) {
|
||||
puppet->SyncFromVtk();
|
||||
for (auto const& [obj, prop3d] : m_Prop3Ds) {
|
||||
prop3d->SyncFromVtk();
|
||||
}
|
||||
}
|
||||
|
||||
Puppet* ObjectsContext::CreatePuppet(uLib::Object* obj) {
|
||||
Prop3D* ObjectsContext::CreateProp3D(uLib::Object* obj) {
|
||||
if (!obj) return nullptr;
|
||||
|
||||
if (auto* vox = dynamic_cast<uLib::Abstract::VoxImage*>(obj)) {
|
||||
@@ -148,12 +148,12 @@ Puppet* ObjectsContext::CreatePuppet(uLib::Object* obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ObjectsContext::PuppetAdded(Puppet* puppet) {
|
||||
ULIB_SIGNAL_EMIT(ObjectsContext::PuppetAdded, puppet);
|
||||
void ObjectsContext::Prop3DAdded(Prop3D* prop3d) {
|
||||
ULIB_SIGNAL_EMIT(ObjectsContext::Prop3DAdded, prop3d);
|
||||
}
|
||||
|
||||
void ObjectsContext::PuppetRemoved(Puppet* puppet) {
|
||||
ULIB_SIGNAL_EMIT(ObjectsContext::PuppetRemoved, puppet);
|
||||
void ObjectsContext::Prop3DRemoved(Prop3D* prop3d) {
|
||||
ULIB_SIGNAL_EMIT(ObjectsContext::Prop3DRemoved, prop3d);
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
@@ -11,31 +11,31 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* @brief ObjectsContext manages VTK representations (Puppets) for a collection of uLib::Objects.
|
||||
* @brief ObjectsContext manages VTK representations (Prop3Ds) for a collection of uLib::Objects.
|
||||
*/
|
||||
class ObjectsContext : public Puppet {
|
||||
class ObjectsContext : public Prop3D {
|
||||
public:
|
||||
uLibTypeMacro(ObjectsContext, Puppet)
|
||||
uLibTypeMacro(ObjectsContext, Prop3D)
|
||||
ObjectsContext(uLib::ObjectsContext *context);
|
||||
virtual ~ObjectsContext();
|
||||
|
||||
/** @brief Synchronizes the VTK puppets with the core ObjectsContext. */
|
||||
/** @brief Synchronizes the VTK prop3ds with the core ObjectsContext. */
|
||||
void Synchronize();
|
||||
|
||||
/** @brief Returns the puppet associated with a specific core object. */
|
||||
Puppet* GetPuppet(uLib::Object* obj);
|
||||
/** @brief Returns the Prop3D associated with a specific core object. */
|
||||
Prop3D* GetProp3D(uLib::Object* obj);
|
||||
|
||||
const std::map<uLib::Object*, Puppet*>& GetPuppets() const { return m_Puppets; }
|
||||
const std::map<uLib::Object*, Prop3D*>& GetProp3Ds() const { return m_Prop3Ds; }
|
||||
|
||||
/** @brief Updates all managed puppets. */
|
||||
/** @brief Updates all managed prop3ds. */
|
||||
virtual void Update() override;
|
||||
|
||||
/** @brief Synchronizes all managed puppets back to their models. */
|
||||
/** @brief Synchronizes all managed prop3ds back to their models. */
|
||||
virtual void SyncFromVtk() override;
|
||||
|
||||
public:
|
||||
virtual void PuppetAdded(Puppet* puppet);
|
||||
virtual void PuppetRemoved(Puppet* puppet);
|
||||
virtual void Prop3DAdded(Prop3D* prop3d);
|
||||
virtual void Prop3DRemoved(Prop3D* prop3d);
|
||||
|
||||
public:
|
||||
/** @brief Slot called when an object is added to the core context. */
|
||||
@@ -44,12 +44,12 @@ public:
|
||||
void OnObjectRemoved(uLib::Object* obj);
|
||||
|
||||
protected:
|
||||
/** @brief Factory method to create a puppet for a core object. */
|
||||
Puppet* CreatePuppet(uLib::Object* obj);
|
||||
/** @brief Factory method to create a Prop3D for a core object. */
|
||||
Prop3D* CreateProp3D(uLib::Object* obj);
|
||||
|
||||
private:
|
||||
uLib::ObjectsContext *m_Context;
|
||||
std::map<uLib::Object*, Puppet*> m_Puppets;
|
||||
std::map<uLib::Object*, Prop3D*> m_Prop3Ds;
|
||||
vtkAssembly *m_Assembly;
|
||||
};
|
||||
|
||||
|
||||
@@ -136,9 +136,9 @@ void QViewport::onProjButtonClicked()
|
||||
SetParallelProjection(m_ProjButton->isChecked());
|
||||
}
|
||||
|
||||
void QViewport::OnSelectionChanged(Puppet* p)
|
||||
void QViewport::OnSelectionChanged(Prop3D* p)
|
||||
{
|
||||
emit puppetSelected(p);
|
||||
emit prop3dSelected(p);
|
||||
}
|
||||
|
||||
void QViewport::resizeEvent(QResizeEvent* event)
|
||||
|
||||
@@ -26,12 +26,12 @@ namespace Vtk {
|
||||
/**
|
||||
* QViewport is a self-contained Qt widget that embeds a VTK renderer
|
||||
* directly into the Qt application (no separate VTK window).
|
||||
* Puppets and actors are added to the embedded renderer.
|
||||
* Prop3Ds and actors are added to the embedded renderer.
|
||||
*/
|
||||
class QViewport : public QWidget, public Viewport {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void puppetSelected(uLib::Vtk::Puppet* p);
|
||||
void prop3dSelected(uLib::Vtk::Prop3D* p);
|
||||
public:
|
||||
explicit QViewport(QWidget* parent = nullptr);
|
||||
virtual ~QViewport();
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
virtual vtkRenderWindowInteractor* GetInteractor() override;
|
||||
QVTKOpenGLNativeWidget* GetWidget() { return m_VtkWidget; }
|
||||
|
||||
virtual void OnSelectionChanged(Puppet* p) override;
|
||||
virtual void OnSelectionChanged(Prop3D* p) override;
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
@@ -201,12 +201,12 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
pv->m_HandlerWidget->GetOverlayRenderer()->SetLayer(1);
|
||||
}
|
||||
|
||||
// Observe InteractionEvent to update the selected puppet when the widget moves it
|
||||
// Observe InteractionEvent to update the selected Prop3D when the widget moves it
|
||||
vtkNew<vtkCallbackCommand> widgetInteractionCallback;
|
||||
widgetInteractionCallback->SetClientData(this);
|
||||
widgetInteractionCallback->SetCallback([](vtkObject*, unsigned long, void* clientdata, void*){
|
||||
auto* self = static_cast<Viewport*>(clientdata);
|
||||
for (auto* p : self->m_Puppets) {
|
||||
for (auto* p : self->m_Prop3Ds) {
|
||||
if (p->IsSelected()) {
|
||||
p->SyncFromVtk();
|
||||
}
|
||||
@@ -246,29 +246,29 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
return false;
|
||||
};
|
||||
|
||||
Puppet* target = nullptr;
|
||||
Prop3D* target = nullptr;
|
||||
if (picked) {
|
||||
// 2. Find the leaf puppet: the one that contains 'picked' and is not a parent of another that also contains it.
|
||||
// 2. Find the leaf Prop3D: the one that contains 'picked' and is not a parent of another that also contains it.
|
||||
// Actually, we can just find all matches and pick the one with most 'nested' prop?
|
||||
// A simpler way: we know 'picked' is the LEAF prop from VTK.
|
||||
// Find a puppet that contains it.
|
||||
Puppet* leafPuppet = nullptr;
|
||||
for (auto* p : self->m_Puppets) {
|
||||
// Find a Prop3D that contains it.
|
||||
Prop3D* leafProp3D = nullptr;
|
||||
for (auto* p : self->m_Prop3Ds) {
|
||||
if (containsProp(p->GetProp(), picked)) {
|
||||
// If we already have a candidate, check if this one is smaller (nested)
|
||||
if (!leafPuppet || containsProp(leafPuppet->GetProp(), p->GetProp())) {
|
||||
leafPuppet = p;
|
||||
if (!leafProp3D || containsProp(leafProp3D->GetProp(), p->GetProp())) {
|
||||
leafProp3D = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leafPuppet) {
|
||||
target = leafPuppet;
|
||||
if (leafProp3D) {
|
||||
target = leafProp3D;
|
||||
|
||||
// 3. Model-driven hierarchy climb:
|
||||
// If the leaf puppet has a uLib object, climb its parents.
|
||||
// If any parent is an Assembly with GroupSelection=true, select the assembly puppet instead.
|
||||
uLib::Object* currentObj = leafPuppet->GetContent();
|
||||
// If the leaf Prop3D has a uLib object, climb its parents.
|
||||
// If any parent is an Assembly with GroupSelection=true, select the assembly Prop3D instead.
|
||||
uLib::Object* currentObj = leafProp3D->GetContent();
|
||||
|
||||
while (currentObj) {
|
||||
// Object doesn't have parent, but AffineTransform does
|
||||
@@ -279,9 +279,9 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
|
||||
if (auto* parentAsm = dynamic_cast<::uLib::Assembly*>(parentObj)) {
|
||||
if (parentAsm->GetGroupSelection()) {
|
||||
// Find the puppet for this parent assembly
|
||||
auto it = self->m_ObjectToPuppet.find(parentAsm);
|
||||
if (it != self->m_ObjectToPuppet.end()) {
|
||||
// Find the Prop3D for this parent assembly
|
||||
auto it = self->m_ObjectToProp3D.find(parentAsm);
|
||||
if (it != self->m_ObjectToProp3D.end()) {
|
||||
target = it->second;
|
||||
// Keep climbing to find even larger groups
|
||||
}
|
||||
@@ -291,7 +291,7 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
}
|
||||
}
|
||||
}
|
||||
self->SelectPuppet(target);
|
||||
self->SelectProp3D(target);
|
||||
});
|
||||
iren->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
|
||||
|
||||
@@ -388,8 +388,8 @@ void Viewport::ZoomSelected()
|
||||
{
|
||||
if (!pv->m_Renderer) return;
|
||||
|
||||
Puppet* selected = nullptr;
|
||||
for (auto* p : m_Puppets) {
|
||||
Prop3D* selected = nullptr;
|
||||
for (auto* p : m_Prop3Ds) {
|
||||
if (p->IsSelected()) {
|
||||
selected = p;
|
||||
break;
|
||||
@@ -427,23 +427,23 @@ void Viewport::ZoomSelected()
|
||||
this->Render();
|
||||
}
|
||||
|
||||
void Viewport::AddPuppet(Puppet& prop)
|
||||
void Viewport::AddProp3D(Prop3D& prop)
|
||||
{
|
||||
this->RegisterPuppet(&prop, false);
|
||||
this->RegisterProp3D(&prop, false);
|
||||
Render();
|
||||
}
|
||||
|
||||
void Viewport::RemovePuppet(Puppet& prop)
|
||||
void Viewport::RemoveProp3D(Prop3D& prop)
|
||||
{
|
||||
this->UnregisterPuppet(&prop);
|
||||
this->UnregisterProp3D(&prop);
|
||||
Render();
|
||||
}
|
||||
|
||||
void Viewport::RegisterPuppet(Puppet* p, bool isPart) {
|
||||
void Viewport::RegisterProp3D(Prop3D* p, bool isPart) {
|
||||
if (!p) return;
|
||||
if (std::find(m_Puppets.begin(), m_Puppets.end(), p) != m_Puppets.end()) return;
|
||||
if (std::find(m_Prop3Ds.begin(), m_Prop3Ds.end(), p) != m_Prop3Ds.end()) return;
|
||||
|
||||
m_Puppets.push_back(p);
|
||||
m_Prop3Ds.push_back(p);
|
||||
p->ConnectRenderer(pv->m_Renderer);
|
||||
|
||||
// If it's a part of an assembly, we don't want to draw it twice.
|
||||
@@ -461,19 +461,19 @@ void Viewport::RegisterPuppet(Puppet* p, bool isPart) {
|
||||
this->ObserveContext(as->GetChildrenContext());
|
||||
}
|
||||
|
||||
if (obj) m_ObjectToPuppet[obj] = p;
|
||||
if (obj) m_ObjectToProp3D[obj] = p;
|
||||
}
|
||||
|
||||
void Viewport::UnregisterPuppet(Puppet* p) {
|
||||
void Viewport::UnregisterProp3D(Prop3D* p) {
|
||||
if (!p) return;
|
||||
if (p->IsSelected()) SelectPuppet(nullptr);
|
||||
if (p->IsSelected()) SelectProp3D(nullptr);
|
||||
|
||||
auto it = std::find(m_Puppets.begin(), m_Puppets.end(), p);
|
||||
if (it != m_Puppets.end()) m_Puppets.erase(it);
|
||||
auto it = std::find(m_Prop3Ds.begin(), m_Prop3Ds.end(), p);
|
||||
if (it != m_Prop3Ds.end()) m_Prop3Ds.erase(it);
|
||||
|
||||
// Remove from map
|
||||
for (auto mapIt = m_ObjectToPuppet.begin(); mapIt != m_ObjectToPuppet.end(); ) {
|
||||
if (mapIt->second == p) mapIt = m_ObjectToPuppet.erase(mapIt);
|
||||
for (auto mapIt = m_ObjectToProp3D.begin(); mapIt != m_ObjectToProp3D.end(); ) {
|
||||
if (mapIt->second == p) mapIt = m_ObjectToProp3D.erase(mapIt);
|
||||
else ++mapIt;
|
||||
}
|
||||
|
||||
@@ -483,23 +483,23 @@ void Viewport::UnregisterPuppet(Puppet* p) {
|
||||
void Viewport::ObserveContext(ObjectsContext* ctx) {
|
||||
if (!ctx) return;
|
||||
|
||||
// Process existing puppets
|
||||
for (auto const& [obj, puppet] : ctx->GetPuppets()) {
|
||||
this->RegisterPuppet(puppet, true);
|
||||
// Process existing Prop3Ds
|
||||
for (auto const& [obj, prop3d] : ctx->GetProp3Ds()) {
|
||||
this->RegisterProp3D(prop3d, true);
|
||||
}
|
||||
|
||||
// Listen for future puppets
|
||||
uLib::Object::connect(ctx, &ObjectsContext::PuppetAdded, [this](Puppet* p){
|
||||
this->RegisterPuppet(p, true);
|
||||
// Listen for future Prop3Ds
|
||||
uLib::Object::connect(ctx, &ObjectsContext::Prop3DAdded, [this](Prop3D* p){
|
||||
this->RegisterProp3D(p, true);
|
||||
});
|
||||
uLib::Object::connect(ctx, &ObjectsContext::PuppetRemoved, [this](Puppet* p){
|
||||
this->UnregisterPuppet(p);
|
||||
uLib::Object::connect(ctx, &ObjectsContext::Prop3DRemoved, [this](Prop3D* p){
|
||||
this->UnregisterProp3D(p);
|
||||
});
|
||||
}
|
||||
|
||||
void Viewport::SelectPuppet(Puppet* prop)
|
||||
void Viewport::SelectProp3D(Prop3D* prop)
|
||||
{
|
||||
for (auto* p : m_Puppets) {
|
||||
for (auto* p : m_Prop3Ds) {
|
||||
p->SetSelected(p == prop);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ public:
|
||||
void ZoomAuto();
|
||||
void ZoomSelected();
|
||||
|
||||
// Puppet / prop management
|
||||
void AddPuppet(Puppet &prop);
|
||||
void RemovePuppet(Puppet &prop);
|
||||
void SelectPuppet(Puppet *prop);
|
||||
// Prop3D / prop management
|
||||
void AddProp3D(Prop3D &prop);
|
||||
void RemoveProp3D(Prop3D &prop);
|
||||
void SelectProp3D(Prop3D *prop);
|
||||
void addProp(vtkProp *prop);
|
||||
void RemoveProp(vtkProp *prop);
|
||||
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
vtkCornerAnnotation* GetAnnotation();
|
||||
vtkCameraOrientationWidget* GetCameraWidget();
|
||||
void DisableHandler();
|
||||
virtual void OnSelectionChanged(Puppet* p) {}
|
||||
const std::vector<Puppet*>& getPuppets() const { return m_Puppets; }
|
||||
virtual void OnSelectionChanged(Prop3D* p) {}
|
||||
const std::vector<Prop3D*>& getProp3Ds() const { return m_Prop3Ds; }
|
||||
|
||||
// Grid control
|
||||
void SetGridVisible(bool visible);
|
||||
@@ -83,15 +83,15 @@ protected:
|
||||
|
||||
void UpdateGrid();
|
||||
|
||||
// Internal puppet registration
|
||||
void RegisterPuppet(Puppet* p, bool isPart = false);
|
||||
void UnregisterPuppet(Puppet* p);
|
||||
// Internal Prop3D registration
|
||||
void RegisterProp3D(Prop3D* p, bool isPart = false);
|
||||
void UnregisterProp3D(Prop3D* p);
|
||||
void ObserveContext(ObjectsContext* ctx);
|
||||
|
||||
struct ViewportData *pv;
|
||||
Axis m_GridAxis;
|
||||
std::vector<Puppet*> m_Puppets;
|
||||
std::map<uLib::Object*, Puppet*> m_ObjectToPuppet;
|
||||
std::vector<Prop3D*> m_Prop3Ds;
|
||||
std::map<uLib::Object*, Prop3D*> m_ObjectToProp3D;
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
Reference in New Issue
Block a user