fixed vtk containerbox handler
This commit is contained in:
@@ -46,15 +46,7 @@ namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
vtkDetectorChamber::vtkDetectorChamber(DetectorChamber *content)
|
||||
: vtkContainerBox(content), m_Actor(vtkActor::New()),
|
||||
m_Widget(vtkBoxWidget::New()) {
|
||||
m_Callback = vtkWidgetCallback::New();
|
||||
m_PickerCallback = vtkSelectionCallback::New();
|
||||
|
||||
m_Callback->SetChamber(this);
|
||||
m_PickerCallback->SetChamber(this);
|
||||
m_Widget->AddObserver(vtkCommand::InteractionEvent, m_Callback);
|
||||
|
||||
: vtkContainerBox(content), m_Actor(vtkActor::New()) {
|
||||
m_InitialTransform = vtkSmartPointer<vtkTransform>::New();
|
||||
m_RelativeTransform = vtkSmartPointer<vtkTransform>::New();
|
||||
m_TotalTransform = vtkSmartPointer<vtkTransform>::New();
|
||||
@@ -64,9 +56,6 @@ vtkDetectorChamber::vtkDetectorChamber(DetectorChamber *content)
|
||||
|
||||
vtkDetectorChamber::~vtkDetectorChamber() {
|
||||
m_Actor->Delete();
|
||||
m_Widget->Delete();
|
||||
m_Callback->Delete();
|
||||
m_PickerCallback->Delete();
|
||||
}
|
||||
|
||||
DetectorChamber *vtkDetectorChamber::GetContent() {
|
||||
@@ -77,20 +66,8 @@ void vtkDetectorChamber::PrintSelf(std::ostream &o) const {
|
||||
vtkContainerBox::PrintSelf(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the interactor to the widget
|
||||
*/
|
||||
void vtkDetectorChamber::ConnectInteractor(
|
||||
vtkRenderWindowInteractor *interactor) {
|
||||
if (!interactor)
|
||||
return;
|
||||
m_Widget->SetInteractor(interactor);
|
||||
m_Widget->SetProp3D(m_Actor);
|
||||
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, m_PickerCallback);
|
||||
}
|
||||
|
||||
void vtkDetectorChamber::SetTransform(vtkTransform *t) {
|
||||
|
||||
if (!t) return;
|
||||
|
||||
m_RelativeTransform->SetMatrix(t->GetMatrix());
|
||||
m_RelativeTransform->Update();
|
||||
@@ -107,11 +84,22 @@ void vtkDetectorChamber::SetTransform(vtkTransform *t) {
|
||||
this->Update();
|
||||
}
|
||||
|
||||
vtkBoxWidget *vtkDetectorChamber::GetWidget() { return m_Widget; }
|
||||
|
||||
void vtkDetectorChamber::Update() {
|
||||
if (m_Actor->GetMapper())
|
||||
m_Actor->GetMapper()->Update();
|
||||
|
||||
// If the actor has a UserMatrix, we update the content.
|
||||
if (m_Actor->GetUserMatrix()) {
|
||||
vtkMatrix4x4* vmat = m_Actor->GetUserMatrix();
|
||||
Matrix4f transform;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
transform(i, j) = vmat->GetElement(i, j);
|
||||
|
||||
this->GetContent()->SetMatrix(transform);
|
||||
this->GetContent()->Updated();
|
||||
}
|
||||
|
||||
BaseClass::Update();
|
||||
}
|
||||
|
||||
@@ -144,56 +132,14 @@ void vtkDetectorChamber::InstallPipe() {
|
||||
m_Actor->GetProperty()->SetOpacity(0.4);
|
||||
m_Actor->GetProperty()->SetAmbient(0.7);
|
||||
|
||||
// Temporarily disable UserTransform to place widget on local base
|
||||
m_Widget->SetProp3D(m_Actor);
|
||||
|
||||
m_TotalTransform->SetInput(m_RelativeTransform);
|
||||
m_TotalTransform->Concatenate(m_InitialTransform);
|
||||
m_Actor->SetUserTransform(m_TotalTransform);
|
||||
m_TotalTransform->Update();
|
||||
|
||||
m_Widget->PlaceWidget();
|
||||
m_Widget->SetPlaceFactor(2);
|
||||
|
||||
this->SetProp(m_Actor);
|
||||
this->Update();
|
||||
}
|
||||
|
||||
void vtkDetectorChamber::vtkWidgetCallback::Execute(vtkObject *caller,
|
||||
unsigned long, void *) {
|
||||
vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget *>(caller);
|
||||
|
||||
// Get the Relative transform from the widget //
|
||||
vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
|
||||
widget->GetTransform(t);
|
||||
chamber->SetTransform(t);
|
||||
|
||||
// Apply to both the content and the actor state //
|
||||
chamber->Update();
|
||||
}
|
||||
|
||||
void vtkDetectorChamber::vtkSelectionCallback::Execute(vtkObject *caller,
|
||||
unsigned long, void *) {
|
||||
vtkRenderWindowInteractor *interactor =
|
||||
reinterpret_cast<vtkRenderWindowInteractor *>(caller);
|
||||
vtkSmartPointer<vtkPropPicker> picker = vtkSmartPointer<vtkPropPicker>::New();
|
||||
int *pos = interactor->GetEventPosition();
|
||||
picker->Pick(
|
||||
pos[0], pos[1], 0,
|
||||
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
|
||||
|
||||
vtkProp *picked = picker->GetViewProp();
|
||||
if (picked == chamber->m_Actor) {
|
||||
if (!chamber->m_Widget->GetEnabled()) {
|
||||
chamber->m_Widget->SetInteractor(interactor);
|
||||
chamber->m_Widget->On();
|
||||
}
|
||||
} else {
|
||||
if (chamber->m_Widget->GetEnabled()) {
|
||||
chamber->m_Widget->Off();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
@@ -56,11 +56,7 @@ public:
|
||||
|
||||
void SetTransform(class vtkTransform *t);
|
||||
|
||||
class vtkBoxWidget *GetWidget();
|
||||
|
||||
void Update();
|
||||
|
||||
void ConnectInteractor(vtkRenderWindowInteractor *interactor) override;
|
||||
void Update() override;
|
||||
|
||||
void PrintSelf(std::ostream &o) const;
|
||||
|
||||
@@ -68,30 +64,7 @@ protected:
|
||||
void InstallPipe() override;
|
||||
|
||||
private:
|
||||
class vtkWidgetCallback : public vtkCommand {
|
||||
public:
|
||||
static vtkWidgetCallback *New() { return new vtkWidgetCallback; }
|
||||
void SetChamber(uLib::Vtk::vtkDetectorChamber *ch) { this->chamber = ch; }
|
||||
virtual void Execute(vtkObject *caller, unsigned long, void *) override;
|
||||
|
||||
private:
|
||||
uLib::Vtk::vtkDetectorChamber *chamber;
|
||||
};
|
||||
|
||||
class vtkSelectionCallback : public vtkCommand {
|
||||
public:
|
||||
static vtkSelectionCallback *New() { return new vtkSelectionCallback; }
|
||||
void SetChamber(uLib::Vtk::vtkDetectorChamber *ch) { this->chamber = ch; }
|
||||
virtual void Execute(vtkObject *caller, unsigned long, void *) override;
|
||||
|
||||
private:
|
||||
uLib::Vtk::vtkDetectorChamber *chamber;
|
||||
};
|
||||
|
||||
vtkActor *m_Actor;
|
||||
vtkBoxWidget *m_Widget;
|
||||
vtkWidgetCallback *m_Callback;
|
||||
vtkSelectionCallback *m_PickerCallback;
|
||||
|
||||
vtkSmartPointer<vtkTransform> m_InitialTransform;
|
||||
vtkSmartPointer<vtkTransform> m_RelativeTransform;
|
||||
|
||||
@@ -110,21 +110,13 @@ BOOST_AUTO_TEST_CASE(vtkVoxRaytracerRepresentationTest) {
|
||||
// renderer //
|
||||
Vtk::Viewer viewer;
|
||||
|
||||
// widget //
|
||||
vtkBoxWidget *widget = v_grid.GetWidget();
|
||||
|
||||
vtkWidgetCallback *cbk = vtkWidgetCallback::New();
|
||||
cbk->SetTracer(&v_rt);
|
||||
cbk->SetMuon(&muon);
|
||||
cbk->SetAnnotation(viewer.GetAnnotation());
|
||||
widget->AddObserver(vtkCommand::InteractionEvent, cbk);
|
||||
widget->SetInteractor(viewer.GetInteractor());
|
||||
widget->PlaceWidget();
|
||||
widget->On();
|
||||
|
||||
viewer.AddPuppet(v_grid);
|
||||
viewer.AddPuppet(v_rt);
|
||||
viewer.AddPuppet(v_muon);
|
||||
|
||||
// Select grid to show handler widget
|
||||
viewer.SelectPuppet(&v_grid);
|
||||
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,35 +42,52 @@ namespace Vtk {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vtkVoxRaytracerRepresentation::vtkVoxRaytracerRepresentation(Content &content)
|
||||
: m_Content(&content), m_Assembly(vtkAssembly::New()),
|
||||
: m_Content(&content),
|
||||
m_Sphere1(vtkSphereSource::New()), m_Sphere2(vtkSphereSource::New()),
|
||||
m_Line1(vtkLineSource::New()), m_Line2(vtkLineSource::New()),
|
||||
m_Line3(vtkLineSource::New()), m_RayLine(vtkAppendPolyData::New()),
|
||||
m_RayLineActor(vtkActor::New()),
|
||||
m_RayRepresentation(vtkAppendPolyData::New()),
|
||||
m_RayRepresentationActor(vtkActor::New()),
|
||||
m_Transform(vtkTransform::New()) {
|
||||
m_Transform(vtkTransform::New()),
|
||||
m_HasMuon(false), m_HasPoca(false) {
|
||||
default_radius = content.GetImage()->GetSpacing()(0) / 4;
|
||||
m_Sphere1->SetRadius(default_radius);
|
||||
m_Sphere2->SetRadius(default_radius);
|
||||
m_SelectedElement = m_RayLine;
|
||||
|
||||
this->SetSelectable(false);
|
||||
InstallPipe();
|
||||
|
||||
if (m_Content && m_Content->GetImage()) {
|
||||
Object::connect(m_Content->GetImage(), &StructuredGrid::Updated, this, &vtkVoxRaytracerRepresentation::imageUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
vtkVoxRaytracerRepresentation::~vtkVoxRaytracerRepresentation() {
|
||||
m_Assembly->Delete();
|
||||
m_RayLine->Delete();
|
||||
m_RayLineActor->Delete();
|
||||
m_RayRepresentationActor->Delete();
|
||||
m_Transform->Delete();
|
||||
}
|
||||
|
||||
VoxRaytracer *vtkVoxRaytracerRepresentation::GetRaytracerAlgorithm() {
|
||||
uLib::VoxRaytracer *vtkVoxRaytracerRepresentation::GetRaytracerAlgorithm() {
|
||||
return m_Content;
|
||||
}
|
||||
|
||||
vtkProp *vtkVoxRaytracerRepresentation::GetProp() { return m_Assembly; }
|
||||
void vtkVoxRaytracerRepresentation::Update() {
|
||||
this->imageUpdate();
|
||||
}
|
||||
|
||||
void vtkVoxRaytracerRepresentation::imageUpdate() {
|
||||
if (m_HasMuon) {
|
||||
if (m_HasPoca) {
|
||||
this->SetMuon(m_Muon, m_Poca);
|
||||
} else {
|
||||
this->SetMuon(m_Muon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vtkPolyData *vtkVoxRaytracerRepresentation::GetPolyData() const {
|
||||
std::cout << "get Raytracer polydata\n";
|
||||
@@ -94,6 +111,10 @@ void vtkVoxRaytracerRepresentation::SetRepresentationElements(
|
||||
}
|
||||
|
||||
void vtkVoxRaytracerRepresentation::SetMuon(MuonScatter &muon) {
|
||||
m_Muon = muon;
|
||||
m_HasMuon = true;
|
||||
m_HasPoca = false;
|
||||
|
||||
HPoint3f pt1, pt2, src;
|
||||
src = muon.LineIn().origin;
|
||||
m_Content->GetEntryPoint(muon.LineIn(), pt1);
|
||||
@@ -152,6 +173,11 @@ void vtkVoxRaytracerRepresentation::SetMuon(MuonScatter &muon) {
|
||||
}
|
||||
|
||||
void vtkVoxRaytracerRepresentation::SetMuon(MuonScatter &muon, HPoint3f poca) {
|
||||
m_Muon = muon;
|
||||
m_Poca = poca;
|
||||
m_HasMuon = true;
|
||||
m_HasPoca = true;
|
||||
|
||||
HPoint3f pt1, pt2, src;
|
||||
src = muon.LineIn().origin;
|
||||
m_Content->GetEntryPoint(muon.LineIn(), pt1);
|
||||
|
||||
@@ -58,7 +58,7 @@ class vtkActor;
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
class vtkVoxRaytracerRepresentation : public Puppet {
|
||||
class vtkVoxRaytracerRepresentation : public Puppet, public Object {
|
||||
typedef VoxRaytracer Content;
|
||||
|
||||
public:
|
||||
@@ -67,7 +67,9 @@ public:
|
||||
|
||||
uLib::VoxRaytracer *GetRaytracerAlgorithm();
|
||||
|
||||
vtkProp *GetProp();
|
||||
virtual void Update() override;
|
||||
|
||||
void imageUpdate();
|
||||
|
||||
vtkPolyData *GetPolyData() const;
|
||||
|
||||
@@ -99,9 +101,12 @@ private:
|
||||
void SetColor(vtkActor *actor, Vector4f rgba);
|
||||
|
||||
VoxRaytracer *m_Content;
|
||||
MuonScatter m_Muon;
|
||||
HPoint3f m_Poca;
|
||||
bool m_HasMuon;
|
||||
bool m_HasPoca;
|
||||
|
||||
Scalarf default_radius;
|
||||
vtkAssembly *m_Assembly;
|
||||
vtkAppendPolyData *m_RayLine;
|
||||
vtkActor *m_RayLineActor;
|
||||
vtkActor *m_RayRepresentationActor;
|
||||
|
||||
@@ -44,5 +44,5 @@ BOOST_AUTO_TEST_CASE(vtkStructuredGridTest) {
|
||||
viewer.Start();
|
||||
}
|
||||
|
||||
BOOST_CHECK(grid_viewer.GetWidget() != nullptr);
|
||||
BOOST_CHECK(grid_viewer.GetProp() != nullptr);
|
||||
}
|
||||
|
||||
54
src/Vtk/Math/vtkDense.h
Normal file
54
src/Vtk/Math/vtkDense.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef U_VTK_DENSE_H
|
||||
#define U_VTK_DENSE_H
|
||||
|
||||
#include "Math/Dense.h"
|
||||
#include <vtkMatrix4x4.h>
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
/**
|
||||
* @brief Converts a uLib::Matrix4f to an existing vtkMatrix4x4.
|
||||
* @param src The source Eigen matrix.
|
||||
* @param dst The destination vtkMatrix4x4.
|
||||
*/
|
||||
inline void Matrix4fToVtk(const Matrix4f& src, vtkMatrix4x4* dst) {
|
||||
if (!dst)
|
||||
return;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
dst->SetElement(i, j, src(i, j));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a uLib::Matrix4f to a new vtkMatrix4x4.
|
||||
* @param src The source Eigen matrix.
|
||||
* @return A new vtkMatrix4x4 (caller is responsible for management/deletion).
|
||||
*/
|
||||
inline vtkMatrix4x4* Matrix4fToVtk(const Matrix4f& src) {
|
||||
vtkMatrix4x4* dst = vtkMatrix4x4::New();
|
||||
Matrix4fToVtk(src, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a vtkMatrix4x4 to a uLib::Matrix4f.
|
||||
* @param src The source vtkMatrix4x4.
|
||||
* @return The converted uLib::Matrix4f matrix.
|
||||
*/
|
||||
inline Matrix4f VtkToMatrix4f(vtkMatrix4x4* src) {
|
||||
Matrix4f dst;
|
||||
if (!src) {
|
||||
dst.setIdentity();
|
||||
return dst;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
dst(i, j) = src->GetElement(i, j);
|
||||
return dst;
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
|
||||
#endif // U_VTK_DENSE_H
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "Math/StructuredGrid.h"
|
||||
#include "Vtk/Math/vtkStructuredGrid.h"
|
||||
|
||||
#include "Vtk/Math/vtkDense.h"
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
@@ -39,73 +41,64 @@ namespace Vtk {
|
||||
|
||||
vtkStructuredGrid::vtkStructuredGrid(Content &content)
|
||||
: m_Content(&content), m_Actor(vtkActor::New()),
|
||||
m_Widget(vtkBoxWidget::New()), m_Transform(vtkTransform::New()) {
|
||||
vtkSmartPointer<vtkWidgetCallback> callback =
|
||||
vtkSmartPointer<vtkWidgetCallback>::New();
|
||||
callback->SetGrid(this);
|
||||
m_Widget->AddObserver(vtkCommand::InteractionEvent, callback);
|
||||
m_Transform(vtkTransform::New()) {
|
||||
|
||||
this->InstallPipe();
|
||||
}
|
||||
|
||||
vtkStructuredGrid::~vtkStructuredGrid() {
|
||||
m_Actor->Delete();
|
||||
m_Widget->Delete();
|
||||
m_Transform->Delete();
|
||||
}
|
||||
|
||||
void vtkStructuredGrid::SetTransform(vtkTransform *t) {
|
||||
vtkMatrix4x4 *vmat = t->GetMatrix();
|
||||
Matrix4f mat;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
mat(i, j) = vmat->GetElement(i, j);
|
||||
Matrix4f mat = VtkToMatrix4f(vmat);
|
||||
m_Content->SetMatrix(mat);
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> vmat2 = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
mat = m_Content->GetWorldMatrix();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
vmat2->SetElement(i, j, mat(i, j));
|
||||
Matrix4fToVtk(mat, vmat2);
|
||||
m_Transform->SetMatrix(vmat2);
|
||||
m_Transform->Update();
|
||||
this->Update();
|
||||
}
|
||||
|
||||
vtkBoxWidget *vtkStructuredGrid::GetWidget() { return m_Widget; }
|
||||
void vtkStructuredGrid::Update() {
|
||||
if (!m_Content) return;
|
||||
|
||||
void vtkStructuredGrid::Update() { m_Actor->GetMapper()->Update(); }
|
||||
vtkProp3D* actor = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (!actor) return;
|
||||
|
||||
vtkMatrix4x4* vmat = actor->GetUserMatrix();
|
||||
if (!vmat) return;
|
||||
|
||||
Matrix4f transform = VtkToMatrix4f(vmat);
|
||||
m_Content->SetMatrix(transform);
|
||||
|
||||
m_Content->Updated(); // Notify others (like raytracer)
|
||||
}
|
||||
|
||||
void vtkStructuredGrid::InstallPipe() {
|
||||
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter> filter =
|
||||
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> vmat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
Matrix4f mat = m_Content->GetWorldMatrix();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
vmat->SetElement(i, j, mat(i, j));
|
||||
m_Transform->SetMatrix(vmat);
|
||||
filter->SetTransform(m_Transform);
|
||||
filter->SetInputConnection(cube->GetOutputPort());
|
||||
|
||||
|
||||
Vector3i dims = m_Content->GetDims();
|
||||
cube->SetBounds(0, dims(0), 0, dims(1), 0, dims(2));
|
||||
cube->Update();
|
||||
filter->Update();
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper =
|
||||
vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
mapper->SetInputConnection(filter->GetOutputPort());
|
||||
mapper->SetInputConnection(cube->GetOutputPort());
|
||||
|
||||
m_Actor->SetMapper(mapper);
|
||||
m_Actor->GetProperty()->SetRepresentationToSurface();
|
||||
m_Actor->GetProperty()->SetEdgeVisibility(true);
|
||||
m_Actor->GetProperty()->SetOpacity(0.4);
|
||||
m_Actor->GetProperty()->SetAmbient(0.7);
|
||||
this->Update();
|
||||
m_Widget->SetProp3D(m_Actor);
|
||||
|
||||
vtkNew<vtkMatrix4x4> vmat;
|
||||
Matrix4fToVtk(m_Content->GetWorldMatrix(), vmat);
|
||||
m_Actor->SetUserMatrix(vmat);
|
||||
|
||||
this->SetProp(m_Actor);
|
||||
}
|
||||
|
||||
@@ -56,32 +56,12 @@ public:
|
||||
|
||||
void SetTransform(class vtkTransform *t);
|
||||
|
||||
class vtkBoxWidget *GetWidget();
|
||||
|
||||
void Update();
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
void InstallPipe();
|
||||
|
||||
class vtkWidgetCallback : public vtkCommand {
|
||||
public:
|
||||
static vtkWidgetCallback *New() { return new vtkWidgetCallback; }
|
||||
|
||||
void SetGrid(uLib::Vtk::vtkStructuredGrid *grid) { this->grid = grid; }
|
||||
|
||||
virtual void Execute(vtkObject *caller, unsigned long, void *) {
|
||||
vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
|
||||
vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget *>(caller);
|
||||
widget->GetTransform(t);
|
||||
grid->SetTransform(t);
|
||||
}
|
||||
|
||||
private:
|
||||
uLib::Vtk::vtkStructuredGrid *grid;
|
||||
};
|
||||
|
||||
vtkActor *m_Actor;
|
||||
vtkBoxWidget *m_Widget;
|
||||
StructuredGrid *m_Content;
|
||||
vtkTransform *m_Transform;
|
||||
};
|
||||
|
||||
@@ -36,9 +36,16 @@ int main() {
|
||||
BEGIN_TESTING(vtk ContainerBox Test);
|
||||
|
||||
ContainerBox box;
|
||||
box.SetSize(Vector3f(2, 3, 4));
|
||||
box.SetPosition(Vector3f(1, 2, 3));
|
||||
box.Scale(Vector3f(1,5,1));
|
||||
box.SetPosition(Vector3f(0,1,0));
|
||||
Vtk::vtkContainerBox v_box(&box);
|
||||
v_box.SetRepresentation(Vtk::Puppet::Surface);
|
||||
v_box.SetOpacity(0.5);
|
||||
v_box.SetSelectable(true);
|
||||
|
||||
box.findOrAddSignal(&ContainerBox::Updated)->connect([&box](){
|
||||
std::cout << "box updated: " << box.GetWorldPoint(HPoint3f(1,1,1)) << std::endl;
|
||||
});
|
||||
|
||||
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
|
||||
Vtk::Viewer v_viewer;
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
|
||||
#include <vtkActor.h>
|
||||
#include <vtkPropCollection.h>
|
||||
#include <vtkProp3DCollection.h>
|
||||
#include <vtkRendererCollection.h>
|
||||
#include <vtkPropAssembly.h>
|
||||
#include <vtkAssembly.h>
|
||||
#include <vtkOutlineSource.h>
|
||||
#include <vtkPolyDataMapper.h>
|
||||
#include <vtkCubeAxesActor.h>
|
||||
@@ -82,7 +83,7 @@ class PuppetData {
|
||||
public:
|
||||
PuppetData() :
|
||||
m_Renderers(vtkSmartPointer<vtkRendererCollection>::New()),
|
||||
m_Assembly(vtkSmartPointer<vtkPropAssembly>::New()),
|
||||
m_Assembly(vtkSmartPointer<vtkAssembly>::New()),
|
||||
m_ShowBoundingBox(false),
|
||||
m_ShowScaleMeasures(false),
|
||||
m_Representation(-1),
|
||||
@@ -99,7 +100,7 @@ public:
|
||||
|
||||
// members //
|
||||
vtkSmartPointer<vtkRendererCollection> m_Renderers;
|
||||
vtkSmartPointer<vtkPropAssembly> m_Assembly;
|
||||
vtkSmartPointer<vtkAssembly> m_Assembly;
|
||||
|
||||
vtkSmartPointer<vtkOutlineSource> m_OutlineSource;
|
||||
vtkSmartPointer<vtkActor> m_OutlineActor;
|
||||
@@ -160,19 +161,16 @@ public:
|
||||
m_HighlightActor->GetProperty()->SetLighting(0);
|
||||
}
|
||||
|
||||
// Update highlight data and transform from first actor
|
||||
vtkPropCollection *parts = m_Assembly->GetParts();
|
||||
parts->InitTraversal();
|
||||
for (int i = 0; i < parts->GetNumberOfItems(); ++i) {
|
||||
vtkActor *actor = vtkActor::SafeDownCast(parts->GetNextProp());
|
||||
if (actor) {
|
||||
// Sync transform
|
||||
m_HighlightActor->SetUserTransform(actor->GetUserTransform());
|
||||
m_HighlightActor->SetPosition(actor->GetPosition());
|
||||
m_HighlightActor->SetOrientation(actor->GetOrientation());
|
||||
m_HighlightActor->SetScale(actor->GetScale());
|
||||
break;
|
||||
}
|
||||
// Update highlight matrix from the root prop
|
||||
vtkProp3D* root = nullptr;
|
||||
if (m_Assembly->GetParts()->GetNumberOfItems() == 1) {
|
||||
root = vtkProp3D::SafeDownCast(m_Assembly->GetParts()->GetLastProp());
|
||||
} else {
|
||||
root = m_Assembly;
|
||||
}
|
||||
|
||||
if (root) {
|
||||
m_HighlightActor->SetUserMatrix(root->GetMatrix());
|
||||
}
|
||||
|
||||
m_Renderers->InitTraversal();
|
||||
@@ -209,18 +207,17 @@ Puppet::~Puppet()
|
||||
vtkProp *Puppet::GetProp()
|
||||
{
|
||||
if (d->m_Assembly->GetParts()->GetNumberOfItems() == 1)
|
||||
{
|
||||
// d->m_Assembly->GetParts()->InitTraversal();
|
||||
// return d->m_Assembly->GetParts()->GetNextProp();
|
||||
return d->m_Assembly->GetParts()->GetLastProp();
|
||||
}
|
||||
else return d->m_Assembly;
|
||||
else
|
||||
return d->m_Assembly;
|
||||
}
|
||||
|
||||
void Puppet::SetProp(vtkProp *prop)
|
||||
{
|
||||
if(prop) {
|
||||
d->m_Assembly->AddPart(prop);
|
||||
if (auto* p3d = vtkProp3D::SafeDownCast(prop)) {
|
||||
d->m_Assembly->AddPart(p3d);
|
||||
}
|
||||
d->ApplyAppearance(prop);
|
||||
}
|
||||
}
|
||||
@@ -240,14 +237,8 @@ void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
||||
{
|
||||
if(renderer) {
|
||||
this->GetRenderers()->AddItem(renderer);
|
||||
if(d->m_Assembly->GetParts()->GetNumberOfItems() == 1)
|
||||
renderer->AddActor(this->GetProp());
|
||||
else if(d->m_Assembly->GetParts()->GetNumberOfItems() >0)
|
||||
{
|
||||
vtkPropCollection *props = d->m_Assembly->GetParts();
|
||||
props->InitTraversal();
|
||||
for (int i=0; i<props->GetNumberOfItems(); ++i)
|
||||
renderer->AddActor(props->GetNextProp());
|
||||
if(vtkProp* prop = this->GetProp()) {
|
||||
renderer->AddViewProp(prop);
|
||||
}
|
||||
|
||||
if (d->m_ShowBoundingBox && d->m_OutlineActor) renderer->AddActor(d->m_OutlineActor);
|
||||
@@ -265,15 +256,8 @@ void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
||||
void Puppet::DisconnectRenderer(vtkRenderer *renderer)
|
||||
{
|
||||
if(renderer) {
|
||||
if(this->GetProp())
|
||||
renderer->RemoveViewProp(this->GetProp());
|
||||
else if(d->m_Assembly->GetParts()->GetNumberOfItems() >0)
|
||||
{
|
||||
vtkPropCollection *props = d->m_Assembly->GetParts();
|
||||
props->InitTraversal();
|
||||
for (int i=0; i<props->GetNumberOfItems(); ++i)
|
||||
renderer->RemoveViewProp(props->GetNextProp());
|
||||
}
|
||||
if(vtkProp* prop = this->GetProp())
|
||||
renderer->RemoveViewProp(prop);
|
||||
|
||||
if (d->m_ShowBoundingBox && d->m_OutlineActor) renderer->RemoveActor(d->m_OutlineActor);
|
||||
if (d->m_ShowScaleMeasures && d->m_CubeAxesActor) renderer->RemoveActor(d->m_CubeAxesActor);
|
||||
@@ -382,10 +366,10 @@ void Puppet::SetRepresentation(Representation mode)
|
||||
}
|
||||
d->m_Representation = rep;
|
||||
|
||||
vtkPropCollection *props = d->m_Assembly->GetParts();
|
||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
||||
props->InitTraversal();
|
||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||
d->ApplyAppearance(props->GetNextProp());
|
||||
d->ApplyAppearance(props->GetNextProp3D());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,10 +387,10 @@ void Puppet::SetColor(double r, double g, double b)
|
||||
d->m_Color[1] = g;
|
||||
d->m_Color[2] = b;
|
||||
|
||||
vtkPropCollection *props = d->m_Assembly->GetParts();
|
||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
||||
props->InitTraversal();
|
||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||
d->ApplyAppearance(props->GetNextProp());
|
||||
d->ApplyAppearance(props->GetNextProp3D());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,10 +398,10 @@ void Puppet::SetOpacity(double alpha)
|
||||
{
|
||||
d->m_Opacity = alpha;
|
||||
|
||||
vtkPropCollection *props = d->m_Assembly->GetParts();
|
||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
||||
props->InitTraversal();
|
||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||
d->ApplyAppearance(props->GetNextProp());
|
||||
d->ApplyAppearance(props->GetNextProp3D());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,6 +434,24 @@ bool Puppet::IsSelected() const
|
||||
return d->m_Selected;
|
||||
}
|
||||
|
||||
void Puppet::Update()
|
||||
{
|
||||
if (d->m_Selected) {
|
||||
d->UpdateHighlight();
|
||||
}
|
||||
|
||||
if (d->m_ShowBoundingBox) {
|
||||
double* bounds = d->m_Assembly->GetBounds();
|
||||
d->m_OutlineSource->SetBounds(bounds);
|
||||
d->m_OutlineSource->Update();
|
||||
}
|
||||
|
||||
if (d->m_ShowScaleMeasures) {
|
||||
double* bounds = d->m_Assembly->GetBounds();
|
||||
d->m_CubeAxesActor->SetBounds(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void Puppet::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ public:
|
||||
void SetSelected(bool selected = true);
|
||||
bool IsSelected() const;
|
||||
|
||||
virtual void Update();
|
||||
|
||||
virtual void ConnectInteractor(class vtkRenderWindowInteractor *interactor);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -41,21 +41,24 @@
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkTransform.h>
|
||||
|
||||
#include "Math/vtkDense.h"
|
||||
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
vtkContainerBox::vtkContainerBox(vtkContainerBox::Content *content)
|
||||
: m_Cube(vtkActor::New()), m_Axes(vtkActor::New()),
|
||||
m_Pivot(vtkActor::New()),
|
||||
// m_Pivot(vtkActor::New()),
|
||||
m_Content(content) {
|
||||
this->InstallPipe();
|
||||
Object::connect(m_Content, &Content::Updated, this, &vtkContainerBox::contentUpdate);
|
||||
}
|
||||
|
||||
vtkContainerBox::~vtkContainerBox() {
|
||||
m_Cube->Delete();
|
||||
m_Axes->Delete();
|
||||
m_Pivot->Delete();
|
||||
// m_Pivot->Delete();
|
||||
}
|
||||
|
||||
vtkPolyData *vtkContainerBox::GetPolyData() const {
|
||||
@@ -63,21 +66,52 @@ vtkPolyData *vtkContainerBox::GetPolyData() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vtkContainerBox::Update() {
|
||||
|
||||
void vtkContainerBox::contentUpdate() {
|
||||
if (!m_Content)
|
||||
return;
|
||||
vtkSmartPointer<vtkMatrix4x4> vmat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
|
||||
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (!root) return;
|
||||
|
||||
vtkMatrix4x4* vmat = root->GetUserMatrix();
|
||||
if (!vmat) {
|
||||
// Should have been set in InstallPipe, but let's be safe
|
||||
vtkNew<vtkMatrix4x4> mat;
|
||||
root->SetUserMatrix(mat);
|
||||
vmat = mat;
|
||||
}
|
||||
|
||||
Matrix4f transform = m_Content->GetMatrix();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
vmat->SetElement(i, j, transform(i, j));
|
||||
}
|
||||
|
||||
// std::cout << "transform: " << transform << std::endl;
|
||||
// m_RelativeTransform->SetMatrix(vmat);
|
||||
// m_RelativeTransform->Update();
|
||||
root->Modified();
|
||||
Puppet::Update();
|
||||
}
|
||||
|
||||
m_Cube->SetUserMatrix(vmat);
|
||||
m_Axes->SetUserMatrix(vmat);
|
||||
|
||||
void vtkContainerBox::Update() {
|
||||
if (!m_Content) return;
|
||||
|
||||
vtkProp3D* assembly = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (!assembly) return;
|
||||
|
||||
vtkMatrix4x4* vmat = assembly->GetUserMatrix();
|
||||
if (!vmat) return;
|
||||
Matrix4f transform = VtkToMatrix4f(vmat);
|
||||
|
||||
// Update uLib model's affine transform
|
||||
if (m_Content->GetParent()) {
|
||||
Matrix4f localT = m_Content->GetParent()->GetWorldMatrix().inverse() * transform;
|
||||
m_Content->SetMatrix(localT);
|
||||
} else {
|
||||
m_Content->SetMatrix(transform);
|
||||
}
|
||||
|
||||
m_Content->Updated(); // Notify change
|
||||
}
|
||||
|
||||
|
||||
@@ -91,24 +125,7 @@ void vtkContainerBox::InstallPipe() {
|
||||
|
||||
// CUBE
|
||||
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
|
||||
|
||||
Vector3f p = c->GetPosition();
|
||||
// cube->SetCenter(p(0), p(1), p(2));
|
||||
// Vector4f p1 = c->GetWorldPoint(HPoint3f(0, 0, 0));
|
||||
// Vector4f p2 = c->GetWorldPoint(HPoint3f(1, 1, 1));
|
||||
// vtkSmartPointer<vtkLineSource> line =
|
||||
// vtkSmartPointer<vtkLineSource>::New(); line->SetPoint1(p1(0), p1(1),
|
||||
// p1(2)); line->SetPoint2(p2(0), p2(1), p2(2)); line->Update();
|
||||
// cube->SetBounds(line->GetOutput()->GetBounds());
|
||||
|
||||
vtkSmartPointer<vtkMatrix4x4> vmat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
Matrix4f transform = c->GetMatrix();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
vmat->SetElement(i, j, transform(i, j));
|
||||
|
||||
m_Cube->SetUserMatrix(vmat);
|
||||
|
||||
|
||||
vtkSmartPointer<vtkPolyDataMapper> mapper =
|
||||
vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
cube->SetBounds(0, 1, 0, 1, 0, 1);
|
||||
@@ -125,9 +142,6 @@ void vtkContainerBox::InstallPipe() {
|
||||
mapper->SetInputConnection(axes->GetOutputPort());
|
||||
mapper->Update();
|
||||
m_Axes->SetMapper(mapper);
|
||||
m_Axes->SetUserMatrix(vmat);
|
||||
Vector3f s = c->GetSize();
|
||||
// m_Axes->SetScale(s(0),s(1),s(2));
|
||||
m_Axes->GetProperty()->SetLineWidth(3);
|
||||
m_Axes->GetProperty()->SetAmbient(0.4);
|
||||
m_Axes->GetProperty()->SetSpecular(0);
|
||||
@@ -138,24 +152,16 @@ void vtkContainerBox::InstallPipe() {
|
||||
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||
mapper->SetInputConnection(axes->GetOutputPort());
|
||||
mapper->Update();
|
||||
m_Pivot->SetUserMatrix(vmat);
|
||||
m_Pivot->SetMapper(mapper);
|
||||
|
||||
Matrix4f pivotTransform = c->AffineTransform::GetWorldMatrix();
|
||||
vtkSmartPointer<vtkMatrix4x4> pmat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int j = 0; j < 4; ++j)
|
||||
pmat->SetElement(i, j, pivotTransform(i, j));
|
||||
m_Pivot->SetUserMatrix(pmat);
|
||||
s = c->GetScale();
|
||||
// m_Pivot->SetScale(s(0),s(1),s(2));
|
||||
m_Pivot->GetProperty()->SetLineWidth(3);
|
||||
m_Pivot->GetProperty()->SetAmbient(0.4);
|
||||
m_Pivot->GetProperty()->SetSpecular(0);
|
||||
|
||||
|
||||
this->SetProp(m_Cube);
|
||||
this->SetProp(m_Axes);
|
||||
this->SetProp(m_Pivot);
|
||||
|
||||
vtkProp3D* root = vtkProp3D::SafeDownCast(this->GetProp());
|
||||
if (root) {
|
||||
vtkNew<vtkMatrix4x4> vmat;
|
||||
Matrix4fToVtk(c->GetMatrix(), vmat);
|
||||
root->SetUserMatrix(vmat);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
@@ -43,15 +43,16 @@ public:
|
||||
|
||||
virtual class vtkPolyData *GetPolyData() const;
|
||||
|
||||
virtual void Update();
|
||||
virtual void contentUpdate();
|
||||
|
||||
virtual void Update();
|
||||
|
||||
protected:
|
||||
virtual void InstallPipe();
|
||||
|
||||
vtkActor *m_Cube;
|
||||
vtkActor *m_Axes;
|
||||
vtkActor *m_Pivot;
|
||||
// vtkActor *m_Pivot;
|
||||
|
||||
Content *m_Content;
|
||||
};
|
||||
|
||||
@@ -616,10 +616,11 @@ void vtkHandlerWidget::UpdateGizmoPosition() {
|
||||
mat_gizmo->SetElement(1, 3, center[1]);
|
||||
mat_gizmo->SetElement(2, 3, center[2]);
|
||||
} else if (m_Frame == GLOBAL) {
|
||||
::vtkMatrix4x4 *mat = this->Prop3D->GetMatrix();
|
||||
mat_gizmo->Identity();
|
||||
mat_gizmo->SetElement(0, 3, pos[0]);
|
||||
mat_gizmo->SetElement(1, 3, pos[1]);
|
||||
mat_gizmo->SetElement(2, 3, pos[2]);
|
||||
mat_gizmo->SetElement(0, 3, mat->GetElement(0, 3));
|
||||
mat_gizmo->SetElement(1, 3, mat->GetElement(1, 3));
|
||||
mat_gizmo->SetElement(2, 3, mat->GetElement(2, 3));
|
||||
} else if (m_Frame == CENTER) {
|
||||
mat_gizmo->Identity();
|
||||
mat_gizmo->SetElement(0, 3, center[0]);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "vtkViewport.h"
|
||||
#include <vtkPropAssembly.h>
|
||||
#include <vtkAssembly.h>
|
||||
#include <vtkPropCollection.h>
|
||||
#include <vtkProp3D.h>
|
||||
#include <vtkProp3DCollection.h>
|
||||
#include <vtkCamera.h>
|
||||
#include <algorithm>
|
||||
#include <vtkInteractorStyleTrackballCamera.h>
|
||||
@@ -126,6 +128,19 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
m_HandlerWidget->GetOverlayRenderer()->SetLayer(1);
|
||||
}
|
||||
|
||||
// Observe InteractionEvent to update the selected puppet 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) {
|
||||
if (p->IsSelected()) {
|
||||
p->Update();
|
||||
}
|
||||
}
|
||||
});
|
||||
m_HandlerWidget->AddObserver(vtkCommand::InteractionEvent, widgetInteractionCallback);
|
||||
|
||||
// Picking for selection
|
||||
m_Picker = vtkSmartPointer<vtkCellPicker>::New();
|
||||
vtkNew<vtkCallbackCommand> clickCallback;
|
||||
@@ -145,10 +160,14 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||
target = p;
|
||||
break;
|
||||
}
|
||||
auto* assembly = vtkPropAssembly::SafeDownCast(p->GetProp());
|
||||
if (assembly) {
|
||||
auto* propAssembly = vtkPropAssembly::SafeDownCast(p->GetProp());
|
||||
auto* actorAssembly = vtkAssembly::SafeDownCast(p->GetProp());
|
||||
vtkPropCollection* parts = nullptr;
|
||||
if (propAssembly) parts = propAssembly->GetParts();
|
||||
else if (actorAssembly) parts = actorAssembly->GetParts();
|
||||
|
||||
if (parts) {
|
||||
bool found = false;
|
||||
auto* parts = assembly->GetParts();
|
||||
parts->InitTraversal();
|
||||
for (int i=0; i<parts->GetNumberOfItems(); ++i) {
|
||||
if (parts->GetNextProp() == picked) {
|
||||
|
||||
Reference in New Issue
Block a user