#include <vtkActor.h>
#include <vtkAxesActor.h>
#include <vtkCamera.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkCubeAxesActor.h>
#include <vtkCubeSource.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkOrientationMarkerWidget.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include “modernTransformRepresentation.hpp”
#include “transformWidget.hpp”
// This does the actual work.
// Callback for the interaction
class transformCallback : public vtkCommand
{
public:
static transformCallback *New()
{
return new transformCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void *)
{
vtkSmartPointer<transformWidget> widget =
dynamic_cast<transformWidget *>(caller);
if (widget != nullptr && actor_ != nullptr)
{
if (auto rep = dynamic_cast<transformRepresentation *>(
widget->GetRepresentation()))
{
vtkNew<vtkTransform> trans;
rep->GetTransform(trans);
vtkNew<vtkMatrix4x4> newMatrix;
newMatrix->DeepCopy(trans->GetMatrix());
actor_->SetUserMatrix(newMatrix);
}
}
}
void setActor(vtkSmartPointer<vtkActor> actor)
{
actor_ = actor;
};
transformCallback() : actor_(nullptr)
{
}
private:
vtkSmartPointer actor_;
};
int main(int, char *)
{
vtkNew camera;
camera->SetParallelProjection(true);
vtkNew<vtkNamedColors> colors;
// A mainRenderer and render window
vtkNew<vtkRenderer> mainRenderer;
mainRenderer->SetBackground(colors->GetColor3d("BurlyWood").GetData());
mainRenderer->SetActiveCamera(camera);
mainRenderer->SetLayer(0);
vtkNew<vtkRenderer> frontRenderer;
frontRenderer->SetActiveCamera(camera);
frontRenderer->SetLayer(1);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetNumberOfLayers(2);
renderWindow->AddRenderer(mainRenderer);
renderWindow->AddRenderer(frontRenderer);
// An interactor
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
vtkNew<vtkSphereSource> sphereSource;
sphereSource->Update();
// Create a mapper and actor
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(sphereSource->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
// Cube Actor
vtkNew<vtkConeSource> cone;
cone->SetCenter(1.0, 1.0, 1.0);
cone->SetHeight(5);
cone->SetRadius(2.5);
cone->Update();
vtkNew<vtkPolyDataMapper> coneMapper;
coneMapper->SetInputData(cone->GetOutput());
vtkNew<vtkActor> coneActor;
coneActor->SetMapper(coneMapper);
coneActor->GetProperty()->SetColor(colors->GetColor3d("Banana").GetData());
coneActor->SetVisibility(true);
mainRenderer->AddActor(coneActor);
// Add transformWidget
vtkNew<modernTransformRepresentation> rep;
vtkNew<transformWidget> myWidget;
myWidget->SetInteractor(renderWindowInteractor);
myWidget->SetRepresentation(rep);
double bounds[6] = {-2.0, 4.0, -2.0, 4.0, -2.0, 4.0};
myWidget->GetRepresentation()->PlaceWidget(bounds);
vtkNew<transformCallback> callback;
callback->setActor(coneActor);
myWidget->AddObserver(vtkCommand::InteractionEvent, callback);
myWidget->SetEnabled(1);
// Add vtkCubeAxesActor
auto cubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
cubeAxesActor->SetBounds(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
cubeAxesActor->SetCamera(mainRenderer->GetActiveCamera());
mainRenderer->AddActor(cubeAxesActor);
// Axes Widget
auto vtkAxes = vtkSmartPointer<vtkAxesActor>::New();
auto axesWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
axesWidget->SetOrientationMarker(vtkAxes);
axesWidget->SetDefaultRenderer(mainRenderer);
axesWidget->SetInteractor(renderWindowInteractor);
axesWidget->SetViewport(0.0, 0.0, 0.20, 0.20);
axesWidget->SetEnabled(1);
axesWidget->InteractiveOff();
// Reset camera
double allBounds[6];
mainRenderer->ComputeVisiblePropBounds(allBounds);
if (vtkMath::AreBoundsInitialized(allBounds))
{
mainRenderer->ResetCamera(allBounds);
}
// Render
renderWindow->Render();
renderWindowInteractor->Initialize();
renderWindow->Render();
// Begin mouse interaction
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
#include <vtkActor.h>
#include <vtkCallbackCommand.h>
#include <vtkCollection.h>
#include <vtkCommand.h>
#include <vtkObjectFactory.h>
#include <vtkPropCollection.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkWidgetCallbackMapper.h>
#include <vtkWidgetEvent.h>
#include “simpleTransformRepresentation.hpp”
#include “transformWidget.hpp”
vtkStandardNewMacro(transformWidget);
transformWidget::transformWidget()
{
this->state_ = WIDGETSTATE::start;
// define widget events
{
this->CallbackMapper->SetCallbackMethod(
vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Select, this,
transformWidget::SelectAction);
this->CallbackMapper->SetCallbackMethod(
vtkCommand::LeftButtonReleaseEvent, vtkWidgetEvent::EndSelect, this,
transformWidget::EndSelectAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
vtkWidgetEvent::Move, this,
transformWidget::MoveAction);
this->keyEventCallbackCommand_ = vtkCallbackCommand::New();
this->keyEventCallbackCommand_->SetClientData(this);
this->keyEventCallbackCommand_->SetCallback(
transformWidget::ProcessKeyEvents);
}
}
transformWidget::~transformWidget()
{
this->keyEventCallbackCommand_->Delete();
}
void transformWidget::SetEnabled(int enabling)
{
const int enabled = this->Enabled;
if (enabling && !enabled)
{
// We do this step first because it sets the CurrentRenderer
vtkAbstractWidget::SetEnabled(enabling);
this->CreateDefaultRepresentation();
if (this->Parent)
{
this->Parent->AddObserver(vtkCommand::KeyPressEvent,
this->keyEventCallbackCommand_,
this->Priority);
this->Parent->AddObserver(vtkCommand::KeyReleaseEvent,
this->keyEventCallbackCommand_,
this->Priority);
}
else
{
this->Interactor->AddObserver(vtkCommand::KeyPressEvent,
this->keyEventCallbackCommand_,
this->Priority);
this->Interactor->AddObserver(vtkCommand::KeyReleaseEvent,
this->keyEventCallbackCommand_,
this->Priority);
}
// Add the actor
{
vtkNew<vtkPropCollection> propsCollection;
this->WidgetRep->GetActors(propsCollection);
vtkCollectionSimpleIterator sIt;
propsCollection->InitTraversal(sIt);
const int nProps = propsCollection->GetNumberOfItems();
for (int i = 0; i < nProps; i++)
{
vtkProp *actor =
vtkProp::SafeDownCast(propsCollection->GetNextProp(sIt));
if (actor != nullptr)
{
this->CurrentRenderer->AddActor(actor);
}
}
}
}
else if (!enabling && enabled)
{
if (this->Parent)
{
this->Parent->RemoveObserver(this->keyEventCallbackCommand_);
}
else
{
this->Interactor->RemoveObserver(this->keyEventCallbackCommand_);
}
// Remove the actor
{
vtkNew<vtkPropCollection> propsCollection;
this->WidgetRep->GetActors(propsCollection);
vtkCollectionSimpleIterator sIt;
propsCollection->InitTraversal(sIt);
const int nProps = propsCollection->GetNumberOfItems();
for (int i = 0; i < nProps; i++)
{
vtkProp *actor =
vtkProp::SafeDownCast(propsCollection->GetNextProp(sIt));
if (actor != nullptr)
{
this->CurrentRenderer->RemoveActor(actor);
}
}
}
// We do this step last because the CurrentRenderer is still useful
vtkAbstractWidget::SetEnabled(enabling);
}
this->Interactor->Render();
}
void transformWidget::CreateDefaultRepresentation()
{
if (!this->WidgetRep)
{
this->WidgetRep = simpleTransformRepresentation::New();
}
}
void transformWidget::SetRepresentation(transformRepresentation *rep)
{
this->Superclass::SetWidgetRepresentation(
vtkWidgetRepresentation::SafeDownCast(rep));
}
void transformWidget::PrintSelf(ostream &os, vtkIndent indent)
{
vtkAbstractWidget::PrintSelf(os, indent);
}
void transformWidget::SelectAction(vtkAbstractWidget *w)
{
auto self = reinterpret_cast<transformWidget *>(w);
if (self->WidgetRep->GetInteractionState() == INTERACTIONSTATE::outside)
{
return;
}
const int x = self->Interactor->GetEventPosition()[0];
const int y = self->Interactor->GetEventPosition()[1];
self->state_ = transformWidget::WIDGETSTATE::active;
self->GrabFocus(self->EventCallbackCommand);
double eventPos[2];
eventPos[0] = static_cast<double>(x);
eventPos[1] = static_cast<double>(y);
self->WidgetRep->StartWidgetInteraction(eventPos);
// start the interaction
self->EventCallbackCommand->SetAbortFlag(1);
self->StartInteraction();
self->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr);
self->Render();
}
void transformWidget::EndSelectAction(vtkAbstractWidget *w)
{
auto self = reinterpret_cast<transformWidget *>(w);
if (self->state_ == transformWidget::WIDGETSTATE::start)
{
return;
}
// Return state to not active
self->state_ = transformWidget::WIDGETSTATE::start;
self->ReleaseFocus();
self->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,
nullptr); // handles observe this
self->EventCallbackCommand->SetAbortFlag(1);
self->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
self->EndInteraction();
self->Render();
}
void transformWidget::MoveAction(vtkAbstractWidget *w)
{
auto self = reinterpret_cast<transformWidget *>(w);
const int x = self->Interactor->GetEventPosition()[0];
const int y = self->Interactor->GetEventPosition()[1];
if (self->state_ ==
transformWidget::WIDGETSTATE::start) // if is not active
{
self->Interactor->Disable(); // avoid extra renders
const int prevState = self->WidgetRep->GetInteractionState();
const int currState = self->WidgetRep->ComputeInteractionState(x, y);
int cursorChanged = 0;
{
if (currState == INTERACTIONSTATE::outside)
{
cursorChanged = self->RequestCursorShape(VTK_CURSOR_DEFAULT);
}
else
{
cursorChanged = self->RequestCursorShape(VTK_CURSOR_HAND);
}
}
self->WidgetRep->Highlight(1);
self->Interactor->Enable(); // avoid extra renders
if (cursorChanged || (prevState != currState))
{
self->Render();
}
}
else // if is active
{
double e[2];
e[0] = static_cast<double>(x);
e[1] = static_cast<double>(y);
self->InvokeEvent(vtkCommand::MouseMoveEvent,
nullptr); // handles observe this
self->WidgetRep->WidgetInteraction(e);
self->EventCallbackCommand->SetAbortFlag(1);
self->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
self->Render();
}
}
void transformWidget::ProcessKeyEvents(vtkObject *, unsigned long, void *,
void *)
{
}
#pragma once
#include “vtkAbstractWidget.h”
class vtkCallbackCommand;
class transformRepresentation;
class transformWidget : public vtkAbstractWidget
{
public:
static transformWidget *New();
vtkTypeMacro(transformWidget, vtkAbstractWidget);
void PrintSelf(ostream &os, vtkIndent indent) override;
void SetEnabled(int enabling) override;
void CreateDefaultRepresentation() override;
void SetRepresentation(transformRepresentation *rep);
protected:
transformWidget();
~transformWidget() override;
static void SelectAction(vtkAbstractWidget *w);
static void EndSelectAction(vtkAbstractWidget *w);
static void MoveAction(vtkAbstractWidget *w);
static void ProcessKeyEvents(vtkObject *, unsigned long, void *, void *);
private:
enum WIDGETSTATE
{
start = 0,
active
};
int state_;
vtkCallbackCommand *keyEventCallbackCommand_;
transformWidget(const transformWidget &) = delete;
void operator=(const transformWidget &) = delete;
};