refactor: update Geant scene visualization to use PhysicalVolumes instead of raw Solids for improved placement and context handling.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -20,3 +20,6 @@ test_boost.cpp
|
||||
.claude/settings.json
|
||||
build_output.log
|
||||
configure_output.log
|
||||
test.xml
|
||||
test_ref_smartpointer.xml
|
||||
test_ref.xml
|
||||
|
||||
@@ -127,6 +127,10 @@ const Vector<Solid*>& Scene::GetSolids() const {
|
||||
return d->m_Solids;
|
||||
}
|
||||
|
||||
const Vector<SmartPointer<PhysicalVolume>>& Scene::GetVolumes() const {
|
||||
return d->m_Volumes;
|
||||
}
|
||||
|
||||
void Scene::ConstructWorldBox(const Vector3f &size, const char *materialName) {
|
||||
d->m_WorldBox->SetSize(size);
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@ public:
|
||||
/// Get the list of solids in the scene
|
||||
const Vector<Solid*>& GetSolids() const;
|
||||
|
||||
/// Get the list of physical volumes in the scene
|
||||
const Vector<SmartPointer<PhysicalVolume>>& GetVolumes() const;
|
||||
|
||||
/// Set the primary generator (emitter) for the simulation.
|
||||
/// The Scene does NOT take ownership of the emitter.
|
||||
void SetEmitter(EmitterPrimary *emitter);
|
||||
|
||||
@@ -75,13 +75,23 @@ int main(int argc, char** argv) {
|
||||
Geant::Scene scene;
|
||||
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||
|
||||
ContainerBox iron_box;
|
||||
iron_box.Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box.SetPosition(Vector3f(0, 0, 0));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
// Iron Cube
|
||||
SmartPointer<ContainerBox> iron_box(new ContainerBox());
|
||||
iron_box->Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box->SetPosition(Vector3f(0, 0, 0));
|
||||
|
||||
SmartPointer<Geant::BoxSolid> iron_solid(new Geant::BoxSolid("IronSolid", iron_box));
|
||||
iron_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> iron_mat(new Geant::Material("IronMat"));
|
||||
iron_mat->SetFromNist("G4_Fe");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> iron_lv(new Geant::LogicalVolume("IronLV"));
|
||||
iron_lv->SetSolid(iron_solid);
|
||||
iron_lv->SetMaterial(iron_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> iron_pv(new Geant::PhysicalVolume("IronPV", iron_lv));
|
||||
scene.AddVolume(iron_pv);
|
||||
|
||||
// Use CylinderEmitterPrimary
|
||||
Geant::CylinderEmitterPrimary* emitter = new Geant::CylinderEmitterPrimary();
|
||||
@@ -103,7 +113,7 @@ int main(int argc, char** argv) {
|
||||
vtkWorld->SetSelectable(false);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(iron_box.Get());
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
@@ -69,31 +69,56 @@ int main(int argc, char** argv) {
|
||||
Geant::Scene scene;
|
||||
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||
|
||||
ContainerBox iron_box;
|
||||
iron_box.Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box.SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
// Iron Cube
|
||||
SmartPointer<ContainerBox> iron_box(new ContainerBox());
|
||||
iron_box->Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box->SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
|
||||
SmartPointer<Geant::BoxSolid> iron_solid(new Geant::BoxSolid("IronSolid", iron_box));
|
||||
iron_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> iron_mat(new Geant::Material("IronMat"));
|
||||
iron_mat->SetFromNist("G4_Fe");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> iron_lv(new Geant::LogicalVolume("IronLV"));
|
||||
iron_lv->SetSolid(iron_solid);
|
||||
iron_lv->SetMaterial(iron_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> iron_pv(new Geant::PhysicalVolume("IronPV", iron_lv));
|
||||
scene.AddVolume(iron_pv);
|
||||
|
||||
// Top Detector Chamber
|
||||
DetectorChamber* top_chamber_box = new DetectorChamber();
|
||||
SmartPointer<DetectorChamber> top_chamber_box(new DetectorChamber());
|
||||
top_chamber_box->Scale(Vector3f(10_m, 10_m, 40_cm));
|
||||
top_chamber_box->SetPosition(Vector3f(-5_m, -5_m, 7_m));
|
||||
Geant::BoxSolid* top_chamber = new Geant::BoxSolid("TopChamber", top_chamber_box);
|
||||
top_chamber->SetNistMaterial("G4_AIR");
|
||||
top_chamber->Update();
|
||||
scene.AddSolid(top_chamber);
|
||||
|
||||
SmartPointer<Geant::BoxSolid> top_solid(new Geant::BoxSolid("TopSolid", top_chamber_box));
|
||||
top_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> air_mat(new Geant::Material("AirMat"));
|
||||
air_mat->SetFromNist("G4_AIR");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> top_lv(new Geant::LogicalVolume("TopLV"));
|
||||
top_lv->SetSolid(top_solid);
|
||||
top_lv->SetMaterial(air_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> top_pv(new Geant::PhysicalVolume("TopPV", top_lv));
|
||||
scene.AddVolume(top_pv);
|
||||
|
||||
// Bottom Detector Chamber
|
||||
DetectorChamber* bottom_chamber_box = new DetectorChamber();
|
||||
SmartPointer<DetectorChamber> bottom_chamber_box(new DetectorChamber());
|
||||
bottom_chamber_box->Scale(Vector3f(10_m, 10_m, 40_cm));
|
||||
bottom_chamber_box->SetPosition(Vector3f(-5_m, -5_m, -7.1_m));
|
||||
Geant::BoxSolid* bottom_chamber = new Geant::BoxSolid("BottomChamber", bottom_chamber_box);
|
||||
bottom_chamber->SetNistMaterial("G4_AIR");
|
||||
bottom_chamber->Update();
|
||||
scene.AddSolid(bottom_chamber);
|
||||
|
||||
SmartPointer<Geant::BoxSolid> bottom_solid(new Geant::BoxSolid("BottomSolid", bottom_chamber_box));
|
||||
bottom_solid->Update();
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> bottom_lv(new Geant::LogicalVolume("BottomLV"));
|
||||
bottom_lv->SetSolid(bottom_solid);
|
||||
bottom_lv->SetMaterial(air_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> bottom_pv(new Geant::PhysicalVolume("BottomPV", bottom_lv));
|
||||
scene.AddVolume(bottom_pv);
|
||||
|
||||
Geant::EmitterPrimary* emitter = new Geant::EmitterPrimary();
|
||||
emitter->SetPosition(Vector3f(0, 0, 14_m));
|
||||
@@ -112,20 +137,20 @@ int main(int argc, char** argv) {
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
// Visualize iron cube
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(iron_box.Get());
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// Visualize Top Chamber
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box);
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box.Get());
|
||||
vtkTop->SetOpacity(0.5);
|
||||
vtkTop->SetColor(0.2, 0.8, 0.2);
|
||||
vtkTop->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkTop);
|
||||
|
||||
// Visualize Bottom Chamber
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box);
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box.Get());
|
||||
vtkBottom->SetOpacity(0.5);
|
||||
vtkBottom->SetColor(0.2, 0.8, 0.2);
|
||||
vtkBottom->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
|
||||
@@ -100,13 +100,22 @@ int main(int argc, char** argv) {
|
||||
Geant::Scene scene;
|
||||
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||
|
||||
ContainerBox iron_box;
|
||||
iron_box.Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box.SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
SmartPointer<ContainerBox> iron_box(new ContainerBox());
|
||||
iron_box->Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box->SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
|
||||
SmartPointer<Geant::BoxSolid> iron_solid(new Geant::BoxSolid("IronSolid", iron_box));
|
||||
iron_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> iron_mat(new Geant::Material("IronMat"));
|
||||
iron_mat->SetFromNist("G4_Fe");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> iron_lv(new Geant::LogicalVolume("IronLV"));
|
||||
iron_lv->SetSolid(iron_solid);
|
||||
iron_lv->SetMaterial(iron_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> iron_pv(new Geant::PhysicalVolume("IronPV", iron_lv));
|
||||
scene.AddVolume(iron_pv);
|
||||
|
||||
RandomEmitter* emitter = new RandomEmitter();
|
||||
scene.SetEmitter(emitter);
|
||||
@@ -123,7 +132,7 @@ int main(int argc, char** argv) {
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
// Visualize iron cube
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(iron_box.Get());
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
@@ -33,13 +33,22 @@ int main(int argc, char** argv) {
|
||||
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||
|
||||
// Add an iron cube inside the world
|
||||
ContainerBox iron_box;
|
||||
iron_box.Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box.SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
SmartPointer<ContainerBox> iron_box(new ContainerBox());
|
||||
iron_box->Scale(Vector3f(10_m, 10_m, 10_m));
|
||||
iron_box->SetPosition(Vector3f(-5_m, -5_m, -5_m));
|
||||
|
||||
SmartPointer<Geant::BoxSolid> iron_solid(new Geant::BoxSolid("IronSolid", iron_box));
|
||||
iron_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> iron_mat(new Geant::Material("IronMat"));
|
||||
iron_mat->SetFromNist("G4_Fe");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> iron_lv(new Geant::LogicalVolume("IronLV"));
|
||||
iron_lv->SetSolid(iron_solid);
|
||||
iron_lv->SetMaterial(iron_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> iron_pv(new Geant::PhysicalVolume("IronPV", iron_lv));
|
||||
scene.AddVolume(iron_pv);
|
||||
scene.Initialize();
|
||||
|
||||
// 2. Build VTK scene representation
|
||||
|
||||
@@ -66,33 +66,58 @@ int main(int argc, char** argv) {
|
||||
Geant::Scene scene;
|
||||
scene.ConstructWorldBox(Vector3f(30_m, 30_m, 30_m), "G4_AIR");
|
||||
|
||||
ContainerBox iron_box;
|
||||
iron_box.Scale(Vector3f(18_m, 18_m, 18_m));
|
||||
iron_box.SetPosition(Vector3f(-9_m, -9_m, -9_m));
|
||||
Geant::BoxSolid* iron_cube = new Geant::BoxSolid("IronCube", &iron_box);
|
||||
iron_cube->SetNistMaterial("G4_Fe");
|
||||
iron_cube->Update();
|
||||
scene.AddSolid(iron_cube);
|
||||
// Iron Cube
|
||||
SmartPointer<ContainerBox> iron_box(new ContainerBox());
|
||||
iron_box->Scale(Vector3f(18_m, 18_m, 18_m));
|
||||
iron_box->SetPosition(Vector3f(-9_m, -9_m, -9_m));
|
||||
|
||||
SmartPointer<Geant::BoxSolid> iron_solid(new Geant::BoxSolid("IronSolid", iron_box));
|
||||
iron_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> iron_mat(new Geant::Material("IronMat"));
|
||||
iron_mat->SetFromNist("G4_Fe");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> iron_lv(new Geant::LogicalVolume("IronLV"));
|
||||
iron_lv->SetSolid(iron_solid);
|
||||
iron_lv->SetMaterial(iron_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> iron_pv(new Geant::PhysicalVolume("IronPV", iron_lv));
|
||||
scene.AddVolume(iron_pv);
|
||||
|
||||
// Top Detector Chamber (along Y axis)
|
||||
DetectorChamber* top_chamber_box = new DetectorChamber();
|
||||
SmartPointer<DetectorChamber> top_chamber_box(new DetectorChamber());
|
||||
top_chamber_box->Scale(Vector3f(20_m, 40_cm, 20_m));
|
||||
top_chamber_box->Rotate(90_deg, Vector3f(1, 0, 0));
|
||||
top_chamber_box->SetPosition(Vector3f(-10_m, 12_m, -10_m));
|
||||
Geant::BoxSolid* top_chamber = new Geant::BoxSolid("TopChamber", top_chamber_box);
|
||||
top_chamber->SetNistMaterial("G4_AIR");
|
||||
top_chamber->Update();
|
||||
scene.AddSolid(top_chamber);
|
||||
|
||||
SmartPointer<Geant::BoxSolid> top_solid(new Geant::BoxSolid("TopSolid", top_chamber_box));
|
||||
top_solid->Update();
|
||||
|
||||
SmartPointer<Geant::Material> air_mat(new Geant::Material("AirMat"));
|
||||
air_mat->SetFromNist("G4_AIR");
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> top_lv(new Geant::LogicalVolume("TopLV"));
|
||||
top_lv->SetSolid(top_solid);
|
||||
top_lv->SetMaterial(air_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> top_pv(new Geant::PhysicalVolume("TopPV", top_lv));
|
||||
scene.AddVolume(top_pv);
|
||||
|
||||
// Bottom Detector Chamber (along Y axis)
|
||||
DetectorChamber* bottom_chamber_box = new DetectorChamber();
|
||||
SmartPointer<DetectorChamber> bottom_chamber_box(new DetectorChamber());
|
||||
bottom_chamber_box->Scale(Vector3f(20_m, 40_cm, 20_m));
|
||||
bottom_chamber_box->Rotate(90_deg, Vector3f(1, 0, 0));
|
||||
bottom_chamber_box->SetPosition(Vector3f(-10_m, -12_m, -10_m));
|
||||
Geant::BoxSolid* bottom_chamber = new Geant::BoxSolid("BottomChamber", bottom_chamber_box);
|
||||
bottom_chamber->SetNistMaterial("G4_AIR");
|
||||
bottom_chamber->Update();
|
||||
scene.AddSolid(bottom_chamber);
|
||||
|
||||
SmartPointer<Geant::BoxSolid> bottom_solid(new Geant::BoxSolid("BottomSolid", bottom_chamber_box));
|
||||
bottom_solid->Update();
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> bottom_lv(new Geant::LogicalVolume("BottomLV"));
|
||||
bottom_lv->SetSolid(bottom_solid);
|
||||
bottom_lv->SetMaterial(air_mat);
|
||||
|
||||
SmartPointer<Geant::PhysicalVolume> bottom_pv(new Geant::PhysicalVolume("BottomPV", bottom_lv));
|
||||
scene.AddVolume(bottom_pv);
|
||||
|
||||
// Use SkyPlaneEmitterPrimary instead of EmitterPrimary
|
||||
Geant::SkyPlaneEmitterPrimary* emitter = new Geant::SkyPlaneEmitterPrimary();
|
||||
@@ -113,20 +138,20 @@ int main(int argc, char** argv) {
|
||||
vtkWorld->SetSelectable(false);
|
||||
viewer.AddProp3D(*vtkWorld);
|
||||
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(&iron_box);
|
||||
Vtk::ContainerBox* vtkIron = new Vtk::ContainerBox(iron_box.Get());
|
||||
vtkIron->SetOpacity(0.2);
|
||||
vtkIron->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkIron);
|
||||
|
||||
// Visualize Top Chamber
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box);
|
||||
Vtk::DetectorChamber* vtkTop = new Vtk::DetectorChamber(top_chamber_box.Get());
|
||||
vtkTop->SetOpacity(0.5);
|
||||
vtkTop->SetColor(0.2, 0.8, 0.2);
|
||||
vtkTop->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
viewer.AddProp3D(*vtkTop);
|
||||
|
||||
// Visualize Bottom Chamber
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box);
|
||||
Vtk::DetectorChamber* vtkBottom = new Vtk::DetectorChamber(bottom_chamber_box.Get());
|
||||
vtkBottom->SetOpacity(0.5);
|
||||
vtkBottom->SetColor(0.2, 0.8, 0.2);
|
||||
vtkBottom->SetRepresentation(Vtk::Prop3D::Surface);
|
||||
|
||||
@@ -25,53 +25,59 @@ using namespace uLib;
|
||||
int main(int argc, char** argv) {
|
||||
bool interactive = (argc > 1 && std::string(argv[1]) == "-i");
|
||||
|
||||
// 1. Create a BoxSolid
|
||||
ContainerBox box;
|
||||
box.Scale(Vector3f(1_m, 2_m, 3_m));
|
||||
Geant::BoxSolid gBox("MyBox", &box);
|
||||
gBox.Update();
|
||||
|
||||
Vtk::BoxSolid vtkBox(&gBox);
|
||||
|
||||
// 2. Create a TessellatedSolid
|
||||
Geant::TessellatedSolid gTess("MyTess");
|
||||
TriangleMesh mesh;
|
||||
// Create a simple pyramid
|
||||
mesh.Points().push_back(Vector3f(0, 0, 1_m)); // apex
|
||||
mesh.Points().push_back(Vector3f(-1_m, -1_m, 0));
|
||||
mesh.Points().push_back(Vector3f( 1_m, -1_m, 0));
|
||||
mesh.Points().push_back(Vector3f( 1_m, 1_m, 0));
|
||||
mesh.Points().push_back(Vector3f(-1_m, 1_m, 0));
|
||||
|
||||
mesh.Triangles().push_back(Vector3i(1, 2, 0));
|
||||
mesh.Triangles().push_back(Vector3i(2, 3, 0));
|
||||
mesh.Triangles().push_back(Vector3i(3, 4, 0));
|
||||
mesh.Triangles().push_back(Vector3i(4, 1, 0));
|
||||
mesh.Triangles().push_back(Vector3i(1, 3, 2)); // base
|
||||
mesh.Triangles().push_back(Vector3i(1, 4, 3)); // base
|
||||
|
||||
gTess.SetMesh(mesh);
|
||||
gTess.Update();
|
||||
|
||||
Vtk::TessellatedSolid vtkTess(&gTess);
|
||||
|
||||
// 3. Visualization setup
|
||||
Vtk::Viewer viewer;
|
||||
|
||||
// 1. Create a BoxSolid
|
||||
SmartPointer<ContainerBox> box(new ContainerBox());
|
||||
box->Scale(Vector3f(1_m, 2_m, 3_m));
|
||||
SmartPointer<Geant::BoxSolid> gBox(new Geant::BoxSolid("MyBox", box));
|
||||
gBox->Update();
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> lvBox(new Geant::LogicalVolume("BoxLV"));
|
||||
lvBox->SetSolid(gBox);
|
||||
SmartPointer<Geant::PhysicalVolume> pvBox(new Geant::PhysicalVolume("BoxPV", lvBox));
|
||||
Vtk::BoxSolid vtkBox(pvBox);
|
||||
vtkBox.AddToViewer(viewer);
|
||||
|
||||
// 2. Create a TessellatedSolid
|
||||
SmartPointer<Geant::TessellatedSolid> gTess(new Geant::TessellatedSolid("MyTess"));
|
||||
SmartPointer<TriangleMesh> mesh(new TriangleMesh());
|
||||
// ... same points ...
|
||||
mesh->Points().push_back(Vector3f(0, 0, 1_m)); // apex
|
||||
mesh->Points().push_back(Vector3f(-1_m, -1_m, 0));
|
||||
mesh->Points().push_back(Vector3f( 1_m, -1_m, 0));
|
||||
mesh->Points().push_back(Vector3f( 1_m, 1_m, 0));
|
||||
mesh->Points().push_back(Vector3f(-1_m, 1_m, 0));
|
||||
|
||||
mesh->Triangles().push_back(Vector3i(1, 2, 0));
|
||||
mesh->Triangles().push_back(Vector3i(2, 3, 0));
|
||||
mesh->Triangles().push_back(Vector3i(3, 4, 0));
|
||||
mesh->Triangles().push_back(Vector3i(4, 1, 0));
|
||||
mesh->Triangles().push_back(Vector3i(1, 3, 2)); // base
|
||||
mesh->Triangles().push_back(Vector3i(1, 4, 3)); // base
|
||||
|
||||
gTess->SetMesh(mesh.Get());
|
||||
gTess->Update();
|
||||
|
||||
SmartPointer<Geant::LogicalVolume> lvTess(new Geant::LogicalVolume("TessLV"));
|
||||
lvTess->SetSolid(gTess);
|
||||
SmartPointer<Geant::PhysicalVolume> pvTess(new Geant::PhysicalVolume("TessPV", lvTess));
|
||||
Vtk::TessellatedSolid vtkTess(pvTess);
|
||||
vtkTess.AddToViewer(viewer);
|
||||
|
||||
// Color them differently
|
||||
vtkBox.SetColor(0.8, 0.2, 0.2); // Redish box
|
||||
vtkTess.SetColor(0.2, 0.8, 0.2); // Greenish tess
|
||||
|
||||
// Position tessellated solid away from box
|
||||
// Position tessellated solid away from box using the PhysicalVolume
|
||||
Matrix4f trans = Matrix4f::Identity();
|
||||
trans.block<3,1>(0,3) = Vector3f(5_m, 0, 0);
|
||||
gTess.SetTransform(trans);
|
||||
pvTess->SetMatrix(trans);
|
||||
vtkTess.Update();
|
||||
|
||||
std::cout << "..:: Testing vtkSolidsTest ::.." << std::endl;
|
||||
std::cout << "Box and Tessellated solids initialized." << std::endl;
|
||||
std::cout << "Box and Tessellated solids (placed via PhysicalVolumes) initialized." << std::endl;
|
||||
|
||||
if (interactive) {
|
||||
viewer.ZoomAuto();
|
||||
|
||||
@@ -24,8 +24,15 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
BoxSolid::BoxSolid(Geant::BoxSolid *content)
|
||||
: GeantSolid(content), m_BoxContent(content) {
|
||||
BoxSolid::BoxSolid(Geant::PhysicalVolume *content)
|
||||
: GeantSolid(content), m_BoxSolid(nullptr) {
|
||||
if (content && content->GetLogical()) {
|
||||
m_BoxSolid = dynamic_cast<Geant::BoxSolid *>(content->GetLogical()->GetSolid());
|
||||
}
|
||||
}
|
||||
|
||||
BoxSolid::BoxSolid(Geant::BoxSolid *solid)
|
||||
: GeantSolid(solid), m_BoxSolid(solid) {
|
||||
}
|
||||
|
||||
BoxSolid::~BoxSolid() {
|
||||
@@ -35,10 +42,10 @@ void BoxSolid::serialize_display(uLib::Archive::display_properties_archive &ar,
|
||||
const unsigned int version) {
|
||||
// Expose Geant solid properties and underlying Box/TRS properties
|
||||
this->Prop3D::serialize_display(ar, version);
|
||||
if (m_BoxContent) {
|
||||
ar & NVP("Box", *m_BoxContent);
|
||||
if (m_BoxContent->GetObject()) {
|
||||
ar & NVP("Container", *m_BoxContent->GetObject());
|
||||
if (m_BoxSolid) {
|
||||
ar & NVP("Box", *m_BoxSolid);
|
||||
if (m_BoxSolid->GetObject()) {
|
||||
ar & NVP("Container", *m_BoxSolid->GetObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ class BoxSolid : public GeantSolid {
|
||||
uLibTypeMacro(BoxSolid, uLib::Vtk::GeantSolid)
|
||||
|
||||
public:
|
||||
BoxSolid(Geant::BoxSolid *content);
|
||||
BoxSolid(Geant::PhysicalVolume *content);
|
||||
BoxSolid(Geant::BoxSolid *solid);
|
||||
virtual ~BoxSolid();
|
||||
|
||||
virtual void serialize_display(uLib::Archive::display_properties_archive &ar,
|
||||
@@ -53,13 +54,13 @@ public:
|
||||
|
||||
template <typename Ar>
|
||||
void serialize(Ar &ar, const unsigned int version) {
|
||||
ar & NVP("BoxSolid", *m_BoxContent);
|
||||
ar & NVP("BoxSolid", *m_BoxSolid);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void InstallPipe() override;
|
||||
|
||||
Geant::BoxSolid *m_BoxContent;
|
||||
Geant::BoxSolid *m_BoxSolid;
|
||||
|
||||
ULIB_DECLARE_PROPERTIES(BoxSolid)
|
||||
};
|
||||
|
||||
@@ -45,25 +45,29 @@ GeantScene::GeantScene(Geant::Scene *scene)
|
||||
m_WorldProp3D->ShowScaleMeasures(true);
|
||||
}
|
||||
|
||||
// 2. Create prop3ds for each non-world solid
|
||||
const Geant::Solid *world = m_Scene->GetWorld();
|
||||
const Vector<Geant::Solid *> &solids = m_Scene->GetSolids();
|
||||
// 2. Create prop3ds for each physical volume in the scene
|
||||
const Vector<SmartPointer<Geant::PhysicalVolume>> &volumes = m_Scene->GetVolumes();
|
||||
|
||||
for (auto &volume : volumes) {
|
||||
if (!volume || !volume->GetLogical() || !volume->GetLogical()->GetSolid())
|
||||
continue;
|
||||
|
||||
Geant::PhysicalVolume *pv = volume.Get();
|
||||
Geant::Solid *solid = pv->GetLogical()->GetSolid();
|
||||
|
||||
for (Geant::Solid *solid : solids) {
|
||||
// Skip the world volume itself — it's already shown as the wireframe box
|
||||
if (solid == world)
|
||||
if (solid == m_Scene->GetWorld())
|
||||
continue;
|
||||
|
||||
// Only create a prop3d if the solid has a valid G4VSolid
|
||||
if (solid->GetG4Solid()) {
|
||||
GeantSolid *vtkSolid = nullptr;
|
||||
if (auto *box = dynamic_cast<Geant::BoxSolid *>(solid)) {
|
||||
vtkSolid = new BoxSolid(box);
|
||||
vtkSolid = new BoxSolid(pv);
|
||||
} else if (auto *tess = dynamic_cast<Geant::TessellatedSolid *>(solid)) {
|
||||
vtkSolid = new TessellatedSolid(tess);
|
||||
vtkSolid = new TessellatedSolid(pv);
|
||||
} else {
|
||||
vtkSolid = new GeantSolid(solid);
|
||||
vtkSolid->Update();
|
||||
vtkSolid = new GeantSolid(pv);
|
||||
}
|
||||
|
||||
if (vtkSolid) {
|
||||
|
||||
@@ -44,15 +44,26 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
GeantSolid::GeantSolid(Content *content)
|
||||
: m_SolidActor(vtkActor::New()), m_Content(content) {
|
||||
GeantSolid::GeantSolid(Geant::PhysicalVolume *content)
|
||||
: m_SolidActor(vtkActor::New()), m_Volume(content), m_Solid(nullptr) {
|
||||
this->InstallPipe();
|
||||
if (m_Content) {
|
||||
m_UpdateConnection = Object::connect(m_Content, &uLib::Object::Updated, [this]() {
|
||||
std::cout << "GeantSolid: Signal Updated received." << std::endl;
|
||||
if (m_Volume) {
|
||||
m_UpdateConnection = Object::connect(m_Volume, &uLib::Object::Updated, [this]() {
|
||||
this->Update();
|
||||
});
|
||||
// Mandatory initial update to generate geometry and apply initial transform
|
||||
// Mandatory initial update
|
||||
this->Update();
|
||||
}
|
||||
}
|
||||
|
||||
GeantSolid::GeantSolid(Geant::Solid *solid)
|
||||
: m_SolidActor(vtkActor::New()), m_Volume(nullptr), m_Solid(solid) {
|
||||
this->InstallPipe();
|
||||
if (m_Solid) {
|
||||
m_UpdateConnection = Object::connect(m_Solid, &uLib::Object::Updated, [this]() {
|
||||
this->Update();
|
||||
});
|
||||
// Mandatory initial update
|
||||
this->Update();
|
||||
}
|
||||
}
|
||||
@@ -75,21 +86,25 @@ void GeantSolid::Update() {
|
||||
}
|
||||
|
||||
void GeantSolid::SyncFromVtk() {
|
||||
if (!m_Content) return;
|
||||
if (!m_Volume) return;
|
||||
this->Prop3D::SyncFromVtk();
|
||||
|
||||
if (auto* proxy = vtkProp3D::SafeDownCast(this->GetProxyProp())) {
|
||||
if (vtkMatrix4x4* mat = proxy->GetUserMatrix()) {
|
||||
m_Content->SetTransform(VtkToMatrix4f(mat));
|
||||
m_Volume->SetMatrix(VtkToMatrix4f(mat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GeantSolid::UpdateGeometry() {
|
||||
if (!m_Content)
|
||||
return;
|
||||
Geant::Solid *solid = m_Solid;
|
||||
if (m_Volume && m_Volume->GetLogical()) {
|
||||
solid = m_Volume->GetLogical()->GetSolid();
|
||||
}
|
||||
|
||||
G4VSolid *g4solid = m_Content->GetG4Solid();
|
||||
if (!solid) return;
|
||||
|
||||
G4VSolid *g4solid = solid->GetG4Solid();
|
||||
if (!g4solid)
|
||||
return;
|
||||
|
||||
@@ -134,37 +149,18 @@ void GeantSolid::UpdateGeometry() {
|
||||
}
|
||||
|
||||
void GeantSolid::UpdateTransform() {
|
||||
if (!m_Content || !m_SolidActor)
|
||||
if (!m_SolidActor)
|
||||
return;
|
||||
|
||||
// Apply the Geant4 transform (position/rotation/scaling)
|
||||
G4ThreeVector pos = m_Content->GetPosition();
|
||||
const G4RotationMatrix *rot = m_Content->GetRotation();
|
||||
G4ThreeVector scale = m_Content->GetScaling();
|
||||
|
||||
std::cout << "GeantSolid: Updating transform. Pos: " << pos.x() << " " << pos.y() << " " << pos.z()
|
||||
<< " Scale: " << scale.x() << " " << scale.y() << " " << scale.z() << std::endl;
|
||||
|
||||
vtkNew<vtkTransform> transform;
|
||||
transform->Identity();
|
||||
transform->Translate(pos.x(), pos.y(), pos.z());
|
||||
|
||||
if (rot) {
|
||||
G4RotationMatrix invRot = *rot;
|
||||
double elements[16] = {
|
||||
invRot.xx(), invRot.xy(), invRot.xz(), 0,
|
||||
invRot.yx(), invRot.yy(), invRot.yz(), 0,
|
||||
invRot.zx(), invRot.zy(), invRot.zz(), 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
vtkNew<vtkMatrix4x4> mat;
|
||||
mat->DeepCopy(elements);
|
||||
transform->Concatenate(mat);
|
||||
if (m_Volume) {
|
||||
// Apply the TRS transform directly from the PhysicalVolume
|
||||
vtkNew<vtkMatrix4x4> vtkMat;
|
||||
Matrix4fToVtk(m_Volume->GetMatrix(), vtkMat);
|
||||
m_SolidActor->SetUserMatrix(vtkMat);
|
||||
} else {
|
||||
// Identity for unplaced solids
|
||||
m_SolidActor->SetUserMatrix(nullptr);
|
||||
}
|
||||
|
||||
transform->Scale(scale.x(), scale.y(), scale.z());
|
||||
|
||||
m_SolidActor->SetUserTransform(transform);
|
||||
m_SolidActor->Modified();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,9 @@ namespace Vtk {
|
||||
* a valid G4VSolid via GetG4Solid().
|
||||
*/
|
||||
class GeantSolid : public Prop3D, public Polydata {
|
||||
typedef Geant::Solid Content;
|
||||
|
||||
public:
|
||||
GeantSolid(Content *content);
|
||||
GeantSolid(Geant::PhysicalVolume *content);
|
||||
GeantSolid(Geant::Solid *solid);
|
||||
~GeantSolid();
|
||||
|
||||
virtual class vtkPolyData *GetPolyData() const override;
|
||||
@@ -57,12 +56,15 @@ public:
|
||||
virtual void UpdateGeometry();
|
||||
virtual void UpdateTransform();
|
||||
|
||||
virtual uLib::Object *GetContent() const override { return (uLib::Object*)m_Content; }
|
||||
virtual uLib::Object *GetContent() const override {
|
||||
return m_Volume ? (uLib::Object*)m_Volume : (uLib::Object*)m_Solid;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void InstallPipe();
|
||||
|
||||
Content *m_Content;
|
||||
Geant::PhysicalVolume *m_Volume;
|
||||
Geant::Solid *m_Solid;
|
||||
vtkActor *m_SolidActor;
|
||||
uLib::Connection m_UpdateConnection;
|
||||
};
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
TessellatedSolid::TessellatedSolid(Geant::TessellatedSolid *content)
|
||||
: GeantSolid(content), m_TessContent(content) {
|
||||
this->Update();
|
||||
TessellatedSolid::TessellatedSolid(Geant::PhysicalVolume *content)
|
||||
: GeantSolid(content), m_TessSolid(nullptr) {
|
||||
if (content && content->GetLogical()) {
|
||||
m_TessSolid = dynamic_cast<Geant::TessellatedSolid *>(content->GetLogical()->GetSolid());
|
||||
}
|
||||
}
|
||||
|
||||
TessellatedSolid::~TessellatedSolid() {}
|
||||
@@ -31,13 +33,13 @@ void TessellatedSolid::Update() {
|
||||
}
|
||||
|
||||
void TessellatedSolid::UpdateGeometry() {
|
||||
if (!m_TessContent || m_TessContent->GetMesh().Points().empty()) {
|
||||
if (!m_TessSolid || !m_TessSolid->GetMesh() || m_TessSolid->GetMesh()->Points().empty()) {
|
||||
// Fallback to base tessellation if no model mesh
|
||||
GeantSolid::UpdateGeometry();
|
||||
return;
|
||||
}
|
||||
|
||||
const TriangleMesh &mesh = m_TessContent->GetMesh();
|
||||
const TriangleMesh &mesh = *m_TessSolid->GetMesh();
|
||||
|
||||
vtkNew<vtkPoints> points;
|
||||
for (const auto& pt : mesh.Points()) {
|
||||
|
||||
@@ -22,14 +22,14 @@ namespace Vtk {
|
||||
*/
|
||||
class TessellatedSolid : public GeantSolid {
|
||||
public:
|
||||
TessellatedSolid(Geant::TessellatedSolid *content);
|
||||
TessellatedSolid(Geant::PhysicalVolume *content);
|
||||
virtual ~TessellatedSolid();
|
||||
|
||||
virtual void Update() override;
|
||||
virtual void UpdateGeometry() override;
|
||||
|
||||
protected:
|
||||
Geant::TessellatedSolid *m_TessContent;
|
||||
Geant::TessellatedSolid *m_TessSolid;
|
||||
};
|
||||
|
||||
} // namespace Vtk
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "Vtk/HEP/Detectors/vtkDetectorChamber.h"
|
||||
#include "Vtk/HEP/Geant/vtkBoxSolid.h"
|
||||
#include "Vtk/HEP/Geant/vtkTessellatedSolid.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
@@ -150,8 +151,20 @@ Prop3D *ObjectsContext::CreateProp3D(uLib::Object *obj) {
|
||||
return new Cylinder(cylinder);
|
||||
} else if (auto *assembly = dynamic_cast<uLib::Assembly *>(obj)) {
|
||||
return new Assembly(assembly);
|
||||
} else if (auto *pv = dynamic_cast<uLib::Geant::PhysicalVolume *>(obj)) {
|
||||
uLib::Geant::Solid *solid = pv->GetLogical()->GetSolid();
|
||||
if (auto *box = dynamic_cast<uLib::Geant::BoxSolid *>(solid)) {
|
||||
return new BoxSolid(pv);
|
||||
} else if (auto *tess = dynamic_cast<uLib::Geant::TessellatedSolid *>(solid)) {
|
||||
return new TessellatedSolid(pv);
|
||||
} else {
|
||||
return new GeantSolid(pv);
|
||||
}
|
||||
} else if (auto *box = dynamic_cast<uLib::Geant::BoxSolid *>(obj)) {
|
||||
return new BoxSolid(box);
|
||||
} else if (auto *solid = dynamic_cast<uLib::Geant::Solid *>(obj)) {
|
||||
// Unplaced solid visualization
|
||||
return new GeantSolid(solid);
|
||||
}
|
||||
|
||||
// Fallback if we don't know the exact class but it might be a context itself
|
||||
|
||||
Reference in New Issue
Block a user