-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add prefix to face namer * Invalidate interior and fix aligned plane in surface clipper * Fix includes * Add infinite bounding zone helper * Add convex surface builder * Fix explicit instantiation * Address review feedback
- Loading branch information
Showing
20 changed files
with
823 additions
and
39 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
//----------------------------------*-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/ConvexSurfaceBuilder.cc | ||
//---------------------------------------------------------------------------// | ||
#include "ConvexSurfaceBuilder.hh" | ||
|
||
#include "orange/surf/RecursiveSimplifier.hh" | ||
#include "orange/surf/SurfaceClipper.hh" | ||
|
||
#include "detail/ConvexSurfaceState.hh" | ||
#include "detail/CsgUnitBuilder.hh" | ||
#include "detail/NegatedSurfaceClipper.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace orangeinp | ||
{ | ||
namespace | ||
{ | ||
//---------------------------------------------------------------------------// | ||
struct ClipImpl | ||
{ | ||
detail::BoundingZone* bzone{nullptr}; | ||
|
||
template<class S> | ||
void operator()(Sense s, S const& surf) | ||
{ | ||
if (s == Sense::inside) | ||
{ | ||
SurfaceClipper clip{&bzone->interior, &bzone->exterior}; | ||
clip(surf); | ||
} | ||
else | ||
{ | ||
detail::NegatedSurfaceClipper clip{bzone}; | ||
clip(surf); | ||
} | ||
} | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Construct with persistent unit builder and less persistent state. | ||
* | ||
* Both arguments must have lifetimes that exceed the surface builder, but the | ||
* "unit builder" will have a duration of the whole unit construction, whereas | ||
* the state just has the duration of the convex surface set being built. | ||
*/ | ||
ConvexSurfaceBuilder::ConvexSurfaceBuilder(UnitBuilder* ub, State* state) | ||
: ub_{ub}, state_{state} | ||
{ | ||
CELER_EXPECT(ub_ && state_); | ||
CELER_EXPECT(*state_); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Add a surface with a sense. | ||
* | ||
* The resulting surface *MUST* result in a convex region. | ||
*/ | ||
template<class S> | ||
void ConvexSurfaceBuilder::operator()(Sense sense, S const& surf) | ||
{ | ||
// First, clip the local bounding zone based on the given surface | ||
RecursiveSimplifier clip_simplified_local(ClipImpl{&state_->local_bzone}, | ||
ub_->tol()); | ||
clip_simplified_local(sense, surf); | ||
|
||
// Next, apply the transform and insert | ||
return this->insert_transformed(state_->make_face_name(sense, surf), | ||
sense, | ||
apply_transform(*state_->transform, surf)); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
// HELPER FUNCTION DEFINITIONS | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Add a surface after transforming it to an unknown type. | ||
* | ||
* \param extension Constructed metadata for the surface node | ||
* \param sense Whether the convex region is inside/outside this surface | ||
* \param surf Type-deleted surface | ||
*/ | ||
void ConvexSurfaceBuilder::insert_transformed(std::string&& extension, | ||
Sense sense, | ||
VariantSurface const& surf) | ||
{ | ||
NodeId node_id; | ||
auto construct_impl = [&](Sense final_sense, auto&& final_surf) { | ||
using SurfaceT = std::decay_t<decltype(final_surf)>; | ||
|
||
// Insert transformed surface, deduplicating and creating CSG node | ||
node_id = ub_->insert_surface(final_surf); | ||
|
||
// Replace sense so we know to flip the node if needed | ||
sense = final_sense; | ||
|
||
// Update surface's global-reference bounding zone using *deduplicated* | ||
// surface | ||
ClipImpl{&state_->global_bzone}(final_sense, | ||
ub_->get_surface<SurfaceT>(node_id)); | ||
}; | ||
|
||
// Construct transformed surface, get back the node ID, update the sense | ||
RecursiveSimplifier construct_final(construct_impl, ub_->tol()); | ||
construct_final(sense, surf); | ||
CELER_ASSERT(node_id); | ||
|
||
// Add metadata for the surface node | ||
ub_->insert_md(node_id, Label{state_->object_name, std::move(extension)}); | ||
|
||
if (sense == Sense::inside) | ||
{ | ||
// "Inside" the surface (negative quadric evaluation) means we have to | ||
// negate the CSG result | ||
static_assert(Sense::inside == to_sense(false)); | ||
node_id = ub_->insert_csg(Negated{node_id}); | ||
} | ||
|
||
// Add sense to "joined" region | ||
state_->nodes.push_back(node_id); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
// FREE FUNCTION DEFINITIONS | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Construct a surface using a variant. | ||
*/ | ||
void visit(ConvexSurfaceBuilder& csb, Sense sense, VariantSurface const& surf) | ||
{ | ||
std::visit([&csb, sense](auto const& s) { csb(sense, s); }, surf); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
} // 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,92 @@ | ||
//----------------------------------*-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/ConvexSurfaceBuilder.hh | ||
//---------------------------------------------------------------------------// | ||
#pragma once | ||
|
||
#include <vector> | ||
|
||
#include "orange/OrangeTypes.hh" | ||
#include "orange/surf/VariantSurface.hh" | ||
|
||
#include "CsgTypes.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace orangeinp | ||
{ | ||
namespace detail | ||
{ | ||
class CsgUnitBuilder; | ||
struct ConvexSurfaceState; | ||
} // namespace detail | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Build a set of intersecting surfaces within a CSG node. | ||
* | ||
* This is the building block for constructing shapes, solids, and so forth. | ||
* The result of this class is: | ||
* - CSG nodes describing the inserted surfaces which have been transformed | ||
* into the global reference frame | ||
* - Metadata combining the surfaces names with the object name | ||
* - Bounding boxes (interior and exterior) | ||
* | ||
* \todo Should we require that the user implicitly guarantee that the result | ||
* is convex, e.g. prohibit quadrics outside "saddle" points? What about a | ||
* torus, which (unless degenerate) is never convex? Or should we just require | ||
* that "exiting a surface exits the region"? (Think about application to OR-ed | ||
* combinations for safety calculation.) | ||
*/ | ||
class ConvexSurfaceBuilder | ||
{ | ||
public: | ||
//! Add a surface with negative quadric value being "inside" | ||
template<class S> | ||
void operator()(S const& surf) | ||
{ | ||
return (*this)(Sense::inside, surf); | ||
} | ||
|
||
// Add a surface with specified sense (usually inside except for planes) | ||
template<class S> | ||
void operator()(Sense sense, S const& surf); | ||
|
||
public: | ||
// "Private", to be used by testing and detail | ||
using State = detail::ConvexSurfaceState; | ||
using UnitBuilder = detail::CsgUnitBuilder; | ||
using VecNode = std::vector<NodeId>; | ||
|
||
// Construct with persistent unit builder and less persistent state | ||
ConvexSurfaceBuilder(UnitBuilder* ub, State* state); | ||
|
||
private: | ||
//// TYPES //// | ||
|
||
// Helper for constructing surfaces | ||
UnitBuilder* ub_; | ||
|
||
// State being modified by this builder | ||
State* state_; | ||
|
||
//// HELPER FUNCTION //// | ||
|
||
void insert_transformed(std::string&& ext, | ||
Sense sense, | ||
VariantSurface const& surf); | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
// FREE FUNCTIONS | ||
//---------------------------------------------------------------------------// | ||
|
||
// Apply a convex surface builder to an unknown type | ||
void visit(ConvexSurfaceBuilder& csb, Sense sense, VariantSurface const& surf); | ||
|
||
//---------------------------------------------------------------------------// | ||
} // 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
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,64 @@ | ||
//----------------------------------*-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/ConvexSurfaceState.hh | ||
//---------------------------------------------------------------------------// | ||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "orange/surf/FaceNamer.hh" | ||
#include "orange/transform/VariantTransform.hh" | ||
|
||
#include "BoundingZone.hh" | ||
#include "../CsgTypes.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace orangeinp | ||
{ | ||
namespace detail | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Local state for building a set of intersected surfaces. | ||
* | ||
* Note that the surface clippers have *pointers* to local and global bounding | ||
* zones. Those must exceed the lifetime of this state. | ||
*/ | ||
struct ConvexSurfaceState | ||
{ | ||
//!@{ | ||
//! \name Input state | ||
//! Local-to-global transform | ||
VariantTransform const* transform{nullptr}; | ||
//! Name of the object being built | ||
std::string object_name; | ||
//! Generate a name from a surface (has internal state) | ||
FaceNamer make_face_name; | ||
//!@} | ||
|
||
//!@{ | ||
//! \name Output state | ||
//! Local (to convex surface state) interior/exterior | ||
BoundingZone local_bzone = BoundingZone::from_infinite(); | ||
//! Global (to unit) interior/exterior | ||
BoundingZone global_bzone = BoundingZone::from_infinite(); | ||
//! Inserted CSG nodes | ||
std::vector<NodeId> nodes; | ||
//!@} | ||
|
||
//! True if the state is valid | ||
explicit operator bool() const | ||
{ | ||
return transform && !object_name.empty(); | ||
} | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace detail | ||
} // namespace orangeinp | ||
} // namespace celeritas |
Oops, something went wrong.