add assembly

This commit is contained in:
AndreaRigoni
2026-03-25 22:48:04 +00:00
parent 422113a0e9
commit 2c5d6842c3
18 changed files with 800 additions and 171 deletions

View File

@@ -7,6 +7,7 @@ set(TESTS
vtkVoxImageInteractiveTest
vtkContainerBoxTest
vtkContainerBoxTest2
vtkAssemblyTest
)
set(LIBRARIES

View File

@@ -1,109 +1,104 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
// All rights reserved
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
//////////////////////////////////////////////////////////////////////////////*/
#include "Vtk/uLibVtkViewer.h"
#include "Vtk/Math/vtkAssembly.h"
#include "Vtk/Math/vtkCylinder.h"
#include "Vtk/Math/vtkContainerBox.h"
#include "Math/Assembly.h"
#include "Math/Cylinder.h"
#include "Math/ContainerBox.h"
#include "Math/Cylinder.h"
#include "Vtk/Math/vtkAssembly.h"
#include "Vtk/vtkObjectsContext.h"
#include "Vtk/uLibVtkViewer.h"
#include "Math/Units.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkPropCollection.h>
#include <iostream>
using namespace uLib;
/**
* @brief This test verifies that uLib::Vtk::Assembly correctly visualizes a collection
* of objects and that transformations applied to the assembly are propagated to its children.
* It also checks that the assembly appears as a bounding box of its contents.
*/
int main() {
std::cout << "Starting vtkAssemblyTest..." << std::endl;
int main(int argc, char **argv) {
bool interactive = (argc > 1 && std::string(argv[1]) == "-i");
// 1. Setup Core Geometry
std::cout << " - Creating core Assembly..." << std::endl;
uLib::Assembly* core_assembly = new uLib::Assembly();
core_assembly->SetInstanceName("MainAssembly");
// ---- 1. Build model objects ----
ContainerBox box1;
box1.Scale(Vector3f(1_m, 2_m, 0.5_m));
box1.SetPosition(Vector3f(0, 0, 0));
// Add a box
std::cout << " - Adding ChildBox (Red)..." << std::endl;
ContainerBox* box = new ContainerBox();
box->SetInstanceName("ChildBox");
box->Translate(Vector3f(1.0, 0, 0));
core_assembly->AddObject(box);
ContainerBox box2;
box2.Scale(Vector3f(0.5_m, 0.5_m, 3_m));
box2.SetPosition(Vector3f(2_m, 0, 0));
// Add a cylinder
// std::cout << " - Adding ChildCylinder (Blue)..." << std::endl;
// Cylinder* cyl = new Cylinder(0.5, 2.0);
// cyl->SetInstanceName("ChildCylinder");
// cyl->Translate(Vector3f(-2.0, 0, 0));
// core_assembly->AddObject(cyl);
Cylinder cyl(0.3_m, 1.5_m, 1);
cyl.SetPosition(Vector3f(0, 3_m, 0));
std::cout << " - Adding another box (Green)..." << std::endl;
ContainerBox* box2 = new ContainerBox();
box2->Scale(Vector3f(1.0, 1.0, 2.0));
box2->SetInstanceName("ChildBox2");
box2->Translate(Vector3f(0, 0, 1.0));
core_assembly->AddObject(box2);
// ---- 2. Create an Assembly and add objects ----
Assembly assembly;
assembly.AddObject(&box1);
assembly.AddObject(&box2);
assembly.AddObject(&cyl);
assembly.SetShowBoundingBox(true);
// 2. Setup VTK Representation
std::cout << " - Creating VTK Assembly representation..." << std::endl;
Vtk::Assembly vtk_assembly(core_assembly);
// Find and colorized the children puppets
Vtk::Puppet* p_box = vtk_assembly.GetPuppet(box);
if (p_box) {
p_box->SetColor(1.0, 0.0, 0.0); // Red
} else {
std::cerr << "Warning: Could not find puppet for box!" << std::endl;
}
// ---- 3. Apply a group transform ----
assembly.SetPosition(Vector3f(1_m, 1_m, 0));
// Vtk::Puppet* p_cyl = vtk_assembly.GetPuppet(cyl);
// if (p_cyl) {
// p_cyl->SetColor(0.0, 0.0, 1.0); // Blue
// } else {
// std::cerr << "Warning: Could not find puppet for cylinder!" << std::endl;
// }
Vtk::Puppet* p_box2 = vtk_assembly.GetPuppet(box2);
if (p_box2) {
p_box2->SetColor(0.0, 1.0, 0.0); // Green
} else {
std::cerr << "Warning: Could not find puppet for box2!" << std::endl;
}
// 3. Test Transformation Propagation
std::cout << " - Rotating Assembly 45 degrees around Z..." << std::endl;
core_assembly->Rotate(45.0_deg, Vector3f::UnitZ());
std::cout << " - Translating Assembly up (+Y)..." << std::endl;
core_assembly->Translate(Vector3f(0, 2.0, 0));
// Notify all puppets of the change
core_assembly->Updated();
// 4. Run Visualization
std::cout << "Starting viewer (close to exit)..." << std::endl;
std::cout << "Expected: A white bounding box containing a red box and a blue cylinder, "
<< "all rotated and translated as a group." << std::endl;
// ---- 5. Visualize (create puppets to set properties) ----
Vtk::Assembly vtkAsm(&assembly);
Vtk::Viewer viewer;
viewer.AddPuppet(*p_box);
viewer.AddPuppet(*p_box2);
viewer.AddPuppet(vtk_assembly);
viewer.Start();
vtkAsm.AddToViewer(viewer); // This triggers puppet creation via ConnectRenderer which eventually calls Puppet::GetProp
// Explicitly update to ensure puppets exist and are added to assemblies
vtkAsm.Update();
// Clean up
delete core_assembly;
delete box;
delete box2;
// delete cyl;
// Use the child context to find child puppets and set colors
if (auto* childCtx = vtkAsm.GetChildrenContext()) {
auto setProps = [](Vtk::Puppet* p, float r, float g, float b) {
if (!p) return;
vtkPropCollection* props = p->GetProps();
props->InitTraversal();
for (int i=0; i < props->GetNumberOfItems(); ++i) {
if (auto* actor = vtkActor::SafeDownCast(props->GetNextProp())) {
actor->GetProperty()->SetColor(r, g, b);
actor->GetProperty()->SetRepresentationToSurface();
actor->GetProperty()->SetOpacity(0.5);
}
}
};
setProps(childCtx->GetPuppet(&box1), 1.0, 0.0, 0.0); // Red
setProps(childCtx->GetPuppet(&box2), 0.0, 1.0, 0.0); // Green
setProps(childCtx->GetPuppet(&cyl), 0.0, 0.0, 1.0); // Blue
}
std::cout << "Puppets in viewport: " << viewer.getPuppets().size() << " (Expected 4: 1 assembly + 3 children)" << std::endl;
// ---- 4. Query the bounding box for terminal output ----
Vector3f bbMin, bbMax;
assembly.GetBoundingBox(bbMin, bbMax);
std::cout << "Assembly bounding box:" << std::endl;
std::cout << " min = " << bbMin.transpose() << std::endl;
std::cout << " max = " << bbMax.transpose() << std::endl;
std::cout << "==================================================\n";
std::cout << " vtkAssemblyTest\n";
std::cout << " 2 boxes + 1 cylinder grouped in an assembly\n";
std::cout << "==================================================" << std::endl;
if (interactive) {
viewer.ZoomAuto();
viewer.Start();
} else {
std::cout << "Non-interactive test passed." << std::endl;
}
return 0;
}