From 61052f80bc0d4777028584840adc96e0e2ccfe82 Mon Sep 17 00:00:00 2001 From: AndreaRigoni Date: Fri, 13 Mar 2026 17:19:51 +0000 Subject: [PATCH] add geant4 scene and gcompose app --- CMakeLists.txt | 12 +- app/CMakeLists.txt | 1 + app/gcompose/CMakeLists.txt | 20 + app/gcompose/src/main.cpp | 45 ++ conanfile.txt | 7 +- src/HEP/CMakeLists.txt | 1 + src/HEP/Detectors/ChamberHitEvent.h | 10 +- src/HEP/Detectors/Hit.h | 11 +- src/HEP/Geant/ActionInitialization.cpp | 25 + src/HEP/Geant/ActionInitialization.hh | 18 + src/HEP/Geant/CMakeLists.txt | 14 +- src/HEP/Geant/DetectorConstruction.cpp | 29 + src/HEP/Geant/DetectorConstruction.hh | 28 + src/HEP/Geant/EmitterPrimary.cpp | 50 ++ src/HEP/Geant/EmitterPrimary.hh | 23 + src/HEP/Geant/GeantEvent.h | 17 +- src/HEP/Geant/PhysicsList.cpp | 22 + src/HEP/Geant/PhysicsList.hh | 14 + src/HEP/Geant/Scene.cpp | 123 +++- src/HEP/Geant/Scene.h | 23 +- src/HEP/Geant/Solid.cpp | 172 +++-- src/HEP/Geant/Solid.h | 68 +- .../Geant/testing/ActionInitialization.cpp | 23 + src/HEP/Geant/testing/CMakeLists.txt | 14 + src/HEP/Geant/testing/EventTest.cpp | 72 ++ src/HEP/Geant/testing/GeantApp.cpp | 18 + src/HEP/Geant/testing/SolidTest.cpp | 69 ++ src/HEP/Geant/testing/testing-prototype.h | 37 + src/HEP/MuonTomography/Hit.h | 6 - src/HEP/MuonTomography/Makefile.am | 11 - src/Math/ContainerBox.h | 245 ++++--- src/Python/math_bindings.cpp | 687 ++++++++++-------- src/Vtk/HEP/Detectors/vtkDetectorChamber.cxx | 3 +- src/Vtk/vtkContainerBox.cpp | 3 +- 34 files changed, 1341 insertions(+), 580 deletions(-) create mode 100644 app/CMakeLists.txt create mode 100644 app/gcompose/CMakeLists.txt create mode 100644 app/gcompose/src/main.cpp create mode 100644 src/HEP/Geant/ActionInitialization.cpp create mode 100644 src/HEP/Geant/ActionInitialization.hh create mode 100644 src/HEP/Geant/DetectorConstruction.cpp create mode 100644 src/HEP/Geant/DetectorConstruction.hh create mode 100644 src/HEP/Geant/EmitterPrimary.cpp create mode 100644 src/HEP/Geant/EmitterPrimary.hh create mode 100644 src/HEP/Geant/PhysicsList.cpp create mode 100644 src/HEP/Geant/PhysicsList.hh create mode 100644 src/HEP/Geant/testing/ActionInitialization.cpp create mode 100644 src/HEP/Geant/testing/CMakeLists.txt create mode 100644 src/HEP/Geant/testing/EventTest.cpp create mode 100644 src/HEP/Geant/testing/GeantApp.cpp create mode 100644 src/HEP/Geant/testing/SolidTest.cpp create mode 100644 src/HEP/Geant/testing/testing-prototype.h delete mode 100644 src/HEP/MuonTomography/Makefile.am diff --git a/CMakeLists.txt b/CMakeLists.txt index 187bcc2..d60f236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,12 @@ ##### CMAKE LISTS ############################################################## ################################################################################ +if(EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake") + include("${CMAKE_BINARY_DIR}/conan_toolchain.cmake") +endif() + cmake_minimum_required (VERSION 3.26) + if(POLICY CMP0167) cmake_policy(SET CMP0167 NEW) endif() @@ -107,6 +112,8 @@ set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}") +find_package(HDF5 REQUIRED CONFIG) + find_package(Boost 1.45.0 COMPONENTS program_options serialization unit_test_framework REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) @@ -120,6 +127,9 @@ include(${ROOT_USE_FILE}) find_package(VTK REQUIRED) # include(${VTK_USE_FILE}) +set(GEANT4_USE_HDF5 OFF CACHE BOOL "Use HDF5" FORCE) +find_package(Geant4 REQUIRED) + find_package(pybind11 REQUIRED) @@ -216,7 +226,7 @@ add_subdirectory(${SRC_DIR}/Vtk) add_subdirectory(${SRC_DIR}/Python) -#add_subdirectory("${SRC_DIR}/utils/make_recipe") +add_subdirectory(app) ## Documentation and packages diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..c47cebd --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(gcompose) diff --git a/app/gcompose/CMakeLists.txt b/app/gcompose/CMakeLists.txt new file mode 100644 index 0000000..7d9ba8e --- /dev/null +++ b/app/gcompose/CMakeLists.txt @@ -0,0 +1,20 @@ + +add_executable(gcompose src/main.cpp) + +target_include_directories(gcompose PRIVATE + ${SRC_DIR} + ${PROJECT_BINARY_DIR} + ${Geant4_INCLUDE_DIRS} + ${VTK_INCLUDE_DIRS} +) + +target_link_libraries(gcompose + mutomCore + mutomMath + mutomGeant + mutomVtk + ${Geant4_LIBRARIES} + ${VTK_LIBRARIES} +) + +install(TARGETS gcompose RUNTIME DESTINATION bin) diff --git a/app/gcompose/src/main.cpp b/app/gcompose/src/main.cpp new file mode 100644 index 0000000..c63ebbb --- /dev/null +++ b/app/gcompose/src/main.cpp @@ -0,0 +1,45 @@ + +#include "Math/ContainerBox.h" +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +using namespace uLib; + +int main(int argc, char** argv) { + std::cout << "Starting gcompose application..." << std::endl; + + uLib::ContainerBox world_box(Vector3f(100, 100, 100)); + + uLib::Scene scene; + scene.ConstructWorldBox(&world_box, "G4_AIR"); + scene.Initialize(); + + // 2. Initialize VTK Viewer + Vtk::Viewer viewer; + + uLib::Vtk::vtkContainerBox vtk_box(&world_box); + viewer.AddPuppet(vtk_box); + + viewer.GetRenderer()->Render(); + + std::cout << "Geant4 and VTK scenes are ready." << std::endl; + std::cout << "Starting VTK Interactor..." << std::endl; + + // 3. Start VTK interactor (blocks until window is closed) + viewer.Start(); + + // 4. Clean up + std::cout << "Shutting down..." << std::endl; + + return 0; +} diff --git a/conanfile.txt b/conanfile.txt index 8af9f6f..5351bfb 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,8 +1,13 @@ [requires] eigen/3.4.0 boost/1.83.0 -pybind11/3.0.2 +# pybind11/3.0.2 +hdf5/1.14.3 [generators] CMakeDeps CMakeToolchain + +[options] +hdf5/*:threadsafe=True +hdf5/*:enable_unsupported=True diff --git a/src/HEP/CMakeLists.txt b/src/HEP/CMakeLists.txt index 58f2afc..1a497b1 100644 --- a/src/HEP/CMakeLists.txt +++ b/src/HEP/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories(${SRC_DIR}/HEP) add_subdirectory(Detectors) add_subdirectory(Geant) +# add_subdirectory(MuonTomography) set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE) set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE) diff --git a/src/HEP/Detectors/ChamberHitEvent.h b/src/HEP/Detectors/ChamberHitEvent.h index 7fbe98e..e69f62e 100644 --- a/src/HEP/Detectors/ChamberHitEvent.h +++ b/src/HEP/Detectors/ChamberHitEvent.h @@ -29,8 +29,8 @@ #define U_CHAMBERHITEVENT_H #include "Core/Vector.h" -#include "Hit.h" -#include "ChamberDetector.h" +#include "Detectors/HitMC.h" +#include "Detectors/DetectorChamber.h" namespace uLib { @@ -38,17 +38,17 @@ class ChamberHitEventData { public: uLibConstRefMacro (Hits, Vector ) - uLibGetMacro (Idv, ChamberDetector::ID) + uLibGetMacro (Idv, uint) private: friend class ChamberHitEvent; Vector m_Hits; - DetectorChamber::ID m_Idv; // -> chamber/view + uint m_Idv; // -> chamber/view }; class ChamberHitEvent : public ChamberHitEventData { public: uLibRefMacro (Hits, Vector ) - uLibSetMacro (Idv, ChamberDetector::ID) + uLibSetMacro (Idv, uint) }; } diff --git a/src/HEP/Detectors/Hit.h b/src/HEP/Detectors/Hit.h index 1261417..4f1db04 100644 --- a/src/HEP/Detectors/Hit.h +++ b/src/HEP/Detectors/Hit.h @@ -33,9 +33,6 @@ namespace uLib { - - - class HitRawCode_CMSDrift : public BitCode4 { @@ -59,7 +56,13 @@ public: }; - +class HitData { +public: + HitData() {} + ~HitData() {} + + +}; diff --git a/src/HEP/Geant/ActionInitialization.cpp b/src/HEP/Geant/ActionInitialization.cpp new file mode 100644 index 0000000..292a30f --- /dev/null +++ b/src/HEP/Geant/ActionInitialization.cpp @@ -0,0 +1,25 @@ +#include "ActionInitialization.hh" +#include "EmitterPrimary.hh" + +ActionInitialization::ActionInitialization() : G4VUserActionInitialization() {} + +ActionInitialization::~ActionInitialization() {} + +void ActionInitialization::BuildForMaster() const { + // Questo metodo viene usato in modalità Multi-Threading. + // Serve per le azioni che devono esistere solo nel thread Master + // (tipicamente solo per inizializzare file di output o il RunAction globale). + + // Esempio: SetUserAction(new RunAction()); +} + +void ActionInitialization::Build() const { + // Questo è il cuore dell'inizializzazione per i thread di lavoro. + // Qui passiamo il nostro generatore di muoni a Geant4. + SetUserAction(new EmitterPrimary()); + + // In una simulazione completa, qui registreresti anche le altre classi: + // SetUserAction(new RunAction()); + // SetUserAction(new EventAction()); + // SetUserAction(new SteppingAction()); +} \ No newline at end of file diff --git a/src/HEP/Geant/ActionInitialization.hh b/src/HEP/Geant/ActionInitialization.hh new file mode 100644 index 0000000..e61b531 --- /dev/null +++ b/src/HEP/Geant/ActionInitialization.hh @@ -0,0 +1,18 @@ +#ifndef ActionInitialization_h +#define ActionInitialization_h + +#include "G4VUserActionInitialization.hh" + +class ActionInitialization : public G4VUserActionInitialization { +public: + ActionInitialization(); + ~ActionInitialization(); + + // Metodo chiamato solo dal thread principale (Master) + virtual void BuildForMaster() const; + + // Metodo chiamato dai thread di lavoro (Worker) o in modalità sequenziale + virtual void Build() const; +}; + +#endif \ No newline at end of file diff --git a/src/HEP/Geant/CMakeLists.txt b/src/HEP/Geant/CMakeLists.txt index 92a2a36..a6801f5 100644 --- a/src/HEP/Geant/CMakeLists.txt +++ b/src/HEP/Geant/CMakeLists.txt @@ -3,8 +3,6 @@ ##### HEP/Geant - Geant4 integration library ################################### ################################################################################ -find_package(Geant4 QUIET) - if(NOT Geant4_FOUND) message(STATUS "Geant4 not found - skipping mutomGeant library") return() @@ -18,11 +16,18 @@ set(HEADERS Matter.h Scene.h Solid.h + DetectorConstruction.hh + PhysicsList.hh + ActionInitialization.hh ) set(SOURCES Scene.cpp Solid.cpp + EmitterPrimary.cpp + DetectorConstruction.cpp + PhysicsList.cpp + ActionInitialization.cpp ) set(libname ${PACKAGE_LIBPREFIX}Geant) @@ -50,3 +55,8 @@ install(TARGETS ${libname} install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/HEP/Geant) + +if(BUILD_TESTING) + include(uLibTargetMacros) + add_subdirectory(testing) +endif() diff --git a/src/HEP/Geant/DetectorConstruction.cpp b/src/HEP/Geant/DetectorConstruction.cpp new file mode 100644 index 0000000..d59daff --- /dev/null +++ b/src/HEP/Geant/DetectorConstruction.cpp @@ -0,0 +1,29 @@ + +#include "DetectorConstruction.hh" + +#include "Core/Object.h" +#include "Math/ContainerBox.h" + +#include "G4Box.hh" +#include "G4LogicalVolume.hh" +#include "G4NistManager.hh" +#include "G4PVPlacement.hh" +#include "G4RunManager.hh" +#include "G4SystemOfUnits.hh" + +namespace uLib { + +DetectorConstruction::DetectorConstruction(const char *name) : G4VUserDetectorConstruction() {} + +DetectorConstruction::~DetectorConstruction() {} + +G4VPhysicalVolume *DetectorConstruction::Construct() { return nullptr; } + +void DetectorConstruction::ConstructSDandField() {} + + + + + + +} \ No newline at end of file diff --git a/src/HEP/Geant/DetectorConstruction.hh b/src/HEP/Geant/DetectorConstruction.hh new file mode 100644 index 0000000..265b15c --- /dev/null +++ b/src/HEP/Geant/DetectorConstruction.hh @@ -0,0 +1,28 @@ +#ifndef DetectorConstruction_h +#define DetectorConstruction_h + +#include "Core/Object.h" +#include "G4VUserDetectorConstruction.hh" +#include "globals.hh" + +class G4VPhysicalVolume; +class G4LogicalVolume; + +namespace uLib { + +class DetectorConstruction : public G4VUserDetectorConstruction { +public: + DetectorConstruction(const char *name); + virtual ~DetectorConstruction(); + + virtual G4VPhysicalVolume *Construct(); + + virtual void ConstructSDandField(); +}; + +} // namespace uLib + +#endif + + + diff --git a/src/HEP/Geant/EmitterPrimary.cpp b/src/HEP/Geant/EmitterPrimary.cpp new file mode 100644 index 0000000..41c3989 --- /dev/null +++ b/src/HEP/Geant/EmitterPrimary.cpp @@ -0,0 +1,50 @@ +#include "EmitterPrimary.hh" + +#include "G4Box.hh" +#include "G4LogicalVolume.hh" +#include "G4LogicalVolumeStore.hh" +#include "G4ParticleDefinition.hh" +#include "G4ParticleGun.hh" +#include "G4ParticleTable.hh" +#include "G4RunManager.hh" +#include "G4SystemOfUnits.hh" +#include "Randomize.hh" + +EmitterPrimary::EmitterPrimary() + : G4VUserPrimaryGeneratorAction(), fParticleGun(nullptr) { + // Creiamo il ParticleGun impostandolo per sparare 1 particella alla volta + G4int n_particle = 1; + fParticleGun = new G4ParticleGun(n_particle); + + // Otteniamo la tabella delle particelle di Geant4 + G4ParticleTable *particleTable = G4ParticleTable::GetParticleTable(); + + // Cerchiamo il muone negativo (usa "mu+" per l'antimuone) + G4String particleName = "mu-"; + G4ParticleDefinition *particle = particleTable->FindParticle(particleName); + + // Configuriamo le proprietà iniziali della particella + fParticleGun->SetParticleDefinition(particle); + + // Impostiamo la direzione della quantità di moto (es. lungo l'asse Z) + fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., -1.)); + + // Impostiamo l'energia cinetica a 1 GeV + fParticleGun->SetParticleEnergy(1.0 * GeV); + + // Impostiamo la posizione di partenza (origine) + fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., 10. * m)); +} + +EmitterPrimary::~EmitterPrimary() { + // Importante: liberare la memoria + delete fParticleGun; +} + +void EmitterPrimary::GeneratePrimaries(G4Event *anEvent) { + // Questo metodo viene invocato all'inizio di ogni evento. + // Qui potresti anche aggiungere una randomizzazione della posizione o + // dell'energia. + + fParticleGun->GeneratePrimaryVertex(anEvent); +} \ No newline at end of file diff --git a/src/HEP/Geant/EmitterPrimary.hh b/src/HEP/Geant/EmitterPrimary.hh new file mode 100644 index 0000000..495e940 --- /dev/null +++ b/src/HEP/Geant/EmitterPrimary.hh @@ -0,0 +1,23 @@ +#ifndef U_GEANT_EMITTERPRIMARY_HH +#define U_GEANT_EMITTERPRIMARY_HH 1 + +#include "G4VUserPrimaryGeneratorAction.hh" +#include "globals.hh" + +class G4ParticleGun; +class G4Event; + +class EmitterPrimary : public G4VUserPrimaryGeneratorAction +{ + public: + EmitterPrimary(); + virtual ~EmitterPrimary(); + + // Metodo principale chiamato all'inizio di ogni evento + virtual void GeneratePrimaries(G4Event*); + + private: + G4ParticleGun* fParticleGun; // Puntatore al cannone di particelle +}; + +#endif \ No newline at end of file diff --git a/src/HEP/Geant/GeantEvent.h b/src/HEP/Geant/GeantEvent.h index c57f55c..ecbed19 100644 --- a/src/HEP/Geant/GeantEvent.h +++ b/src/HEP/Geant/GeantEvent.h @@ -30,17 +30,18 @@ #include "Core/Vector.h" #include "Math/Dense.h" -#include "ChamberHitEvent.h" +#include "Detectors/ChamberHitEvent.h" namespace uLib { class GeantEventData { public: -uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf) - uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f) - uLibConstRefMacro(ChEvents, Vector) + uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf) + uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f) + uLibConstRefMacro(ChEvents, Vector) - private : friend class GeantEvent; +private: + friend class GeantEvent; Id_t m_EventID; Scalarf m_Momentum; Vector3f m_GenPos; @@ -48,11 +49,11 @@ uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf) Vector m_ChEvents; }; -class GeantEvent { +class GeantEvent : public GeantEventData { public: uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf) - uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f) - uLibRefMacro(ChEvents, Vector) + uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f) + uLibRefMacro(ChEvents, Vector) }; } // namespace uLib diff --git a/src/HEP/Geant/PhysicsList.cpp b/src/HEP/Geant/PhysicsList.cpp new file mode 100644 index 0000000..7905146 --- /dev/null +++ b/src/HEP/Geant/PhysicsList.cpp @@ -0,0 +1,22 @@ +#include "PhysicsList.hh" + +#include "G4DecayPhysics.hh" +#include "G4EmStandardPhysics.hh" +#include "G4RadioactiveDecayPhysics.hh" + +PhysicsList::PhysicsList() : G4VModularPhysicsList() { + SetVerboseLevel(1); + + // Default physics + RegisterPhysics(new G4DecayPhysics()); + + // EM physics + RegisterPhysics(new G4EmStandardPhysics()); + + // Radioactive decay + RegisterPhysics(new G4RadioactiveDecayPhysics()); +} + +PhysicsList::~PhysicsList() {} + +void PhysicsList::SetCuts() { G4VModularPhysicsList::SetCuts(); } diff --git a/src/HEP/Geant/PhysicsList.hh b/src/HEP/Geant/PhysicsList.hh new file mode 100644 index 0000000..a497582 --- /dev/null +++ b/src/HEP/Geant/PhysicsList.hh @@ -0,0 +1,14 @@ +#ifndef PhysicsList_h +#define PhysicsList_h + +#include "G4VModularPhysicsList.hh" + +class PhysicsList : public G4VModularPhysicsList { +public: + PhysicsList(); + virtual ~PhysicsList(); + + virtual void SetCuts(); +}; + +#endif diff --git a/src/HEP/Geant/Scene.cpp b/src/HEP/Geant/Scene.cpp index 5cdfdd8..60af8da 100644 --- a/src/HEP/Geant/Scene.cpp +++ b/src/HEP/Geant/Scene.cpp @@ -23,52 +23,127 @@ //////////////////////////////////////////////////////////////////////////////*/ - - - - +#include +#include #include #include -#include +#include +#include +#include +#include +#include #include "Core/Vector.h" -#include "Matter.h" +#include "HEP/Geant/DetectorConstruction.hh" +#include "Math/ContainerBox.h" +#include "Math/Dense.h" #include "Solid.h" #include "Scene.h" - +#include "PhysicsList.hh" +#include "ActionInitialization.hh" namespace uLib { - -class DetectorsScenePimpl { - +class SceneDetectorConstruction : public DetectorConstruction { public: - - - // members // - //Vector m_Solids; + SceneDetectorConstruction(class SceneImpl *owner); + G4VPhysicalVolume *Construct() override; +private: + class SceneImpl *m_Owner; }; +class SceneImpl { +public: + // constructor // + SceneImpl() : m_RunManager(G4RunManagerFactory::CreateRunManager()) {} + // destructor // + ~SceneImpl() { + if (m_RunManager) delete m_RunManager; + if (m_World) delete m_World; + } + void Initialize() { + // Set mandatory initialization classes for Geant4 + m_RunManager->SetUserInitialization(new SceneDetectorConstruction(this)); + m_RunManager->SetUserInitialization(new PhysicsList); + m_RunManager->SetUserInitialization(new ActionInitialization); -DetectorsScene::DetectorsScene() : - d(new DetectorsScenePimpl()) -{} + // Initialize Geant4 + m_RunManager->Initialize(); + } -DetectorsScene::~DetectorsScene() -{ - delete d; -} + // members // + Vector m_Solids; + Solid *m_World = nullptr; + G4RunManager *m_RunManager; +}; -void DetectorsScene::AddSolid(const Solid &solid) -{ -// d->m_Solids.push_back(solid); +SceneDetectorConstruction::SceneDetectorConstruction(SceneImpl *owner) + : DetectorConstruction("Scene"), m_Owner(owner) {} + +G4VPhysicalVolume *SceneDetectorConstruction::Construct() { + return m_Owner->m_World->GetPhysical(); } + + +Scene::Scene() : d(new SceneImpl()) {} +Scene::~Scene() { delete d; } + +void Scene::AddSolid(Solid *solid, Solid *parent) { + d->m_Solids.push_back(solid); + if (!d->m_World) { + d->m_World = solid; + } else { + solid->SetParent(parent ? parent : d->m_World); + } } + +void Scene::ConstructWorldBox(const ContainerBox *box, const char *material) { + // Get nist material manager + if (!d->m_World) { + d->m_World = new Solid("World"); + d->m_World->SetNistMaterial(material); + AddSolid(d->m_World); + } + + Vector3f size = box->GetSize(); + + G4Box *solidWorld = new G4Box("World", + 0.5 * size(0), + 0.5 * size(1), + 0.5 * size(2)); + + G4LogicalVolume *logicWorld = new G4LogicalVolume(solidWorld, + d->m_World->GetMaterial(), + d->m_World->GetName()); + + d->m_World->SetLogical(logicWorld); + + G4PVPlacement *physWorld = new G4PVPlacement( + nullptr, + G4ThreeVector(0, 0, 0), + logicWorld, + d->m_World->GetName(), + 0, + false, + 0, + true); + + d->m_World->SetPhysical(physWorld); + + Matrix4f transform = box->GetMatrix(); + d->m_World->SetTransform(transform); +} + +void Scene::Initialize() { + d->Initialize(); +} + +} // namespace uLib diff --git a/src/HEP/Geant/Scene.h b/src/HEP/Geant/Scene.h index e7c7edb..6560a69 100644 --- a/src/HEP/Geant/Scene.h +++ b/src/HEP/Geant/Scene.h @@ -23,30 +23,33 @@ //////////////////////////////////////////////////////////////////////////////*/ - - #ifndef SCENE_H #define SCENE_H + + #include "Core/Object.h" #include "Core/Vector.h" #include "Solid.h" +class G4VPhysicalVolume; + namespace uLib { - -class DetectorsScene : public Object { +class Scene : public Object { public: - DetectorsScene(); - ~DetectorsScene(); + Scene(); + ~Scene(); + void AddSolid(Solid *solid, Solid *parent = nullptr); + + void ConstructWorldBox(const ContainerBox *box, const char *material); - void AddSolid(const Solid &solid); + void Initialize(); private: - class DetectorsScenePimpl *d; + class SceneImpl *d; }; - -} +} // namespace uLib #endif // SCENE_H diff --git a/src/HEP/Geant/Solid.cpp b/src/HEP/Geant/Solid.cpp index 46597b2..993d0e5 100644 --- a/src/HEP/Geant/Solid.cpp +++ b/src/HEP/Geant/Solid.cpp @@ -23,20 +23,21 @@ //////////////////////////////////////////////////////////////////////////////*/ - - // G4 Solid // +#include #include #include -#include // Tessellated solid // #include -#include #include +#include +#include +#include #include "Math/Dense.h" +#include "Math/Transform.h" #include "Solid.h" @@ -44,71 +45,130 @@ namespace uLib { class DetectorsSolidPimpl { public: - static G4ThreeVector getG4Vector3f(const Vector3f &vector) { - return G4ThreeVector( vector(0), vector(1), vector(2) ); - } + static G4ThreeVector getG4Vector3f(const Vector3f &vector) { + return G4ThreeVector(vector(0), vector(1), vector(2)); + } }; +Solid::Solid() + : m_Logical(new G4LogicalVolume(NULL, NULL, "unnamed_solid")), + m_Material(NULL) {} +Solid::Solid(const char *name) + : m_Logical(new G4LogicalVolume(NULL, NULL, name)), m_Material(NULL) {} -Solid::Solid() : - m_Logical (new G4LogicalVolume(NULL,NULL,"unnamed_solid")), - m_Material(NULL) -{} - -Solid::Solid(const char *name) : - m_Logical(new G4LogicalVolume(NULL,NULL,name)), - m_Material(NULL) -{} - - - -void Solid::SetNistMaterial(const char *name) -{ - G4NistManager *nist = G4NistManager::Instance(); - if (m_Material) delete m_Material; - m_Material = nist->FindOrBuildMaterial(name); - m_Logical->SetMaterial(m_Material); +void Solid::SetNistMaterial(const char *name) { + G4NistManager *nist = G4NistManager::Instance(); + m_Material = nist->FindOrBuildMaterial(name); + m_Logical->SetMaterial(m_Material); } -void Solid::SetMaterial(G4Material *material) -{ - if(material) - { - m_Material = material; - m_Logical->SetMaterial(material); +void Solid::SetMaterial(G4Material *material) { + if (material) { + m_Material = material; + m_Logical->SetMaterial(material); + } +} + +void Solid::SetTransform(Matrix4f transform) { + uLib::AffineTransform t; + t.SetMatrix(transform); + + // 2. Extracto position and rotation for Geant4 + Vector3f pos = t.GetPosition(); + G4ThreeVector g4pos(pos(0), pos(1), pos(2)); + + // Create a G4 rotation matrix from the 4x4 matrix + Matrix3f m = t.GetRotation(); + G4RotationMatrix* rot = new G4RotationMatrix(); + rot->set(G4ThreeVector(m(0,0), m(1,0), m(2,0)), + G4ThreeVector(m(0,1), m(1,1), m(2,1)), + G4ThreeVector(m(0,2), m(1,2), m(2,2))); + + // 3. Se l'oggetto è già stato piazzato, aggiorniamo la sua trasformazione + if (m_Physical) { + m_Physical->SetTranslation(g4pos); + m_Physical->SetRotation(rot); } } +void Solid::SetParent(Solid *parent) { + if (!m_Logical) { + std::cerr << "logical volume not created for solid " << GetName() << std::endl; + return; + } + if(m_Physical) { + std::cerr << "physical volume already created for solid " << GetName() << std::endl; + return; + } - - - - - - - -TessellatedSolid::TessellatedSolid(const char *name) : - BaseClass(name), - m_Solid(new G4TessellatedSolid(name)) -{} - - -void TessellatedSolid::SetMesh(TriangleMesh &mesh) -{ - G4TessellatedSolid *ts = this->m_Solid; - for (int i=0; iAddFacet((G4VFacet *)facet); + G4LogicalVolume* parentLogical = nullptr; + if (parent) { + parentLogical = parent->GetLogical(); + if (!parentLogical) { + std::cerr << "parent logical volume not created for solid " << parent->GetName() << std::endl; + return; } - this->m_Logical->SetSolid(ts); + } + + // G4PVPlacement + m_Physical = new G4PVPlacement( + nullptr, // Rotation + G4ThreeVector(0,0,0), // Position (translation) inside the parent + m_Logical, // The logical volume of this solid (the child) + GetName(), // Name of the physical volume + parentLogical, // The logical volume of the parent (nullptr if it's the World volume) + false, // Boolean operations (usually false) + 0, // Copy number + true // Check overlaps (useful to enable in debug phase) + ); } + + + + + +TessellatedSolid::TessellatedSolid(const char *name) + : BaseClass(name), m_Solid(new G4TessellatedSolid(name)) {} + +void TessellatedSolid::SetMesh(TriangleMesh &mesh) { + G4TessellatedSolid *ts = this->m_Solid; + for (int i = 0; i < mesh.Triangles().size(); ++i) { + const Vector3i &trg = mesh.Triangles().at(i); + G4TriangularFacet *facet = new G4TriangularFacet( + DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(0))), + DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(1))), + DetectorsSolidPimpl::getG4Vector3f(mesh.Points().at(trg(2))), ABSOLUTE); + ts->AddFacet((G4VFacet *)facet); + } + this->m_Logical->SetSolid(ts); } + + + + + +BoxSolid::BoxSolid(const char *name, ContainerBox *box) : BaseClass(name) { + m_Solid = new G4Box(name, 0.5, 0.5, 0.5); + m_Object = box; + Object::connect(box, &ContainerBox::Updated, this, &BoxSolid::Update); + this->m_Logical->SetSolid(m_Solid); +} + +void BoxSolid::Update() { + if (m_Object) { + Vector3f size = m_Object->GetSize(); + m_Solid->SetXHalfLength(size(0) * 0.5); + m_Solid->SetYHalfLength(size(1) * 0.5); + m_Solid->SetZHalfLength(size(2) * 0.5); + + this->SetTransform(m_Object->GetMatrix()); + // this->m_Logical->SetSolid(m_Solid); + } +} + + +} // namespace uLib diff --git a/src/HEP/Geant/Solid.h b/src/HEP/Geant/Solid.h index 7babd27..fc81ec3 100644 --- a/src/HEP/Geant/Solid.h +++ b/src/HEP/Geant/Solid.h @@ -23,39 +23,51 @@ //////////////////////////////////////////////////////////////////////////////*/ - - #ifndef SOLID_H #define SOLID_H #include "Core/Object.h" +#include "Geant/Matter.h" +#include +#include "Math/ContainerBox.h" #include "Math/Dense.h" #include "Math/TriangleMesh.h" -#include "Detectors/Matter.h" class G4Material; class G4LogicalVolume; class G4TessellatedSolid; - +class G4Box; namespace uLib { class Solid : public Object { public: + Solid(); + Solid(const char *name); - Solid(); - Solid(const char *name); + void SetNistMaterial(const char *name); + void SetMaterial(G4Material *material); - void SetNistMaterial(const char *name); + // Implementiamo SetParent qui, per tutti. + virtual void SetParent(Solid *parent); - void SetMaterial(G4Material *material); + // Setters per la posizione (necessari per il piazzamento) + void SetTransform(Matrix4f transform); - uLibGetMacro(Material,G4Material *) - uLibGetMacro(Logical,G4LogicalVolume *) + uLibGetMacro(Material, G4Material *) + uLibGetSetMacro(Logical, G4LogicalVolume *) + uLibGetSetMacro(Physical, G4VPhysicalVolume *) -protected: - G4Material *m_Material; - G4LogicalVolume *m_Logical; + inline const char *GetName() const { return m_Logical->GetName().c_str(); } + +protected: + + G4Material *m_Material; + G4LogicalVolume *m_Logical; + G4VPhysicalVolume *m_Physical; // <-- Memorizza l'oggetto posizionato + + G4ThreeVector *m_Position; // <-- Offset rispetto al centro del padre + G4RotationMatrix* m_Rotation; // <-- Rotazione rispetto al padre }; @@ -63,24 +75,38 @@ protected: class TessellatedSolid : public Solid { - typedef Solid BaseClass; - + typedef Solid BaseClass; public: - TessellatedSolid(const char *name); + TessellatedSolid(const char *name); + void SetMesh(TriangleMesh &mesh); + uLibGetMacro(Solid, G4TessellatedSolid *) - void SetMesh(TriangleMesh &mesh); +public slots: + void Update(); - uLibGetMacro(Solid,G4TessellatedSolid *) -private: - G4TessellatedSolid *m_Solid; +private : + G4TessellatedSolid *m_Solid; }; -} +class BoxSolid : public Solid { + typedef Solid BaseClass; +public: + BoxSolid(const char *name, ContainerBox *box); + +public slots: + void Update(); + +private: + ContainerBox *m_Object; + G4Box *m_Solid; +}; + +} // namespace uLib #endif // SOLID_H diff --git a/src/HEP/Geant/testing/ActionInitialization.cpp b/src/HEP/Geant/testing/ActionInitialization.cpp new file mode 100644 index 0000000..341c525 --- /dev/null +++ b/src/HEP/Geant/testing/ActionInitialization.cpp @@ -0,0 +1,23 @@ +#include "HEP/Geant/ActionInitialization.hh" // Il file appena creato +#include "G4RunManagerFactory.hh" // Per il RunManager moderno +// ... altri include (DetectorConstruction, PhysicsList, ecc.) + +int main(int argc, char **argv) { + // Creazione del Run Manager + auto *runManager = G4RunManagerFactory::CreateRunManager(); + + // 1. Inizializzazione della Geometria + // runManager->SetUserInitialization(new DetectorConstruction()); + + // 2. Inizializzazione della Fisica + // runManager->SetUserInitialization(new PhysicsList()); + + // 3. INIZIALIZZAZIONE DELLE AZIONI (Il nostro generatore!) + runManager->SetUserInitialization(new ActionInitialization()); + + // ... Inizializzazione del kernel ( runManager->Initialize(); ), UI manager, + // vis manager, ecc. + + delete runManager; + return 0; +} \ No newline at end of file diff --git a/src/HEP/Geant/testing/CMakeLists.txt b/src/HEP/Geant/testing/CMakeLists.txt new file mode 100644 index 0000000..2c9b3cd --- /dev/null +++ b/src/HEP/Geant/testing/CMakeLists.txt @@ -0,0 +1,14 @@ +# TESTS +set(TESTS + SolidTest + EventTest + GeantApp +) + +set(LIBRARIES + ${PACKAGE_LIBPREFIX}Core + ${PACKAGE_LIBPREFIX}Math + ${PACKAGE_LIBPREFIX}Geant + Eigen3::Eigen +) +uLib_add_tests(Geant) diff --git a/src/HEP/Geant/testing/EventTest.cpp b/src/HEP/Geant/testing/EventTest.cpp new file mode 100644 index 0000000..19db892 --- /dev/null +++ b/src/HEP/Geant/testing/EventTest.cpp @@ -0,0 +1,72 @@ +#include "Geant/Solid.h" +#include "HEP/Geant/GeantEvent.h" +#include "Math/TriangleMesh.h" +#include "testing-prototype.h" +#include +#include +#include +#include +#include + +using namespace uLib; + +int main() { + BEGIN_TESTING(Geant Event); + + // Test Solid initialization and NIST material // + { + Solid solid("test_solid"); + TEST1(solid.GetLogical() != nullptr); + + solid.SetNistMaterial("G4_AIR"); + TEST1(solid.GetMaterial() != nullptr); + TEST1(solid.GetMaterial()->GetName() == "G4_AIR"); + } + + // Test TessellatedSolid with a simple mesh // + { + TessellatedSolid tsolid("test_tessellated"); + TEST1(tsolid.GetLogical() != nullptr); + TEST1(tsolid.GetSolid() != nullptr); + + // cube mesh // + TriangleMesh mesh; + mesh.AddPoint(Vector3f(0,0,0)); + mesh.AddPoint(Vector3f(1,0,0)); + mesh.AddPoint(Vector3f(0,1,0)); + mesh.AddPoint(Vector3f(1,1,0)); + mesh.AddPoint(Vector3f(0,0,1)); + mesh.AddPoint(Vector3f(1,0,1)); + mesh.AddPoint(Vector3f(0,1,1)); + mesh.AddPoint(Vector3f(1,1,1)); + + // create triangles (consistent outward winding) // + // bottom (z=0) + mesh.AddTriangle(Vector3i(0,2,3)); + mesh.AddTriangle(Vector3i(0,3,1)); + // top (z=1) + mesh.AddTriangle(Vector3i(4,5,7)); + mesh.AddTriangle(Vector3i(4,7,6)); + // left (x=0) + mesh.AddTriangle(Vector3i(0,4,6)); + mesh.AddTriangle(Vector3i(0,6,2)); + // right (x=1) + mesh.AddTriangle(Vector3i(1,3,7)); + mesh.AddTriangle(Vector3i(1,7,5)); + // front (y=0) + mesh.AddTriangle(Vector3i(0,1,5)); + mesh.AddTriangle(Vector3i(0,5,4)); + // back (y=1) + mesh.AddTriangle(Vector3i(2,6,7)); + mesh.AddTriangle(Vector3i(2,7,3)); + + + + tsolid.SetMesh(mesh); + // GeantEvent geant_event; + + + } + + END_TESTING +} diff --git a/src/HEP/Geant/testing/GeantApp.cpp b/src/HEP/Geant/testing/GeantApp.cpp new file mode 100644 index 0000000..67634d1 --- /dev/null +++ b/src/HEP/Geant/testing/GeantApp.cpp @@ -0,0 +1,18 @@ + + +#include "Math/ContainerBox.h" +#include "Math/Dense.h" +#include "HEP/Geant/Scene.h" + +using namespace uLib; + +int main() { + + uLib::ContainerBox world_box(Vector3f(100, 100, 100)); + uLib::Scene scene; + + scene.ConstructWorldBox(&world_box, "G4_AIR"); + scene.Initialize(); + + return 0; +} diff --git a/src/HEP/Geant/testing/SolidTest.cpp b/src/HEP/Geant/testing/SolidTest.cpp new file mode 100644 index 0000000..2d5914e --- /dev/null +++ b/src/HEP/Geant/testing/SolidTest.cpp @@ -0,0 +1,69 @@ +#include "Geant/Solid.h" +#include "Math/TriangleMesh.h" +#include "testing-prototype.h" +#include +#include +#include +#include +#include + +using namespace uLib; + +int main() { + BEGIN_TESTING(Geant Solid); + + // Test Solid initialization and NIST material // + { + Solid solid("test_solid"); + TEST1(solid.GetLogical() != nullptr); + + solid.SetNistMaterial("G4_AIR"); + TEST1(solid.GetMaterial() != nullptr); + TEST1(solid.GetMaterial()->GetName() == "G4_AIR"); + } + + // Test TessellatedSolid with a simple mesh // + { + TessellatedSolid tsolid("test_tessellated"); + TEST1(tsolid.GetLogical() != nullptr); + TEST1(tsolid.GetSolid() != nullptr); + + // cube mesh // + TriangleMesh mesh; + mesh.AddPoint(Vector3f(0,0,0)); + mesh.AddPoint(Vector3f(1,0,0)); + mesh.AddPoint(Vector3f(0,1,0)); + mesh.AddPoint(Vector3f(1,1,0)); + mesh.AddPoint(Vector3f(0,0,1)); + mesh.AddPoint(Vector3f(1,0,1)); + mesh.AddPoint(Vector3f(0,1,1)); + mesh.AddPoint(Vector3f(1,1,1)); + + // create triangles (consistent outward winding) // + // bottom (z=0) + mesh.AddTriangle(Vector3i(0,2,3)); + mesh.AddTriangle(Vector3i(0,3,1)); + // top (z=1) + mesh.AddTriangle(Vector3i(4,5,7)); + mesh.AddTriangle(Vector3i(4,7,6)); + // left (x=0) + mesh.AddTriangle(Vector3i(0,4,6)); + mesh.AddTriangle(Vector3i(0,6,2)); + // right (x=1) + mesh.AddTriangle(Vector3i(1,3,7)); + mesh.AddTriangle(Vector3i(1,7,5)); + // front (y=0) + mesh.AddTriangle(Vector3i(0,1,5)); + mesh.AddTriangle(Vector3i(0,5,4)); + // back (y=1) + mesh.AddTriangle(Vector3i(2,6,7)); + mesh.AddTriangle(Vector3i(2,7,3)); + + + + tsolid.SetMesh(mesh); + TEST1(tsolid.GetSolid()->GetNumberOfFacets() == 12); + } + + END_TESTING +} diff --git a/src/HEP/Geant/testing/testing-prototype.h b/src/HEP/Geant/testing/testing-prototype.h new file mode 100644 index 0000000..39f4e6c --- /dev/null +++ b/src/HEP/Geant/testing/testing-prototype.h @@ -0,0 +1,37 @@ +/*////////////////////////////////////////////////////////////////////////////// +// 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 + +#define BEGIN_TESTING(name) \ +static int _fail = 0; \ +printf("..:: Testing " #name " ::..\n"); + +#define TEST1(val) _fail += (val)==0 +#define TEST0(val) _fail += (val)!=0 +#define END_TESTING return _fail; + diff --git a/src/HEP/MuonTomography/Hit.h b/src/HEP/MuonTomography/Hit.h index a5b071a..63f79f4 100644 --- a/src/HEP/MuonTomography/Hit.h +++ b/src/HEP/MuonTomography/Hit.h @@ -39,12 +39,6 @@ class Hit { Type m_DriftTime; }; - - - - - - class HitMC { public: virtual Id_t GetChamber() = 0; diff --git a/src/HEP/MuonTomography/Makefile.am b/src/HEP/MuonTomography/Makefile.am deleted file mode 100644 index d169be8..0000000 --- a/src/HEP/MuonTomography/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -include $(top_srcdir)/Common.am - -library_includedir = $(includedir)/libmutom-${PACKAGE_VERSION}/ParticlePhysics/MuonTomography -library_include_HEADERS = - -_PPMUTOM_SOURCES = - -noinst_LTLIBRARIES = libmutomppmutom.la -libmutomppmutom_la_SOURCES = ${_PPMUTOM_SOURCES} - - diff --git a/src/Math/ContainerBox.h b/src/Math/ContainerBox.h index 04a7a89..fc20538 100644 --- a/src/Math/ContainerBox.h +++ b/src/Math/ContainerBox.h @@ -23,160 +23,165 @@ //////////////////////////////////////////////////////////////////////////////*/ - - #ifndef U_CONTAINERBOX_H #define U_CONTAINERBOX_H #include "Geometry.h" +#include "Core/Object.h" #include "Math/Dense.h" #include "Math/Transform.h" #include - namespace uLib { - - /** - * @brief Represents an oriented bounding box (OBB) within a hierarchical transformation system. + * @brief Represents an oriented bounding box (OBB) within a hierarchical + * transformation system. * - * ContainerBox inherits from AffineTransform, which defines its parent coordinate system. - * It contains an internal local transformation (m_LocalT) that defines the box's - * specific origin and size relative to its own coordinate system. + * ContainerBox inherits from AffineTransform, which defines its parent + * coordinate system. It contains an internal local transformation (m_LocalT) + * that defines the box's specific origin and size relative to its own + * coordinate system. */ -class ContainerBox : public AffineTransform { +class ContainerBox : public AffineTransform, public Object { - typedef AffineTransform BaseClass; + typedef AffineTransform BaseClass; public: - /** - * @brief Default constructor. - * Initializes the local transformation with this instance as its parent. - */ - ContainerBox() : - m_LocalT(this) // BaseClass is Parent of m_LocalTransform - {} + /** + * @brief Default constructor. + * Initializes the local transformation with this instance as its parent. + */ + ContainerBox() + : m_LocalT(this) // BaseClass is Parent of m_LocalTransform + {} - /** - * @brief Copy constructor. - * @param copy The ContainerBox instance to copy from. - */ - ContainerBox(const ContainerBox ©) : - m_LocalT(this), // BaseClass is Parent of m_LocalTransform - AffineTransform(copy) - { - this->SetOrigin(copy.GetOrigin()); - this->SetSize(copy.GetSize()); - } + /** + * @brief Constructor with size. + * @param size The size vector. + */ + ContainerBox(const Vector3f &size) : m_LocalT(this) { this->SetSize(size); } - /** - * @brief Sets the box origin relative to its coordinate system. - * @param v The origin position vector. - */ - inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); } + /** + * @brief Copy constructor. + * @param copy The ContainerBox instance to copy from. + */ + ContainerBox(const ContainerBox ©) + : m_LocalT(this), // BaseClass is Parent of m_LocalTransform + AffineTransform(copy) { + this->SetOrigin(copy.GetOrigin()); + this->SetSize(copy.GetSize()); + } - /** - * @brief Gets the box origin relative to its coordinate system. - * @return The origin position vector. - */ - inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); } + /** + * @brief Sets the box origin relative to its coordinate system. + * @param v The origin position vector. + */ + inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); } - /** - * @brief Sets the size of the box. - * Re-initializes the local transformation and applies the new scale. - * @param v The size vector (width, height, depth). - */ - void SetSize(const Vector3f &v) { - Vector3f pos = this->GetOrigin(); - m_LocalT = AffineTransform(this); // regenerate local transform - m_LocalT.Scale(v); - m_LocalT.SetPosition(pos); - } + /** + * @brief Gets the box origin relative to its coordinate system. + * @return The origin position vector. + */ + inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); } - /** - * @brief Gets the current size (scale) of the box. - * @return The size vector. - */ - inline Vector3f GetSize() const { return m_LocalT.GetScale(); } + /** + * @brief Sets the size of the box. + * Re-initializes the local transformation and applies the new scale. + * @param v The size vector (width, height, depth). + */ + void SetSize(const Vector3f &v) { + Vector3f pos = this->GetOrigin(); + m_LocalT = AffineTransform(this); // regenerate local transform + m_LocalT.Scale(v); + m_LocalT.SetPosition(pos); + } - /** - * @brief Swaps two local axes of the box. - * @param first Index of the first axis (0=X, 1=Y, 2=Z). - * @param second Index of the second axis (0=X, 1=Y, 2=Z). - */ - inline void FlipLocalAxes(int first, int second) - { m_LocalT.FlipAxes(first,second); } + /** + * @brief Gets the current size (scale) of the box. + * @return The size vector. + */ + inline Vector3f GetSize() const { return m_LocalT.GetScale(); } - /** - * @brief Returns the world transformation matrix of the box's volume. - * @return A 4x4 transformation matrix. - */ - Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } + /** + * @brief Swaps two local axes of the box. + * @param first Index of the first axis (0=X, 1=Y, 2=Z). + * @param second Index of the second axis (0=X, 1=Y, 2=Z). + */ + inline void FlipLocalAxes(int first, int second) { + m_LocalT.FlipAxes(first, second); + } - /** - * @brief Returns the local transformation matrix of the box's volume. - * @return A 4x4 transformation matrix. - */ - Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); } + /** + * @brief Returns the world transformation matrix of the box's volume. + * @return A 4x4 transformation matrix. + */ + Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } - /** - * @brief Transforms a point from box-local space to world space. - * @param v The local point (4D homogeneous vector). - * @return The transformed point in world space. - */ - inline Vector4f GetWorldPoint(const Vector4f &v) const { - return m_LocalT.GetWorldMatrix() * v; - } + /** + * @brief Returns the local transformation matrix of the box's volume. + * @return A 4x4 transformation matrix. + */ + Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); } - /** - * @brief Transforms a point from box-local space coordinates to world space. - * @param x X coordinate in local space. - * @param y Y coordinate in local space. - * @param z Z coordinate in local space. - * @return The transformed point in world space. - */ - inline Vector4f GetWorldPoint(const float x, const float y, const float z) { - return this->GetWorldPoint(Vector4f(x,y,z,1)); - } + /** + * @brief Transforms a point from box-local space to world space. + * @param v The local point (4D homogeneous vector). + * @return The transformed point in world space. + */ + inline Vector4f GetWorldPoint(const Vector4f &v) const { + return m_LocalT.GetWorldMatrix() * v; + } - /** - * @brief Transforms a point from world space to box-local space. - * @param v The world point (4D homogeneous vector). - * @return The transformed point in box-local space. - */ - inline Vector4f GetLocalPoint(const Vector4f &v) const { - return m_LocalT.GetWorldMatrix().inverse() * v; - } + /** + * @brief Transforms a point from box-local space coordinates to world space. + * @param x X coordinate in local space. + * @param y Y coordinate in local space. + * @param z Z coordinate in local space. + * @return The transformed point in world space. + */ + inline Vector4f GetWorldPoint(const float x, const float y, const float z) { + return this->GetWorldPoint(Vector4f(x, y, z, 1)); + } - /** - * @brief Transforms a point from world space coordinates to box-local space. - * @param x X coordinate in world space. - * @param y Y coordinate in world space. - * @param z Z coordinate in world space. - * @return The transformed point in box-local space. - */ - inline Vector4f GetLocalPoint(const float x, const float y, const float z) { - return this->GetLocalPoint(Vector4f(x,y,z,1)); - } + /** + * @brief Transforms a point from world space to box-local space. + * @param v The world point (4D homogeneous vector). + * @return The transformed point in box-local space. + */ + inline Vector4f GetLocalPoint(const Vector4f &v) const { + return m_LocalT.GetWorldMatrix().inverse() * v; + } - /** Translate using transformation chain */ - using BaseClass::Translate; + /** + * @brief Transforms a point from world space coordinates to box-local space. + * @param x X coordinate in world space. + * @param y Y coordinate in world space. + * @param z Z coordinate in world space. + * @return The transformed point in box-local space. + */ + inline Vector4f GetLocalPoint(const float x, const float y, const float z) { + return this->GetLocalPoint(Vector4f(x, y, z, 1)); + } - /** Rotate using transformation chain */ - using BaseClass::Rotate; + /** Translate using transformation chain */ + using BaseClass::Translate; - /** Scale using transformation chain */ - using BaseClass::Scale; + /** Rotate using transformation chain */ + using BaseClass::Rotate; + + /** Scale using transformation chain */ + using BaseClass::Scale; + +signals: + + // signal to emit when the box is updated // + void Updated() { ULIB_SIGNAL_EMIT(ContainerBox::Updated); } - private: - AffineTransform m_LocalT; + AffineTransform m_LocalT; }; - -} - - +} // namespace uLib #endif // CONTAINERBOX_H diff --git a/src/Python/math_bindings.cpp b/src/Python/math_bindings.cpp index 746466b..3d8742b 100644 --- a/src/Python/math_bindings.cpp +++ b/src/Python/math_bindings.cpp @@ -1,22 +1,22 @@ -#include #include +#include #include #include #include -#include "Math/Dense.h" -#include "Math/Transform.h" -#include "Math/Geometry.h" +#include "Math/Accumulator.h" #include "Math/ContainerBox.h" -#include "Math/StructuredData.h" -#include "Math/StructuredGrid.h" +#include "Math/Dense.h" +#include "Math/Geometry.h" #include "Math/Structured2DGrid.h" #include "Math/Structured4DGrid.h" +#include "Math/StructuredData.h" +#include "Math/StructuredGrid.h" +#include "Math/Transform.h" #include "Math/TriangleMesh.h" -#include "Math/VoxRaytracer.h" -#include "Math/Accumulator.h" #include "Math/VoxImage.h" +#include "Math/VoxRaytracer.h" namespace py = pybind11; using namespace uLib; @@ -40,345 +40,416 @@ PYBIND11_MAKE_OPAQUE(uLib::Vector); template void bind_eigen_type(py::module_ &m, const char *name) { - using Scalar = typename MatrixType::Scalar; - constexpr bool is_vector = MatrixType::IsVectorAtCompileTime; + using Scalar = typename MatrixType::Scalar; + constexpr bool is_vector = MatrixType::IsVectorAtCompileTime; - // Default constructor (zeros) - m.def(name, []() -> MatrixType { - if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) { - return MatrixType(); // Empty dynamic matrix - } else { - return MatrixType::Zero(); // Zero static matrix - } - }); - - // Specialized constructor for dynamic matrices - if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) { - m.def(name, [](int rows, int cols) -> MatrixType { - MatrixType mat; - mat.setZero(rows, cols); - return mat; - }); + // Default constructor (zeros) + m.def(name, []() -> MatrixType { + if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || + MatrixType::ColsAtCompileTime == Eigen::Dynamic) { + return MatrixType(); // Empty dynamic matrix + } else { + return MatrixType::Zero(); // Zero static matrix } + }); - // Initialize from list - m.def(name, [](py::list l) -> MatrixType { - MatrixType mat; - if constexpr (is_vector) { - mat.setZero(l.size()); - for (size_t i = 0; i < l.size(); ++i) { - mat(i) = l[i].cast(); - } - } else { - int rows = MatrixType::RowsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::RowsAtCompileTime; - int cols = MatrixType::ColsAtCompileTime == Eigen::Dynamic ? (int)std::sqrt(l.size()) : MatrixType::ColsAtCompileTime; - mat.setZero(rows, cols); - for (size_t i = 0; i < (size_t)l.size(); ++i) { - mat(i / cols, i % cols) = l[i].cast(); - } - } - return mat; + // Specialized constructor for dynamic matrices + if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || + MatrixType::ColsAtCompileTime == Eigen::Dynamic) { + m.def(name, [](int rows, int cols) -> MatrixType { + MatrixType mat; + mat.setZero(rows, cols); + return mat; }); + } - // Initialize from py::array - m.def(name, [](py::array_t arr) -> MatrixType { - auto buf = arr.request(); - MatrixType mat; - if constexpr (is_vector) { + // Initialize from list + m.def(name, [](py::list l) -> MatrixType { + MatrixType mat; + if constexpr (is_vector) { + mat.setZero(l.size()); + for (size_t i = 0; i < l.size(); ++i) { + mat(i) = l[i].cast(); + } + } else { + int rows = MatrixType::RowsAtCompileTime == Eigen::Dynamic + ? (int)std::sqrt(l.size()) + : MatrixType::RowsAtCompileTime; + int cols = MatrixType::ColsAtCompileTime == Eigen::Dynamic + ? (int)std::sqrt(l.size()) + : MatrixType::ColsAtCompileTime; + mat.setZero(rows, cols); + for (size_t i = 0; i < (size_t)l.size(); ++i) { + mat(i / cols, i % cols) = l[i].cast(); + } + } + return mat; + }); + + // Initialize from py::array + m.def(name, + [](py::array_t arr) + -> MatrixType { + auto buf = arr.request(); + MatrixType mat; + if constexpr (is_vector) { mat.setZero(buf.size); - Scalar* ptr = static_cast(buf.ptr); - for (ssize_t i = 0; i < buf.size; ++i) mat(i) = ptr[i]; - } else { + Scalar *ptr = static_cast(buf.ptr); + for (ssize_t i = 0; i < buf.size; ++i) + mat(i) = ptr[i]; + } else { int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1; int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1; mat.setZero(rows, cols); - Scalar* ptr = static_cast(buf.ptr); + Scalar *ptr = static_cast(buf.ptr); for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - mat(i, j) = ptr[i * cols + j]; - } + for (int j = 0; j < cols; ++j) { + mat(i, j) = ptr[i * cols + j]; + } } - } - return mat; - }); + } + return mat; + }); } void init_math(py::module_ &m) { - // 1. Basic Eigen Types (Vectors and Matrices) - bind_eigen_type(m, "Vector1f"); - bind_eigen_type(m, "Vector2f"); - bind_eigen_type(m, "Vector3f"); - bind_eigen_type(m, "Vector4f"); - bind_eigen_type(m, "Vector1i"); - bind_eigen_type(m, "Vector2i"); - bind_eigen_type(m, "Vector3i"); - bind_eigen_type(m, "Vector4i"); - bind_eigen_type(m, "Vector1d"); - bind_eigen_type(m, "Vector2d"); - bind_eigen_type(m, "Vector3d"); - bind_eigen_type(m, "Vector4d"); + // 1. Basic Eigen Types (Vectors and Matrices) + bind_eigen_type(m, "Vector1f"); + bind_eigen_type(m, "Vector2f"); + bind_eigen_type(m, "Vector3f"); + bind_eigen_type(m, "Vector4f"); + bind_eigen_type(m, "Vector1i"); + bind_eigen_type(m, "Vector2i"); + bind_eigen_type(m, "Vector3i"); + bind_eigen_type(m, "Vector4i"); + bind_eigen_type(m, "Vector1d"); + bind_eigen_type(m, "Vector2d"); + bind_eigen_type(m, "Vector3d"); + bind_eigen_type(m, "Vector4d"); - bind_eigen_type(m, "Matrix2f"); - bind_eigen_type(m, "Matrix3f"); - bind_eigen_type(m, "Matrix4f"); - bind_eigen_type(m, "Matrix2i"); - bind_eigen_type(m, "Matrix3i"); - bind_eigen_type(m, "Matrix4i"); - bind_eigen_type(m, "Matrix2d"); - bind_eigen_type(m, "Matrix3d"); - bind_eigen_type(m, "Matrix4d"); + bind_eigen_type(m, "Matrix2f"); + bind_eigen_type(m, "Matrix3f"); + bind_eigen_type(m, "Matrix4f"); + bind_eigen_type(m, "Matrix2i"); + bind_eigen_type(m, "Matrix3i"); + bind_eigen_type(m, "Matrix4i"); + bind_eigen_type(m, "Matrix2d"); + bind_eigen_type(m, "Matrix3d"); + bind_eigen_type(m, "Matrix4d"); - bind_eigen_type(m, "MatrixXi"); - bind_eigen_type(m, "MatrixXf"); - bind_eigen_type(m, "MatrixXd"); + bind_eigen_type(m, "MatrixXi"); + bind_eigen_type(m, "MatrixXf"); + bind_eigen_type(m, "MatrixXd"); - // 2. Homogeneous types - py::class_(m, "HPoint3f") - .def(py::init<>()) - .def(py::init()) - .def(py::init()); - py::class_(m, "HVector3f") - .def(py::init<>()) - .def(py::init()) - .def(py::init()); - py::class_(m, "HLine3f") - .def(py::init<>()) - .def_readwrite("origin", &HLine3f::origin) - .def_readwrite("direction", &HLine3f::direction); - py::class_(m, "HError3f") - .def(py::init<>()) - .def_readwrite("position_error", &HError3f::position_error) - .def_readwrite("direction_error", &HError3f::direction_error); + // 2. Homogeneous types + py::class_(m, "HPoint3f") + .def(py::init<>()) + .def(py::init()) + .def(py::init()); + py::class_(m, "HVector3f") + .def(py::init<>()) + .def(py::init()) + .def(py::init()); + py::class_(m, "HLine3f") + .def(py::init<>()) + .def_readwrite("origin", &HLine3f::origin) + .def_readwrite("direction", &HLine3f::direction); + py::class_(m, "HError3f") + .def(py::init<>()) + .def_readwrite("position_error", &HError3f::position_error) + .def_readwrite("direction_error", &HError3f::direction_error); - // 3. Dynamic Vectors (uLib::Vector) - py::bind_vector>(m, "Vector_i") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_ui") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_l") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_ul") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_f") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_d") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); + // 3. Dynamic Vectors (uLib::Vector) + py::bind_vector>(m, "Vector_i") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_ui") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_l") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_ul") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_f") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_d") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector3f") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector3i") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector4f") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector4i") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector3d") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Vector4d") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_Voxel") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); - py::bind_vector>(m, "Vector_VoxRaytracerRayDataElement") - .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) - .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector3f") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector3i") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector4f") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector4i") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector3d") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Vector4d") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>(m, "Vector_Voxel") + .def("MoveToVRAM", &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", &uLib::Vector::MoveToRAM); + py::bind_vector>( + m, "Vector_VoxRaytracerRayDataElement") + .def("MoveToVRAM", + &uLib::Vector::MoveToVRAM) + .def("MoveToRAM", + &uLib::Vector::MoveToRAM); - // 4. Accumulators - py::class_>(m, "Accumulator_Mean_f") - .def(py::init<>()) - .def("AddPass", &Accumulator_Mean::AddPass) - .def("__call__", py::overload_cast(&Accumulator_Mean::operator())) - .def("__call__", py::overload_cast<>(&Accumulator_Mean::operator(), py::const_)); + // 4. Accumulators + py::class_>(m, "Accumulator_Mean_f") + .def(py::init<>()) + .def("AddPass", &Accumulator_Mean::AddPass) + .def("__call__", + py::overload_cast(&Accumulator_Mean::operator())) + .def("__call__", py::overload_cast<>(&Accumulator_Mean::operator(), + py::const_)); - py::class_>(m, "Accumulator_Mean_d") - .def(py::init<>()) - .def("AddPass", &Accumulator_Mean::AddPass) - .def("__call__", py::overload_cast(&Accumulator_Mean::operator())) - .def("__call__", py::overload_cast<>(&Accumulator_Mean::operator(), py::const_)); + py::class_>(m, "Accumulator_Mean_d") + .def(py::init<>()) + .def("AddPass", &Accumulator_Mean::AddPass) + .def("__call__", py::overload_cast( + &Accumulator_Mean::operator())) + .def("__call__", py::overload_cast<>( + &Accumulator_Mean::operator(), py::const_)); - py::class_>(m, "Accumulator_ABTrim_f") - .def(py::init<>()) - .def("SetABTrim", &Accumulator_ABTrim::SetABTrim) - .def("__iadd__", [](Accumulator_ABTrim &self, float val) { self += val; return &self; }) - .def("__call__", &Accumulator_ABTrim::operator()); + py::class_>(m, "Accumulator_ABTrim_f") + .def(py::init<>()) + .def("SetABTrim", &Accumulator_ABTrim::SetABTrim) + .def("__iadd__", + [](Accumulator_ABTrim &self, float val) { + self += val; + return &self; + }) + .def("__call__", &Accumulator_ABTrim::operator()); - py::class_>(m, "Accumulator_ABTrim_d") - .def(py::init<>()) - .def("SetABTrim", &Accumulator_ABTrim::SetABTrim) - .def("__iadd__", [](Accumulator_ABTrim &self, double val) { self += val; return &self; }) - .def("__call__", &Accumulator_ABTrim::operator()); + py::class_>(m, "Accumulator_ABTrim_d") + .def(py::init<>()) + .def("SetABTrim", &Accumulator_ABTrim::SetABTrim) + .def("__iadd__", + [](Accumulator_ABTrim &self, double val) { + self += val; + return &self; + }) + .def("__call__", &Accumulator_ABTrim::operator()); - py::class_>(m, "Accumulator_ABClip_f") - .def(py::init<>()) - .def("SetABTrim", &Accumulator_ABClip::SetABTrim) - .def("__iadd__", [](Accumulator_ABClip &self, float val) { self += val; return &self; }) - .def("__call__", &Accumulator_ABClip::operator()); + py::class_>(m, "Accumulator_ABClip_f") + .def(py::init<>()) + .def("SetABTrim", &Accumulator_ABClip::SetABTrim) + .def("__iadd__", + [](Accumulator_ABClip &self, float val) { + self += val; + return &self; + }) + .def("__call__", &Accumulator_ABClip::operator()); - py::class_>(m, "Accumulator_ABClip_d") - .def(py::init<>()) - .def("SetABTrim", &Accumulator_ABClip::SetABTrim) - .def("__iadd__", [](Accumulator_ABClip &self, double val) { self += val; return &self; }) - .def("__call__", &Accumulator_ABClip::operator()); + py::class_>(m, "Accumulator_ABClip_d") + .def(py::init<>()) + .def("SetABTrim", &Accumulator_ABClip::SetABTrim) + .def("__iadd__", + [](Accumulator_ABClip &self, double val) { + self += val; + return &self; + }) + .def("__call__", &Accumulator_ABClip::operator()); - // 5. Core Math Structures - py::class_(m, "AffineTransform") - .def(py::init<>()) - .def("GetWorldMatrix", &AffineTransform::GetWorldMatrix) - .def("SetPosition", &AffineTransform::SetPosition) - .def("GetPosition", &AffineTransform::GetPosition) - .def("Translate", &AffineTransform::Translate) - .def("Scale", &AffineTransform::Scale) - .def("SetRotation", &AffineTransform::SetRotation) - .def("GetRotation", &AffineTransform::GetRotation) - .def("Rotate", &AffineTransform::Rotate) - .def("EulerYZYRotate", &AffineTransform::EulerYZYRotate) - .def("FlipAxes", &AffineTransform::FlipAxes); + // 5. Core Math Structures + py::class_(m, "AffineTransform") + .def(py::init<>()) + .def("GetWorldMatrix", &AffineTransform::GetWorldMatrix) + .def("SetPosition", &AffineTransform::SetPosition) + .def("GetPosition", &AffineTransform::GetPosition) + .def("Translate", &AffineTransform::Translate) + .def("Scale", &AffineTransform::Scale) + .def("SetRotation", &AffineTransform::SetRotation) + .def("GetRotation", &AffineTransform::GetRotation) + .def("Rotate", + py::overload_cast(&AffineTransform::Rotate)) + .def("Rotate", + py::overload_cast(&AffineTransform::Rotate)) + .def("Rotate", py::overload_cast(&AffineTransform::Rotate)) + .def("EulerYZYRotate", &AffineTransform::EulerYZYRotate) + .def("FlipAxes", &AffineTransform::FlipAxes); - py::class_(m, "Geometry") - .def(py::init<>()) - .def("GetWorldPoint", &Geometry::GetWorldPoint) - .def("GetLocalPoint", &Geometry::GetLocalPoint); + py::class_(m, "Geometry") + .def(py::init<>()) + .def("GetWorldPoint", py::overload_cast( + &Geometry::GetWorldPoint, py::const_)) + .def("GetWorldPoint", + py::overload_cast(&Geometry::GetWorldPoint)) + .def("GetLocalPoint", py::overload_cast( + &Geometry::GetLocalPoint, py::const_)) + .def("GetLocalPoint", + py::overload_cast(&Geometry::GetLocalPoint)); - py::class_(m, "ContainerBox") - .def(py::init<>()) - .def("SetOrigin", &ContainerBox::SetOrigin) - .def("GetOrigin", &ContainerBox::GetOrigin) - .def("SetSize", &ContainerBox::SetSize) - .def("GetSize", &ContainerBox::GetSize) - .def("GetWorldMatrix", &ContainerBox::GetWorldMatrix) - .def("GetWorldPoint", &ContainerBox::GetWorldPoint) - .def("GetLocalPoint", &ContainerBox::GetLocalPoint); + py::class_(m, "ContainerBox") + .def(py::init<>()) + .def("SetOrigin", &ContainerBox::SetOrigin) + .def("GetOrigin", &ContainerBox::GetOrigin) + .def("SetSize", &ContainerBox::SetSize) + .def("GetSize", &ContainerBox::GetSize) + .def("GetLocalMatrix", &ContainerBox::GetLocalMatrix) + .def("GetWorldMatrix", &ContainerBox::GetWorldMatrix) + .def("GetWorldPoint", py::overload_cast( + &ContainerBox::GetWorldPoint, py::const_)) + .def("GetWorldPoint", + py::overload_cast(&ContainerBox::GetWorldPoint)) + .def("GetLocalPoint", py::overload_cast( + &ContainerBox::GetLocalPoint, py::const_)) + .def("GetLocalPoint", + py::overload_cast(&ContainerBox::GetLocalPoint)) + .def("FlipLocalAxes", &ContainerBox::FlipLocalAxes); - py::enum_(m, "StructuredDataOrder") - .value("CustomOrder", StructuredData::CustomOrder) - .value("XYZ", StructuredData::XYZ) - .value("XZY", StructuredData::XZY) - .value("YXZ", StructuredData::YXZ) - .value("YZX", StructuredData::YZX) - .value("ZXY", StructuredData::ZXY) - .value("ZYX", StructuredData::ZYX) - .export_values(); + py::enum_(m, "StructuredDataOrder") + .value("CustomOrder", StructuredData::CustomOrder) + .value("XYZ", StructuredData::XYZ) + .value("XZY", StructuredData::XZY) + .value("YXZ", StructuredData::YXZ) + .value("YZX", StructuredData::YZX) + .value("ZXY", StructuredData::ZXY) + .value("ZYX", StructuredData::ZYX) + .export_values(); - py::class_(m, "StructuredData") - .def(py::init()) - .def("GetDims", &StructuredData::GetDims) - .def("SetDims", &StructuredData::SetDims) - .def("GetIncrements", &StructuredData::GetIncrements) - .def("SetIncrements", &StructuredData::SetIncrements) - .def("SetDataOrder", &StructuredData::SetDataOrder) - .def("GetDataOrder", &StructuredData::GetDataOrder) - .def("IsInsideGrid", &StructuredData::IsInsideGrid) - .def("Map", &StructuredData::Map) - .def("UnMap", &StructuredData::UnMap); + py::class_(m, "StructuredData") + .def(py::init()) + .def("GetDims", &StructuredData::GetDims) + .def("SetDims", &StructuredData::SetDims) + .def("GetIncrements", &StructuredData::GetIncrements) + .def("SetIncrements", &StructuredData::SetIncrements) + .def("SetDataOrder", &StructuredData::SetDataOrder) + .def("GetDataOrder", &StructuredData::GetDataOrder) + .def("IsInsideGrid", &StructuredData::IsInsideGrid) + .def("Map", &StructuredData::Map) + .def("UnMap", &StructuredData::UnMap); - py::class_(m, "StructuredGrid") - .def(py::init()) - .def("SetSpacing", &StructuredGrid::SetSpacing) - .def("GetSpacing", &StructuredGrid::GetSpacing) - .def("IsInsideBounds", &StructuredGrid::IsInsideBounds) - .def("Find", [](StructuredGrid &self, Vector3f pt) { - return self.Find(HPoint3f(pt)); - }); + py::class_(m, "StructuredGrid") + .def(py::init()) + .def("SetSpacing", &StructuredGrid::SetSpacing) + .def("GetSpacing", &StructuredGrid::GetSpacing) + .def("IsInsideBounds", &StructuredGrid::IsInsideBounds) + .def("Find", [](StructuredGrid &self, Vector3f pt) { + return self.Find(HPoint3f(pt)); + }); - py::class_(m, "Structured2DGrid") - .def(py::init<>()) - .def("SetDims", &Structured2DGrid::SetDims) - .def("GetDims", &Structured2DGrid::GetDims) - .def("IsInsideGrid", &Structured2DGrid::IsInsideGrid) - .def("Map", &Structured2DGrid::Map) - .def("UnMap", &Structured2DGrid::UnMap) - .def("SetPhysicalSpace", &Structured2DGrid::SetPhysicalSpace) - .def("GetSpacing", &Structured2DGrid::GetSpacing) - .def("GetOrigin", &Structured2DGrid::GetOrigin) - .def("IsInsideBounds", &Structured2DGrid::IsInsideBounds) - .def("PhysicsToUnitSpace", &Structured2DGrid::PhysicsToUnitSpace) - .def("UnitToPhysicsSpace", &Structured2DGrid::UnitToPhysicsSpace) - .def("SetDebug", &Structured2DGrid::SetDebug); + py::class_(m, "Structured2DGrid") + .def(py::init<>()) + .def("SetDims", &Structured2DGrid::SetDims) + .def("GetDims", &Structured2DGrid::GetDims) + .def("IsInsideGrid", &Structured2DGrid::IsInsideGrid) + .def("Map", &Structured2DGrid::Map) + .def("UnMap", &Structured2DGrid::UnMap) + .def("SetPhysicalSpace", &Structured2DGrid::SetPhysicalSpace) + .def("GetSpacing", &Structured2DGrid::GetSpacing) + .def("GetOrigin", &Structured2DGrid::GetOrigin) + .def("IsInsideBounds", &Structured2DGrid::IsInsideBounds) + .def("PhysicsToUnitSpace", &Structured2DGrid::PhysicsToUnitSpace) + .def("UnitToPhysicsSpace", &Structured2DGrid::UnitToPhysicsSpace) + .def("SetDebug", &Structured2DGrid::SetDebug); - py::class_(m, "Structured4DGrid") - .def(py::init<>()) - .def("SetDims", &Structured4DGrid::SetDims) - .def("GetDims", &Structured4DGrid::GetDims) - .def("IsInsideGrid", &Structured4DGrid::IsInsideGrid) - .def("Map", &Structured4DGrid::Map) - .def("UnMap", &Structured4DGrid::UnMap) - .def("SetPhysicalSpace", &Structured4DGrid::SetPhysicalSpace) - .def("GetSpacing", &Structured4DGrid::GetSpacing) - .def("GetOrigin", &Structured4DGrid::GetOrigin) - .def("IsInsideBounds", &Structured4DGrid::IsInsideBounds) - .def("PhysicsToUnitSpace", &Structured4DGrid::PhysicsToUnitSpace) - .def("UnitToPhysicsSpace", &Structured4DGrid::UnitToPhysicsSpace) - .def("SetDebug", &Structured4DGrid::SetDebug); + py::class_(m, "Structured4DGrid") + .def(py::init<>()) + .def("SetDims", &Structured4DGrid::SetDims) + .def("GetDims", &Structured4DGrid::GetDims) + .def("IsInsideGrid", &Structured4DGrid::IsInsideGrid) + .def("Map", &Structured4DGrid::Map) + .def("UnMap", &Structured4DGrid::UnMap) + .def("SetPhysicalSpace", &Structured4DGrid::SetPhysicalSpace) + .def("GetSpacing", &Structured4DGrid::GetSpacing) + .def("GetOrigin", &Structured4DGrid::GetOrigin) + .def("IsInsideBounds", &Structured4DGrid::IsInsideBounds) + .def("PhysicsToUnitSpace", &Structured4DGrid::PhysicsToUnitSpace) + .def("UnitToPhysicsSpace", &Structured4DGrid::UnitToPhysicsSpace) + .def("SetDebug", &Structured4DGrid::SetDebug); - // 6. High-level Structures - py::class_(m, "Voxel") - .def(py::init<>()) - .def_readwrite("Value", &Voxel::Value) - .def_readwrite("Count", &Voxel::Count); + // 6. High-level Structures + py::class_(m, "Voxel") + .def(py::init<>()) + .def_readwrite("Value", &Voxel::Value) + .def_readwrite("Count", &Voxel::Count); - py::class_(m, "AbstractVoxImage") - .def("GetValue", py::overload_cast(&Abstract::VoxImage::GetValue, py::const_)) - .def("GetValue", py::overload_cast(&Abstract::VoxImage::GetValue, py::const_)) - .def("SetValue", py::overload_cast(&Abstract::VoxImage::SetValue)) - .def("SetValue", py::overload_cast(&Abstract::VoxImage::SetValue)) - .def("ExportToVtk", &Abstract::VoxImage::ExportToVtk) - .def("ExportToVti", &Abstract::VoxImage::ExportToVti) - .def("ImportFromVtk", &Abstract::VoxImage::ImportFromVtk) - .def("ImportFromVti", &Abstract::VoxImage::ImportFromVti); + py::class_(m, "AbstractVoxImage") + .def("GetValue", py::overload_cast( + &Abstract::VoxImage::GetValue, py::const_)) + .def("GetValue", py::overload_cast( + &Abstract::VoxImage::GetValue, py::const_)) + .def("SetValue", py::overload_cast( + &Abstract::VoxImage::SetValue)) + .def("SetValue", + py::overload_cast(&Abstract::VoxImage::SetValue)) + .def("ExportToVtk", &Abstract::VoxImage::ExportToVtk) + .def("ExportToVti", &Abstract::VoxImage::ExportToVti) + .def("ImportFromVtk", &Abstract::VoxImage::ImportFromVtk) + .def("ImportFromVti", &Abstract::VoxImage::ImportFromVti); - py::class_, Abstract::VoxImage>(m, "VoxImage") - .def(py::init<>()) - .def(py::init()) - .def("Data", &VoxImage::Data, py::return_value_policy::reference_internal) - .def("InitVoxels", &VoxImage::InitVoxels) - .def("Abs", &VoxImage::Abs) - .def("clipImage", py::overload_cast(&VoxImage::clipImage, py::const_)) - .def("clipImage", py::overload_cast(&VoxImage::clipImage, py::const_)) - .def("clipImage", py::overload_cast(&VoxImage::clipImage, py::const_)) - .def("maskImage", py::overload_cast(&VoxImage::maskImage, py::const_)) - .def("maskImage", py::overload_cast(&VoxImage::maskImage, py::const_), py::arg("threshold"), py::arg("belowValue") = 0, py::arg("aboveValue") = 0) - .def("fixVoxels", py::overload_cast(&VoxImage::fixVoxels, py::const_)) - .def("__getitem__", py::overload_cast(&VoxImage::operator[])) - .def("__getitem__", py::overload_cast(&VoxImage::operator[])); + py::class_, Abstract::VoxImage>(m, "VoxImage") + .def(py::init<>()) + .def(py::init()) + .def("Data", &VoxImage::Data, + py::return_value_policy::reference_internal) + .def("InitVoxels", &VoxImage::InitVoxels) + .def("Abs", &VoxImage::Abs) + .def("clipImage", py::overload_cast( + &VoxImage::clipImage, py::const_)) + .def("clipImage", py::overload_cast( + &VoxImage::clipImage, py::const_)) + .def("clipImage", py::overload_cast( + &VoxImage::clipImage, py::const_)) + .def("maskImage", + py::overload_cast( + &VoxImage::maskImage, py::const_)) + .def("maskImage", + py::overload_cast( + &VoxImage::maskImage, py::const_), + py::arg("threshold"), py::arg("belowValue") = 0, + py::arg("aboveValue") = 0) + .def("fixVoxels", py::overload_cast( + &VoxImage::fixVoxels, py::const_)) + .def("__getitem__", + py::overload_cast(&VoxImage::operator[])) + .def("__getitem__", + py::overload_cast(&VoxImage::operator[])); - py::class_(m, "TriangleMesh") - .def(py::init<>()) - .def("AddPoint", &TriangleMesh::AddPoint) - .def("AddTriangle", py::overload_cast(&TriangleMesh::AddTriangle)) - .def("Points", &TriangleMesh::Points, py::return_value_policy::reference_internal) - .def("Triangles", &TriangleMesh::Triangles, py::return_value_policy::reference_internal); + py::class_(m, "TriangleMesh") + .def(py::init<>()) + .def("AddPoint", &TriangleMesh::AddPoint) + .def("AddTriangle", + py::overload_cast(&TriangleMesh::AddTriangle)) + .def("Points", &TriangleMesh::Points, + py::return_value_policy::reference_internal) + .def("Triangles", &TriangleMesh::Triangles, + py::return_value_policy::reference_internal); - py::class_(m, "VoxRaytracerRayDataElement") - .def(py::init<>()) - .def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id) - .def_readwrite("L", &VoxRaytracer::RayData::Element::L); + py::class_(m, "VoxRaytracerRayDataElement") + .def(py::init<>()) + .def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id) + .def_readwrite("L", &VoxRaytracer::RayData::Element::L); - py::class_(m, "VoxRaytracerRayData") - .def(py::init<>()) - .def("AppendRay", &VoxRaytracer::RayData::AppendRay) - .def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data), py::return_value_policy::reference_internal) - .def("Count", &VoxRaytracer::RayData::Count) - .def("TotalLength", &VoxRaytracer::RayData::TotalLength) - .def("SetCount", &VoxRaytracer::RayData::SetCount) - .def("SetTotalLength", &VoxRaytracer::RayData::SetTotalLength); - - py::class_(m, "VoxRaytracer") - .def(py::init(), py::keep_alive<1, 2>()) - .def("GetImage", &VoxRaytracer::GetImage, py::return_value_policy::reference_internal) - .def("TraceLine", &VoxRaytracer::TraceLine) - .def("TraceBetweenPoints", &VoxRaytracer::TraceBetweenPoints); + py::class_(m, "VoxRaytracerRayData") + .def(py::init<>()) + .def("AppendRay", &VoxRaytracer::RayData::AppendRay) + .def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data), + py::return_value_policy::reference_internal) + .def("Count", &VoxRaytracer::RayData::Count) + .def("TotalLength", &VoxRaytracer::RayData::TotalLength) + .def("SetCount", &VoxRaytracer::RayData::SetCount) + .def("SetTotalLength", &VoxRaytracer::RayData::SetTotalLength); + py::class_(m, "VoxRaytracer") + .def(py::init(), py::keep_alive<1, 2>()) + .def("GetImage", &VoxRaytracer::GetImage, + py::return_value_policy::reference_internal) + .def("TraceLine", &VoxRaytracer::TraceLine) + .def("TraceBetweenPoints", &VoxRaytracer::TraceBetweenPoints); } diff --git a/src/Vtk/HEP/Detectors/vtkDetectorChamber.cxx b/src/Vtk/HEP/Detectors/vtkDetectorChamber.cxx index 86fa751..e0beae8 100644 --- a/src/Vtk/HEP/Detectors/vtkDetectorChamber.cxx +++ b/src/Vtk/HEP/Detectors/vtkDetectorChamber.cxx @@ -102,7 +102,8 @@ void vtkDetectorChamber::SetTransform(vtkTransform *t) { for (int j = 0; j < 4; ++j) transform(i, j) = vmat->GetElement(i, j); this->GetContent()->SetMatrix(transform); - + this->GetContent()->Updated(); // emit signal + this->Update(); } diff --git a/src/Vtk/vtkContainerBox.cpp b/src/Vtk/vtkContainerBox.cpp index c3f2a90..736c081 100644 --- a/src/Vtk/vtkContainerBox.cpp +++ b/src/Vtk/vtkContainerBox.cpp @@ -72,8 +72,7 @@ void vtkContainerBox::Update() { for (int j = 0; j < 4; ++j) vmat->SetElement(i, j, transform(i, j)); - std::cout << "transform: " << transform << std::endl; - + // std::cout << "transform: " << transform << std::endl; // m_RelativeTransform->SetMatrix(vmat); // m_RelativeTransform->Update();