fix transforms from handler
This commit is contained in:
@@ -14,6 +14,8 @@
|
|||||||
ContextPanel::ContextPanel(QWidget* parent)
|
ContextPanel::ContextPanel(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_context(nullptr) {
|
, m_context(nullptr) {
|
||||||
|
this->setObjectName("ContextPanel");
|
||||||
|
this->setAttribute(Qt::WA_StyledBackground);
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
m_layout->setContentsMargins(0, 0, 0, 0);
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_layout->setSpacing(0);
|
m_layout->setSpacing(0);
|
||||||
@@ -88,6 +90,5 @@ void ContextPanel::onSelectionChanged(const QItemSelection& selected, const QIte
|
|||||||
}
|
}
|
||||||
|
|
||||||
emit objectSelected(target);
|
emit objectSelected(target);
|
||||||
|
|
||||||
m_propertiesPanel->setObject(target);
|
m_propertiesPanel->setObject(target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#include "StyleManager.h"
|
#include "StyleManager.h"
|
||||||
|
|
||||||
MainPanel::MainPanel(QWidget* parent) : QWidget(parent), m_context(nullptr), m_mainVtkContext(nullptr) {
|
MainPanel::MainPanel(QWidget* parent) : QWidget(parent), m_context(nullptr), m_mainVtkContext(nullptr) {
|
||||||
|
this->setObjectName("MainPanel");
|
||||||
|
this->setAttribute(Qt::WA_StyledBackground);
|
||||||
auto* mainLayout = new QVBoxLayout(this);
|
auto* mainLayout = new QVBoxLayout(this);
|
||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
mainLayout->setSpacing(0);
|
mainLayout->setSpacing(0);
|
||||||
@@ -158,7 +160,6 @@ void MainPanel::setContext(uLib::ObjectsContext* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uLib::Object::connect(context, &uLib::Object::Updated, [viewport]() {
|
uLib::Object::connect(context, &uLib::Object::Updated, [viewport]() {
|
||||||
viewport->ZoomAuto();
|
|
||||||
viewport->Render();
|
viewport->Render();
|
||||||
});
|
});
|
||||||
viewport->ZoomAuto();
|
viewport->ZoomAuto();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
PropertiesPanel::PropertiesPanel(QWidget* parent) : QWidget(parent) {
|
PropertiesPanel::PropertiesPanel(QWidget* parent) : QWidget(parent) {
|
||||||
this->setObjectName("PropertiesPanel");
|
this->setObjectName("PropertiesPanel");
|
||||||
|
this->setAttribute(Qt::WA_StyledBackground);
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
m_layout->setContentsMargins(0, 0, 0, 0);
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_layout->setSpacing(0);
|
m_layout->setSpacing(0);
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ QLabel#TitleLabel { font-weight: bold; margin-left: 2px; }
|
|||||||
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #ccc; }
|
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #ccc; }
|
||||||
QToolButton#PaneCloseButton:hover { color: white; background: #c42b1c; }
|
QToolButton#PaneCloseButton:hover { color: white; background: #c42b1c; }
|
||||||
|
|
||||||
/* Viewport & Properties Panels */
|
/* Global & Panel Backgrounds */
|
||||||
QWidget#DisplayPropertiesPanel, QWidget#PropertiesPanel { background-color: #252526; border-left: 1px solid #3e3e42; }
|
QMainWindow, QWidget#MainPanel { background-color: #1e1e1e; }
|
||||||
|
QWidget#DisplayPropertiesPanel, QWidget#PropertiesPanel, QWidget#ContextPanel { background-color: #252526; border-left: 1px solid #3e3e42; }
|
||||||
QPushButton#DisplayToggleBtn { background-color: #333337; border: 1px solid #3e3e42; border-radius: 2px; color: #f1f1f1; font-size: 11px; }
|
QPushButton#DisplayToggleBtn { background-color: #333337; border: 1px solid #3e3e42; border-radius: 2px; color: #f1f1f1; font-size: 11px; }
|
||||||
QPushButton#DisplayToggleBtn:checked { background-color: #0078d7; color: white; border-color: #005a9e; font-weight: bold; }
|
QPushButton#DisplayToggleBtn:checked { background-color: #0078d7; color: white; border-color: #005a9e; font-weight: bold; }
|
||||||
QPushButton#DisplayToggleBtn:hover { border-color: #0078d7; }
|
QPushButton#DisplayToggleBtn:hover { border-color: #0078d7; }
|
||||||
@@ -53,8 +54,9 @@ QLabel#TitleLabel { font-weight: bold; margin-left: 2px; }
|
|||||||
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #666; }
|
QToolButton#PaneCloseButton { border: none; font-weight: bold; background: transparent; color: #666; }
|
||||||
QToolButton#PaneCloseButton:hover { color: white; background: #e81123; }
|
QToolButton#PaneCloseButton:hover { color: white; background: #e81123; }
|
||||||
|
|
||||||
/* Viewport & Properties Panels */
|
/* Global & Panel Backgrounds */
|
||||||
QWidget#DisplayPropertiesPanel { background-color: #ffffff; border-left: 1px solid #cccccc; }
|
QMainWindow, QWidget#MainPanel { background-color: #f3f3f3; }
|
||||||
|
QWidget#DisplayPropertiesPanel, QWidget#PropertiesPanel, QWidget#ContextPanel { background-color: #ffffff; border-left: 1px solid #cccccc; }
|
||||||
QPushButton#DisplayToggleBtn { background-color: #ffffff; border: 1px solid #cccccc; border-radius: 2px; color: #333; font-size: 11px; }
|
QPushButton#DisplayToggleBtn { background-color: #ffffff; border: 1px solid #cccccc; border-radius: 2px; color: #333; font-size: 11px; }
|
||||||
QPushButton#DisplayToggleBtn:checked { background-color: #0078d7; color: white; border-color: #005a9e; font-weight: bold; }
|
QPushButton#DisplayToggleBtn:checked { background-color: #0078d7; color: white; border-color: #005a9e; font-weight: bold; }
|
||||||
QPushButton#DisplayToggleBtn:hover { border-color: #0078d7; }
|
QPushButton#DisplayToggleBtn:hover { border-color: #0078d7; }
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ ObjectsContext::~ObjectsContext() {}
|
|||||||
void ObjectsContext::AddObject(Object* obj) {
|
void ObjectsContext::AddObject(Object* obj) {
|
||||||
if (obj && std::find(m_objects.begin(), m_objects.end(), obj) == m_objects.end()) {
|
if (obj && std::find(m_objects.begin(), m_objects.end(), obj) == m_objects.end()) {
|
||||||
m_objects.push_back(obj);
|
m_objects.push_back(obj);
|
||||||
|
// Connect child's update to context's update to trigger re-renders
|
||||||
|
Object::connect(obj, &Object::Updated, this, &Object::Updated);
|
||||||
ULIB_SIGNAL_EMIT(ObjectsContext::ObjectAdded, obj);
|
ULIB_SIGNAL_EMIT(ObjectsContext::ObjectAdded, obj);
|
||||||
this->Updated(); // Signal that the context has been updated
|
this->Updated(); // Signal that the context has been updated
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ public:
|
|||||||
if (*m_value != value) {
|
if (*m_value != value) {
|
||||||
*m_value = value;
|
*m_value = value;
|
||||||
ULIB_SIGNAL_EMIT(Property<T>::PropertyChanged);
|
ULIB_SIGNAL_EMIT(Property<T>::PropertyChanged);
|
||||||
|
this->Updated();
|
||||||
|
if (m_owner) m_owner->Updated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public:
|
|||||||
|
|
||||||
Matrix3f GetRotation() const { return this->m_T.rotation(); }
|
Matrix3f GetRotation() const { return this->m_T.rotation(); }
|
||||||
|
|
||||||
void Translate(const Vector3f v) { this->m_T.pretranslate(v); }
|
void Translate(const Vector3f v) { this->m_T.translate(v); }
|
||||||
|
|
||||||
void Scale(const Vector3f v) { this->m_T.scale(v); }
|
void Scale(const Vector3f v) { this->m_T.scale(v); }
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ set(TESTS
|
|||||||
vtkQuadMeshTest
|
vtkQuadMeshTest
|
||||||
vtkVoxImageTest
|
vtkVoxImageTest
|
||||||
vtkVoxImageInteractiveTest
|
vtkVoxImageInteractiveTest
|
||||||
|
vtkContainerBoxTest2
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
|
|||||||
45
src/Vtk/Math/testing/vtkContainerBoxTest2.cpp
Normal file
45
src/Vtk/Math/testing/vtkContainerBoxTest2.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
// All rights reserved
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#include "Vtk/uLibVtkViewer.h"
|
||||||
|
#include "Math/ContainerBox.h"
|
||||||
|
#include "Math/Units.h"
|
||||||
|
#include "Vtk/vtkContainerBox.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace uLib;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Creating ContainerBox..." << std::endl;
|
||||||
|
ContainerBox box(Vector3f(1.0, 1.0, 1.0)); // 1x1x1 unit box
|
||||||
|
box.SetInstanceName("MyTestBox");
|
||||||
|
|
||||||
|
std::cout << "Creating VTK representation..." << std::endl;
|
||||||
|
Vtk::vtkContainerBox v_box(&box);
|
||||||
|
v_box.SetRepresentation(Vtk::Puppet::Wireframe);
|
||||||
|
v_box.SetColor(1.0, 0.0, 0.0); // Red
|
||||||
|
|
||||||
|
// // 1. Initial Visualization setup (handled by Viewer)
|
||||||
|
|
||||||
|
// // 3. Apply scaling of half the size along x
|
||||||
|
// std::cout << "Applying scaling of 0.5 along X..." << std::endl;
|
||||||
|
// box.Scale(Vector3f(0.5f, 1.0f, 1.0f));
|
||||||
|
// box.Updated();
|
||||||
|
|
||||||
|
// // 2. Apply rotation along Y axes of 45 deg
|
||||||
|
// std::cout << "Applying 45 deg rotation along Y..." << std::endl;
|
||||||
|
// // box.Rotate(45.0_deg, Vector3f::UnitY());
|
||||||
|
// box.EulerYZYRotate(Vector3f(45.0_deg, 0, 0));
|
||||||
|
// box.Updated();
|
||||||
|
|
||||||
|
std::cout << "Starting viewer (close window to exit)..." << std::endl;
|
||||||
|
Vtk::Viewer viewer;
|
||||||
|
viewer.AddPuppet(v_box);
|
||||||
|
viewer.Start();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -71,11 +71,31 @@ vtkHandlerWidget::vtkHandlerWidget() {
|
|||||||
this->m_TranslationEnabled = true;
|
this->m_TranslationEnabled = true;
|
||||||
this->m_RotationEnabled = true;
|
this->m_RotationEnabled = true;
|
||||||
this->m_ScalingEnabled = true;
|
this->m_ScalingEnabled = true;
|
||||||
|
this->m_BaseMatrix = vtkSmartPointer<::vtkMatrix4x4>::New();
|
||||||
|
this->m_BaseMatrix->Identity();
|
||||||
this->CreateGizmos();
|
this->CreateGizmos();
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkHandlerWidget::~vtkHandlerWidget() {}
|
vtkHandlerWidget::~vtkHandlerWidget() {}
|
||||||
|
|
||||||
|
void vtkHandlerWidget::SetProp3D(::vtkProp3D *prop) {
|
||||||
|
if (this->Prop3D == prop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->Prop3D = prop;
|
||||||
|
if (this->Prop3D) {
|
||||||
|
// Initialize m_BaseMatrix from the object's current matrix
|
||||||
|
if (this->Prop3D->GetUserMatrix()) {
|
||||||
|
this->m_BaseMatrix->DeepCopy(this->Prop3D->GetUserMatrix());
|
||||||
|
} else {
|
||||||
|
this->m_BaseMatrix->Identity();
|
||||||
|
}
|
||||||
|
this->m_TransformChain.clear(); // Clear any previous transform chain
|
||||||
|
this->UpdateGizmoPosition();
|
||||||
|
}
|
||||||
|
this->Modified();
|
||||||
|
}
|
||||||
|
|
||||||
void vtkHandlerWidget::SetEnabled(int enabling) {
|
void vtkHandlerWidget::SetEnabled(int enabling) {
|
||||||
if (enabling) {
|
if (enabling) {
|
||||||
if (this->Enabled)
|
if (this->Enabled)
|
||||||
@@ -109,6 +129,8 @@ void vtkHandlerWidget::SetEnabled(int enabling) {
|
|||||||
this->Priority);
|
this->Priority);
|
||||||
i->AddObserver(::vtkCommand::RenderEvent, this->EventCallbackCommand,
|
i->AddObserver(::vtkCommand::RenderEvent, this->EventCallbackCommand,
|
||||||
this->Priority);
|
this->Priority);
|
||||||
|
i->AddObserver(::vtkCommand::KeyPressEvent, this->EventCallbackCommand,
|
||||||
|
this->Priority);
|
||||||
|
|
||||||
this->UpdateGizmoPosition();
|
this->UpdateGizmoPosition();
|
||||||
|
|
||||||
@@ -181,6 +203,37 @@ void vtkHandlerWidget::ProcessEvents(::vtkObject *caller, unsigned long event,
|
|||||||
case ::vtkCommand::RenderEvent:
|
case ::vtkCommand::RenderEvent:
|
||||||
self->UpdateGizmoPosition();
|
self->UpdateGizmoPosition();
|
||||||
break;
|
break;
|
||||||
|
case ::vtkCommand::KeyPressEvent:
|
||||||
|
self->OnKeyPress();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vtkHandlerWidget::OnKeyPress() {
|
||||||
|
std::string key = this->Interactor->GetKeySym();
|
||||||
|
bool ctrl = (this->Interactor->GetControlKey() != 0);
|
||||||
|
|
||||||
|
if (ctrl && key == "z") {
|
||||||
|
if (!this->m_TransformChain.empty()) {
|
||||||
|
std::cout << "Undoing last transform action..." << std::endl;
|
||||||
|
this->m_TransformChain.pop_back();
|
||||||
|
|
||||||
|
// Update object from chain
|
||||||
|
vtkNew<vtkTransform> total;
|
||||||
|
total->PostMultiply();
|
||||||
|
total->SetMatrix(this->m_BaseMatrix.GetPointer());
|
||||||
|
for (auto& t : m_TransformChain) {
|
||||||
|
total->Concatenate(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->Prop3D && this->Prop3D->GetUserMatrix()) {
|
||||||
|
this->Prop3D->GetUserMatrix()->DeepCopy(total->GetMatrix());
|
||||||
|
this->Prop3D->Modified();
|
||||||
|
this->UpdateGizmoPosition();
|
||||||
|
this->InvokeEvent(::vtkCommand::InteractionEvent, nullptr);
|
||||||
|
this->Interactor->Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +282,17 @@ void vtkHandlerWidget::OnLeftButtonDown() {
|
|||||||
vtkNew<vtkMatrix4x4> vmat;
|
vtkNew<vtkMatrix4x4> vmat;
|
||||||
this->Prop3D->SetUserMatrix(vmat);
|
this->Prop3D->SetUserMatrix(vmat);
|
||||||
}
|
}
|
||||||
this->m_InitialTransform->SetMatrix(this->Prop3D->GetUserMatrix());
|
|
||||||
|
// If the chain is empty, initialize base from current state?
|
||||||
|
// Actually, if we just started selecting this object, we should have initialized BaseMatrix.
|
||||||
|
// For now, let's keep m_InitialTransform as the state BEFORE this drag
|
||||||
|
vtkNew<vtkTransform> current;
|
||||||
|
current->PostMultiply();
|
||||||
|
current->SetMatrix(this->m_BaseMatrix.GetPointer());
|
||||||
|
for (auto& t : m_TransformChain) {
|
||||||
|
current->Concatenate(t);
|
||||||
|
}
|
||||||
|
this->m_InitialTransform->SetMatrix(current->GetMatrix());
|
||||||
}
|
}
|
||||||
this->EventCallbackCommand->SetAbortFlag(1);
|
this->EventCallbackCommand->SetAbortFlag(1);
|
||||||
this->InvokeEvent(::vtkCommand::StartInteractionEvent, nullptr);
|
this->InvokeEvent(::vtkCommand::StartInteractionEvent, nullptr);
|
||||||
@@ -241,6 +304,27 @@ void vtkHandlerWidget::OnLeftButtonUp() {
|
|||||||
if (this->Interaction == IDLE)
|
if (this->Interaction == IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Finalize the current interaction into the chain
|
||||||
|
int X = this->Interactor->GetEventPosition()[0];
|
||||||
|
int Y = this->Interactor->GetEventPosition()[1];
|
||||||
|
|
||||||
|
// We need to re-calculate the final 'op' to store it
|
||||||
|
// Actually, we could have stored it in OnMouseMove, but let's re-calculate or
|
||||||
|
// just capture the delta between m_InitialTransform and current UserMatrix.
|
||||||
|
if (this->Prop3D && this->Prop3D->GetUserMatrix()) {
|
||||||
|
vtkNew<vtkMatrix4x4> inv;
|
||||||
|
vtkMatrix4x4::Invert(this->m_InitialTransform->GetMatrix(), inv);
|
||||||
|
|
||||||
|
vtkNew<vtkMatrix4x4> final_op_mat;
|
||||||
|
vtkMatrix4x4::Multiply4x4(this->Prop3D->GetUserMatrix(), inv, final_op_mat);
|
||||||
|
|
||||||
|
vtkNew<vtkTransform> final_op;
|
||||||
|
final_op->SetMatrix(final_op_mat);
|
||||||
|
|
||||||
|
this->m_TransformChain.push_back(final_op);
|
||||||
|
std::cout << "Action finalized. Chain size: " << this->m_TransformChain.size() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
this->Interaction = IDLE;
|
this->Interaction = IDLE;
|
||||||
this->EventCallbackCommand->SetAbortFlag(1);
|
this->EventCallbackCommand->SetAbortFlag(1);
|
||||||
this->InvokeEvent(::vtkCommand::EndInteractionEvent, nullptr);
|
this->InvokeEvent(::vtkCommand::EndInteractionEvent, nullptr);
|
||||||
@@ -390,19 +474,46 @@ void vtkHandlerWidget::OnMouseMove() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCALE_X:
|
case SCALE_X:
|
||||||
mag = get_motion_magnitude(gx, gpos);
|
|
||||||
op->Scale(std::max(0.1, 1.0 + mag), 1.0, 1.0);
|
|
||||||
// Note: Scale might need orient_inv/orient if we want to scale along local axes nicely
|
|
||||||
// but the current logic for scale already handles this if we concatenated basis.
|
|
||||||
// For now we keep it simple since user only reported rotation issue.
|
|
||||||
break;
|
|
||||||
case SCALE_Y:
|
case SCALE_Y:
|
||||||
mag = get_motion_magnitude(gy, gpos);
|
|
||||||
op->Scale(1.0, std::max(0.1, 1.0 + mag), 1.0);
|
|
||||||
break;
|
|
||||||
case SCALE_Z:
|
case SCALE_Z:
|
||||||
mag = get_motion_magnitude(gz, gpos);
|
{
|
||||||
op->Scale(1.0, 1.0, std::max(0.1, 1.0 + mag));
|
// 1. Calculate magnitude
|
||||||
|
if (this->Interaction == SCALE_X) mag = get_motion_magnitude(gx, gpos);
|
||||||
|
else if (this->Interaction == SCALE_Y) mag = get_motion_magnitude(gy, gpos);
|
||||||
|
else mag = get_motion_magnitude(gz, gpos);
|
||||||
|
|
||||||
|
double s = std::max(0.1, 1.0 + mag);
|
||||||
|
|
||||||
|
// 2. Build a strictly orthonormal basis from the gizmo axes
|
||||||
|
double X[3] = {gx[0], gx[1], gx[2]};
|
||||||
|
double Y[3] = {gy[0], gy[1], gy[2]};
|
||||||
|
double Z[3];
|
||||||
|
|
||||||
|
vtkMath::Normalize(X);
|
||||||
|
double dot = vtkMath::Dot(X, Y);
|
||||||
|
for(int i=0; i<3; ++i) Y[i] -= dot * X[i];
|
||||||
|
vtkMath::Normalize(Y);
|
||||||
|
vtkMath::Cross(X, Y, Z); // Z is now orthogonal to X and Y
|
||||||
|
|
||||||
|
vtkNew<vtkMatrix4x4> basis;
|
||||||
|
basis->Identity();
|
||||||
|
for(int i=0; i<3; ++i) {
|
||||||
|
basis->SetElement(i, 0, X[i]);
|
||||||
|
basis->SetElement(i, 1, Y[i]);
|
||||||
|
basis->SetElement(i, 2, Z[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkNew<vtkMatrix4x4> basis_inv;
|
||||||
|
vtkMatrix4x4::Invert(basis, basis_inv);
|
||||||
|
|
||||||
|
// 3. Assemble oriented scale: T(gpos) * basis * S * basis_inv * T(-gpos)
|
||||||
|
// With PostMultiply: Result = T(gpos) * (basis * (S * (basis_inv * (T(-gpos) * Ident))))
|
||||||
|
op->Concatenate(basis_inv);
|
||||||
|
if (this->Interaction == SCALE_X) op->Scale(s, 1.0, 1.0);
|
||||||
|
else if (this->Interaction == SCALE_Y) op->Scale(1.0, s, 1.0);
|
||||||
|
else op->Scale(1.0, 1.0, s);
|
||||||
|
op->Concatenate(basis);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ROT_CAM: {
|
case ROT_CAM: {
|
||||||
double camPos[3];
|
double camPos[3];
|
||||||
@@ -428,16 +539,15 @@ void vtkHandlerWidget::OnMouseMove() {
|
|||||||
|
|
||||||
op->Translate(gpos[0], gpos[1], gpos[2]);
|
op->Translate(gpos[0], gpos[1], gpos[2]);
|
||||||
|
|
||||||
// Apply op on top of the initial object state
|
// Total transform = Base * Chain * Interaction
|
||||||
vtkNew<vtkTransform> final_t;
|
vtkNew<vtkTransform> total;
|
||||||
final_t->PostMultiply();
|
total->PostMultiply();
|
||||||
final_t->SetMatrix(this->m_InitialTransform->GetMatrix());
|
total->SetMatrix(this->m_InitialTransform->GetMatrix()); // m_InitialTransform is already Base*Chain
|
||||||
final_t->Concatenate(op);
|
total->Concatenate(op);
|
||||||
|
|
||||||
vtkMatrix4x4* targetMat = this->Prop3D->GetUserMatrix();
|
vtkMatrix4x4* targetMat = this->Prop3D->GetUserMatrix();
|
||||||
if (targetMat) {
|
if (targetMat) {
|
||||||
targetMat->DeepCopy(final_t->GetMatrix());
|
targetMat->DeepCopy(total->GetMatrix());
|
||||||
// std::cout << "Updated UserMatrix for interaction " << this->Interaction << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->Prop3D->Modified();
|
this->Prop3D->Modified();
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include <vtk3DWidget.h>
|
#include <vtk3DWidget.h>
|
||||||
#include <vtkSmartPointer.h>
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkMatrix4x4.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// Forward declarations of VTK classes in global namespace
|
// Forward declarations of VTK classes in global namespace
|
||||||
class vtkActor;
|
class vtkActor;
|
||||||
@@ -39,6 +41,7 @@ class vtkCellPicker;
|
|||||||
class vtkTransform;
|
class vtkTransform;
|
||||||
class vtkObject;
|
class vtkObject;
|
||||||
class vtkPlane;
|
class vtkPlane;
|
||||||
|
class vtkProp3D;
|
||||||
class vtkRenderWindowInteractor;
|
class vtkRenderWindowInteractor;
|
||||||
|
|
||||||
namespace uLib {
|
namespace uLib {
|
||||||
@@ -137,6 +140,13 @@ protected:
|
|||||||
double m_StartPickPosition[3];
|
double m_StartPickPosition[3];
|
||||||
vtkSmartPointer<::vtkTransform> m_InitialTransform;
|
vtkSmartPointer<::vtkTransform> m_InitialTransform;
|
||||||
|
|
||||||
|
std::vector<vtkSmartPointer<::vtkTransform>> m_TransformChain;
|
||||||
|
vtkSmartPointer<::vtkMatrix4x4> m_BaseMatrix;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void SetProp3D(::vtkProp3D *prop) override;
|
||||||
|
void OnKeyPress();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vtkHandlerWidget(const vtkHandlerWidget &) = delete;
|
vtkHandlerWidget(const vtkHandlerWidget &) = delete;
|
||||||
void operator=(const vtkHandlerWidget &) = delete;
|
void operator=(const vtkHandlerWidget &) = delete;
|
||||||
|
|||||||
Reference in New Issue
Block a user