add geant4 scene and gcompose app

This commit is contained in:
AndreaRigoni
2026-03-13 17:19:51 +00:00
parent f2133c31d5
commit 61052f80bc
34 changed files with 1341 additions and 580 deletions

View File

@@ -3,7 +3,12 @@
##### CMAKE LISTS ############################################################## ##### CMAKE LISTS ##############################################################
################################################################################ ################################################################################
if(EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
include("${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
endif()
cmake_minimum_required (VERSION 3.26) cmake_minimum_required (VERSION 3.26)
if(POLICY CMP0167) if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW) cmake_policy(SET CMP0167 NEW)
endif() endif()
@@ -107,6 +112,8 @@ set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_USE_STATIC_RUNTIME OFF)
message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}") 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) find_package(Boost 1.45.0 COMPONENTS program_options serialization unit_test_framework REQUIRED)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
@@ -120,6 +127,9 @@ include(${ROOT_USE_FILE})
find_package(VTK REQUIRED) find_package(VTK REQUIRED)
# include(${VTK_USE_FILE}) # include(${VTK_USE_FILE})
set(GEANT4_USE_HDF5 OFF CACHE BOOL "Use HDF5" FORCE)
find_package(Geant4 REQUIRED)
find_package(pybind11 REQUIRED) find_package(pybind11 REQUIRED)
@@ -216,7 +226,7 @@ add_subdirectory(${SRC_DIR}/Vtk)
add_subdirectory(${SRC_DIR}/Python) add_subdirectory(${SRC_DIR}/Python)
#add_subdirectory("${SRC_DIR}/utils/make_recipe") add_subdirectory(app)
## Documentation and packages ## Documentation and packages

1
app/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
add_subdirectory(gcompose)

View File

@@ -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)

45
app/gcompose/src/main.cpp Normal file
View File

@@ -0,0 +1,45 @@
#include "Math/ContainerBox.h"
#include <HEP/Geant/Scene.h>
#include <Vtk/uLibVtkViewer.h>
#include <Vtk/vtkContainerBox.h>
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <iostream>
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;
}

View File

@@ -1,8 +1,13 @@
[requires] [requires]
eigen/3.4.0 eigen/3.4.0
boost/1.83.0 boost/1.83.0
pybind11/3.0.2 # pybind11/3.0.2
hdf5/1.14.3
[generators] [generators]
CMakeDeps CMakeDeps
CMakeToolchain CMakeToolchain
[options]
hdf5/*:threadsafe=True
hdf5/*:enable_unsupported=True

View File

@@ -7,6 +7,7 @@ include_directories(${SRC_DIR}/HEP)
add_subdirectory(Detectors) add_subdirectory(Detectors)
add_subdirectory(Geant) add_subdirectory(Geant)
# add_subdirectory(MuonTomography)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE) set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} PARENT_SCOPE)
set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE) set(ULIB_SELECTED_MODULES ${ULIB_SELECTED_MODULES} PARENT_SCOPE)

View File

@@ -29,8 +29,8 @@
#define U_CHAMBERHITEVENT_H #define U_CHAMBERHITEVENT_H
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Hit.h" #include "Detectors/HitMC.h"
#include "ChamberDetector.h" #include "Detectors/DetectorChamber.h"
namespace uLib { namespace uLib {
@@ -38,17 +38,17 @@ class ChamberHitEventData
{ {
public: public:
uLibConstRefMacro (Hits, Vector<HitData> ) uLibConstRefMacro (Hits, Vector<HitData> )
uLibGetMacro (Idv, ChamberDetector::ID) uLibGetMacro (Idv, uint)
private: private:
friend class ChamberHitEvent; friend class ChamberHitEvent;
Vector<HitData> m_Hits; Vector<HitData> m_Hits;
DetectorChamber::ID m_Idv; // -> chamber/view uint m_Idv; // -> chamber/view
}; };
class ChamberHitEvent : public ChamberHitEventData { class ChamberHitEvent : public ChamberHitEventData {
public: public:
uLibRefMacro (Hits, Vector<HitData> ) uLibRefMacro (Hits, Vector<HitData> )
uLibSetMacro (Idv, ChamberDetector::ID) uLibSetMacro (Idv, uint)
}; };
} }

View File

@@ -33,9 +33,6 @@
namespace uLib { namespace uLib {
class HitRawCode_CMSDrift : class HitRawCode_CMSDrift :
public BitCode4<unsigned short,6,3,2,5> public BitCode4<unsigned short,6,3,2,5>
{ {
@@ -59,7 +56,13 @@ public:
}; };
class HitData {
public:
HitData() {}
~HitData() {}
};

View File

@@ -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());
}

View File

@@ -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

View File

@@ -3,8 +3,6 @@
##### HEP/Geant - Geant4 integration library ################################### ##### HEP/Geant - Geant4 integration library ###################################
################################################################################ ################################################################################
find_package(Geant4 QUIET)
if(NOT Geant4_FOUND) if(NOT Geant4_FOUND)
message(STATUS "Geant4 not found - skipping mutomGeant library") message(STATUS "Geant4 not found - skipping mutomGeant library")
return() return()
@@ -18,11 +16,18 @@ set(HEADERS
Matter.h Matter.h
Scene.h Scene.h
Solid.h Solid.h
DetectorConstruction.hh
PhysicsList.hh
ActionInitialization.hh
) )
set(SOURCES set(SOURCES
Scene.cpp Scene.cpp
Solid.cpp Solid.cpp
EmitterPrimary.cpp
DetectorConstruction.cpp
PhysicsList.cpp
ActionInitialization.cpp
) )
set(libname ${PACKAGE_LIBPREFIX}Geant) set(libname ${PACKAGE_LIBPREFIX}Geant)
@@ -50,3 +55,8 @@ install(TARGETS ${libname}
install(FILES ${HEADERS} install(FILES ${HEADERS}
DESTINATION ${INSTALL_INC_DIR}/HEP/Geant) DESTINATION ${INSTALL_INC_DIR}/HEP/Geant)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

View File

@@ -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() {}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -30,17 +30,18 @@
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "ChamberHitEvent.h" #include "Detectors/ChamberHitEvent.h"
namespace uLib { namespace uLib {
class GeantEventData { class GeantEventData {
public: public:
uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf) uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f) uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f)
uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>) uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>)
private : friend class GeantEvent; private:
friend class GeantEvent;
Id_t m_EventID; Id_t m_EventID;
Scalarf m_Momentum; Scalarf m_Momentum;
Vector3f m_GenPos; Vector3f m_GenPos;
@@ -48,11 +49,11 @@ uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
Vector<ChamberHitEventData> m_ChEvents; Vector<ChamberHitEventData> m_ChEvents;
}; };
class GeantEvent { class GeantEvent : public GeantEventData {
public: public:
uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf) uLibSetMacro(EventID, Id_t) uLibSetMacro(Momentum, Scalarf)
uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f) uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f)
uLibRefMacro(ChEvents, Vector<ChamberHitEventData>) uLibRefMacro(ChEvents, Vector<ChamberHitEventData>)
}; };
} // namespace uLib } // namespace uLib

View File

@@ -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(); }

View File

@@ -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

View File

@@ -23,52 +23,127 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <Geant4/G4Box.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4Material.hh> #include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh> #include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh> #include <Geant4/G4PVPlacement.hh>
#include <Geant4/G4RunManager.hh>
#include <Geant4/G4RunManagerFactory.hh>
#include <Geant4/G4SystemOfUnits.hh>
#include <Geant4/G4VPhysicalVolume.hh>
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Matter.h" #include "HEP/Geant/DetectorConstruction.hh"
#include "Math/ContainerBox.h"
#include "Math/Dense.h"
#include "Solid.h" #include "Solid.h"
#include "Scene.h" #include "Scene.h"
#include "PhysicsList.hh"
#include "ActionInitialization.hh"
namespace uLib { namespace uLib {
class SceneDetectorConstruction : public DetectorConstruction {
class DetectorsScenePimpl {
public: public:
SceneDetectorConstruction(class SceneImpl *owner);
G4VPhysicalVolume *Construct() override;
// members // private:
//Vector<Solid> m_Solids; 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() : // Initialize Geant4
d(new DetectorsScenePimpl()) m_RunManager->Initialize();
{} }
DetectorsScene::~DetectorsScene() // members //
{ Vector<Solid *> m_Solids;
delete d; Solid *m_World = nullptr;
} G4RunManager *m_RunManager;
};
void DetectorsScene::AddSolid(const Solid &solid) SceneDetectorConstruction::SceneDetectorConstruction(SceneImpl *owner)
{ : DetectorConstruction("Scene"), m_Owner(owner) {}
// d->m_Solids.push_back(solid);
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

View File

@@ -23,30 +23,33 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef SCENE_H #ifndef SCENE_H
#define SCENE_H #define SCENE_H
#include "Core/Object.h" #include "Core/Object.h"
#include "Core/Vector.h" #include "Core/Vector.h"
#include "Solid.h" #include "Solid.h"
class G4VPhysicalVolume;
namespace uLib { namespace uLib {
class Scene : public Object {
class DetectorsScene : public Object {
public: public:
DetectorsScene(); Scene();
~DetectorsScene(); ~Scene();
void AddSolid(Solid *solid, Solid *parent = nullptr);
void ConstructWorldBox(const ContainerBox *box, const char *material);
void AddSolid(const Solid &solid); void Initialize();
private: private:
class DetectorsScenePimpl *d; class SceneImpl *d;
}; };
} // namespace uLib
}
#endif // SCENE_H #endif // SCENE_H

View File

@@ -23,20 +23,21 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
// G4 Solid // // G4 Solid //
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4Material.hh> #include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh> #include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
// Tessellated solid // // Tessellated solid //
#include <Geant4/G4TessellatedSolid.hh> #include <Geant4/G4TessellatedSolid.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4ThreeVector.hh> #include <Geant4/G4ThreeVector.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4Box.hh>
#include <Geant4/G4PVPlacement.hh>
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/Transform.h"
#include "Solid.h" #include "Solid.h"
@@ -44,71 +45,130 @@ namespace uLib {
class DetectorsSolidPimpl { class DetectorsSolidPimpl {
public: public:
static G4ThreeVector getG4Vector3f(const Vector3f &vector) { static G4ThreeVector getG4Vector3f(const Vector3f &vector) {
return G4ThreeVector( vector(0), vector(1), vector(2) ); 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() : void Solid::SetNistMaterial(const char *name) {
m_Logical (new G4LogicalVolume(NULL,NULL,"unnamed_solid")), G4NistManager *nist = G4NistManager::Instance();
m_Material(NULL) m_Material = nist->FindOrBuildMaterial(name);
{} m_Logical->SetMaterial(m_Material);
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::SetMaterial(G4Material *material) void Solid::SetMaterial(G4Material *material) {
{ if (material) {
if(material) m_Material = material;
{ m_Logical->SetMaterial(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;
}
G4LogicalVolume* parentLogical = nullptr;
if (parent) {
parentLogical = parent->GetLogical();
if (!parentLogical) {
std::cerr << "parent logical volume not created for solid " << parent->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; 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); }
// 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

View File

@@ -23,39 +23,51 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef SOLID_H #ifndef SOLID_H
#define SOLID_H #define SOLID_H
#include "Core/Object.h" #include "Core/Object.h"
#include "Geant/Matter.h"
#include <Geant4/G4LogicalVolume.hh>
#include "Math/ContainerBox.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/TriangleMesh.h" #include "Math/TriangleMesh.h"
#include "Detectors/Matter.h"
class G4Material; class G4Material;
class G4LogicalVolume; class G4LogicalVolume;
class G4TessellatedSolid; class G4TessellatedSolid;
class G4Box;
namespace uLib { namespace uLib {
class Solid : public Object { class Solid : public Object {
public: public:
Solid();
Solid(const char *name);
Solid(); void SetNistMaterial(const char *name);
Solid(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(Material, G4Material *)
uLibGetMacro(Logical,G4LogicalVolume *) uLibGetSetMacro(Logical, G4LogicalVolume *)
uLibGetSetMacro(Physical, G4VPhysicalVolume *)
protected: inline const char *GetName() const { return m_Logical->GetName().c_str(); }
G4Material *m_Material;
G4LogicalVolume *m_Logical; 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 { class TessellatedSolid : public Solid {
typedef Solid BaseClass; typedef Solid BaseClass;
public: 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 :
private: G4TessellatedSolid *m_Solid;
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 #endif // SOLID_H

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -0,0 +1,72 @@
#include "Geant/Solid.h"
#include "HEP/Geant/GeantEvent.h"
#include "Math/TriangleMesh.h"
#include "testing-prototype.h"
#include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4TessellatedSolid.hh>
#include <string.h>
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
}

View File

@@ -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;
}

View File

@@ -0,0 +1,69 @@
#include "Geant/Solid.h"
#include "Math/TriangleMesh.h"
#include "testing-prototype.h"
#include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4TessellatedSolid.hh>
#include <string.h>
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
}

View File

@@ -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 <stdio.h>
#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;

View File

@@ -39,12 +39,6 @@ class Hit {
Type m_DriftTime; Type m_DriftTime;
}; };
class HitMC { class HitMC {
public: public:
virtual Id_t GetChamber() = 0; virtual Id_t GetChamber() = 0;

View File

@@ -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}

View File

@@ -23,160 +23,165 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CONTAINERBOX_H #ifndef U_CONTAINERBOX_H
#define U_CONTAINERBOX_H #define U_CONTAINERBOX_H
#include "Geometry.h" #include "Geometry.h"
#include "Core/Object.h"
#include "Math/Dense.h" #include "Math/Dense.h"
#include "Math/Transform.h" #include "Math/Transform.h"
#include <utility> #include <utility>
namespace uLib { 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. * ContainerBox inherits from AffineTransform, which defines its parent
* It contains an internal local transformation (m_LocalT) that defines the box's * coordinate system. It contains an internal local transformation (m_LocalT)
* specific origin and size relative to its own coordinate system. * 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: public:
/** /**
* @brief Default constructor. * @brief Default constructor.
* Initializes the local transformation with this instance as its parent. * Initializes the local transformation with this instance as its parent.
*/ */
ContainerBox() : ContainerBox()
m_LocalT(this) // BaseClass is Parent of m_LocalTransform : m_LocalT(this) // BaseClass is Parent of m_LocalTransform
{} {}
/** /**
* @brief Copy constructor. * @brief Constructor with size.
* @param copy The ContainerBox instance to copy from. * @param size The size vector.
*/ */
ContainerBox(const ContainerBox &copy) : ContainerBox(const Vector3f &size) : m_LocalT(this) { this->SetSize(size); }
m_LocalT(this), // BaseClass is Parent of m_LocalTransform
AffineTransform(copy)
{
this->SetOrigin(copy.GetOrigin());
this->SetSize(copy.GetSize());
}
/** /**
* @brief Sets the box origin relative to its coordinate system. * @brief Copy constructor.
* @param v The origin position vector. * @param copy The ContainerBox instance to copy from.
*/ */
inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); } ContainerBox(const ContainerBox &copy)
: 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. * @brief Sets the box origin relative to its coordinate system.
* @return The origin position vector. * @param v The origin position vector.
*/ */
inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); } inline void SetOrigin(const Vector3f &v) { m_LocalT.SetPosition(v); }
/** /**
* @brief Sets the size of the box. * @brief Gets the box origin relative to its coordinate system.
* Re-initializes the local transformation and applies the new scale. * @return The origin position vector.
* @param v The size vector (width, height, depth). */
*/ inline Vector3f GetOrigin() const { return m_LocalT.GetPosition(); }
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 current size (scale) of the box. * @brief Sets the size of the box.
* @return The size vector. * Re-initializes the local transformation and applies the new scale.
*/ * @param v The size vector (width, height, depth).
inline Vector3f GetSize() const { return m_LocalT.GetScale(); } */
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. * @brief Gets the current size (scale) of the box.
* @param first Index of the first axis (0=X, 1=Y, 2=Z). * @return The size vector.
* @param second Index of the second axis (0=X, 1=Y, 2=Z). */
*/ inline Vector3f GetSize() const { return m_LocalT.GetScale(); }
inline void FlipLocalAxes(int first, int second)
{ m_LocalT.FlipAxes(first,second); }
/** /**
* @brief Returns the world transformation matrix of the box's volume. * @brief Swaps two local axes of the box.
* @return A 4x4 transformation matrix. * @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).
Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); } */
inline void FlipLocalAxes(int first, int second) {
m_LocalT.FlipAxes(first, second);
}
/** /**
* @brief Returns the local transformation matrix of the box's volume. * @brief Returns the world transformation matrix of the box's volume.
* @return A 4x4 transformation matrix. * @return A 4x4 transformation matrix.
*/ */
Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); } Matrix4f GetWorldMatrix() const { return m_LocalT.GetWorldMatrix(); }
/** /**
* @brief Transforms a point from box-local space to world space. * @brief Returns the local transformation matrix of the box's volume.
* @param v The local point (4D homogeneous vector). * @return A 4x4 transformation matrix.
* @return The transformed point in world space. */
*/ Matrix4f GetLocalMatrix() const { return m_LocalT.GetMatrix(); }
inline Vector4f GetWorldPoint(const Vector4f &v) const {
return m_LocalT.GetWorldMatrix() * v;
}
/** /**
* @brief Transforms a point from box-local space coordinates to world space. * @brief Transforms a point from box-local space to world space.
* @param x X coordinate in local space. * @param v The local point (4D homogeneous vector).
* @param y Y coordinate in local space. * @return The transformed point in world space.
* @param z Z coordinate in local space. */
* @return The transformed point in world space. inline Vector4f GetWorldPoint(const Vector4f &v) const {
*/ return m_LocalT.GetWorldMatrix() * v;
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 to box-local space. * @brief Transforms a point from box-local space coordinates to world space.
* @param v The world point (4D homogeneous vector). * @param x X coordinate in local space.
* @return The transformed point in box-local space. * @param y Y coordinate in local space.
*/ * @param z Z coordinate in local space.
inline Vector4f GetLocalPoint(const Vector4f &v) const { * @return The transformed point in world space.
return m_LocalT.GetWorldMatrix().inverse() * v; */
} 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. * @brief Transforms a point from world space to box-local space.
* @param x X coordinate in world space. * @param v The world point (4D homogeneous vector).
* @param y Y coordinate in world space. * @return The transformed point in box-local space.
* @param z Z coordinate in world space. */
* @return The transformed point in box-local space. inline Vector4f GetLocalPoint(const Vector4f &v) const {
*/ return m_LocalT.GetWorldMatrix().inverse() * v;
inline Vector4f GetLocalPoint(const float x, const float y, const float z) { }
return this->GetLocalPoint(Vector4f(x,y,z,1));
}
/** 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 */ /** Translate using transformation chain */
using BaseClass::Rotate; using BaseClass::Translate;
/** Scale using transformation chain */ /** Rotate using transformation chain */
using BaseClass::Scale; 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: private:
AffineTransform m_LocalT; AffineTransform m_LocalT;
}; };
} // namespace uLib
}
#endif // CONTAINERBOX_H #endif // CONTAINERBOX_H

View File

@@ -1,22 +1,22 @@
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h> #include <pybind11/eigen.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/stl_bind.h> #include <pybind11/stl_bind.h>
#include <pybind11/numpy.h> #include <pybind11/numpy.h>
#include "Math/Dense.h" #include "Math/Accumulator.h"
#include "Math/Transform.h"
#include "Math/Geometry.h"
#include "Math/ContainerBox.h" #include "Math/ContainerBox.h"
#include "Math/StructuredData.h" #include "Math/Dense.h"
#include "Math/StructuredGrid.h" #include "Math/Geometry.h"
#include "Math/Structured2DGrid.h" #include "Math/Structured2DGrid.h"
#include "Math/Structured4DGrid.h" #include "Math/Structured4DGrid.h"
#include "Math/StructuredData.h"
#include "Math/StructuredGrid.h"
#include "Math/Transform.h"
#include "Math/TriangleMesh.h" #include "Math/TriangleMesh.h"
#include "Math/VoxRaytracer.h"
#include "Math/Accumulator.h"
#include "Math/VoxImage.h" #include "Math/VoxImage.h"
#include "Math/VoxRaytracer.h"
namespace py = pybind11; namespace py = pybind11;
using namespace uLib; using namespace uLib;
@@ -40,345 +40,416 @@ PYBIND11_MAKE_OPAQUE(uLib::Vector<VoxRaytracer::RayData::Element>);
template <typename MatrixType> template <typename MatrixType>
void bind_eigen_type(py::module_ &m, const char *name) { void bind_eigen_type(py::module_ &m, const char *name) {
using Scalar = typename MatrixType::Scalar; using Scalar = typename MatrixType::Scalar;
constexpr bool is_vector = MatrixType::IsVectorAtCompileTime; constexpr bool is_vector = MatrixType::IsVectorAtCompileTime;
// Default constructor (zeros) // Default constructor (zeros)
m.def(name, []() -> MatrixType { m.def(name, []() -> MatrixType {
if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic || MatrixType::ColsAtCompileTime == Eigen::Dynamic) { if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic ||
return MatrixType(); // Empty dynamic matrix MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
} else { return MatrixType(); // Empty dynamic matrix
return MatrixType::Zero(); // Zero static 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;
});
} }
});
// Initialize from list // Specialized constructor for dynamic matrices
m.def(name, [](py::list l) -> MatrixType { if constexpr (MatrixType::RowsAtCompileTime == Eigen::Dynamic ||
MatrixType mat; MatrixType::ColsAtCompileTime == Eigen::Dynamic) {
if constexpr (is_vector) { m.def(name, [](int rows, int cols) -> MatrixType {
mat.setZero(l.size()); MatrixType mat;
for (size_t i = 0; i < l.size(); ++i) { mat.setZero(rows, cols);
mat(i) = l[i].cast<Scalar>(); return mat;
}
} 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<Scalar>();
}
}
return mat;
}); });
}
// Initialize from py::array // Initialize from list
m.def(name, [](py::array_t<Scalar, py::array::c_style | py::array::forcecast> arr) -> MatrixType { m.def(name, [](py::list l) -> MatrixType {
auto buf = arr.request(); MatrixType mat;
MatrixType mat; if constexpr (is_vector) {
if constexpr (is_vector) { mat.setZero(l.size());
for (size_t i = 0; i < l.size(); ++i) {
mat(i) = l[i].cast<Scalar>();
}
} 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<Scalar>();
}
}
return mat;
});
// Initialize from py::array
m.def(name,
[](py::array_t<Scalar, py::array::c_style | py::array::forcecast> arr)
-> MatrixType {
auto buf = arr.request();
MatrixType mat;
if constexpr (is_vector) {
mat.setZero(buf.size); mat.setZero(buf.size);
Scalar* ptr = static_cast<Scalar*>(buf.ptr); Scalar *ptr = static_cast<Scalar *>(buf.ptr);
for (ssize_t i = 0; i < buf.size; ++i) mat(i) = ptr[i]; for (ssize_t i = 0; i < buf.size; ++i)
} else { mat(i) = ptr[i];
} else {
int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1; int rows = buf.shape.size() > 0 ? (int)buf.shape[0] : 1;
int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1; int cols = buf.shape.size() > 1 ? (int)buf.shape[1] : 1;
mat.setZero(rows, cols); mat.setZero(rows, cols);
Scalar* ptr = static_cast<Scalar*>(buf.ptr); Scalar *ptr = static_cast<Scalar *>(buf.ptr);
for (int i = 0; i < rows; ++i) { for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) { for (int j = 0; j < cols; ++j) {
mat(i, j) = ptr[i * cols + j]; mat(i, j) = ptr[i * cols + j];
} }
} }
} }
return mat; return mat;
}); });
} }
void init_math(py::module_ &m) { void init_math(py::module_ &m) {
// 1. Basic Eigen Types (Vectors and Matrices) // 1. Basic Eigen Types (Vectors and Matrices)
bind_eigen_type<Vector1f>(m, "Vector1f"); bind_eigen_type<Vector1f>(m, "Vector1f");
bind_eigen_type<Vector2f>(m, "Vector2f"); bind_eigen_type<Vector2f>(m, "Vector2f");
bind_eigen_type<Vector3f>(m, "Vector3f"); bind_eigen_type<Vector3f>(m, "Vector3f");
bind_eigen_type<Vector4f>(m, "Vector4f"); bind_eigen_type<Vector4f>(m, "Vector4f");
bind_eigen_type<Vector1i>(m, "Vector1i"); bind_eigen_type<Vector1i>(m, "Vector1i");
bind_eigen_type<Vector2i>(m, "Vector2i"); bind_eigen_type<Vector2i>(m, "Vector2i");
bind_eigen_type<Vector3i>(m, "Vector3i"); bind_eigen_type<Vector3i>(m, "Vector3i");
bind_eigen_type<Vector4i>(m, "Vector4i"); bind_eigen_type<Vector4i>(m, "Vector4i");
bind_eigen_type<Vector1d>(m, "Vector1d"); bind_eigen_type<Vector1d>(m, "Vector1d");
bind_eigen_type<Vector2d>(m, "Vector2d"); bind_eigen_type<Vector2d>(m, "Vector2d");
bind_eigen_type<Vector3d>(m, "Vector3d"); bind_eigen_type<Vector3d>(m, "Vector3d");
bind_eigen_type<Vector4d>(m, "Vector4d"); bind_eigen_type<Vector4d>(m, "Vector4d");
bind_eigen_type<Matrix2f>(m, "Matrix2f"); bind_eigen_type<Matrix2f>(m, "Matrix2f");
bind_eigen_type<Matrix3f>(m, "Matrix3f"); bind_eigen_type<Matrix3f>(m, "Matrix3f");
bind_eigen_type<Matrix4f>(m, "Matrix4f"); bind_eigen_type<Matrix4f>(m, "Matrix4f");
bind_eigen_type<Matrix2i>(m, "Matrix2i"); bind_eigen_type<Matrix2i>(m, "Matrix2i");
bind_eigen_type<Matrix3i>(m, "Matrix3i"); bind_eigen_type<Matrix3i>(m, "Matrix3i");
bind_eigen_type<Matrix4i>(m, "Matrix4i"); bind_eigen_type<Matrix4i>(m, "Matrix4i");
bind_eigen_type<Matrix2d>(m, "Matrix2d"); bind_eigen_type<Matrix2d>(m, "Matrix2d");
bind_eigen_type<Matrix3d>(m, "Matrix3d"); bind_eigen_type<Matrix3d>(m, "Matrix3d");
bind_eigen_type<Matrix4d>(m, "Matrix4d"); bind_eigen_type<Matrix4d>(m, "Matrix4d");
bind_eigen_type<MatrixXi>(m, "MatrixXi"); bind_eigen_type<MatrixXi>(m, "MatrixXi");
bind_eigen_type<MatrixXf>(m, "MatrixXf"); bind_eigen_type<MatrixXf>(m, "MatrixXf");
bind_eigen_type<MatrixXd>(m, "MatrixXd"); bind_eigen_type<MatrixXd>(m, "MatrixXd");
// 2. Homogeneous types // 2. Homogeneous types
py::class_<HPoint3f>(m, "HPoint3f") py::class_<HPoint3f>(m, "HPoint3f")
.def(py::init<>()) .def(py::init<>())
.def(py::init<float, float, float>()) .def(py::init<float, float, float>())
.def(py::init<Vector3f &>()); .def(py::init<Vector3f &>());
py::class_<HVector3f>(m, "HVector3f") py::class_<HVector3f>(m, "HVector3f")
.def(py::init<>()) .def(py::init<>())
.def(py::init<float, float, float>()) .def(py::init<float, float, float>())
.def(py::init<Vector3f &>()); .def(py::init<Vector3f &>());
py::class_<HLine3f>(m, "HLine3f") py::class_<HLine3f>(m, "HLine3f")
.def(py::init<>()) .def(py::init<>())
.def_readwrite("origin", &HLine3f::origin) .def_readwrite("origin", &HLine3f::origin)
.def_readwrite("direction", &HLine3f::direction); .def_readwrite("direction", &HLine3f::direction);
py::class_<HError3f>(m, "HError3f") py::class_<HError3f>(m, "HError3f")
.def(py::init<>()) .def(py::init<>())
.def_readwrite("position_error", &HError3f::position_error) .def_readwrite("position_error", &HError3f::position_error)
.def_readwrite("direction_error", &HError3f::direction_error); .def_readwrite("direction_error", &HError3f::direction_error);
// 3. Dynamic Vectors (uLib::Vector) // 3. Dynamic Vectors (uLib::Vector)
py::bind_vector<uLib::Vector<Scalari>>(m, "Vector_i") py::bind_vector<uLib::Vector<Scalari>>(m, "Vector_i")
.def("MoveToVRAM", &uLib::Vector<Scalari>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalari>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalari>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalari>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarui>>(m, "Vector_ui") py::bind_vector<uLib::Vector<Scalarui>>(m, "Vector_ui")
.def("MoveToVRAM", &uLib::Vector<Scalarui>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalarui>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarui>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalarui>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarl>>(m, "Vector_l") py::bind_vector<uLib::Vector<Scalarl>>(m, "Vector_l")
.def("MoveToVRAM", &uLib::Vector<Scalarl>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalarl>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarl>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalarl>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarul>>(m, "Vector_ul") py::bind_vector<uLib::Vector<Scalarul>>(m, "Vector_ul")
.def("MoveToVRAM", &uLib::Vector<Scalarul>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalarul>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarul>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalarul>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarf>>(m, "Vector_f") py::bind_vector<uLib::Vector<Scalarf>>(m, "Vector_f")
.def("MoveToVRAM", &uLib::Vector<Scalarf>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalarf>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarf>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalarf>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalard>>(m, "Vector_d") py::bind_vector<uLib::Vector<Scalard>>(m, "Vector_d")
.def("MoveToVRAM", &uLib::Vector<Scalard>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Scalard>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalard>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Scalard>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3f>>(m, "Vector_Vector3f") py::bind_vector<uLib::Vector<Vector3f>>(m, "Vector_Vector3f")
.def("MoveToVRAM", &uLib::Vector<Vector3f>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector3f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3f>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector3f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3i>>(m, "Vector_Vector3i") py::bind_vector<uLib::Vector<Vector3i>>(m, "Vector_Vector3i")
.def("MoveToVRAM", &uLib::Vector<Vector3i>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector3i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3i>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector3i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4f>>(m, "Vector_Vector4f") py::bind_vector<uLib::Vector<Vector4f>>(m, "Vector_Vector4f")
.def("MoveToVRAM", &uLib::Vector<Vector4f>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector4f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4f>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector4f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4i>>(m, "Vector_Vector4i") py::bind_vector<uLib::Vector<Vector4i>>(m, "Vector_Vector4i")
.def("MoveToVRAM", &uLib::Vector<Vector4i>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector4i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4i>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector4i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3d>>(m, "Vector_Vector3d") py::bind_vector<uLib::Vector<Vector3d>>(m, "Vector_Vector3d")
.def("MoveToVRAM", &uLib::Vector<Vector3d>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector3d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3d>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector3d>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4d>>(m, "Vector_Vector4d") py::bind_vector<uLib::Vector<Vector4d>>(m, "Vector_Vector4d")
.def("MoveToVRAM", &uLib::Vector<Vector4d>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Vector4d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4d>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Vector4d>::MoveToRAM);
py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel") py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel")
.def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM) .def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM); .def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM);
py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(m, "Vector_VoxRaytracerRayDataElement") py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(
.def("MoveToVRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM) m, "Vector_VoxRaytracerRayDataElement")
.def("MoveToRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM); .def("MoveToVRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM)
.def("MoveToRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM);
// 4. Accumulators // 4. Accumulators
py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f") py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f")
.def(py::init<>()) .def(py::init<>())
.def("AddPass", &Accumulator_Mean<float>::AddPass) .def("AddPass", &Accumulator_Mean<float>::AddPass)
.def("__call__", py::overload_cast<const float>(&Accumulator_Mean<float>::operator())) .def("__call__",
.def("__call__", py::overload_cast<>(&Accumulator_Mean<float>::operator(), py::const_)); py::overload_cast<const float>(&Accumulator_Mean<float>::operator()))
.def("__call__", py::overload_cast<>(&Accumulator_Mean<float>::operator(),
py::const_));
py::class_<Accumulator_Mean<double>>(m, "Accumulator_Mean_d") py::class_<Accumulator_Mean<double>>(m, "Accumulator_Mean_d")
.def(py::init<>()) .def(py::init<>())
.def("AddPass", &Accumulator_Mean<double>::AddPass) .def("AddPass", &Accumulator_Mean<double>::AddPass)
.def("__call__", py::overload_cast<const double>(&Accumulator_Mean<double>::operator())) .def("__call__", py::overload_cast<const double>(
.def("__call__", py::overload_cast<>(&Accumulator_Mean<double>::operator(), py::const_)); &Accumulator_Mean<double>::operator()))
.def("__call__", py::overload_cast<>(
&Accumulator_Mean<double>::operator(), py::const_));
py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f") py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim) .def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<float> &self, float val) { self += val; return &self; }) .def("__iadd__",
.def("__call__", &Accumulator_ABTrim<float>::operator()); [](Accumulator_ABTrim<float> &self, float val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABTrim<float>::operator());
py::class_<Accumulator_ABTrim<double>>(m, "Accumulator_ABTrim_d") py::class_<Accumulator_ABTrim<double>>(m, "Accumulator_ABTrim_d")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim) .def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<double> &self, double val) { self += val; return &self; }) .def("__iadd__",
.def("__call__", &Accumulator_ABTrim<double>::operator()); [](Accumulator_ABTrim<double> &self, double val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABTrim<double>::operator());
py::class_<Accumulator_ABClip<float>>(m, "Accumulator_ABClip_f") py::class_<Accumulator_ABClip<float>>(m, "Accumulator_ABClip_f")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim) .def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<float> &self, float val) { self += val; return &self; }) .def("__iadd__",
.def("__call__", &Accumulator_ABClip<float>::operator()); [](Accumulator_ABClip<float> &self, float val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABClip<float>::operator());
py::class_<Accumulator_ABClip<double>>(m, "Accumulator_ABClip_d") py::class_<Accumulator_ABClip<double>>(m, "Accumulator_ABClip_d")
.def(py::init<>()) .def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim) .def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<double> &self, double val) { self += val; return &self; }) .def("__iadd__",
.def("__call__", &Accumulator_ABClip<double>::operator()); [](Accumulator_ABClip<double> &self, double val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABClip<double>::operator());
// 5. Core Math Structures // 5. Core Math Structures
py::class_<AffineTransform>(m, "AffineTransform") py::class_<AffineTransform>(m, "AffineTransform")
.def(py::init<>()) .def(py::init<>())
.def("GetWorldMatrix", &AffineTransform::GetWorldMatrix) .def("GetWorldMatrix", &AffineTransform::GetWorldMatrix)
.def("SetPosition", &AffineTransform::SetPosition) .def("SetPosition", &AffineTransform::SetPosition)
.def("GetPosition", &AffineTransform::GetPosition) .def("GetPosition", &AffineTransform::GetPosition)
.def("Translate", &AffineTransform::Translate) .def("Translate", &AffineTransform::Translate)
.def("Scale", &AffineTransform::Scale) .def("Scale", &AffineTransform::Scale)
.def("SetRotation", &AffineTransform::SetRotation) .def("SetRotation", &AffineTransform::SetRotation)
.def("GetRotation", &AffineTransform::GetRotation) .def("GetRotation", &AffineTransform::GetRotation)
.def("Rotate", &AffineTransform::Rotate) .def("Rotate",
.def("EulerYZYRotate", &AffineTransform::EulerYZYRotate) py::overload_cast<const Matrix3f>(&AffineTransform::Rotate))
.def("FlipAxes", &AffineTransform::FlipAxes); .def("Rotate",
py::overload_cast<float, Vector3f>(&AffineTransform::Rotate))
.def("Rotate", py::overload_cast<Vector3f>(&AffineTransform::Rotate))
.def("EulerYZYRotate", &AffineTransform::EulerYZYRotate)
.def("FlipAxes", &AffineTransform::FlipAxes);
py::class_<Geometry, AffineTransform>(m, "Geometry") py::class_<Geometry, AffineTransform>(m, "Geometry")
.def(py::init<>()) .def(py::init<>())
.def("GetWorldPoint", &Geometry::GetWorldPoint) .def("GetWorldPoint", py::overload_cast<const Vector4f>(
.def("GetLocalPoint", &Geometry::GetLocalPoint); &Geometry::GetWorldPoint, py::const_))
.def("GetWorldPoint",
py::overload_cast<float, float, float>(&Geometry::GetWorldPoint))
.def("GetLocalPoint", py::overload_cast<const Vector4f>(
&Geometry::GetLocalPoint, py::const_))
.def("GetLocalPoint",
py::overload_cast<float, float, float>(&Geometry::GetLocalPoint));
py::class_<ContainerBox, AffineTransform>(m, "ContainerBox") py::class_<ContainerBox, AffineTransform, Object>(m, "ContainerBox")
.def(py::init<>()) .def(py::init<>())
.def("SetOrigin", &ContainerBox::SetOrigin) .def("SetOrigin", &ContainerBox::SetOrigin)
.def("GetOrigin", &ContainerBox::GetOrigin) .def("GetOrigin", &ContainerBox::GetOrigin)
.def("SetSize", &ContainerBox::SetSize) .def("SetSize", &ContainerBox::SetSize)
.def("GetSize", &ContainerBox::GetSize) .def("GetSize", &ContainerBox::GetSize)
.def("GetWorldMatrix", &ContainerBox::GetWorldMatrix) .def("GetLocalMatrix", &ContainerBox::GetLocalMatrix)
.def("GetWorldPoint", &ContainerBox::GetWorldPoint) .def("GetWorldMatrix", &ContainerBox::GetWorldMatrix)
.def("GetLocalPoint", &ContainerBox::GetLocalPoint); .def("GetWorldPoint", py::overload_cast<const Vector4f &>(
&ContainerBox::GetWorldPoint, py::const_))
.def("GetWorldPoint",
py::overload_cast<float, float, float>(&ContainerBox::GetWorldPoint))
.def("GetLocalPoint", py::overload_cast<const Vector4f &>(
&ContainerBox::GetLocalPoint, py::const_))
.def("GetLocalPoint",
py::overload_cast<float, float, float>(&ContainerBox::GetLocalPoint))
.def("FlipLocalAxes", &ContainerBox::FlipLocalAxes);
py::enum_<StructuredData::_Order>(m, "StructuredDataOrder") py::enum_<StructuredData::_Order>(m, "StructuredDataOrder")
.value("CustomOrder", StructuredData::CustomOrder) .value("CustomOrder", StructuredData::CustomOrder)
.value("XYZ", StructuredData::XYZ) .value("XYZ", StructuredData::XYZ)
.value("XZY", StructuredData::XZY) .value("XZY", StructuredData::XZY)
.value("YXZ", StructuredData::YXZ) .value("YXZ", StructuredData::YXZ)
.value("YZX", StructuredData::YZX) .value("YZX", StructuredData::YZX)
.value("ZXY", StructuredData::ZXY) .value("ZXY", StructuredData::ZXY)
.value("ZYX", StructuredData::ZYX) .value("ZYX", StructuredData::ZYX)
.export_values(); .export_values();
py::class_<StructuredData>(m, "StructuredData") py::class_<StructuredData>(m, "StructuredData")
.def(py::init<const Vector3i &>()) .def(py::init<const Vector3i &>())
.def("GetDims", &StructuredData::GetDims) .def("GetDims", &StructuredData::GetDims)
.def("SetDims", &StructuredData::SetDims) .def("SetDims", &StructuredData::SetDims)
.def("GetIncrements", &StructuredData::GetIncrements) .def("GetIncrements", &StructuredData::GetIncrements)
.def("SetIncrements", &StructuredData::SetIncrements) .def("SetIncrements", &StructuredData::SetIncrements)
.def("SetDataOrder", &StructuredData::SetDataOrder) .def("SetDataOrder", &StructuredData::SetDataOrder)
.def("GetDataOrder", &StructuredData::GetDataOrder) .def("GetDataOrder", &StructuredData::GetDataOrder)
.def("IsInsideGrid", &StructuredData::IsInsideGrid) .def("IsInsideGrid", &StructuredData::IsInsideGrid)
.def("Map", &StructuredData::Map) .def("Map", &StructuredData::Map)
.def("UnMap", &StructuredData::UnMap); .def("UnMap", &StructuredData::UnMap);
py::class_<StructuredGrid, ContainerBox, StructuredData>(m, "StructuredGrid") py::class_<StructuredGrid, ContainerBox, StructuredData>(m, "StructuredGrid")
.def(py::init<const Vector3i &>()) .def(py::init<const Vector3i &>())
.def("SetSpacing", &StructuredGrid::SetSpacing) .def("SetSpacing", &StructuredGrid::SetSpacing)
.def("GetSpacing", &StructuredGrid::GetSpacing) .def("GetSpacing", &StructuredGrid::GetSpacing)
.def("IsInsideBounds", &StructuredGrid::IsInsideBounds) .def("IsInsideBounds", &StructuredGrid::IsInsideBounds)
.def("Find", [](StructuredGrid &self, Vector3f pt) { .def("Find", [](StructuredGrid &self, Vector3f pt) {
return self.Find(HPoint3f(pt)); return self.Find(HPoint3f(pt));
}); });
py::class_<Structured2DGrid>(m, "Structured2DGrid") py::class_<Structured2DGrid>(m, "Structured2DGrid")
.def(py::init<>()) .def(py::init<>())
.def("SetDims", &Structured2DGrid::SetDims) .def("SetDims", &Structured2DGrid::SetDims)
.def("GetDims", &Structured2DGrid::GetDims) .def("GetDims", &Structured2DGrid::GetDims)
.def("IsInsideGrid", &Structured2DGrid::IsInsideGrid) .def("IsInsideGrid", &Structured2DGrid::IsInsideGrid)
.def("Map", &Structured2DGrid::Map) .def("Map", &Structured2DGrid::Map)
.def("UnMap", &Structured2DGrid::UnMap) .def("UnMap", &Structured2DGrid::UnMap)
.def("SetPhysicalSpace", &Structured2DGrid::SetPhysicalSpace) .def("SetPhysicalSpace", &Structured2DGrid::SetPhysicalSpace)
.def("GetSpacing", &Structured2DGrid::GetSpacing) .def("GetSpacing", &Structured2DGrid::GetSpacing)
.def("GetOrigin", &Structured2DGrid::GetOrigin) .def("GetOrigin", &Structured2DGrid::GetOrigin)
.def("IsInsideBounds", &Structured2DGrid::IsInsideBounds) .def("IsInsideBounds", &Structured2DGrid::IsInsideBounds)
.def("PhysicsToUnitSpace", &Structured2DGrid::PhysicsToUnitSpace) .def("PhysicsToUnitSpace", &Structured2DGrid::PhysicsToUnitSpace)
.def("UnitToPhysicsSpace", &Structured2DGrid::UnitToPhysicsSpace) .def("UnitToPhysicsSpace", &Structured2DGrid::UnitToPhysicsSpace)
.def("SetDebug", &Structured2DGrid::SetDebug); .def("SetDebug", &Structured2DGrid::SetDebug);
py::class_<Structured4DGrid>(m, "Structured4DGrid") py::class_<Structured4DGrid>(m, "Structured4DGrid")
.def(py::init<>()) .def(py::init<>())
.def("SetDims", &Structured4DGrid::SetDims) .def("SetDims", &Structured4DGrid::SetDims)
.def("GetDims", &Structured4DGrid::GetDims) .def("GetDims", &Structured4DGrid::GetDims)
.def("IsInsideGrid", &Structured4DGrid::IsInsideGrid) .def("IsInsideGrid", &Structured4DGrid::IsInsideGrid)
.def("Map", &Structured4DGrid::Map) .def("Map", &Structured4DGrid::Map)
.def("UnMap", &Structured4DGrid::UnMap) .def("UnMap", &Structured4DGrid::UnMap)
.def("SetPhysicalSpace", &Structured4DGrid::SetPhysicalSpace) .def("SetPhysicalSpace", &Structured4DGrid::SetPhysicalSpace)
.def("GetSpacing", &Structured4DGrid::GetSpacing) .def("GetSpacing", &Structured4DGrid::GetSpacing)
.def("GetOrigin", &Structured4DGrid::GetOrigin) .def("GetOrigin", &Structured4DGrid::GetOrigin)
.def("IsInsideBounds", &Structured4DGrid::IsInsideBounds) .def("IsInsideBounds", &Structured4DGrid::IsInsideBounds)
.def("PhysicsToUnitSpace", &Structured4DGrid::PhysicsToUnitSpace) .def("PhysicsToUnitSpace", &Structured4DGrid::PhysicsToUnitSpace)
.def("UnitToPhysicsSpace", &Structured4DGrid::UnitToPhysicsSpace) .def("UnitToPhysicsSpace", &Structured4DGrid::UnitToPhysicsSpace)
.def("SetDebug", &Structured4DGrid::SetDebug); .def("SetDebug", &Structured4DGrid::SetDebug);
// 6. High-level Structures // 6. High-level Structures
py::class_<Voxel>(m, "Voxel") py::class_<Voxel>(m, "Voxel")
.def(py::init<>()) .def(py::init<>())
.def_readwrite("Value", &Voxel::Value) .def_readwrite("Value", &Voxel::Value)
.def_readwrite("Count", &Voxel::Count); .def_readwrite("Count", &Voxel::Count);
py::class_<Abstract::VoxImage, StructuredGrid>(m, "AbstractVoxImage") py::class_<Abstract::VoxImage, StructuredGrid>(m, "AbstractVoxImage")
.def("GetValue", py::overload_cast<const Vector3i &>(&Abstract::VoxImage::GetValue, py::const_)) .def("GetValue", py::overload_cast<const Vector3i &>(
.def("GetValue", py::overload_cast<const int>(&Abstract::VoxImage::GetValue, py::const_)) &Abstract::VoxImage::GetValue, py::const_))
.def("SetValue", py::overload_cast<const Vector3i &, float>(&Abstract::VoxImage::SetValue)) .def("GetValue", py::overload_cast<const int>(
.def("SetValue", py::overload_cast<const int, float>(&Abstract::VoxImage::SetValue)) &Abstract::VoxImage::GetValue, py::const_))
.def("ExportToVtk", &Abstract::VoxImage::ExportToVtk) .def("SetValue", py::overload_cast<const Vector3i &, float>(
.def("ExportToVti", &Abstract::VoxImage::ExportToVti) &Abstract::VoxImage::SetValue))
.def("ImportFromVtk", &Abstract::VoxImage::ImportFromVtk) .def("SetValue",
.def("ImportFromVti", &Abstract::VoxImage::ImportFromVti); py::overload_cast<const int, float>(&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_<VoxImage<Voxel>, Abstract::VoxImage>(m, "VoxImage") py::class_<VoxImage<Voxel>, Abstract::VoxImage>(m, "VoxImage")
.def(py::init<>()) .def(py::init<>())
.def(py::init<const Vector3i &>()) .def(py::init<const Vector3i &>())
.def("Data", &VoxImage<Voxel>::Data, py::return_value_policy::reference_internal) .def("Data", &VoxImage<Voxel>::Data,
.def("InitVoxels", &VoxImage<Voxel>::InitVoxels) py::return_value_policy::reference_internal)
.def("Abs", &VoxImage<Voxel>::Abs) .def("InitVoxels", &VoxImage<Voxel>::InitVoxels)
.def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(&VoxImage<Voxel>::clipImage, py::const_)) .def("Abs", &VoxImage<Voxel>::Abs)
.def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(&VoxImage<Voxel>::clipImage, py::const_)) .def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(
.def("clipImage", py::overload_cast<const float>(&VoxImage<Voxel>::clipImage, py::const_)) &VoxImage<Voxel>::clipImage, py::const_))
.def("maskImage", py::overload_cast<const HPoint3f, const HPoint3f, float>(&VoxImage<Voxel>::maskImage, py::const_)) .def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(
.def("maskImage", py::overload_cast<const float, float, float>(&VoxImage<Voxel>::maskImage, py::const_), py::arg("threshold"), py::arg("belowValue") = 0, py::arg("aboveValue") = 0) &VoxImage<Voxel>::clipImage, py::const_))
.def("fixVoxels", py::overload_cast<const float, float>(&VoxImage<Voxel>::fixVoxels, py::const_)) .def("clipImage", py::overload_cast<const float>(
.def("__getitem__", py::overload_cast<unsigned int>(&VoxImage<Voxel>::operator[])) &VoxImage<Voxel>::clipImage, py::const_))
.def("__getitem__", py::overload_cast<const Vector3i &>(&VoxImage<Voxel>::operator[])); .def("maskImage",
py::overload_cast<const HPoint3f, const HPoint3f, float>(
&VoxImage<Voxel>::maskImage, py::const_))
.def("maskImage",
py::overload_cast<const float, float, float>(
&VoxImage<Voxel>::maskImage, py::const_),
py::arg("threshold"), py::arg("belowValue") = 0,
py::arg("aboveValue") = 0)
.def("fixVoxels", py::overload_cast<const float, float>(
&VoxImage<Voxel>::fixVoxels, py::const_))
.def("__getitem__",
py::overload_cast<unsigned int>(&VoxImage<Voxel>::operator[]))
.def("__getitem__",
py::overload_cast<const Vector3i &>(&VoxImage<Voxel>::operator[]));
py::class_<TriangleMesh>(m, "TriangleMesh") py::class_<TriangleMesh>(m, "TriangleMesh")
.def(py::init<>()) .def(py::init<>())
.def("AddPoint", &TriangleMesh::AddPoint) .def("AddPoint", &TriangleMesh::AddPoint)
.def("AddTriangle", py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle)) .def("AddTriangle",
.def("Points", &TriangleMesh::Points, py::return_value_policy::reference_internal) py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle))
.def("Triangles", &TriangleMesh::Triangles, py::return_value_policy::reference_internal); .def("Points", &TriangleMesh::Points,
py::return_value_policy::reference_internal)
.def("Triangles", &TriangleMesh::Triangles,
py::return_value_policy::reference_internal);
py::class_<VoxRaytracer::RayData::Element>(m, "VoxRaytracerRayDataElement") py::class_<VoxRaytracer::RayData::Element>(m, "VoxRaytracerRayDataElement")
.def(py::init<>()) .def(py::init<>())
.def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id) .def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id)
.def_readwrite("L", &VoxRaytracer::RayData::Element::L); .def_readwrite("L", &VoxRaytracer::RayData::Element::L);
py::class_<VoxRaytracer::RayData>(m, "VoxRaytracerRayData") py::class_<VoxRaytracer::RayData>(m, "VoxRaytracerRayData")
.def(py::init<>()) .def(py::init<>())
.def("AppendRay", &VoxRaytracer::RayData::AppendRay) .def("AppendRay", &VoxRaytracer::RayData::AppendRay)
.def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data), py::return_value_policy::reference_internal) .def("Data", py::overload_cast<>(&VoxRaytracer::RayData::Data),
.def("Count", &VoxRaytracer::RayData::Count) py::return_value_policy::reference_internal)
.def("TotalLength", &VoxRaytracer::RayData::TotalLength) .def("Count", &VoxRaytracer::RayData::Count)
.def("SetCount", &VoxRaytracer::RayData::SetCount) .def("TotalLength", &VoxRaytracer::RayData::TotalLength)
.def("SetTotalLength", &VoxRaytracer::RayData::SetTotalLength); .def("SetCount", &VoxRaytracer::RayData::SetCount)
.def("SetTotalLength", &VoxRaytracer::RayData::SetTotalLength);
py::class_<VoxRaytracer>(m, "VoxRaytracer")
.def(py::init<StructuredGrid &>(), 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_<VoxRaytracer>(m, "VoxRaytracer")
.def(py::init<StructuredGrid &>(), py::keep_alive<1, 2>())
.def("GetImage", &VoxRaytracer::GetImage,
py::return_value_policy::reference_internal)
.def("TraceLine", &VoxRaytracer::TraceLine)
.def("TraceBetweenPoints", &VoxRaytracer::TraceBetweenPoints);
} }

View File

@@ -102,7 +102,8 @@ void vtkDetectorChamber::SetTransform(vtkTransform *t) {
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
transform(i, j) = vmat->GetElement(i, j); transform(i, j) = vmat->GetElement(i, j);
this->GetContent()->SetMatrix(transform); this->GetContent()->SetMatrix(transform);
this->GetContent()->Updated(); // emit signal
this->Update(); this->Update();
} }

View File

@@ -72,8 +72,7 @@ void vtkContainerBox::Update() {
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
vmat->SetElement(i, j, transform(i, 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->SetMatrix(vmat);
// m_RelativeTransform->Update(); // m_RelativeTransform->Update();