Skip to content

Commit

Permalink
Fix conversion of boolean solids when the "left" solid is displaced (#…
Browse files Browse the repository at this point in the history
…1069)

* Fix assumption about only the "right" boolean being displaced
* Add an asterisk for the temporary volume that is displaced
  • Loading branch information
sethrj committed Dec 19, 2023
1 parent 478fbcc commit 237f4e3
Showing 1 changed file with 23 additions and 22 deletions.
45 changes: 23 additions & 22 deletions src/celeritas/ext/g4vg/SolidConverter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -686,39 +686,40 @@ auto SolidConverter::unionsolid(arg_type solid_base) -> result_type
auto SolidConverter::convert_bool_impl(G4BooleanSolid const& bs)
-> PlacedBoolVolumes
{
Array<G4VSolid const*, 2> solids{
{bs.GetConstituentSolid(0), bs.GetConstituentSolid(1)}};

Transformation3D inverse;
{
// The "right" shape should be a G4DisplacedSolid which holds the
// matrix: replace solid and get inverse transform
CELER_EXPECT(!dynamic_cast<G4DisplacedSolid const*>(solids[0]));
CELER_EXPECT(dynamic_cast<G4DisplacedSolid const*>(solids[1]));
auto* displaced = static_cast<G4DisplacedSolid const*>(solids[1]);
solids[1] = displaced->GetConstituentMovedSolid();
inverse = convert_transform_(displaced->GetTransform().Invert());
}

static Array<char const*, 2> const lr = {{"left", "right"}};
Array<Transformation3D const*, 2> transforms
= {{&Transformation3D::kIdentity, &inverse}};
PlacedBoolVolumes result;

for (auto i : range(solids.size()))
for (auto i : range(lr.size()))
{
// Convert solid
VUnplacedVolume const* converted = (*this)(*solids[i]);
G4VSolid const* solid = bs.GetConstituentSolid(i);
CELER_ASSERT(solid);

// Expand the possibly transformed solid into a transform
std::unique_ptr<Transformation3D> trans;
if (auto* displaced = dynamic_cast<G4DisplacedSolid const*>(solid))
{
solid = displaced->GetConstituentMovedSolid();
CELER_ASSERT(solid);
trans = std::make_unique<Transformation3D>(
convert_transform_(displaced->GetTransform().Invert()));
}

VUnplacedVolume const* converted = (*this)(*solid);

// Construct name
std::ostringstream label;
label << "[TEMP]@" << bs.GetName() << '/' << lr[i] << '/'
<< solids[i]->GetName();
label << "[TEMP]@" << bs.GetName() << '/' << lr[i];
if (trans)
{
label << '*';
}
label << '/' << solid->GetName();

// Create temporary LV from converted solid
auto* temp_lv = new LogicalVolume(label.str().c_str(), converted);
// Place the transformed LV
result[i] = temp_lv->Place(transforms[i]);
result[i] = temp_lv->Place(trans ? trans.get()
: &Transformation3D::kIdentity);
}

CELER_ENSURE(result[0] && result[1]);
Expand Down

0 comments on commit 237f4e3

Please sign in to comment.