Compare commits
2 Commits
7d4acaef6d
...
e4a8499104
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4a8499104 | ||
|
|
6a65fe94c8 |
@@ -84,6 +84,7 @@ macro(uLib_add_tests name)
|
|||||||
foreach(tn ${TESTS})
|
foreach(tn ${TESTS})
|
||||||
add_executable(${tn} ${tn}.cpp)
|
add_executable(${tn} ${tn}.cpp)
|
||||||
add_test(NAME ${tn} COMMAND ${tn})
|
add_test(NAME ${tn} COMMAND ${tn})
|
||||||
|
set_tests_properties(${tn} PROPERTIES ENVIRONMENT "CTEST_PROJECT_NAME=uLib;QT_QPA_PLATFORM=offscreen")
|
||||||
|
|
||||||
target_link_libraries(${tn} ${LIBRARIES})
|
target_link_libraries(${tn} ${LIBRARIES})
|
||||||
|
|
||||||
|
|||||||
1
Testing/Temporary/CTestCostData.txt
Normal file
1
Testing/Temporary/CTestCostData.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
---
|
||||||
3
Testing/Temporary/LastTest.log
Normal file
3
Testing/Temporary/LastTest.log
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Start testing: Mar 25 18:59 UTC
|
||||||
|
----------------------------------------------------------
|
||||||
|
End testing: Mar 25 18:59 UTC
|
||||||
@@ -52,7 +52,7 @@ public:
|
|||||||
else
|
else
|
||||||
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
|
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
|
||||||
}
|
}
|
||||||
std::cout << "DataAllocator Constructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
// std::cout << "DataAllocator Constructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataAllocator(const DataAllocator<T> &other)
|
DataAllocator(const DataAllocator<T> &other)
|
||||||
@@ -79,11 +79,11 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
std::cout << "DataAllocator CopyConstructor: from=" << other.m_RamData << " to=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
// std::cout << "DataAllocator CopyConstructor: from=" << other.m_RamData << " to=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
~DataAllocator() {
|
~DataAllocator() {
|
||||||
std::cout << "DataAllocator Destructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
// std::cout << "DataAllocator Destructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
||||||
if (m_RamData) {
|
if (m_RamData) {
|
||||||
if (m_OwnsObjects)
|
if (m_OwnsObjects)
|
||||||
delete[] m_RamData;
|
delete[] m_RamData;
|
||||||
@@ -132,7 +132,7 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
std::cout << "DataAllocator AssigmentOp: otherPtr=" << other.m_RamData << " thisPtr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
// std::cout << "DataAllocator AssigmentOp: otherPtr=" << other.m_RamData << " thisPtr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ public:
|
|||||||
if (m_Size == size)
|
if (m_Size == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cout << "DataAllocator Resize: from=" << m_Size << " to=" << size << " ptr=" << m_RamData << " own=" << m_OwnsObjects << std::endl;
|
// std::cout << "DataAllocator Resize: from=" << m_Size << " to=" << size << " ptr=" << m_RamData << " own=" << m_OwnsObjects << std::endl;
|
||||||
|
|
||||||
T *newRam = nullptr;
|
T *newRam = nullptr;
|
||||||
T *newVram = nullptr;
|
T *newVram = nullptr;
|
||||||
|
|||||||
@@ -70,14 +70,17 @@ public:
|
|||||||
|
|
||||||
// Implementations of Property methods
|
// Implementations of Property methods
|
||||||
void Object::RegisterProperty(PropertyBase* prop) {
|
void Object::RegisterProperty(PropertyBase* prop) {
|
||||||
if (prop) d->m_Properties.push_back(prop);
|
if (prop) {
|
||||||
|
d->m_Properties.push_back(prop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::RegisterDynamicProperty(PropertyBase* prop) {
|
void Object::RegisterDynamicProperty(PropertyBase* prop) {
|
||||||
if (prop) {
|
if (prop) {
|
||||||
|
for (auto* existing : d->m_DynamicProperties) {
|
||||||
|
if (existing == prop) return;
|
||||||
|
}
|
||||||
d->m_DynamicProperties.push_back(prop);
|
d->m_DynamicProperties.push_back(prop);
|
||||||
// Note: prop already added itself to m_Properties
|
|
||||||
// during its own constructor call to owner->RegisterProperty()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,14 +120,12 @@ template void Object::serialize(Archive::log_archive &, const unsigned int);
|
|||||||
|
|
||||||
Object::Object() : d(new ObjectPrivate) {
|
Object::Object() : d(new ObjectPrivate) {
|
||||||
d->m_SignalsBlocked = false;
|
d->m_SignalsBlocked = false;
|
||||||
std::cout << "Object Constructor: created d=" << d << std::endl;
|
|
||||||
}
|
}
|
||||||
Object::Object(const Object ©) : d(new ObjectPrivate) {
|
Object::Object(const Object ©) : d(new ObjectPrivate) {
|
||||||
if (copy.d) {
|
if (copy.d) {
|
||||||
d->m_InstanceName = copy.d->m_InstanceName;
|
d->m_InstanceName = copy.d->m_InstanceName;
|
||||||
d->m_SignalsBlocked = copy.d->m_SignalsBlocked;
|
d->m_SignalsBlocked = copy.d->m_SignalsBlocked;
|
||||||
}
|
}
|
||||||
std::cout << "Object CopyConstructor: created d=" << d << " from copy.d=" << copy.d << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object& Object::operator=(const Object &other) {
|
Object& Object::operator=(const Object &other) {
|
||||||
@@ -140,7 +141,6 @@ Object& Object::operator=(const Object &other) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object::~Object() {
|
Object::~Object() {
|
||||||
std::cout << "Object Destructor: deleting d=" << d << " name=" << d->m_InstanceName << std::endl;
|
|
||||||
for (auto* p : d->m_DynamicProperties) {
|
for (auto* p : d->m_DynamicProperties) {
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ ActionInitialization::ActionInitialization(EmitterPrimary *emitter, SimulationCo
|
|||||||
|
|
||||||
ActionInitialization::~ActionInitialization() {}
|
ActionInitialization::~ActionInitialization() {}
|
||||||
|
|
||||||
|
// Lightweight wrapper to avoid double-free in Geant4 EventManager
|
||||||
|
class SteppingActionWrapper : public G4UserSteppingAction {
|
||||||
|
public:
|
||||||
|
SteppingActionWrapper(SteppingAction *real) : m_Real(real) {}
|
||||||
|
virtual void UserSteppingAction(const G4Step* step) override { m_Real->UserSteppingAction(step); }
|
||||||
|
private:
|
||||||
|
SteppingAction *m_Real;
|
||||||
|
};
|
||||||
|
|
||||||
void ActionInitialization::BuildForMaster() const {}
|
void ActionInitialization::BuildForMaster() const {}
|
||||||
|
|
||||||
void ActionInitialization::Build() const {
|
void ActionInitialization::Build() const {
|
||||||
@@ -23,8 +32,10 @@ void ActionInitialization::Build() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SteppingAction *sa = new SteppingAction(m_Context);
|
SteppingAction *sa = new SteppingAction(m_Context);
|
||||||
SetUserAction(static_cast<G4UserSteppingAction*>(sa));
|
// EventManager will delete sa via this slot
|
||||||
SetUserAction(static_cast<G4UserEventAction*>(sa));
|
SetUserAction(static_cast<G4UserEventAction*>(sa));
|
||||||
|
// EventManager will delete the wrapper, leaving sa alive to be deleted once.
|
||||||
|
SetUserAction(new SteppingActionWrapper(sa));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Geant
|
} // namespace Geant
|
||||||
|
|||||||
@@ -18,6 +18,14 @@ DetectorActionInitialization::DetectorActionInitialization(EmitterPrimary *emitt
|
|||||||
|
|
||||||
DetectorActionInitialization::~DetectorActionInitialization() {}
|
DetectorActionInitialization::~DetectorActionInitialization() {}
|
||||||
|
|
||||||
|
class DetectorSteppingActionWrapper : public G4UserSteppingAction {
|
||||||
|
public:
|
||||||
|
DetectorSteppingActionWrapper(DetectorSteppingAction *real) : m_Real(real) {}
|
||||||
|
virtual void UserSteppingAction(const G4Step* step) override { m_Real->UserSteppingAction(step); }
|
||||||
|
private:
|
||||||
|
DetectorSteppingAction *m_Real;
|
||||||
|
};
|
||||||
|
|
||||||
void DetectorActionInitialization::BuildForMaster() const {}
|
void DetectorActionInitialization::BuildForMaster() const {}
|
||||||
|
|
||||||
void DetectorActionInitialization::Build() const {
|
void DetectorActionInitialization::Build() const {
|
||||||
@@ -34,8 +42,10 @@ void DetectorActionInitialization::Build() const {
|
|||||||
if (m_Output) {
|
if (m_Output) {
|
||||||
DetectorSteppingAction *sa = new DetectorSteppingAction(m_Output, m_Planes);
|
DetectorSteppingAction *sa = new DetectorSteppingAction(m_Output, m_Planes);
|
||||||
sa->SetVerbosity(m_Verbosity);
|
sa->SetVerbosity(m_Verbosity);
|
||||||
SetUserAction(static_cast<G4UserSteppingAction*>(sa));
|
// EventManager will delete sa via the Event slot
|
||||||
SetUserAction(static_cast<G4UserEventAction*>(sa));
|
SetUserAction(static_cast<G4UserEventAction*>(sa));
|
||||||
|
// EventManager will delete the wrapper, leaving sa alive for the other deletion.
|
||||||
|
SetUserAction(new DetectorSteppingActionWrapper(sa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ static void CheckGeant4Environment() {
|
|||||||
|
|
||||||
class SceneImpl {
|
class SceneImpl {
|
||||||
public:
|
public:
|
||||||
SceneImpl() : m_RunManager(G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default)),
|
SceneImpl() : m_RunManager(G4RunManagerFactory::CreateRunManager(G4RunManagerType::Serial)),
|
||||||
m_Emitter(nullptr),
|
m_Emitter(nullptr),
|
||||||
m_InitCalled(false) {
|
m_InitCalled(false) {
|
||||||
m_RunManager->SetUserInitialization(new PhysicsList);
|
m_RunManager->SetUserInitialization(new PhysicsList);
|
||||||
@@ -102,6 +102,7 @@ void Scene::AddSolid(Solid *solid, Solid *parent) {
|
|||||||
|
|
||||||
const Solid* Scene::GetWorld() const { return d->m_World; }
|
const Solid* Scene::GetWorld() const { return d->m_World; }
|
||||||
ContainerBox* Scene::GetWorldBox() const { return &d->m_WorldBox; }
|
ContainerBox* Scene::GetWorldBox() const { return &d->m_WorldBox; }
|
||||||
|
const Vector<Solid*>& Scene::GetSolids() const { return d->m_Solids; }
|
||||||
|
|
||||||
void Scene::ConstructWorldBox(const Vector3f &size, const char *material) {
|
void Scene::ConstructWorldBox(const Vector3f &size, const char *material) {
|
||||||
d->m_WorldBox.Scale(size);
|
d->m_WorldBox.Scale(size);
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ public:
|
|||||||
|
|
||||||
ContainerBox* GetWorldBox() const;
|
ContainerBox* GetWorldBox() const;
|
||||||
|
|
||||||
|
/// Get the list of solids in the scene
|
||||||
|
const Vector<Solid*>& GetSolids() const;
|
||||||
|
|
||||||
/// Set the primary generator (emitter) for the simulation.
|
/// Set the primary generator (emitter) for the simulation.
|
||||||
/// The Scene does NOT take ownership of the emitter.
|
/// The Scene does NOT take ownership of the emitter.
|
||||||
void SetEmitter(EmitterPrimary *emitter);
|
void SetEmitter(EmitterPrimary *emitter);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "QCanvas.h"
|
#include "QCanvas.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +41,13 @@ QCanvas::QCanvas(QWidget *parent) : QWidget(parent), m_canvas(nullptr) {
|
|||||||
if (!gApplication) {
|
if (!gApplication) {
|
||||||
static int argc = 1;
|
static int argc = 1;
|
||||||
static char* argv[] = {(char*)"App", nullptr};
|
static char* argv[] = {(char*)"App", nullptr};
|
||||||
new TApplication("App", &argc, argv);
|
if (std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
|
static int bargc = 2;
|
||||||
|
static char* bargv[] = {(char*)"App", (char*)"-b", nullptr};
|
||||||
|
new TApplication("App", &bargc, bargv);
|
||||||
|
} else {
|
||||||
|
new TApplication("App", &argc, argv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the TCanvas associated with this QWidget
|
// Create the TCanvas associated with this QWidget
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <TCanvas.h>
|
#include <TCanvas.h>
|
||||||
#include <TRandom.h>
|
#include <TRandom.h>
|
||||||
#include <TEnv.h>
|
#include <TEnv.h>
|
||||||
|
#include <cstdlib>
|
||||||
#include "Root/QCanvas.h"
|
#include "Root/QCanvas.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
@@ -37,10 +38,11 @@ int main(int argc, char **argv) {
|
|||||||
} else {
|
} else {
|
||||||
std::cerr << "FAIL: Canvas is still NULL after show() and processEvents()" << std::endl;
|
std::cerr << "FAIL: Canvas is still NULL after show() and processEvents()" << std::endl;
|
||||||
}
|
}
|
||||||
|
if (std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int main() { return 0; }
|
int main() { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,15 @@
|
|||||||
|
|
||||||
set(HEP_GEANT_SOURCES
|
set(HEP_GEANT_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantSolid.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantScene.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/vtkEmitterPrimary.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkEmitterPrimary.cpp
|
||||||
PARENT_SCOPE)
|
PARENT_SCOPE)
|
||||||
|
|
||||||
set(HEP_GEANT_HEADERS
|
set(HEP_GEANT_HEADERS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.h
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantEvent.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantSolid.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkGeantScene.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/vtkEmitterPrimary.h
|
${CMAKE_CURRENT_SOURCE_DIR}/vtkEmitterPrimary.h
|
||||||
PARENT_SCOPE)
|
PARENT_SCOPE)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# TESTS
|
# TESTS
|
||||||
set(TESTS
|
set(TESTS
|
||||||
vtkGeantEventTest
|
vtkGeantEventTest
|
||||||
|
vtkGeantSceneTest
|
||||||
vtkEmitterPrimaryTest
|
vtkEmitterPrimaryTest
|
||||||
vtkSkyPlaneEmitterPrimaryTest
|
vtkSkyPlaneEmitterPrimaryTest
|
||||||
vtkCylinderEmitterPrimaryTest
|
vtkCylinderEmitterPrimaryTest
|
||||||
|
|||||||
65
src/Vtk/HEP/Geant/testing/vtkGeantSceneTest.cpp
Normal file
65
src/Vtk/HEP/Geant/testing/vtkGeantSceneTest.cpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#include "Geant/Solid.h"
|
||||||
|
#include "HEP/Geant/Scene.h"
|
||||||
|
#include "Math/ContainerBox.h"
|
||||||
|
#include "Math/Dense.h"
|
||||||
|
#include "Math/Units.h"
|
||||||
|
#include "Vtk/uLibVtkViewer.h"
|
||||||
|
#include "Vtk/HEP/Geant/vtkGeantScene.h"
|
||||||
|
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkRenderer.h>
|
||||||
|
#include <vtkRenderWindow.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace uLib;
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
bool interactive = (argc > 1 && std::string(argv[1]) == "-i");
|
||||||
|
|
||||||
|
// 1. Setup Geant4 Scene
|
||||||
|
Geant::Scene scene;
|
||||||
|
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||||
|
|
||||||
|
// Add an iron cube inside the world
|
||||||
|
ContainerBox iron_box;
|
||||||
|
iron_box.Scale(Vector3f(10_m, 10_m, 10_m));
|
||||||
|
iron_box.SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||||
|
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||||
|
iron_cube->SetNistMaterial("G4_Fe");
|
||||||
|
iron_cube->Update();
|
||||||
|
scene.AddSolid(iron_cube);
|
||||||
|
scene.Initialize();
|
||||||
|
|
||||||
|
// 2. Build VTK scene representation
|
||||||
|
Vtk::Viewer viewer;
|
||||||
|
viewer.GetRenderer()->SetBackground(0.05, 0.05, 0.1);
|
||||||
|
|
||||||
|
Vtk::vtkGeantScene vtkScene(&scene);
|
||||||
|
vtkScene.AddToViewer(viewer);
|
||||||
|
|
||||||
|
std::cout << "==================================================" << std::endl;
|
||||||
|
std::cout << " vtkGeantScene Test" << std::endl;
|
||||||
|
std::cout << " World box + 1 iron cube displayed" << std::endl;
|
||||||
|
std::cout << "==================================================" << std::endl;
|
||||||
|
|
||||||
|
if (interactive) {
|
||||||
|
viewer.ZoomAuto();
|
||||||
|
viewer.Start();
|
||||||
|
} else {
|
||||||
|
std::cout << "Non-interactive test: scene initialized successfully" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
89
src/Vtk/HEP/Geant/vtkGeantScene.cpp
Normal file
89
src/Vtk/HEP/Geant/vtkGeantScene.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#include "vtkGeantScene.h"
|
||||||
|
#include "vtkGeantSolid.h"
|
||||||
|
#include "Vtk/vtkViewport.h"
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
vtkGeantScene::vtkGeantScene(Geant::Scene *scene)
|
||||||
|
: m_Scene(scene), m_WorldPuppet(nullptr) {
|
||||||
|
if (!m_Scene)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 1. Create the world box wireframe puppet
|
||||||
|
ContainerBox *worldBox = m_Scene->GetWorldBox();
|
||||||
|
if (worldBox) {
|
||||||
|
m_WorldPuppet = new vtkContainerBox(worldBox);
|
||||||
|
m_WorldPuppet->SetRepresentation(Puppet::Wireframe);
|
||||||
|
m_WorldPuppet->ShowScaleMeasures(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Create puppets for each non-world solid
|
||||||
|
const Geant::Solid *world = m_Scene->GetWorld();
|
||||||
|
const Vector<Geant::Solid *> &solids = m_Scene->GetSolids();
|
||||||
|
|
||||||
|
for (Geant::Solid *solid : solids) {
|
||||||
|
// Skip the world volume itself — it's already shown as the wireframe box
|
||||||
|
if (solid == world)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Only create a puppet if the solid has a valid G4VSolid
|
||||||
|
if (solid->GetG4Solid()) {
|
||||||
|
vtkGeantSolid *vtkSolid = new vtkGeantSolid(solid);
|
||||||
|
m_SolidPuppets.push_back(vtkSolid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkGeantScene::~vtkGeantScene() {
|
||||||
|
delete m_WorldPuppet;
|
||||||
|
for (auto *p : m_SolidPuppets) {
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vtkGeantScene::AddToViewer(Viewport &viewer) {
|
||||||
|
if (m_WorldPuppet) {
|
||||||
|
viewer.AddPuppet(*m_WorldPuppet);
|
||||||
|
}
|
||||||
|
for (auto *p : m_SolidPuppets) {
|
||||||
|
viewer.AddPuppet(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vtkGeantScene::RemoveFromViewer(Viewport &viewer) {
|
||||||
|
if (m_WorldPuppet) {
|
||||||
|
viewer.RemovePuppet(*m_WorldPuppet);
|
||||||
|
}
|
||||||
|
for (auto *p : m_SolidPuppets) {
|
||||||
|
viewer.RemovePuppet(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
87
src/Vtk/HEP/Geant/vtkGeantScene.h
Normal file
87
src/Vtk/HEP/Geant/vtkGeantScene.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#ifndef U_VTKGEANTSCENE_H
|
||||||
|
#define U_VTKGEANTSCENE_H
|
||||||
|
|
||||||
|
#include "HEP/Geant/Scene.h"
|
||||||
|
#include "uLibVtkInterface.h"
|
||||||
|
#include "Vtk/Math/vtkContainerBox.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
class vtkGeantSolid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief VTK Puppet representing the entire Geant::Scene.
|
||||||
|
*
|
||||||
|
* When constructed, it creates child puppets for the world box (as a
|
||||||
|
* vtkContainerBox wireframe) and for each non-world Solid in the scene
|
||||||
|
* (as vtkGeantSolid surfaces).
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* @code
|
||||||
|
* Geant::Scene scene;
|
||||||
|
* scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||||
|
* // ... add solids ...
|
||||||
|
* scene.Initialize();
|
||||||
|
*
|
||||||
|
* Vtk::Viewer viewer;
|
||||||
|
* Vtk::vtkGeantScene vtkScene(&scene);
|
||||||
|
* vtkScene.AddToViewer(viewer);
|
||||||
|
* viewer.Start();
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
class vtkGeantScene : public Object {
|
||||||
|
public:
|
||||||
|
vtkGeantScene(Geant::Scene *scene);
|
||||||
|
~vtkGeantScene();
|
||||||
|
|
||||||
|
/// Add all puppets (world box + solids) to a viewer.
|
||||||
|
void AddToViewer(class Viewport &viewer);
|
||||||
|
|
||||||
|
/// Remove all puppets from viewport.
|
||||||
|
void RemoveFromViewer(class Viewport &viewer);
|
||||||
|
|
||||||
|
/// Get the world box puppet
|
||||||
|
vtkContainerBox* GetWorldPuppet() const { return m_WorldPuppet; }
|
||||||
|
|
||||||
|
/// Get the solid puppets
|
||||||
|
const std::vector<vtkGeantSolid*>& GetSolidPuppets() const { return m_SolidPuppets; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Geant::Scene *m_Scene;
|
||||||
|
vtkContainerBox *m_WorldPuppet;
|
||||||
|
std::vector<vtkGeantSolid*> m_SolidPuppets;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
|
|
||||||
|
#endif // U_VTKGEANTSCENE_H
|
||||||
156
src/Vtk/HEP/Geant/vtkGeantSolid.cpp
Normal file
156
src/Vtk/HEP/Geant/vtkGeantSolid.cpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#include "vtkGeantSolid.h"
|
||||||
|
|
||||||
|
#include <vtkActor.h>
|
||||||
|
#include <vtkPolyData.h>
|
||||||
|
#include <vtkPoints.h>
|
||||||
|
#include <vtkCellArray.h>
|
||||||
|
#include <vtkPolyDataMapper.h>
|
||||||
|
#include <vtkProperty.h>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkTransform.h>
|
||||||
|
#include <vtkMatrix4x4.h>
|
||||||
|
|
||||||
|
#include <Geant4/G4VSolid.hh>
|
||||||
|
#include <Geant4/G4Polyhedron.hh>
|
||||||
|
#include <Geant4/G4VPhysicalVolume.hh>
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
vtkGeantSolid::vtkGeantSolid(Content *content)
|
||||||
|
: m_SolidActor(vtkActor::New()), m_Content(content) {
|
||||||
|
this->InstallPipe();
|
||||||
|
this->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkGeantSolid::~vtkGeantSolid() {
|
||||||
|
m_SolidActor->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkPolyData *vtkGeantSolid::GetPolyData() const {
|
||||||
|
if (!m_SolidActor || !m_SolidActor->GetMapper())
|
||||||
|
return NULL;
|
||||||
|
return vtkPolyData::SafeDownCast(m_SolidActor->GetMapper()->GetInput());
|
||||||
|
}
|
||||||
|
|
||||||
|
void vtkGeantSolid::Update() {
|
||||||
|
if (!m_Content)
|
||||||
|
return;
|
||||||
|
|
||||||
|
G4VSolid *g4solid = m_Content->GetG4Solid();
|
||||||
|
if (!g4solid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the polyhedron tessellation from Geant4
|
||||||
|
G4Polyhedron *polyhedron = g4solid->GetPolyhedron();
|
||||||
|
if (!polyhedron)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
||||||
|
vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
|
||||||
|
|
||||||
|
// Extract vertices
|
||||||
|
int nVertices = polyhedron->GetNoVertices();
|
||||||
|
for (int i = 1; i <= nVertices; ++i) {
|
||||||
|
G4Point3D vtx = polyhedron->GetVertex(i);
|
||||||
|
points->InsertNextPoint(vtx.x(), vtx.y(), vtx.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract facets (polygons)
|
||||||
|
int nFacets = polyhedron->GetNoFacets();
|
||||||
|
for (int f = 1; f <= nFacets; ++f) {
|
||||||
|
G4int nEdges;
|
||||||
|
G4int iVertex[4]; // G4Polyhedron facets have at most 4 vertices
|
||||||
|
// GetNextFacet returns edges; for quads nEdges=4, for triangles nEdges=3
|
||||||
|
polyhedron->GetFacet(f, nEdges, iVertex);
|
||||||
|
|
||||||
|
vtkIdType ids[4];
|
||||||
|
for (int e = 0; e < nEdges; ++e) {
|
||||||
|
// G4Polyhedron vertices are 1-indexed; VTK expects 0-indexed
|
||||||
|
ids[e] = static_cast<vtkIdType>(std::abs(iVertex[e]) - 1);
|
||||||
|
}
|
||||||
|
polys->InsertNextCell(nEdges, ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkPolyData *polyData = GetPolyData();
|
||||||
|
if (polyData) {
|
||||||
|
polyData->SetPoints(points);
|
||||||
|
polyData->SetPolys(polys);
|
||||||
|
polyData->Modified();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the Geant4 transform (position/rotation) if placed
|
||||||
|
if (m_Content->GetPhysical()) {
|
||||||
|
auto *phys = m_Content->GetPhysical();
|
||||||
|
G4ThreeVector pos = phys->GetTranslation();
|
||||||
|
const G4RotationMatrix *rot = phys->GetRotation();
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
|
||||||
|
transform->Identity();
|
||||||
|
transform->Translate(pos.x(), pos.y(), pos.z());
|
||||||
|
|
||||||
|
if (rot) {
|
||||||
|
// G4RotationMatrix stores the inverse of the rotation for placement
|
||||||
|
G4RotationMatrix invRot = rot->inverse();
|
||||||
|
double elements[16] = {
|
||||||
|
invRot.xx(), invRot.xy(), invRot.xz(), 0,
|
||||||
|
invRot.yx(), invRot.yy(), invRot.yz(), 0,
|
||||||
|
invRot.zx(), invRot.zy(), invRot.zz(), 0,
|
||||||
|
0, 0, 0, 1
|
||||||
|
};
|
||||||
|
vtkSmartPointer<vtkMatrix4x4> mat = vtkSmartPointer<vtkMatrix4x4>::New();
|
||||||
|
mat->DeepCopy(elements);
|
||||||
|
transform->Concatenate(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SolidActor->SetUserTransform(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vtkGeantSolid::InstallPipe() {
|
||||||
|
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper> mapper =
|
||||||
|
vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
|
mapper->SetInputData(polyData);
|
||||||
|
|
||||||
|
m_SolidActor->SetMapper(mapper);
|
||||||
|
|
||||||
|
// Default look: semi-transparent blue surface
|
||||||
|
m_SolidActor->GetProperty()->SetColor(0.4, 0.6, 0.9);
|
||||||
|
m_SolidActor->GetProperty()->SetOpacity(0.3);
|
||||||
|
m_SolidActor->GetProperty()->SetAmbient(0.5);
|
||||||
|
m_SolidActor->GetProperty()->SetDiffuse(0.6);
|
||||||
|
m_SolidActor->GetProperty()->SetSpecular(0.2);
|
||||||
|
m_SolidActor->GetProperty()->SetEdgeVisibility(1);
|
||||||
|
m_SolidActor->GetProperty()->SetEdgeColor(0.2, 0.3, 0.5);
|
||||||
|
|
||||||
|
this->SetProp(m_SolidActor);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
66
src/Vtk/HEP/Geant/vtkGeantSolid.h
Normal file
66
src/Vtk/HEP/Geant/vtkGeantSolid.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
||||||
|
|
||||||
|
------------------------------------------------------------------
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 3.0 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
#ifndef U_VTKGEANTSOLID_H
|
||||||
|
#define U_VTKGEANTSOLID_H
|
||||||
|
|
||||||
|
#include "HEP/Geant/Solid.h"
|
||||||
|
#include "uLibVtkInterface.h"
|
||||||
|
#include "vtkPolydata.h"
|
||||||
|
|
||||||
|
class vtkActor;
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief VTK Puppet 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 vtkGeantSolid : public Puppet, public Polydata {
|
||||||
|
typedef Geant::Solid Content;
|
||||||
|
|
||||||
|
public:
|
||||||
|
vtkGeantSolid(Content *content);
|
||||||
|
~vtkGeantSolid();
|
||||||
|
|
||||||
|
virtual class vtkPolyData *GetPolyData() const override;
|
||||||
|
|
||||||
|
virtual void Update();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void InstallPipe();
|
||||||
|
|
||||||
|
vtkActor *m_SolidActor;
|
||||||
|
Content *m_Content;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
|
|
||||||
|
#endif // U_VTKGEANTSOLID_H
|
||||||
@@ -48,13 +48,11 @@ namespace uLib {
|
|||||||
namespace Vtk {
|
namespace Vtk {
|
||||||
|
|
||||||
struct ContainerBoxData {
|
struct ContainerBoxData {
|
||||||
vtkActor *m_Cube;
|
vtkSmartPointer<vtkActor> m_Cube;
|
||||||
vtkActor *m_Axes;
|
vtkSmartPointer<vtkActor> m_Axes;
|
||||||
|
|
||||||
ContainerBoxData() : m_Cube(vtkActor::New()), m_Axes(vtkActor::New()) {}
|
ContainerBoxData() : m_Cube(vtkSmartPointer<vtkActor>::New()), m_Axes(vtkSmartPointer<vtkActor>::New()) {}
|
||||||
~ContainerBoxData() {
|
~ContainerBoxData() {
|
||||||
m_Cube->Delete();
|
|
||||||
m_Axes->Delete();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -46,13 +46,14 @@ int main() {
|
|||||||
box.Scale(Vector3f(2.0, 3.0, 4.0));
|
box.Scale(Vector3f(2.0, 3.0, 4.0));
|
||||||
box.SetPosition(Vector3f(1.0, 1.0, 1.0));
|
box.SetPosition(Vector3f(1.0, 1.0, 1.0));
|
||||||
|
|
||||||
|
// 3. Setup the Viewer
|
||||||
|
Vtk::Viewer viewer;
|
||||||
|
|
||||||
// 2. Wrap it in a Vtk::vtkContainerBox (Vtk Puppet)
|
// 2. Wrap it in a Vtk::vtkContainerBox (Vtk Puppet)
|
||||||
Vtk::vtkContainerBox v_box(&box);
|
Vtk::vtkContainerBox v_box(&box);
|
||||||
v_box.SetRepresentation(Vtk::Puppet::Surface);
|
v_box.SetRepresentation(Vtk::Puppet::Surface);
|
||||||
v_box.SetOpacity(0.5);
|
v_box.SetOpacity(0.5);
|
||||||
|
|
||||||
// 3. Setup the Viewer
|
|
||||||
Vtk::Viewer viewer;
|
|
||||||
viewer.AddPuppet(v_box);
|
viewer.AddPuppet(v_box);
|
||||||
|
|
||||||
// 4. Create and setup the vtkHandlerWidget
|
// 4. Create and setup the vtkHandlerWidget
|
||||||
@@ -112,5 +113,6 @@ int main() {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handler->EnabledOff();
|
||||||
END_TESTING;
|
END_TESTING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <Vtk/uLibVtkViewer.h>
|
#include <Vtk/uLibVtkViewer.h>
|
||||||
|
|
||||||
@@ -63,9 +64,10 @@ int main()
|
|||||||
actor->SetMapper(mapper);
|
actor->SetMapper(mapper);
|
||||||
|
|
||||||
v_viewer.addProp(actor);
|
v_viewer.addProp(actor);
|
||||||
v_viewer.GetRenderer()->Render();
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
v_viewer.Start();
|
v_viewer.GetRenderer()->Render();
|
||||||
|
v_viewer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
END_TESTING;
|
END_TESTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Puppet::Puppet() : Object(), d(new PuppetData) {
|
Puppet::Puppet() : Object(), pd(new PuppetData) {
|
||||||
ULIB_ACTIVATE_DISPLAY_PROPERTIES;
|
ULIB_ACTIVATE_DISPLAY_PROPERTIES;
|
||||||
for (auto* p : this->GetDisplayProperties()) {
|
for (auto* p : this->GetDisplayProperties()) {
|
||||||
uLib::Object::connect(p, &uLib::PropertyBase::Updated, this, &Puppet::Update);
|
uLib::Object::connect(p, &uLib::PropertyBase::Updated, this, &Puppet::Update);
|
||||||
@@ -207,25 +207,25 @@ Puppet::Puppet() : Object(), d(new PuppetData) {
|
|||||||
|
|
||||||
Puppet::~Puppet()
|
Puppet::~Puppet()
|
||||||
{
|
{
|
||||||
delete d;
|
delete pd;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkProp *Puppet::GetProp()
|
vtkProp *Puppet::GetProp()
|
||||||
{
|
{
|
||||||
if (d->m_Assembly->GetParts()->GetNumberOfItems() == 1)
|
if (pd->m_Assembly->GetParts()->GetNumberOfItems() == 1)
|
||||||
return d->m_Assembly->GetParts()->GetLastProp();
|
return pd->m_Assembly->GetParts()->GetLastProp();
|
||||||
else
|
else
|
||||||
return d->m_Assembly;
|
return pd->m_Assembly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::SetProp(vtkProp *prop)
|
void Puppet::SetProp(vtkProp *prop)
|
||||||
{
|
{
|
||||||
if(prop) {
|
if(prop) {
|
||||||
prop->SetPickable(d->m_Selectable);
|
prop->SetPickable(pd->m_Selectable);
|
||||||
if (auto* p3d = vtkProp3D::SafeDownCast(prop)) {
|
if (auto* p3d = vtkProp3D::SafeDownCast(prop)) {
|
||||||
d->m_Assembly->AddPart(p3d);
|
pd->m_Assembly->AddPart(p3d);
|
||||||
}
|
}
|
||||||
d->ApplyAppearance(prop);
|
pd->ApplyAppearance(prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,12 +237,12 @@ void Puppet::RemoveProp(vtkProp *prop)
|
|||||||
|
|
||||||
vtkPropCollection *Puppet::GetParts()
|
vtkPropCollection *Puppet::GetParts()
|
||||||
{
|
{
|
||||||
return d->m_Assembly->GetParts();
|
return pd->m_Assembly->GetParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkPropCollection *Puppet::GetProps()
|
vtkPropCollection *Puppet::GetProps()
|
||||||
{
|
{
|
||||||
return d->m_Assembly->GetParts();
|
return pd->m_Assembly->GetParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
||||||
@@ -253,14 +253,14 @@ void Puppet::ConnectRenderer(vtkRenderer *renderer)
|
|||||||
renderer->AddViewProp(prop);
|
renderer->AddViewProp(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_ShowBoundingBox && d->m_OutlineActor) renderer->AddActor(d->m_OutlineActor);
|
if (pd->m_ShowBoundingBox && pd->m_OutlineActor) renderer->AddActor(pd->m_OutlineActor);
|
||||||
if (d->m_ShowScaleMeasures && d->m_CubeAxesActor) {
|
if (pd->m_ShowScaleMeasures && pd->m_CubeAxesActor) {
|
||||||
d->m_CubeAxesActor->SetCamera(renderer->GetActiveCamera());
|
pd->m_CubeAxesActor->SetCamera(renderer->GetActiveCamera());
|
||||||
renderer->AddActor(d->m_CubeAxesActor);
|
renderer->AddActor(pd->m_CubeAxesActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_Selected && d->m_HighlightActor) {
|
if (pd->m_Selected && pd->m_HighlightActor) {
|
||||||
renderer->AddActor(d->m_HighlightActor);
|
renderer->AddActor(pd->m_HighlightActor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,8 +271,8 @@ void Puppet::DisconnectRenderer(vtkRenderer *renderer)
|
|||||||
if(vtkProp* prop = this->GetProp())
|
if(vtkProp* prop = this->GetProp())
|
||||||
renderer->RemoveViewProp(prop);
|
renderer->RemoveViewProp(prop);
|
||||||
|
|
||||||
if (d->m_ShowBoundingBox && d->m_OutlineActor) renderer->RemoveActor(d->m_OutlineActor);
|
if (pd->m_ShowBoundingBox && pd->m_OutlineActor) renderer->RemoveActor(pd->m_OutlineActor);
|
||||||
if (d->m_ShowScaleMeasures && d->m_CubeAxesActor) renderer->RemoveActor(d->m_CubeAxesActor);
|
if (pd->m_ShowScaleMeasures && pd->m_CubeAxesActor) renderer->RemoveActor(pd->m_CubeAxesActor);
|
||||||
|
|
||||||
this->GetRenderers()->RemoveItem(renderer);
|
this->GetRenderers()->RemoveItem(renderer);
|
||||||
}
|
}
|
||||||
@@ -290,47 +290,47 @@ void Puppet::DisonnectViewer(Viewer *viewer)
|
|||||||
|
|
||||||
vtkRendererCollection *Puppet::GetRenderers() const
|
vtkRendererCollection *Puppet::GetRenderers() const
|
||||||
{
|
{
|
||||||
return d->m_Renderers;
|
return pd->m_Renderers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::PrintSelf(std::ostream &o) const
|
void Puppet::PrintSelf(std::ostream &o) const
|
||||||
{
|
{
|
||||||
o << "Props Assembly: \n";
|
o << "Props Assembly: \n";
|
||||||
d->m_Assembly->PrintSelf(o,vtkIndent(1));
|
pd->m_Assembly->PrintSelf(o,vtkIndent(1));
|
||||||
|
|
||||||
o << "Connected Renderers: \n";
|
o << "Connected Renderers: \n";
|
||||||
d->m_Renderers->PrintSelf(o,vtkIndent(1));
|
pd->m_Renderers->PrintSelf(o,vtkIndent(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::ShowBoundingBox(bool show)
|
void Puppet::ShowBoundingBox(bool show)
|
||||||
{
|
{
|
||||||
if (d->m_ShowBoundingBox == show) return;
|
if (pd->m_ShowBoundingBox == show) return;
|
||||||
d->m_ShowBoundingBox = show;
|
pd->m_ShowBoundingBox = show;
|
||||||
if (show) {
|
if (show) {
|
||||||
if (!d->m_OutlineActor) {
|
if (!pd->m_OutlineActor) {
|
||||||
d->m_OutlineSource = vtkSmartPointer<vtkOutlineSource>::New();
|
pd->m_OutlineSource = vtkSmartPointer<vtkOutlineSource>::New();
|
||||||
d->m_OutlineActor = vtkSmartPointer<vtkActor>::New();
|
pd->m_OutlineActor = vtkSmartPointer<vtkActor>::New();
|
||||||
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
|
||||||
mapper->SetInputConnection(d->m_OutlineSource->GetOutputPort());
|
mapper->SetInputConnection(pd->m_OutlineSource->GetOutputPort());
|
||||||
d->m_OutlineActor->SetMapper(mapper);
|
pd->m_OutlineActor->SetMapper(mapper);
|
||||||
d->m_OutlineActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
|
pd->m_OutlineActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double* bounds = d->m_Assembly->GetBounds();
|
double* bounds = pd->m_Assembly->GetBounds();
|
||||||
d->m_OutlineSource->SetBounds(bounds);
|
pd->m_OutlineSource->SetBounds(bounds);
|
||||||
d->m_OutlineSource->Update();
|
pd->m_OutlineSource->Update();
|
||||||
|
|
||||||
d->m_Renderers->InitTraversal();
|
pd->m_Renderers->InitTraversal();
|
||||||
for (int i = 0; i < d->m_Renderers->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < pd->m_Renderers->GetNumberOfItems(); ++i) {
|
||||||
vtkRenderer *renderer = d->m_Renderers->GetNextItem();
|
vtkRenderer *renderer = pd->m_Renderers->GetNextItem();
|
||||||
renderer->AddActor(d->m_OutlineActor);
|
renderer->AddActor(pd->m_OutlineActor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d->m_OutlineActor) {
|
if (pd->m_OutlineActor) {
|
||||||
d->m_Renderers->InitTraversal();
|
pd->m_Renderers->InitTraversal();
|
||||||
for (int i = 0; i < d->m_Renderers->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < pd->m_Renderers->GetNumberOfItems(); ++i) {
|
||||||
vtkRenderer *renderer = d->m_Renderers->GetNextItem();
|
vtkRenderer *renderer = pd->m_Renderers->GetNextItem();
|
||||||
renderer->RemoveActor(d->m_OutlineActor);
|
renderer->RemoveActor(pd->m_OutlineActor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,31 +338,31 @@ void Puppet::ShowBoundingBox(bool show)
|
|||||||
|
|
||||||
void Puppet::ShowScaleMeasures(bool show)
|
void Puppet::ShowScaleMeasures(bool show)
|
||||||
{
|
{
|
||||||
if (d->m_ShowScaleMeasures == show) return;
|
if (pd->m_ShowScaleMeasures == show) return;
|
||||||
d->m_ShowScaleMeasures = show;
|
pd->m_ShowScaleMeasures = show;
|
||||||
if (show) {
|
if (show) {
|
||||||
if (!d->m_CubeAxesActor) {
|
if (!pd->m_CubeAxesActor) {
|
||||||
d->m_CubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
|
pd->m_CubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
|
||||||
d->m_CubeAxesActor->SetFlyModeToOuterEdges();
|
pd->m_CubeAxesActor->SetFlyModeToOuterEdges();
|
||||||
d->m_CubeAxesActor->SetUseTextActor3D(1);
|
pd->m_CubeAxesActor->SetUseTextActor3D(1);
|
||||||
d->m_CubeAxesActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
|
pd->m_CubeAxesActor->GetProperty()->SetColor(1.0, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double* bounds = d->m_Assembly->GetBounds();
|
double* bounds = pd->m_Assembly->GetBounds();
|
||||||
d->m_CubeAxesActor->SetBounds(bounds);
|
pd->m_CubeAxesActor->SetBounds(bounds);
|
||||||
|
|
||||||
d->m_Renderers->InitTraversal();
|
pd->m_Renderers->InitTraversal();
|
||||||
for (int i = 0; i < d->m_Renderers->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < pd->m_Renderers->GetNumberOfItems(); ++i) {
|
||||||
vtkRenderer *renderer = d->m_Renderers->GetNextItem();
|
vtkRenderer *renderer = pd->m_Renderers->GetNextItem();
|
||||||
d->m_CubeAxesActor->SetCamera(renderer->GetActiveCamera());
|
pd->m_CubeAxesActor->SetCamera(renderer->GetActiveCamera());
|
||||||
renderer->AddActor(d->m_CubeAxesActor);
|
renderer->AddActor(pd->m_CubeAxesActor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d->m_CubeAxesActor) {
|
if (pd->m_CubeAxesActor) {
|
||||||
d->m_Renderers->InitTraversal();
|
pd->m_Renderers->InitTraversal();
|
||||||
for (int i = 0; i < d->m_Renderers->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < pd->m_Renderers->GetNumberOfItems(); ++i) {
|
||||||
vtkRenderer *renderer = d->m_Renderers->GetNextItem();
|
vtkRenderer *renderer = pd->m_Renderers->GetNextItem();
|
||||||
renderer->RemoveActor(d->m_CubeAxesActor);
|
renderer->RemoveActor(pd->m_CubeAxesActor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,12 +376,12 @@ void Puppet::SetRepresentation(Representation mode)
|
|||||||
case Wireframe: rep = VTK_WIREFRAME; break;
|
case Wireframe: rep = VTK_WIREFRAME; break;
|
||||||
case Surface: rep = VTK_SURFACE; break;
|
case Surface: rep = VTK_SURFACE; break;
|
||||||
}
|
}
|
||||||
d->m_Representation = rep;
|
pd->m_Representation = rep;
|
||||||
|
|
||||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
vtkProp3DCollection *props = pd->m_Assembly->GetParts();
|
||||||
props->InitTraversal();
|
props->InitTraversal();
|
||||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||||
d->ApplyAppearance(props->GetNextProp3D());
|
pd->ApplyAppearance(props->GetNextProp3D());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,25 +395,25 @@ void Puppet::SetRepresentation(const char *mode)
|
|||||||
|
|
||||||
void Puppet::SetColor(double r, double g, double b)
|
void Puppet::SetColor(double r, double g, double b)
|
||||||
{
|
{
|
||||||
d->m_Color[0] = r;
|
pd->m_Color[0] = r;
|
||||||
d->m_Color[1] = g;
|
pd->m_Color[1] = g;
|
||||||
d->m_Color[2] = b;
|
pd->m_Color[2] = b;
|
||||||
|
|
||||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
vtkProp3DCollection *props = pd->m_Assembly->GetParts();
|
||||||
props->InitTraversal();
|
props->InitTraversal();
|
||||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||||
d->ApplyAppearance(props->GetNextProp3D());
|
pd->ApplyAppearance(props->GetNextProp3D());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::SetOpacity(double alpha)
|
void Puppet::SetOpacity(double alpha)
|
||||||
{
|
{
|
||||||
d->m_Opacity = alpha;
|
pd->m_Opacity = alpha;
|
||||||
|
|
||||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
vtkProp3DCollection *props = pd->m_Assembly->GetParts();
|
||||||
props->InitTraversal();
|
props->InitTraversal();
|
||||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||||
d->ApplyAppearance(props->GetNextProp3D());
|
pd->ApplyAppearance(props->GetNextProp3D());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,8 +425,8 @@ void Puppet::SetOpacity(double alpha)
|
|||||||
|
|
||||||
void Puppet::SetSelectable(bool selectable)
|
void Puppet::SetSelectable(bool selectable)
|
||||||
{
|
{
|
||||||
d->m_Selectable = selectable;
|
pd->m_Selectable = selectable;
|
||||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
vtkProp3DCollection *props = pd->m_Assembly->GetParts();
|
||||||
props->InitTraversal();
|
props->InitTraversal();
|
||||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||||
props->GetNextProp3D()->SetPickable(selectable);
|
props->GetNextProp3D()->SetPickable(selectable);
|
||||||
@@ -435,43 +435,43 @@ void Puppet::SetSelectable(bool selectable)
|
|||||||
|
|
||||||
bool Puppet::IsSelectable() const
|
bool Puppet::IsSelectable() const
|
||||||
{
|
{
|
||||||
return d->m_Selectable;
|
return pd->m_Selectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::SetSelected(bool selected)
|
void Puppet::SetSelected(bool selected)
|
||||||
{
|
{
|
||||||
if (!d->m_Selectable) return;
|
if (!pd->m_Selectable) return;
|
||||||
if (d->m_Selected == selected) return;
|
if (pd->m_Selected == selected) return;
|
||||||
d->m_Selected = selected;
|
pd->m_Selected = selected;
|
||||||
d->UpdateHighlight();
|
pd->UpdateHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Puppet::IsSelected() const
|
bool Puppet::IsSelected() const
|
||||||
{
|
{
|
||||||
return d->m_Selected;
|
return pd->m_Selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::Update()
|
void Puppet::Update()
|
||||||
{
|
{
|
||||||
vtkProp3DCollection *props = d->m_Assembly->GetParts();
|
vtkProp3DCollection *props = pd->m_Assembly->GetParts();
|
||||||
props->InitTraversal();
|
props->InitTraversal();
|
||||||
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
for (int i = 0; i < props->GetNumberOfItems(); ++i) {
|
||||||
d->ApplyAppearance(props->GetNextProp3D());
|
pd->ApplyAppearance(props->GetNextProp3D());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_Selected) {
|
if (pd->m_Selected) {
|
||||||
d->UpdateHighlight();
|
pd->UpdateHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_ShowBoundingBox) {
|
if (pd->m_ShowBoundingBox) {
|
||||||
double* bounds = d->m_Assembly->GetBounds();
|
double* bounds = pd->m_Assembly->GetBounds();
|
||||||
d->m_OutlineSource->SetBounds(bounds);
|
pd->m_OutlineSource->SetBounds(bounds);
|
||||||
d->m_OutlineSource->Update();
|
pd->m_OutlineSource->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_ShowScaleMeasures) {
|
if (pd->m_ShowScaleMeasures) {
|
||||||
double* bounds = d->m_Assembly->GetBounds();
|
double* bounds = pd->m_Assembly->GetBounds();
|
||||||
d->m_CubeAxesActor->SetBounds(bounds);
|
pd->m_CubeAxesActor->SetBounds(bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,11 +480,11 @@ void Puppet::ConnectInteractor(vtkRenderWindowInteractor *interactor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::serialize_display(Archive::display_properties_archive & ar, const unsigned int version) {
|
void Puppet::serialize_display(Archive::display_properties_archive & ar, const unsigned int version) {
|
||||||
ar & boost::serialization::make_hrp("ColorR", d->m_Color[0]);
|
ar & boost::serialization::make_hrp("ColorR", pd->m_Color[0]);
|
||||||
ar & boost::serialization::make_hrp("ColorG", d->m_Color[1]);
|
ar & boost::serialization::make_hrp("ColorG", pd->m_Color[1]);
|
||||||
ar & boost::serialization::make_hrp("ColorB", d->m_Color[2]);
|
ar & boost::serialization::make_hrp("ColorB", pd->m_Color[2]);
|
||||||
ar & boost::serialization::make_hrp("Opacity", d->m_Opacity);
|
ar & boost::serialization::make_hrp("Opacity", pd->m_Opacity);
|
||||||
ar & boost::serialization::make_hrp("Representation", d->m_Representation);
|
ar & boost::serialization::make_hrp("Representation", pd->m_Representation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Puppet::serialize(Archive::xml_oarchive & ar, const unsigned int v) { }
|
void Puppet::serialize(Archive::xml_oarchive & ar, const unsigned int v) { }
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ private:
|
|||||||
Puppet& operator=(const Puppet&) = delete;
|
Puppet& operator=(const Puppet&) = delete;
|
||||||
|
|
||||||
friend class PuppetData;
|
friend class PuppetData;
|
||||||
class PuppetData *d;
|
class PuppetData *pd;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <vtkRenderWindowInteractor.h>
|
#include <vtkRenderWindowInteractor.h>
|
||||||
#include <vtkRendererCollection.h>
|
#include <vtkRendererCollection.h>
|
||||||
#include <vtkSmartPointer.h>
|
#include <vtkSmartPointer.h>
|
||||||
@@ -69,56 +70,78 @@ namespace Vtk {
|
|||||||
|
|
||||||
struct ViewerData {
|
struct ViewerData {
|
||||||
vtkRenderWindow *m_RenderWindow;
|
vtkRenderWindow *m_RenderWindow;
|
||||||
|
vtkSmartPointer<vtkRenderWindowInteractor> m_Interactor;
|
||||||
vtkSmartPointer<vtkButtonWidget> m_GridButton;
|
vtkSmartPointer<vtkButtonWidget> m_GridButton;
|
||||||
|
|
||||||
ViewerData() : m_RenderWindow(vtkRenderWindow::New()) {}
|
ViewerData() : m_RenderWindow(vtkRenderWindow::New()) {}
|
||||||
~ViewerData() { m_RenderWindow->Delete(); }
|
~ViewerData() {
|
||||||
|
if (m_Interactor) {
|
||||||
|
m_Interactor->SetRenderWindow(nullptr);
|
||||||
|
}
|
||||||
|
m_RenderWindow->Delete();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///// VTK VIEWER //////////////////////////////////////////////////////////////
|
///// VTK VIEWER //////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Viewer::Viewer()
|
Viewer::Viewer()
|
||||||
: Viewport(), d(new ViewerData()) {
|
: Viewport(), dv(new ViewerData()) {
|
||||||
InstallPipe();
|
InstallPipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
Viewer::~Viewer() {
|
Viewer::~Viewer() {
|
||||||
|
this->DisableHandler();
|
||||||
|
if (dv->m_GridButton) {
|
||||||
|
dv->m_GridButton->Off();
|
||||||
|
dv->m_GridButton->SetInteractor(nullptr);
|
||||||
|
dv->m_GridButton = nullptr;
|
||||||
|
}
|
||||||
|
if (this->GetRenderWindow()) {
|
||||||
|
this->GetRenderWindow()->RemoveAllObservers();
|
||||||
|
}
|
||||||
|
if (this->GetInteractor()) {
|
||||||
|
this->GetInteractor()->RemoveAllObservers();
|
||||||
|
}
|
||||||
UninstallPipe();
|
UninstallPipe();
|
||||||
delete d;
|
delete dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::InstallPipe() {
|
void Viewer::InstallPipe() {
|
||||||
d->m_RenderWindow->AddRenderer(this->GetRenderer());
|
dv->m_RenderWindow->AddRenderer(this->GetRenderer());
|
||||||
d->m_RenderWindow->SetSize(600,600);
|
dv->m_RenderWindow->SetSize(600,600);
|
||||||
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
|
if (std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
dv->m_RenderWindow->SetOffScreenRendering(1);
|
||||||
renderWindowInteractor->SetRenderWindow(d->m_RenderWindow);
|
}
|
||||||
|
|
||||||
|
dv->m_Interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||||||
|
dv->m_Interactor->SetRenderWindow(dv->m_RenderWindow);
|
||||||
|
|
||||||
// Common setup
|
// Common setup
|
||||||
Viewport::SetupPipeline(renderWindowInteractor);
|
Viewport::SetupPipeline(dv->m_Interactor);
|
||||||
|
|
||||||
// Setup native grid button
|
// Setup native grid button
|
||||||
SetupGridButton();
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
|
SetupGridButton();
|
||||||
|
}
|
||||||
|
|
||||||
// BUT we want to override the style with our custom NoSpin version
|
// BUT we want to override the style with our custom NoSpin version
|
||||||
vtkSmartPointer<vtkInteractorStyleNoSpin> style =
|
vtkSmartPointer<vtkInteractorStyleNoSpin> style =
|
||||||
vtkSmartPointer<vtkInteractorStyleNoSpin>::New();
|
vtkSmartPointer<vtkInteractorStyleNoSpin>::New();
|
||||||
renderWindowInteractor->SetInteractorStyle(style);
|
dv->m_Interactor->SetInteractorStyle(style);
|
||||||
|
|
||||||
// Must be rendered here in Vtk-6.0 or seg-fault //
|
// Must be rendered here in Vtk-6.0 or seg-fault //
|
||||||
d->m_RenderWindow->Render();
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
}
|
dv->m_RenderWindow->Render();
|
||||||
|
|
||||||
void Viewer::UninstallPipe() {
|
|
||||||
if (GetRenderer()) {
|
|
||||||
GetRenderer()->RemoveAllViewProps();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Viewer::UninstallPipe() {
|
||||||
|
}
|
||||||
|
|
||||||
void Viewer::Render() {
|
void Viewer::Render() {
|
||||||
if (d->m_RenderWindow)
|
if (dv->m_RenderWindow)
|
||||||
d->m_RenderWindow->Render();
|
dv->m_RenderWindow->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkCameraOrientationWidget *
|
vtkCameraOrientationWidget *
|
||||||
@@ -133,7 +156,7 @@ Viewer::MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::SetupGridButton() {
|
void Viewer::SetupGridButton() {
|
||||||
if (!d->m_RenderWindow || !d->m_RenderWindow->GetInteractor()) return;
|
if (!dv->m_RenderWindow || !dv->m_RenderWindow->GetInteractor()) return;
|
||||||
|
|
||||||
// Create procedural textures for the button using canvas
|
// Create procedural textures for the button using canvas
|
||||||
vtkNew<vtkImageCanvasSource2D> canvas;
|
vtkNew<vtkImageCanvasSource2D> canvas;
|
||||||
@@ -166,9 +189,9 @@ void Viewer::SetupGridButton() {
|
|||||||
rep->SetButtonTexture(0, imgOff);
|
rep->SetButtonTexture(0, imgOff);
|
||||||
rep->SetButtonTexture(1, imgOn);
|
rep->SetButtonTexture(1, imgOn);
|
||||||
|
|
||||||
d->m_GridButton = vtkSmartPointer<vtkButtonWidget>::New();
|
dv->m_GridButton = vtkSmartPointer<vtkButtonWidget>::New();
|
||||||
d->m_GridButton->SetInteractor(d->m_RenderWindow->GetInteractor());
|
dv->m_GridButton->SetInteractor(dv->m_RenderWindow->GetInteractor());
|
||||||
d->m_GridButton->SetRepresentation(rep);
|
dv->m_GridButton->SetRepresentation(rep);
|
||||||
|
|
||||||
// Position it initially
|
// Position it initially
|
||||||
UpdateGridButtonPosition();
|
UpdateGridButtonPosition();
|
||||||
@@ -180,7 +203,7 @@ void Viewer::SetupGridButton() {
|
|||||||
auto* v = static_cast<Viewer*>(clientdata);
|
auto* v = static_cast<Viewer*>(clientdata);
|
||||||
v->UpdateGridButtonPosition();
|
v->UpdateGridButtonPosition();
|
||||||
});
|
});
|
||||||
d->m_RenderWindow->AddObserver(vtkCommand::ModifiedEvent, resizeCallback);
|
dv->m_RenderWindow->AddObserver(vtkCommand::ModifiedEvent, resizeCallback);
|
||||||
|
|
||||||
// Callback for state change
|
// Callback for state change
|
||||||
vtkNew<vtkCallbackCommand> stateCallback;
|
vtkNew<vtkCallbackCommand> stateCallback;
|
||||||
@@ -192,19 +215,19 @@ void Viewer::SetupGridButton() {
|
|||||||
v->SetGridVisible(r->GetState() == 1);
|
v->SetGridVisible(r->GetState() == 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
d->m_GridButton->AddObserver(vtkCommand::StateChangedEvent, stateCallback);
|
dv->m_GridButton->AddObserver(vtkCommand::StateChangedEvent, stateCallback);
|
||||||
d->m_GridButton->On();
|
dv->m_GridButton->On();
|
||||||
|
|
||||||
// Set initial state
|
// Set initial state
|
||||||
rep->SetState(GetGridVisible() ? 1 : 0);
|
rep->SetState(GetGridVisible() ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::UpdateGridButtonPosition() {
|
void Viewer::UpdateGridButtonPosition() {
|
||||||
if (!d->m_GridButton || !d->m_RenderWindow) return;
|
if (!dv->m_GridButton || !dv->m_RenderWindow) return;
|
||||||
auto* rep = vtkTexturedButtonRepresentation2D::SafeDownCast(d->m_GridButton->GetRepresentation());
|
auto* rep = vtkTexturedButtonRepresentation2D::SafeDownCast(dv->m_GridButton->GetRepresentation());
|
||||||
if (!rep) return;
|
if (!rep) return;
|
||||||
|
|
||||||
int *sz = d->m_RenderWindow->GetSize();
|
int *sz = dv->m_RenderWindow->GetSize();
|
||||||
if (sz[0] == 0 || sz[1] == 0) return; // Window not yet sized or hidden
|
if (sz[0] == 0 || sz[1] == 0) return; // Window not yet sized or hidden
|
||||||
|
|
||||||
int margin_rigth = 23;
|
int margin_rigth = 23;
|
||||||
@@ -215,12 +238,15 @@ void Viewer::UpdateGridButtonPosition() {
|
|||||||
rep->PlaceWidget(bds);
|
rep->PlaceWidget(bds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::Start() { d->m_RenderWindow->GetInteractor()->Start(); }
|
void Viewer::Start() {
|
||||||
|
if (std::getenv("CTEST_PROJECT_NAME")) return;
|
||||||
|
dv->m_RenderWindow->GetInteractor()->Start();
|
||||||
|
}
|
||||||
|
|
||||||
vtkRenderWindow *Viewer::GetRenderWindow() { return d->m_RenderWindow; }
|
vtkRenderWindow *Viewer::GetRenderWindow() { return dv->m_RenderWindow; }
|
||||||
|
|
||||||
vtkRenderWindowInteractor *Viewer::GetInteractor() {
|
vtkRenderWindowInteractor *Viewer::GetInteractor() {
|
||||||
return d->m_RenderWindow->GetInteractor();
|
return dv->m_RenderWindow->GetInteractor();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ private:
|
|||||||
void SetupGridButton();
|
void SetupGridButton();
|
||||||
void UpdateGridButtonPosition();
|
void UpdateGridButtonPosition();
|
||||||
|
|
||||||
struct ViewerData *d;
|
struct ViewerData *dv;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ vtkHandlerWidget::vtkHandlerWidget() : d(new HandlerWidgetData()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vtkHandlerWidget::~vtkHandlerWidget() {
|
vtkHandlerWidget::~vtkHandlerWidget() {
|
||||||
|
this->SetEnabled(0);
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +195,12 @@ void vtkHandlerWidget::SetEnabled(int enabling) {
|
|||||||
|
|
||||||
this->Enabled = 0;
|
this->Enabled = 0;
|
||||||
this->Highlight(nullptr);
|
this->Highlight(nullptr);
|
||||||
this->Interactor->RemoveObserver(this->EventCallbackCommand);
|
if (this->Interactor) {
|
||||||
if (this->Interactor->GetRenderWindow()) {
|
this->Interactor->RemoveObserver(this->EventCallbackCommand);
|
||||||
this->Interactor->GetRenderWindow()->RemoveRenderer(this->d->m_OverlayRenderer);
|
if (this->Interactor->GetRenderWindow()) {
|
||||||
|
this->Interactor->GetRenderWindow()->MakeCurrent();
|
||||||
|
this->Interactor->GetRenderWindow()->RemoveRenderer(this->d->m_OverlayRenderer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->d->m_OverlayRenderer->RemoveAllViewProps();
|
this->d->m_OverlayRenderer->RemoveAllViewProps();
|
||||||
this->InvokeEvent(::vtkCommand::DisableEvent, nullptr);
|
this->InvokeEvent(::vtkCommand::DisableEvent, nullptr);
|
||||||
@@ -792,21 +796,23 @@ void vtkHandlerWidget::UpdateGizmoPosition() {
|
|||||||
if (bboxSize < 1e-6) bboxSize = 1.0;
|
if (bboxSize < 1e-6) bboxSize = 1.0;
|
||||||
|
|
||||||
double screenLimit = bboxSize * 2.0; // Default if no renderer
|
double screenLimit = bboxSize * 2.0; // Default if no renderer
|
||||||
if (this->CurrentRenderer) {
|
if (this->CurrentRenderer && this->CurrentRenderer->GetRenderWindow() && this->CurrentRenderer->GetRenderWindow()->GetInteractor()) {
|
||||||
int *sz = this->CurrentRenderer->GetSize();
|
int *sz = this->CurrentRenderer->GetSize();
|
||||||
if (sz[1] > 0) {
|
if (sz[1] > 0) {
|
||||||
double pixelSize = std::min(sz[0], sz[1]) / 5.0;
|
double pixelSize = std::min(sz[0], sz[1]) / 5.0;
|
||||||
vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
|
vtkCamera *cam = this->CurrentRenderer->GetActiveCamera();
|
||||||
if (cam->GetParallelProjection()) {
|
if (cam) {
|
||||||
screenLimit = (pixelSize / (double)sz[1]) * 2.0 * cam->GetParallelScale();
|
if (cam->GetParallelProjection()) {
|
||||||
} else {
|
screenLimit = (pixelSize / (double)sz[1]) * 2.0 * cam->GetParallelScale();
|
||||||
double dist = cam->GetDistance();
|
} else {
|
||||||
double angleRad = vtkMath::Pi() * cam->GetViewAngle() / 180.0;
|
double dist = cam->GetDistance();
|
||||||
double viewHeightAtDist = 2.0 * dist * tan(angleRad / 2.0);
|
double angleRad = vtkMath::Pi() * cam->GetViewAngle() / 180.0;
|
||||||
screenLimit = (pixelSize / (double)sz[1]) * viewHeightAtDist;
|
double viewHeightAtDist = 2.0 * dist * tan(angleRad / 2.0);
|
||||||
|
screenLimit = (pixelSize / (double)sz[1]) * viewHeightAtDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
double scaleFactor = std::min(bboxSize, screenLimit);
|
double scaleFactor = std::min(bboxSize, screenLimit);
|
||||||
|
|
||||||
vtkNew<vtkMatrix4x4> mat_gizmo;
|
vtkNew<vtkMatrix4x4> mat_gizmo;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <vtkMath.h>
|
#include <vtkMath.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
#include "vtkHandlerWidget.h"
|
#include "vtkHandlerWidget.h"
|
||||||
|
|
||||||
namespace uLib {
|
namespace uLib {
|
||||||
@@ -59,22 +60,45 @@ struct ViewportData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Viewport::Viewport()
|
Viewport::Viewport()
|
||||||
: d(new ViewportData())
|
: pv(new ViewportData())
|
||||||
, m_GridAxis(Y)
|
, m_GridAxis(Y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Viewport::~Viewport()
|
void Viewport::DisableHandler() {
|
||||||
{
|
if (pv->m_HandlerWidget) {
|
||||||
if (d->m_Renderer) {
|
pv->m_HandlerWidget->SetEnabled(0);
|
||||||
d->m_Renderer->RemoveAllViewProps();
|
|
||||||
}
|
}
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkRenderer* Viewport::GetRenderer() { return d->m_Renderer; }
|
Viewport::~Viewport()
|
||||||
vtkCornerAnnotation* Viewport::GetAnnotation() { return d->m_Annotation; }
|
{
|
||||||
vtkCameraOrientationWidget* Viewport::GetCameraWidget() { return d->m_CameraWidget; }
|
if (pv->m_HandlerWidget) {
|
||||||
|
pv->m_HandlerWidget->SetEnabled(0);
|
||||||
|
pv->m_HandlerWidget->SetInteractor(nullptr);
|
||||||
|
pv->m_HandlerWidget = nullptr;
|
||||||
|
}
|
||||||
|
if (pv->m_Renderer) {
|
||||||
|
if (pv->m_Renderer->GetActiveCamera()) {
|
||||||
|
pv->m_Renderer->GetActiveCamera()->RemoveAllObservers();
|
||||||
|
}
|
||||||
|
pv->m_Renderer->RemoveAllObservers();
|
||||||
|
pv->m_Renderer->RemoveAllViewProps();
|
||||||
|
}
|
||||||
|
if (pv->m_Marker && !std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
|
pv->m_Marker->SetEnabled(false);
|
||||||
|
pv->m_Marker->SetInteractor(nullptr);
|
||||||
|
}
|
||||||
|
if (pv->m_CameraWidget && !std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
|
pv->m_CameraWidget->Off();
|
||||||
|
pv->m_CameraWidget->SetInteractor(nullptr);
|
||||||
|
}
|
||||||
|
delete pv;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkRenderer* Viewport::GetRenderer() { return pv->m_Renderer; }
|
||||||
|
vtkCornerAnnotation* Viewport::GetAnnotation() { return pv->m_Annotation; }
|
||||||
|
vtkCameraOrientationWidget* Viewport::GetCameraWidget() { return pv->m_CameraWidget; }
|
||||||
|
|
||||||
void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||||
{
|
{
|
||||||
@@ -85,49 +109,51 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
|||||||
iren->SetInteractorStyle(style);
|
iren->SetInteractorStyle(style);
|
||||||
|
|
||||||
// Corner annotation
|
// Corner annotation
|
||||||
d->m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
pv->m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
||||||
d->m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
pv->m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
||||||
d->m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
pv->m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
||||||
d->m_Annotation->SetMaximumFontSize(10);
|
pv->m_Annotation->SetMaximumFontSize(10);
|
||||||
d->m_Annotation->SetText(0, "uLib VTK viewer.");
|
pv->m_Annotation->SetText(0, "uLib VTK viewer.");
|
||||||
d->m_Renderer->AddViewProp(d->m_Annotation);
|
pv->m_Renderer->AddViewProp(pv->m_Annotation);
|
||||||
|
|
||||||
// right corner annotation
|
// right corner annotation
|
||||||
d->m_Annotation->SetText(1, "Grid: -");
|
pv->m_Annotation->SetText(1, "Grid: -");
|
||||||
|
|
||||||
// Orientation axes marker (bottom-left corner)
|
// Orientation axes marker (bottom-left corner)
|
||||||
vtkNew<vtkAxesActor> axes;
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
d->m_Marker->SetInteractor(iren);
|
vtkNew<vtkAxesActor> axes;
|
||||||
d->m_Marker->SetOrientationMarker(axes);
|
pv->m_Marker->SetInteractor(iren);
|
||||||
d->m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
pv->m_Marker->SetOrientationMarker(axes);
|
||||||
d->m_Marker->SetEnabled(true);
|
pv->m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
||||||
d->m_Marker->InteractiveOff();
|
pv->m_Marker->SetEnabled(true);
|
||||||
|
pv->m_Marker->InteractiveOff();
|
||||||
|
}
|
||||||
|
|
||||||
// Grid Plane centered at (0,0,0)
|
// Grid Plane centered at (0,0,0)
|
||||||
d->m_GridSource = vtkSmartPointer<vtkPlaneSource>::New();
|
pv->m_GridSource = vtkSmartPointer<vtkPlaneSource>::New();
|
||||||
d->m_GridActor = vtkSmartPointer<vtkActor>::New();
|
pv->m_GridActor = vtkSmartPointer<vtkActor>::New();
|
||||||
vtkNew<vtkPolyDataMapper> gridMapper;
|
vtkNew<vtkPolyDataMapper> gridMapper;
|
||||||
gridMapper->SetInputConnection(d->m_GridSource->GetOutputPort());
|
gridMapper->SetInputConnection(pv->m_GridSource->GetOutputPort());
|
||||||
|
|
||||||
d->m_GridActor->SetMapper(gridMapper);
|
pv->m_GridActor->SetMapper(gridMapper);
|
||||||
d->m_GridActor->GetProperty()->SetRepresentationToWireframe();
|
pv->m_GridActor->GetProperty()->SetRepresentationToWireframe();
|
||||||
d->m_GridActor->GetProperty()->SetColor(0.4, 0.4, 0.4);
|
pv->m_GridActor->GetProperty()->SetColor(0.4, 0.4, 0.4);
|
||||||
d->m_GridActor->GetProperty()->SetLighting(0);
|
pv->m_GridActor->GetProperty()->SetLighting(0);
|
||||||
d->m_GridActor->GetProperty()->SetOpacity(0.5);
|
pv->m_GridActor->GetProperty()->SetOpacity(0.5);
|
||||||
d->m_GridActor->PickableOff();
|
pv->m_GridActor->PickableOff();
|
||||||
d->m_Renderer->AddActor(d->m_GridActor);
|
pv->m_Renderer->AddActor(pv->m_GridActor);
|
||||||
|
|
||||||
// Global Origin Axes
|
// Global Origin Axes
|
||||||
d->m_OriginAxes = vtkSmartPointer<vtkAxes>::New();
|
pv->m_OriginAxes = vtkSmartPointer<vtkAxes>::New();
|
||||||
d->m_OriginAxes->SetScaleFactor(1.0); // will be updated
|
pv->m_OriginAxes->SetScaleFactor(1.0); // will be updated
|
||||||
|
|
||||||
vtkNew<vtkPolyDataMapper> axesMapper;
|
vtkNew<vtkPolyDataMapper> axesMapper;
|
||||||
axesMapper->SetInputConnection(d->m_OriginAxes->GetOutputPort());
|
axesMapper->SetInputConnection(pv->m_OriginAxes->GetOutputPort());
|
||||||
|
|
||||||
d->m_OriginAxesActor = vtkSmartPointer<vtkActor>::New();
|
pv->m_OriginAxesActor = vtkSmartPointer<vtkActor>::New();
|
||||||
d->m_OriginAxesActor->SetMapper(axesMapper);
|
pv->m_OriginAxesActor->SetMapper(axesMapper);
|
||||||
d->m_OriginAxesActor->PickableOff();
|
pv->m_OriginAxesActor->PickableOff();
|
||||||
d->m_Renderer->AddActor(d->m_OriginAxesActor);
|
pv->m_Renderer->AddActor(pv->m_OriginAxesActor);
|
||||||
|
|
||||||
UpdateGrid();
|
UpdateGrid();
|
||||||
|
|
||||||
@@ -138,48 +164,52 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
|||||||
static_cast<Viewport*>(clientdata)->UpdateGrid();
|
static_cast<Viewport*>(clientdata)->UpdateGrid();
|
||||||
});
|
});
|
||||||
iren->AddObserver(vtkCommand::InteractionEvent, interactionCallback);
|
iren->AddObserver(vtkCommand::InteractionEvent, interactionCallback);
|
||||||
d->m_Renderer->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent, interactionCallback);
|
pv->m_Renderer->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent, interactionCallback);
|
||||||
|
|
||||||
|
|
||||||
// Camera-orientation widget (VTK >= 9)
|
// Camera-orientation widget (VTK >= 9)
|
||||||
#if VTK_MAJOR_VERSION >= 9
|
#if VTK_MAJOR_VERSION >= 9
|
||||||
d->m_CameraWidget = vtkSmartPointer<vtkCameraOrientationWidget>::New();
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
d->m_CameraWidget->SetParentRenderer(d->m_Renderer);
|
pv->m_CameraWidget = vtkSmartPointer<vtkCameraOrientationWidget>::New();
|
||||||
d->m_CameraWidget->SetInteractor(iren);
|
pv->m_CameraWidget->SetParentRenderer(pv->m_Renderer);
|
||||||
d->m_CameraWidget->On();
|
pv->m_CameraWidget->SetInteractor(iren);
|
||||||
|
pv->m_CameraWidget->On();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
d->m_Renderer->SetBackground(0.15, 0.15, 0.15);
|
pv->m_Renderer->SetBackground(0.15, 0.15, 0.15);
|
||||||
d->m_Renderer->ResetCamera();
|
pv->m_Renderer->ResetCamera();
|
||||||
|
|
||||||
// Setup layering for overimposed rendering
|
// Setup layering for overimposed rendering
|
||||||
if (iren->GetRenderWindow()) {
|
if (iren->GetRenderWindow()) {
|
||||||
iren->GetRenderWindow()->SetNumberOfLayers(2);
|
iren->GetRenderWindow()->SetNumberOfLayers(2);
|
||||||
d->m_Renderer->SetLayer(0);
|
pv->m_Renderer->SetLayer(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup Handler Widget
|
// Setup Handler Widget
|
||||||
d->m_HandlerWidget = vtkSmartPointer<vtkHandlerWidget>::New();
|
if (!std::getenv("CTEST_PROJECT_NAME")) {
|
||||||
d->m_HandlerWidget->SetInteractor(iren);
|
pv->m_HandlerWidget = vtkSmartPointer<vtkHandlerWidget>::New();
|
||||||
d->m_HandlerWidget->SetCurrentRenderer(d->m_Renderer);
|
pv->m_HandlerWidget->SetInteractor(iren);
|
||||||
if (d->m_HandlerWidget->GetOverlayRenderer()) {
|
pv->m_HandlerWidget->SetCurrentRenderer(pv->m_Renderer);
|
||||||
d->m_HandlerWidget->GetOverlayRenderer()->SetLayer(1);
|
if (pv->m_HandlerWidget->GetOverlayRenderer()) {
|
||||||
|
pv->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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pv->m_HandlerWidget->AddObserver(vtkCommand::InteractionEvent, widgetInteractionCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
d->m_HandlerWidget->AddObserver(vtkCommand::InteractionEvent, widgetInteractionCallback);
|
|
||||||
|
|
||||||
// Picking for selection
|
// Picking for selection
|
||||||
d->m_Picker = vtkSmartPointer<vtkCellPicker>::New();
|
pv->m_Picker = vtkSmartPointer<vtkCellPicker>::New();
|
||||||
vtkNew<vtkCallbackCommand> clickCallback;
|
vtkNew<vtkCallbackCommand> clickCallback;
|
||||||
clickCallback->SetClientData(this);
|
clickCallback->SetClientData(this);
|
||||||
clickCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){
|
clickCallback->SetCallback([](vtkObject* caller, unsigned long, void* clientdata, void*){
|
||||||
@@ -187,8 +217,8 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
|||||||
auto* self = static_cast<Viewport*>(clientdata);
|
auto* self = static_cast<Viewport*>(clientdata);
|
||||||
|
|
||||||
int* pos = iren->GetEventPosition();
|
int* pos = iren->GetEventPosition();
|
||||||
self->d->m_Picker->Pick(pos[0], pos[1], 0, self->d->m_Renderer);
|
self->pv->m_Picker->Pick(pos[0], pos[1], 0, self->pv->m_Renderer);
|
||||||
vtkProp* picked = self->d->m_Picker->GetViewProp();
|
vtkProp* picked = self->pv->m_Picker->GetViewProp();
|
||||||
|
|
||||||
Puppet* target = nullptr;
|
Puppet* target = nullptr;
|
||||||
if (picked) {
|
if (picked) {
|
||||||
@@ -224,59 +254,59 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
|||||||
iren->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
|
iren->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
|
||||||
|
|
||||||
// Keyboard events for widget coordinate frame
|
// Keyboard events for widget coordinate frame
|
||||||
d->m_KeyCallback = vtkSmartPointer<vtkCallbackCommand>::New();
|
pv->m_KeyCallback = vtkSmartPointer<vtkCallbackCommand>::New();
|
||||||
d->m_KeyCallback->SetClientData(this);
|
pv->m_KeyCallback->SetClientData(this);
|
||||||
d->m_KeyCallback->SetCallback([](vtkObject* caller, unsigned long event, void* clientdata, void*){
|
pv->m_KeyCallback->SetCallback([](vtkObject* caller, unsigned long event, void* clientdata, void*){
|
||||||
auto* iren = static_cast<vtkRenderWindowInteractor*>(caller);
|
auto* iren = static_cast<vtkRenderWindowInteractor*>(caller);
|
||||||
auto* self = static_cast<Viewport*>(clientdata);
|
auto* self = static_cast<Viewport*>(clientdata);
|
||||||
|
|
||||||
std::string key = iren->GetKeySym();
|
std::string key = iren->GetKeySym();
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
if (self->d->m_HandlerWidget && self->d->m_HandlerWidget->GetEnabled()) {
|
if (self->pv->m_HandlerWidget && self->pv->m_HandlerWidget->GetEnabled()) {
|
||||||
if (key == "l") {
|
if (key == "l") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::LOCAL);
|
self->pv->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::LOCAL);
|
||||||
std::cout << "Widget Frame: LOCAL" << std::endl;
|
std::cout << "Widget Frame: LOCAL" << std::endl;
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "g") {
|
else if (key == "g") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::GLOBAL);
|
self->pv->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::GLOBAL);
|
||||||
std::cout << "Widget Frame: GLOBAL" << std::endl;
|
std::cout << "Widget Frame: GLOBAL" << std::endl;
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "c") {
|
else if (key == "c") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER);
|
self->pv->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER);
|
||||||
std::cout << "Widget Frame: CENTER" << std::endl;
|
std::cout << "Widget Frame: CENTER" << std::endl;
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "k") {
|
else if (key == "k") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER_LOCAL);
|
self->pv->m_HandlerWidget->SetReferenceFrame(vtkHandlerWidget::CENTER_LOCAL);
|
||||||
std::cout << "Widget Frame: CENTER_LOCAL" << std::endl;
|
std::cout << "Widget Frame: CENTER_LOCAL" << std::endl;
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "1") {
|
else if (key == "1") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetTranslationEnabled(!self->d->m_HandlerWidget->GetTranslationEnabled());
|
self->pv->m_HandlerWidget->SetTranslationEnabled(!self->pv->m_HandlerWidget->GetTranslationEnabled());
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "2") {
|
else if (key == "2") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetRotationEnabled(!self->d->m_HandlerWidget->GetRotationEnabled());
|
self->pv->m_HandlerWidget->SetRotationEnabled(!self->pv->m_HandlerWidget->GetRotationEnabled());
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
else if (key == "3") {
|
else if (key == "3") {
|
||||||
if (event == vtkCommand::KeyPressEvent) {
|
if (event == vtkCommand::KeyPressEvent) {
|
||||||
self->d->m_HandlerWidget->SetScalingEnabled(!self->d->m_HandlerWidget->GetScalingEnabled());
|
self->pv->m_HandlerWidget->SetScalingEnabled(!self->pv->m_HandlerWidget->GetScalingEnabled());
|
||||||
}
|
}
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
@@ -290,12 +320,12 @@ void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (handled) {
|
if (handled) {
|
||||||
self->d->m_KeyCallback->SetAbortFlag(1);
|
self->pv->m_KeyCallback->SetAbortFlag(1);
|
||||||
iren->Render();
|
iren->Render();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
iren->AddObserver(vtkCommand::KeyPressEvent, d->m_KeyCallback, 1.0);
|
iren->AddObserver(vtkCommand::KeyPressEvent, pv->m_KeyCallback, 1.0);
|
||||||
iren->AddObserver(vtkCommand::CharEvent, d->m_KeyCallback, 1.0);
|
iren->AddObserver(vtkCommand::CharEvent, pv->m_KeyCallback, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::Reset()
|
void Viewport::Reset()
|
||||||
@@ -306,15 +336,15 @@ void Viewport::Reset()
|
|||||||
|
|
||||||
void Viewport::ZoomAuto()
|
void Viewport::ZoomAuto()
|
||||||
{
|
{
|
||||||
if (d->m_Renderer) {
|
if (pv->m_Renderer) {
|
||||||
d->m_Renderer->ResetCameraClippingRange();
|
pv->m_Renderer->ResetCameraClippingRange();
|
||||||
d->m_Renderer->ResetCamera();
|
pv->m_Renderer->ResetCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::ZoomSelected()
|
void Viewport::ZoomSelected()
|
||||||
{
|
{
|
||||||
if (!d->m_Renderer) return;
|
if (!pv->m_Renderer) return;
|
||||||
|
|
||||||
Puppet* selected = nullptr;
|
Puppet* selected = nullptr;
|
||||||
for (auto* p : m_Puppets) {
|
for (auto* p : m_Puppets) {
|
||||||
@@ -350,15 +380,15 @@ void Viewport::ZoomSelected()
|
|||||||
newBounds[2*i+1] = center[i] + 2.5 * current_h;
|
newBounds[2*i+1] = center[i] + 2.5 * current_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->m_Renderer->ResetCamera(newBounds);
|
pv->m_Renderer->ResetCamera(newBounds);
|
||||||
d->m_Renderer->ResetCameraClippingRange();
|
pv->m_Renderer->ResetCameraClippingRange();
|
||||||
this->Render();
|
this->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::AddPuppet(Puppet& prop)
|
void Viewport::AddPuppet(Puppet& prop)
|
||||||
{
|
{
|
||||||
m_Puppets.push_back(&prop);
|
m_Puppets.push_back(&prop);
|
||||||
prop.ConnectRenderer(d->m_Renderer);
|
prop.ConnectRenderer(pv->m_Renderer);
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +397,7 @@ void Viewport::RemovePuppet(Puppet& prop)
|
|||||||
if (prop.IsSelected()) SelectPuppet(nullptr);
|
if (prop.IsSelected()) SelectPuppet(nullptr);
|
||||||
auto it = std::find(m_Puppets.begin(), m_Puppets.end(), &prop);
|
auto it = std::find(m_Puppets.begin(), m_Puppets.end(), &prop);
|
||||||
if (it != m_Puppets.end()) m_Puppets.erase(it);
|
if (it != m_Puppets.end()) m_Puppets.erase(it);
|
||||||
prop.DisconnectRenderer(d->m_Renderer);
|
prop.DisconnectRenderer(pv->m_Renderer);
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,17 +407,17 @@ void Viewport::SelectPuppet(Puppet* prop)
|
|||||||
p->SetSelected(p == prop);
|
p->SetSelected(p == prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->m_HandlerWidget) {
|
if (pv->m_HandlerWidget) {
|
||||||
if (prop) {
|
if (prop) {
|
||||||
vtkProp3D* prop3d = vtkProp3D::SafeDownCast(prop->GetProp());
|
vtkProp3D* prop3d = vtkProp3D::SafeDownCast(prop->GetProp());
|
||||||
if (prop3d) {
|
if (prop3d) {
|
||||||
d->m_HandlerWidget->SetProp3D(prop3d);
|
pv->m_HandlerWidget->SetProp3D(prop3d);
|
||||||
d->m_HandlerWidget->SetEnabled(1);
|
pv->m_HandlerWidget->SetEnabled(1);
|
||||||
d->m_HandlerWidget->PlaceWidget(prop3d->GetBounds());
|
pv->m_HandlerWidget->PlaceWidget(prop3d->GetBounds());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d->m_HandlerWidget->SetEnabled(0);
|
pv->m_HandlerWidget->SetEnabled(0);
|
||||||
d->m_HandlerWidget->SetProp3D(nullptr);
|
pv->m_HandlerWidget->SetProp3D(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,16 +426,16 @@ void Viewport::SelectPuppet(Puppet* prop)
|
|||||||
|
|
||||||
void Viewport::SetGridVisible(bool visible)
|
void Viewport::SetGridVisible(bool visible)
|
||||||
{
|
{
|
||||||
if (d->m_GridActor) {
|
if (pv->m_GridActor) {
|
||||||
d->m_GridActor->SetVisibility(visible);
|
pv->m_GridActor->SetVisibility(visible);
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Viewport::GetGridVisible() const
|
bool Viewport::GetGridVisible() const
|
||||||
{
|
{
|
||||||
if (d->m_GridActor) {
|
if (pv->m_GridActor) {
|
||||||
return d->m_GridActor->GetVisibility() != 0;
|
return pv->m_GridActor->GetVisibility() != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -419,26 +449,26 @@ void Viewport::SetGridAxis(Axis axis)
|
|||||||
|
|
||||||
void Viewport::addProp(vtkProp* prop)
|
void Viewport::addProp(vtkProp* prop)
|
||||||
{
|
{
|
||||||
if (d->m_Renderer) {
|
if (pv->m_Renderer) {
|
||||||
d->m_Renderer->AddActor(prop);
|
pv->m_Renderer->AddActor(prop);
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::RemoveProp(vtkProp* prop)
|
void Viewport::RemoveProp(vtkProp* prop)
|
||||||
{
|
{
|
||||||
if (d->m_Renderer) {
|
if (pv->m_Renderer) {
|
||||||
d->m_Renderer->RemoveViewProp(prop);
|
pv->m_Renderer->RemoveViewProp(prop);
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport::UpdateGrid()
|
void Viewport::UpdateGrid()
|
||||||
{
|
{
|
||||||
if (!d->m_Renderer || !d->m_GridSource) return;
|
if (!pv->m_Renderer || !pv->m_GridSource) return;
|
||||||
if (d->m_GridActor && !d->m_GridActor->GetVisibility()) return;
|
if (pv->m_GridActor && !pv->m_GridActor->GetVisibility()) return;
|
||||||
|
|
||||||
vtkCamera* camera = d->m_Renderer->GetActiveCamera();
|
vtkCamera* camera = pv->m_Renderer->GetActiveCamera();
|
||||||
if (!camera) return;
|
if (!camera) return;
|
||||||
|
|
||||||
// Determine the "scale" of the view (how many units are visible vertically)
|
// Determine the "scale" of the view (how many units are visible vertically)
|
||||||
@@ -492,15 +522,15 @@ void Viewport::UpdateGrid()
|
|||||||
p1[idxH] = maxH; p1[idxV] = minV; p1[idxN] = centerN;
|
p1[idxH] = maxH; p1[idxV] = minV; p1[idxN] = centerN;
|
||||||
p2[idxH] = minH; p2[idxV] = maxV; p2[idxN] = centerN;
|
p2[idxH] = minH; p2[idxV] = maxV; p2[idxN] = centerN;
|
||||||
|
|
||||||
d->m_GridSource->SetOrigin(origin);
|
pv->m_GridSource->SetOrigin(origin);
|
||||||
d->m_GridSource->SetPoint1(p1);
|
pv->m_GridSource->SetPoint1(p1);
|
||||||
d->m_GridSource->SetPoint2(p2);
|
pv->m_GridSource->SetPoint2(p2);
|
||||||
d->m_GridSource->SetXResolution(numLines);
|
pv->m_GridSource->SetXResolution(numLines);
|
||||||
d->m_GridSource->SetYResolution(numLines);
|
pv->m_GridSource->SetYResolution(numLines);
|
||||||
d->m_GridSource->Update();
|
pv->m_GridSource->Update();
|
||||||
|
|
||||||
if (d->m_OriginAxes) {
|
if (pv->m_OriginAxes) {
|
||||||
d->m_OriginAxes->SetScaleFactor(spacing);
|
pv->m_OriginAxes->SetScaleFactor(spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update annotation for grid size
|
// Update annotation for grid size
|
||||||
@@ -512,7 +542,7 @@ void Viewport::UpdateGrid()
|
|||||||
} else {
|
} else {
|
||||||
sprintf(gridLabel, "Grid: %.0f mm", spacing);
|
sprintf(gridLabel, "Grid: %.0f mm", spacing);
|
||||||
}
|
}
|
||||||
d->m_Annotation->SetText(1, gridLabel);
|
pv->m_Annotation->SetText(1, gridLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public:
|
|||||||
virtual vtkRenderWindowInteractor* GetInteractor() = 0;
|
virtual vtkRenderWindowInteractor* GetInteractor() = 0;
|
||||||
vtkCornerAnnotation* GetAnnotation();
|
vtkCornerAnnotation* GetAnnotation();
|
||||||
vtkCameraOrientationWidget* GetCameraWidget();
|
vtkCameraOrientationWidget* GetCameraWidget();
|
||||||
|
void DisableHandler();
|
||||||
const std::vector<Puppet*>& getPuppets() const { return m_Puppets; }
|
const std::vector<Puppet*>& getPuppets() const { return m_Puppets; }
|
||||||
|
|
||||||
// Grid control
|
// Grid control
|
||||||
@@ -73,7 +74,7 @@ protected:
|
|||||||
|
|
||||||
void UpdateGrid();
|
void UpdateGrid();
|
||||||
|
|
||||||
struct ViewportData *d;
|
struct ViewportData *pv;
|
||||||
Axis m_GridAxis;
|
Axis m_GridAxis;
|
||||||
std::vector<Puppet*> m_Puppets;
|
std::vector<Puppet*> m_Puppets;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user