forked from celeritas-project/celeritas
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CSG unit and unit builder (celeritas-project#1079)
* Add CSG unit builder * Add transform IO * Redefine MaterialId as anonymous ID * Move CSG-to-JSON to a separate helper function * Add CSG unit builder test * Add tolerance and constructed surface accessors
- Loading branch information
Showing
20 changed files
with
1,006 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file orange/orangeinp/detail/CsgUnit.hh | ||
//---------------------------------------------------------------------------// | ||
#pragma once | ||
|
||
#include <set> | ||
#include <variant> | ||
#include <vector> | ||
|
||
#include "corecel/io/Label.hh" | ||
#include "orange/BoundingBox.hh" | ||
#include "orange/OrangeTypes.hh" | ||
#include "orange/construct/CsgTree.hh" | ||
#include "orange/construct/CsgTypes.hh" | ||
#include "orange/surf/VariantSurface.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace orangeinp | ||
{ | ||
namespace detail | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Constructed CSG geometry data for a unit. | ||
* | ||
* This contains all the construction-time surfaces, volumes, and properties. | ||
* These are stored in a way so that they can be remapped and/or optimized | ||
* further before committing them to the constructed GPU data. | ||
* | ||
* The "exterior" is optional *only* in the degenerate case of an infinite | ||
* global universe (TODO: prohibit this??) | ||
* | ||
* TODO: improve metadata (provenance, nicer container, mapping?, calculated | ||
* volumes) | ||
*/ | ||
struct CsgUnit | ||
{ | ||
//// TYPES //// | ||
|
||
using Metadata = Label; | ||
using SetMd = std::set<Metadata>; | ||
using NodeId = ::celeritas::csg::NodeId; | ||
using BBox = ::celeritas::BoundingBox<>; | ||
using Fill = std::variant<std::monostate, MaterialId, Daughter>; | ||
|
||
//// DATA //// | ||
|
||
//!@{ | ||
//! \name Surfaces | ||
//! Vectors are indexed by LocalSurfaceId. | ||
std::vector<VariantSurface> surfaces; | ||
//!@} | ||
|
||
//!@{ | ||
//! \name Nodes | ||
//! Vectors are indexed by NodeId. | ||
CsgTree tree; //!< CSG tree | ||
std::vector<SetMd> metadata; //!< CSG node labels and provenance | ||
std::vector<BBox> bboxes; | ||
//!@} | ||
|
||
//!@{ | ||
//! \name Volumes | ||
//! Vectors are indexed by LocalVolumeId. | ||
std::vector<NodeId> volumes; //!< CSG node of each volume | ||
std::vector<Fill> fills; //!< Content of each volume | ||
NodeId exterior; | ||
//!@} | ||
|
||
//!@{ | ||
//! \name Transforms | ||
//! Vectors are indexed by TransformId. | ||
std::vector<VariantTransform> transforms; | ||
//!@} | ||
|
||
//// FUNCTIONS //// | ||
|
||
// Whether the processed unit is valid for use | ||
explicit inline operator bool() const; | ||
|
||
// Whether the unit has no constructed data | ||
inline bool empty() const; | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Utility for telling whether a fill is assigned. | ||
*/ | ||
inline constexpr bool is_filled(CsgUnit::Fill const& fill) | ||
{ | ||
return !std::holds_alternative<std::monostate>(fill); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
// INLINE DEFINITIONS | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Whether the processed unit is valid for use. | ||
*/ | ||
CsgUnit::operator bool() const | ||
{ | ||
return this->metadata.size() == this->tree.size() | ||
&& this->bboxes.size() == this->tree.size() && !this->volumes.empty() | ||
&& this->volumes.size() == this->fills.size(); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* True if the unit has no constructed data. | ||
*/ | ||
bool CsgUnit::empty() const | ||
{ | ||
return this->surfaces.empty() && this->metadata.empty() | ||
&& this->bboxes.empty() && this->volumes.empty() | ||
&& this->fills.empty() && !this->exterior | ||
&& this->transforms.empty(); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace detail | ||
} // namespace orangeinp | ||
} // namespace celeritas |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file orange/orangeinp/detail/CsgUnitBuilder.cc | ||
//---------------------------------------------------------------------------// | ||
#include "CsgUnitBuilder.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace orangeinp | ||
{ | ||
namespace detail | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Set a bounding box for a node. | ||
*/ | ||
void CsgUnitBuilder::set_bbox(NodeId n, BBox const& bbox) | ||
{ | ||
CELER_EXPECT(n < unit_->bboxes.size()); | ||
CELER_EXPECT(!unit_->bboxes[n.unchecked_get()]); | ||
|
||
unit_->bboxes[n.unchecked_get()] = bbox; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Mark a CSG node as a volume of real space. | ||
*/ | ||
LocalVolumeId CsgUnitBuilder::insert_volume(NodeId n) | ||
{ | ||
CELER_EXPECT(n < unit_->tree.size()); | ||
|
||
LocalVolumeId result{static_cast<size_type>(unit_->volumes.size())}; | ||
|
||
unit_->volumes.push_back(n); | ||
unit_->fills.resize(unit_->volumes.size()); | ||
|
||
CELER_ENSURE(*unit_); | ||
return result; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Fill a volume node with a material. | ||
*/ | ||
void CsgUnitBuilder::fill_volume(LocalVolumeId v, MaterialId m) | ||
{ | ||
CELER_EXPECT(v < unit_->fills.size()); | ||
CELER_EXPECT(m); | ||
|
||
unit_->fills[v.unchecked_get()] = m; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Fill a volume node with a daughter. | ||
*/ | ||
void CsgUnitBuilder::fill_volume(LocalVolumeId v, | ||
UniverseId u, | ||
VariantTransform&& vt) | ||
{ | ||
CELER_EXPECT(v < unit_->fills.size()); | ||
CELER_EXPECT(!is_filled(unit_->fills[v.unchecked_get()])); | ||
CELER_EXPECT(u); | ||
|
||
Daughter new_daughter; | ||
new_daughter.universe_id = u; | ||
new_daughter.transform_id | ||
= TransformId{static_cast<size_type>(unit_->transforms.size())}; | ||
|
||
// Add transform | ||
unit_->transforms.push_back(std::move(vt)); | ||
// Save fill | ||
unit_->fills[v.unchecked_get()] = std::move(new_daughter); | ||
|
||
CELER_ENSURE(is_filled(unit_->fills[v.unchecked_get()])); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Set an exterior node. | ||
* | ||
* This should be called only once (but this could be relaxed if needed). | ||
*/ | ||
void CsgUnitBuilder::set_exterior(NodeId n) | ||
{ | ||
CELER_EXPECT(n < unit_->tree.size()); | ||
CELER_EXPECT(!unit_->exterior); | ||
|
||
unit_->exterior = n; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Get a variant surface from a node ID. | ||
*/ | ||
VariantSurface const& CsgUnitBuilder::get_surface_impl(NodeId nid) const | ||
{ | ||
CELER_EXPECT(nid < unit_->tree.size()); | ||
|
||
using SurfaceNode = ::celeritas::csg::Surface; | ||
|
||
// Get the surface ID from the tree | ||
auto const& node = unit_->tree[nid]; | ||
CELER_ASSUME(std::holds_alternative<SurfaceNode>(node)); | ||
LocalSurfaceId lsid = std::get<SurfaceNode>(node).id; | ||
|
||
// Get the variant surfaces from the unit | ||
CELER_EXPECT(lsid < unit_->surfaces.size()); | ||
return unit_->surfaces[lsid.unchecked_get()]; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace detail | ||
} // namespace orangeinp | ||
} // namespace celeritas |
Oops, something went wrong.