File indexing completed on 2026-05-27 07:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/algebra.hpp"
0013 #include "detray/definitions/indexing.hpp"
0014 #include "detray/geometry/coordinates/coordinates.hpp"
0015
0016
0017 #include <concepts>
0018 #include <ostream>
0019 #include <type_traits>
0020
0021 namespace detray::concepts {
0022
0023
0024 template <class F>
0025 concept coordinate_frame = requires() {
0026 requires concepts::point<typename F::loc_point>;
0027 requires concepts::algebra<typename F::algebra_type>;
0028
0029 {
0030 F::global_to_local_3D(dtransform3D<typename F::algebra_type>(),
0031 dpoint3D<typename F::algebra_type>(),
0032 dvector3D<typename F::algebra_type>())
0033 } -> std::same_as<dpoint3D<typename F::algebra_type>>;
0034
0035 {
0036 F::global_to_local(dtransform3D<typename F::algebra_type>(),
0037 dpoint3D<typename F::algebra_type>(),
0038 dvector3D<typename F::algebra_type>())
0039 } -> std::same_as<typename F::loc_point>;
0040
0041 {
0042 F::local_to_global(dtransform3D<typename F::algebra_type>(),
0043 dpoint3D<typename F::algebra_type>())
0044 } -> std::same_as<dpoint3D<typename F::algebra_type>>;
0045
0046 {
0047 F::normal(dtransform3D<typename F::algebra_type>(),
0048 dpoint3D<typename F::algebra_type>())
0049 } -> std::same_as<dvector3D<typename F::algebra_type>>;
0050 };
0051
0052
0053 template <typename S, typename A>
0054 concept shape = concepts::algebra<A> && requires(const S sh, std::ostream os) {
0055 requires std::is_enum_v<typename S::boundaries>;
0056
0057 requires concepts::coordinate_frame<typename S::template local_frame_type<A>>;
0058
0059 typename S::template result_type<dbool<A>>;
0060 typename S::template bounds_type<dscalar<A>>;
0061
0062 S::dim;
0063
0064 {
0065 sh.min_dist_to_boundary(typename S::template bounds_type<dscalar<A>>(),
0066 dpoint2D<A>())
0067 } -> std::same_as<dscalar<A>>;
0068
0069 {
0070 sh.template check_boundaries<A>(
0071 typename S::template bounds_type<dscalar<A>>(), dtransform3D<A>(),
0072 dpoint3D<A>(), dscalar<A>())
0073 } -> std::same_as<typename S::template result_type<dbool<A>>>;
0074
0075 {
0076 sh.measure(typename S::template bounds_type<dscalar<A>>())
0077 } -> std::same_as<dscalar<A>>;
0078
0079 {
0080 sh.merge(typename S::template bounds_type<dscalar<A>>(),
0081 typename S::template bounds_type<dscalar<A>>())
0082 } -> std::same_as<typename S::template bounds_type<dscalar<A>>>;
0083
0084 {
0085 sh.template local_min_bounds<A>(
0086 typename S::template bounds_type<dscalar<A>>(), dscalar<A>())
0087 } -> std::same_as<darray<dscalar<A>, 6>>;
0088
0089 {
0090 sh.template centroid<A>(typename S::template bounds_type<dscalar<A>>())
0091 } -> std::same_as<dpoint3D<A>>;
0092
0093 {
0094 sh.template vertices<A>(typename S::template bounds_type<dscalar<A>>(),
0095 dindex())
0096 } -> std::same_as<dvector<dpoint3D<A>>>;
0097
0098 {
0099 sh.check_consistency(typename S::template bounds_type<dscalar<A>>(), os)
0100 } -> std::same_as<bool>;
0101 };
0102
0103
0104
0105 template <class G>
0106 concept has_shape =
0107 concepts::algebra<typename G::algebra_type> &&
0108 concepts::shape<typename G::shape, typename G::algebra_type>;
0109
0110 template <class G>
0111 concept has_local_frame = concepts::coordinate_frame<typename G::local_frame>;
0112
0113 template <class G>
0114 concept geometric_object =
0115 concepts::algebra<typename G::algebra_type> &&
0116 (concepts::has_shape<G> || concepts::has_local_frame<G>);
0117
0118
0119
0120
0121 template <class F>
0122 concept planar_frame =
0123 concepts::coordinate_frame<F> &&
0124 (std::same_as<F, cartesian2D<typename F::algebra_type>> ||
0125 std::same_as<F, polar2D<typename F::algebra_type>>);
0126
0127 template <class F>
0128 concept rectilinear_frame =
0129 concepts::coordinate_frame<F> &&
0130 (std::same_as<F, cartesian2D<typename F::algebra_type>> ||
0131 std::same_as<F, cartesian3D<typename F::algebra_type>>);
0132
0133 template <class F>
0134 concept cylindrical_frame =
0135 concepts::coordinate_frame<F> &&
0136 (std::same_as<F, cylindrical2D<typename F::algebra_type>> ||
0137 std::same_as<F, cylindrical3D<typename F::algebra_type>> ||
0138 std::same_as<F, concentric_cylindrical2D<typename F::algebra_type>>);
0139
0140 template <class F>
0141 concept line_frame = concepts::coordinate_frame<F> &&
0142 std::same_as<F, line2D<typename F::algebra_type>>;
0143
0144
0145
0146
0147 template <class S, class A>
0148 concept planar_shape =
0149 concepts::shape<S, A> &&
0150 concepts::planar_frame<typename S::template local_frame_type<A>>;
0151
0152 template <class S, class A>
0153 concept rectilinear_shape =
0154 concepts::shape<S, A> &&
0155 concepts::rectilinear_frame<typename S::template local_frame_type<A>>;
0156
0157 template <class S, class A>
0158 concept cylindrical_shape =
0159 concepts::shape<S, A> &&
0160 concepts::cylindrical_frame<typename S::template local_frame_type<A>>;
0161
0162 template <class S, class A>
0163 concept line_shape =
0164 concepts::shape<S, A> &&
0165 concepts::line_frame<typename S::template local_frame_type<A>>;
0166
0167
0168
0169
0170 template <class G>
0171 concept planar_object =
0172 (concepts::geometric_object<G>) &&
0173 ((concepts::has_shape<G> &&
0174 concepts::planar_shape<typename G::shape, typename G::algebra_type>) ||
0175 (concepts::has_local_frame<G> &&
0176 concepts::planar_frame<typename G::local_frame>));
0177
0178 template <class G>
0179 concept rectilinear_object =
0180 (concepts::geometric_object<G>) &&
0181 ((concepts::has_shape<G> &&
0182 concepts::rectilinear_shape<typename G::shape,
0183 typename G::algebra_type>) ||
0184 (concepts::has_local_frame<G> &&
0185 concepts::rectilinear_frame<typename G::local_frame>));
0186
0187 template <class G>
0188 concept cylindrical_object =
0189 (concepts::geometric_object<G>) &&
0190 ((concepts::has_shape<G> &&
0191 concepts::cylindrical_shape<typename G::shape,
0192 typename G::algebra_type>) ||
0193 (concepts::has_local_frame<G> &&
0194 concepts::cylindrical_frame<typename G::local_frame>));
0195
0196 template <class G>
0197 concept line_object =
0198 (concepts::geometric_object<G>) &&
0199 ((concepts::has_shape<G> &&
0200 concepts::line_shape<typename G::shape, typename G::algebra_type>) ||
0201 (concepts::has_local_frame<G> &&
0202 concepts::line_frame<typename G::local_frame>));
0203
0204
0205
0206 template <class T>
0207 concept planar = concepts::planar_frame<T> || concepts::planar_object<T>;
0208
0209 template <class T>
0210 concept rectilinear =
0211 concepts::rectilinear_frame<T> || concepts::rectilinear_object<T>;
0212
0213 template <class T>
0214 concept cylindrical =
0215 concepts::cylindrical_frame<T> || concepts::cylindrical_object<T>;
0216
0217 template <class T>
0218 concept line = concepts::line_frame<T> || concepts::line_object<T>;
0219
0220 }