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

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

View File

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

View File

@@ -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<HitData> )
uLibGetMacro (Idv, ChamberDetector::ID)
uLibGetMacro (Idv, uint)
private:
friend class ChamberHitEvent;
Vector<HitData> m_Hits;
DetectorChamber::ID m_Idv; // -> chamber/view
uint m_Idv; // -> chamber/view
};
class ChamberHitEvent : public ChamberHitEventData {
public:
uLibRefMacro (Hits, Vector<HitData> )
uLibSetMacro (Idv, ChamberDetector::ID)
uLibSetMacro (Idv, uint)
};
}

View File

@@ -33,9 +33,6 @@
namespace uLib {
class HitRawCode_CMSDrift :
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 ###################################
################################################################################
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()

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 "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<ChamberHitEventData>)
uLibGetMacro(EventID, Id_t) uLibGetMacro(Momentum, Scalarf)
uLibConstRefMacro(GenPos, Vector3f) uLibConstRefMacro(GenDir, Vector3f)
uLibConstRefMacro(ChEvents, Vector<ChamberHitEventData>)
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<ChamberHitEventData> 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<ChamberHitEventData>)
uLibRefMacro(GenPos, Vector3f) uLibRefMacro(GenDir, Vector3f)
uLibRefMacro(ChEvents, Vector<ChamberHitEventData>)
};
} // 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/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 "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<Solid> 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<Solid *> 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

View File

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

View File

@@ -23,20 +23,21 @@
//////////////////////////////////////////////////////////////////////////////*/
// G4 Solid //
#include <Geant4/G4LogicalVolume.hh>
#include <Geant4/G4Material.hh>
#include <Geant4/G4NistManager.hh>
#include <Geant4/G4LogicalVolume.hh>
// Tessellated solid //
#include <Geant4/G4TessellatedSolid.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4ThreeVector.hh>
#include <Geant4/G4TriangularFacet.hh>
#include <Geant4/G4Box.hh>
#include <Geant4/G4PVPlacement.hh>
#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; 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);
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

View File

@@ -23,39 +23,51 @@
//////////////////////////////////////////////////////////////////////////////*/
#ifndef SOLID_H
#define SOLID_H
#include "Core/Object.h"
#include "Geant/Matter.h"
#include <Geant4/G4LogicalVolume.hh>
#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

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;
};
class HitMC {
public:
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
#define U_CONTAINERBOX_H
#include "Geometry.h"
#include "Core/Object.h"
#include "Math/Dense.h"
#include "Math/Transform.h"
#include <utility>
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 &copy) :
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 &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.
* @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

View File

@@ -1,22 +1,22 @@
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#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<VoxRaytracer::RayData::Element>);
template <typename MatrixType>
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<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;
// 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<Scalar, py::array::c_style | py::array::forcecast> 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<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);
Scalar* ptr = static_cast<Scalar*>(buf.ptr);
for (ssize_t i = 0; i < buf.size; ++i) mat(i) = ptr[i];
} else {
Scalar *ptr = static_cast<Scalar *>(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<Scalar*>(buf.ptr);
Scalar *ptr = static_cast<Scalar *>(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<Vector1f>(m, "Vector1f");
bind_eigen_type<Vector2f>(m, "Vector2f");
bind_eigen_type<Vector3f>(m, "Vector3f");
bind_eigen_type<Vector4f>(m, "Vector4f");
bind_eigen_type<Vector1i>(m, "Vector1i");
bind_eigen_type<Vector2i>(m, "Vector2i");
bind_eigen_type<Vector3i>(m, "Vector3i");
bind_eigen_type<Vector4i>(m, "Vector4i");
bind_eigen_type<Vector1d>(m, "Vector1d");
bind_eigen_type<Vector2d>(m, "Vector2d");
bind_eigen_type<Vector3d>(m, "Vector3d");
bind_eigen_type<Vector4d>(m, "Vector4d");
// 1. Basic Eigen Types (Vectors and Matrices)
bind_eigen_type<Vector1f>(m, "Vector1f");
bind_eigen_type<Vector2f>(m, "Vector2f");
bind_eigen_type<Vector3f>(m, "Vector3f");
bind_eigen_type<Vector4f>(m, "Vector4f");
bind_eigen_type<Vector1i>(m, "Vector1i");
bind_eigen_type<Vector2i>(m, "Vector2i");
bind_eigen_type<Vector3i>(m, "Vector3i");
bind_eigen_type<Vector4i>(m, "Vector4i");
bind_eigen_type<Vector1d>(m, "Vector1d");
bind_eigen_type<Vector2d>(m, "Vector2d");
bind_eigen_type<Vector3d>(m, "Vector3d");
bind_eigen_type<Vector4d>(m, "Vector4d");
bind_eigen_type<Matrix2f>(m, "Matrix2f");
bind_eigen_type<Matrix3f>(m, "Matrix3f");
bind_eigen_type<Matrix4f>(m, "Matrix4f");
bind_eigen_type<Matrix2i>(m, "Matrix2i");
bind_eigen_type<Matrix3i>(m, "Matrix3i");
bind_eigen_type<Matrix4i>(m, "Matrix4i");
bind_eigen_type<Matrix2d>(m, "Matrix2d");
bind_eigen_type<Matrix3d>(m, "Matrix3d");
bind_eigen_type<Matrix4d>(m, "Matrix4d");
bind_eigen_type<Matrix2f>(m, "Matrix2f");
bind_eigen_type<Matrix3f>(m, "Matrix3f");
bind_eigen_type<Matrix4f>(m, "Matrix4f");
bind_eigen_type<Matrix2i>(m, "Matrix2i");
bind_eigen_type<Matrix3i>(m, "Matrix3i");
bind_eigen_type<Matrix4i>(m, "Matrix4i");
bind_eigen_type<Matrix2d>(m, "Matrix2d");
bind_eigen_type<Matrix3d>(m, "Matrix3d");
bind_eigen_type<Matrix4d>(m, "Matrix4d");
bind_eigen_type<MatrixXi>(m, "MatrixXi");
bind_eigen_type<MatrixXf>(m, "MatrixXf");
bind_eigen_type<MatrixXd>(m, "MatrixXd");
bind_eigen_type<MatrixXi>(m, "MatrixXi");
bind_eigen_type<MatrixXf>(m, "MatrixXf");
bind_eigen_type<MatrixXd>(m, "MatrixXd");
// 2. Homogeneous types
py::class_<HPoint3f>(m, "HPoint3f")
.def(py::init<>())
.def(py::init<float, float, float>())
.def(py::init<Vector3f &>());
py::class_<HVector3f>(m, "HVector3f")
.def(py::init<>())
.def(py::init<float, float, float>())
.def(py::init<Vector3f &>());
py::class_<HLine3f>(m, "HLine3f")
.def(py::init<>())
.def_readwrite("origin", &HLine3f::origin)
.def_readwrite("direction", &HLine3f::direction);
py::class_<HError3f>(m, "HError3f")
.def(py::init<>())
.def_readwrite("position_error", &HError3f::position_error)
.def_readwrite("direction_error", &HError3f::direction_error);
// 2. Homogeneous types
py::class_<HPoint3f>(m, "HPoint3f")
.def(py::init<>())
.def(py::init<float, float, float>())
.def(py::init<Vector3f &>());
py::class_<HVector3f>(m, "HVector3f")
.def(py::init<>())
.def(py::init<float, float, float>())
.def(py::init<Vector3f &>());
py::class_<HLine3f>(m, "HLine3f")
.def(py::init<>())
.def_readwrite("origin", &HLine3f::origin)
.def_readwrite("direction", &HLine3f::direction);
py::class_<HError3f>(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<uLib::Vector<Scalari>>(m, "Vector_i")
.def("MoveToVRAM", &uLib::Vector<Scalari>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalari>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarui>>(m, "Vector_ui")
.def("MoveToVRAM", &uLib::Vector<Scalarui>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarui>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarl>>(m, "Vector_l")
.def("MoveToVRAM", &uLib::Vector<Scalarl>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarl>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarul>>(m, "Vector_ul")
.def("MoveToVRAM", &uLib::Vector<Scalarul>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarul>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarf>>(m, "Vector_f")
.def("MoveToVRAM", &uLib::Vector<Scalarf>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarf>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalard>>(m, "Vector_d")
.def("MoveToVRAM", &uLib::Vector<Scalard>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalard>::MoveToRAM);
// 3. Dynamic Vectors (uLib::Vector)
py::bind_vector<uLib::Vector<Scalari>>(m, "Vector_i")
.def("MoveToVRAM", &uLib::Vector<Scalari>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalari>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarui>>(m, "Vector_ui")
.def("MoveToVRAM", &uLib::Vector<Scalarui>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarui>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarl>>(m, "Vector_l")
.def("MoveToVRAM", &uLib::Vector<Scalarl>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarl>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarul>>(m, "Vector_ul")
.def("MoveToVRAM", &uLib::Vector<Scalarul>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarul>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalarf>>(m, "Vector_f")
.def("MoveToVRAM", &uLib::Vector<Scalarf>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalarf>::MoveToRAM);
py::bind_vector<uLib::Vector<Scalard>>(m, "Vector_d")
.def("MoveToVRAM", &uLib::Vector<Scalard>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Scalard>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3f>>(m, "Vector_Vector3f")
.def("MoveToVRAM", &uLib::Vector<Vector3f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3i>>(m, "Vector_Vector3i")
.def("MoveToVRAM", &uLib::Vector<Vector3i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4f>>(m, "Vector_Vector4f")
.def("MoveToVRAM", &uLib::Vector<Vector4f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4i>>(m, "Vector_Vector4i")
.def("MoveToVRAM", &uLib::Vector<Vector4i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3d>>(m, "Vector_Vector3d")
.def("MoveToVRAM", &uLib::Vector<Vector3d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3d>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4d>>(m, "Vector_Vector4d")
.def("MoveToVRAM", &uLib::Vector<Vector4d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4d>::MoveToRAM);
py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel")
.def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM);
py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(m, "Vector_VoxRaytracerRayDataElement")
.def("MoveToVRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3f>>(m, "Vector_Vector3f")
.def("MoveToVRAM", &uLib::Vector<Vector3f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3i>>(m, "Vector_Vector3i")
.def("MoveToVRAM", &uLib::Vector<Vector3i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4f>>(m, "Vector_Vector4f")
.def("MoveToVRAM", &uLib::Vector<Vector4f>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4f>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4i>>(m, "Vector_Vector4i")
.def("MoveToVRAM", &uLib::Vector<Vector4i>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4i>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector3d>>(m, "Vector_Vector3d")
.def("MoveToVRAM", &uLib::Vector<Vector3d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector3d>::MoveToRAM);
py::bind_vector<uLib::Vector<Vector4d>>(m, "Vector_Vector4d")
.def("MoveToVRAM", &uLib::Vector<Vector4d>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Vector4d>::MoveToRAM);
py::bind_vector<uLib::Vector<Voxel>>(m, "Vector_Voxel")
.def("MoveToVRAM", &uLib::Vector<Voxel>::MoveToVRAM)
.def("MoveToRAM", &uLib::Vector<Voxel>::MoveToRAM);
py::bind_vector<uLib::Vector<VoxRaytracer::RayData::Element>>(
m, "Vector_VoxRaytracerRayDataElement")
.def("MoveToVRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToVRAM)
.def("MoveToRAM",
&uLib::Vector<VoxRaytracer::RayData::Element>::MoveToRAM);
// 4. Accumulators
py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f")
.def(py::init<>())
.def("AddPass", &Accumulator_Mean<float>::AddPass)
.def("__call__", py::overload_cast<const float>(&Accumulator_Mean<float>::operator()))
.def("__call__", py::overload_cast<>(&Accumulator_Mean<float>::operator(), py::const_));
// 4. Accumulators
py::class_<Accumulator_Mean<float>>(m, "Accumulator_Mean_f")
.def(py::init<>())
.def("AddPass", &Accumulator_Mean<float>::AddPass)
.def("__call__",
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")
.def(py::init<>())
.def("AddPass", &Accumulator_Mean<double>::AddPass)
.def("__call__", py::overload_cast<const double>(&Accumulator_Mean<double>::operator()))
.def("__call__", py::overload_cast<>(&Accumulator_Mean<double>::operator(), py::const_));
py::class_<Accumulator_Mean<double>>(m, "Accumulator_Mean_d")
.def(py::init<>())
.def("AddPass", &Accumulator_Mean<double>::AddPass)
.def("__call__", py::overload_cast<const double>(
&Accumulator_Mean<double>::operator()))
.def("__call__", py::overload_cast<>(
&Accumulator_Mean<double>::operator(), py::const_));
py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<float> &self, float val) { self += val; return &self; })
.def("__call__", &Accumulator_ABTrim<float>::operator());
py::class_<Accumulator_ABTrim<float>>(m, "Accumulator_ABTrim_f")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<float>::SetABTrim)
.def("__iadd__",
[](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")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABTrim<double> &self, double val) { self += val; return &self; })
.def("__call__", &Accumulator_ABTrim<double>::operator());
py::class_<Accumulator_ABTrim<double>>(m, "Accumulator_ABTrim_d")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABTrim<double>::SetABTrim)
.def("__iadd__",
[](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")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<float> &self, float val) { self += val; return &self; })
.def("__call__", &Accumulator_ABClip<float>::operator());
py::class_<Accumulator_ABClip<float>>(m, "Accumulator_ABClip_f")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<float>::SetABTrim)
.def("__iadd__",
[](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")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim)
.def("__iadd__", [](Accumulator_ABClip<double> &self, double val) { self += val; return &self; })
.def("__call__", &Accumulator_ABClip<double>::operator());
py::class_<Accumulator_ABClip<double>>(m, "Accumulator_ABClip_d")
.def(py::init<>())
.def("SetABTrim", &Accumulator_ABClip<double>::SetABTrim)
.def("__iadd__",
[](Accumulator_ABClip<double> &self, double val) {
self += val;
return &self;
})
.def("__call__", &Accumulator_ABClip<double>::operator());
// 5. Core Math Structures
py::class_<AffineTransform>(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_<AffineTransform>(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<const Matrix3f>(&AffineTransform::Rotate))
.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")
.def(py::init<>())
.def("GetWorldPoint", &Geometry::GetWorldPoint)
.def("GetLocalPoint", &Geometry::GetLocalPoint);
py::class_<Geometry, AffineTransform>(m, "Geometry")
.def(py::init<>())
.def("GetWorldPoint", py::overload_cast<const Vector4f>(
&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")
.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_<ContainerBox, AffineTransform, Object>(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<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")
.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_<StructuredData::_Order>(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_<StructuredData>(m, "StructuredData")
.def(py::init<const Vector3i &>())
.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_<StructuredData>(m, "StructuredData")
.def(py::init<const Vector3i &>())
.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_<StructuredGrid, ContainerBox, StructuredData>(m, "StructuredGrid")
.def(py::init<const Vector3i &>())
.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_<StructuredGrid, ContainerBox, StructuredData>(m, "StructuredGrid")
.def(py::init<const Vector3i &>())
.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_<Structured2DGrid>(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_<Structured2DGrid>(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_<Structured4DGrid>(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_<Structured4DGrid>(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_<Voxel>(m, "Voxel")
.def(py::init<>())
.def_readwrite("Value", &Voxel::Value)
.def_readwrite("Count", &Voxel::Count);
// 6. High-level Structures
py::class_<Voxel>(m, "Voxel")
.def(py::init<>())
.def_readwrite("Value", &Voxel::Value)
.def_readwrite("Count", &Voxel::Count);
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 int>(&Abstract::VoxImage::GetValue, py::const_))
.def("SetValue", py::overload_cast<const Vector3i &, float>(&Abstract::VoxImage::SetValue))
.def("SetValue", 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_<Abstract::VoxImage, StructuredGrid>(m, "AbstractVoxImage")
.def("GetValue", py::overload_cast<const Vector3i &>(
&Abstract::VoxImage::GetValue, py::const_))
.def("GetValue", py::overload_cast<const int>(
&Abstract::VoxImage::GetValue, py::const_))
.def("SetValue", py::overload_cast<const Vector3i &, float>(
&Abstract::VoxImage::SetValue))
.def("SetValue",
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")
.def(py::init<>())
.def(py::init<const Vector3i &>())
.def("Data", &VoxImage<Voxel>::Data, py::return_value_policy::reference_internal)
.def("InitVoxels", &VoxImage<Voxel>::InitVoxels)
.def("Abs", &VoxImage<Voxel>::Abs)
.def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(&VoxImage<Voxel>::clipImage, py::const_))
.def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(&VoxImage<Voxel>::clipImage, py::const_))
.def("clipImage", py::overload_cast<const float>(&VoxImage<Voxel>::clipImage, py::const_))
.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_<VoxImage<Voxel>, Abstract::VoxImage>(m, "VoxImage")
.def(py::init<>())
.def(py::init<const Vector3i &>())
.def("Data", &VoxImage<Voxel>::Data,
py::return_value_policy::reference_internal)
.def("InitVoxels", &VoxImage<Voxel>::InitVoxels)
.def("Abs", &VoxImage<Voxel>::Abs)
.def("clipImage", py::overload_cast<const Vector3i, const Vector3i>(
&VoxImage<Voxel>::clipImage, py::const_))
.def("clipImage", py::overload_cast<const HPoint3f, const HPoint3f>(
&VoxImage<Voxel>::clipImage, py::const_))
.def("clipImage", py::overload_cast<const float>(
&VoxImage<Voxel>::clipImage, py::const_))
.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")
.def(py::init<>())
.def("AddPoint", &TriangleMesh::AddPoint)
.def("AddTriangle", py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle))
.def("Points", &TriangleMesh::Points, py::return_value_policy::reference_internal)
.def("Triangles", &TriangleMesh::Triangles, py::return_value_policy::reference_internal);
py::class_<TriangleMesh>(m, "TriangleMesh")
.def(py::init<>())
.def("AddPoint", &TriangleMesh::AddPoint)
.def("AddTriangle",
py::overload_cast<const Vector3i &>(&TriangleMesh::AddTriangle))
.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")
.def(py::init<>())
.def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id)
.def_readwrite("L", &VoxRaytracer::RayData::Element::L);
py::class_<VoxRaytracer::RayData::Element>(m, "VoxRaytracerRayDataElement")
.def(py::init<>())
.def_readwrite("vox_id", &VoxRaytracer::RayData::Element::vox_id)
.def_readwrite("L", &VoxRaytracer::RayData::Element::L);
py::class_<VoxRaytracer::RayData>(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_<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::RayData>(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_<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)
transform(i, j) = vmat->GetElement(i, j);
this->GetContent()->SetMatrix(transform);
this->GetContent()->Updated(); // emit signal
this->Update();
}

View File

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