#pragma once
#include
#include
#include
namespace internal
{
struct extrude_t final : public primitive {
extrude_t(const extrude_axis* axis,
bool closed_axis,
const Eigen::AffineCompact3d& axis_to_world,
const pattern* pattern,
primitive_data_center_t* data_center_ptr)
: primitive(data_center_ptr)
{
paired_model_matrix axis_transform{};
axis_transform.local_to_world = axis_to_world;
axis_transform.world_to_local = axis_to_world.inverse();
// TODO: 修改为更紧密的aabb
auto aabb = axis->get_local_aabb();
aabb.transform(axis_to_world);
auto pattern_max_length = pattern->get_max_bounding_length();
aabb.min().array() -= pattern_max_length;
aabb.max().array() += pattern_max_length;
if (closed_axis) {
has_end_caps = false;
initialize(
{
make_pointer_wrapper(axis_transform)
},
{{(void*)axis, (void*)pattern}},
aabb);
} else {
paired_model_matrix bottom_cap_transform{};
bottom_cap_transform.local_to_world = axis_to_world * axis->get_local_cap_mat(0, true);
bottom_cap_transform.world_to_local = bottom_cap_transform.local_to_world.inverse();
paired_model_matrix top_cap_transform{};
top_cap_transform.local_to_world = axis_to_world * axis->get_local_cap_mat(1, false);
top_cap_transform.world_to_local = top_cap_transform.local_to_world.inverse();
has_end_caps = true;
initialize(
{
make_pointer_wrapper(axis_transform),
make_pointer_wrapper(bottom_cap_transform),
make_pointer_wrapper(top_cap_transform)
},
{{(void*)axis, (void*)pattern}, {}, {}},
aabb);
}
}
primitive_type get_type() const override { return PRIMITIVE_TYPE_EXTRUDE; };
span> get_subfaces() const override
{
return {const_cast*>(subfaces.data()), has_end_caps ? 3u : 1u};
}
std::vector get_subface_types() const override
{
if (!has_end_caps)
return {surface_type::extrude_side};
else
return {surface_type::extrude_side, surface_type::plane, surface_type::plane};
}
std::array, 3> subfaces{nullptr, nullptr, nullptr};
bool has_end_caps{};
};
} // namespace internal