Skip to content
Snippets Groups Projects

Canvas: add_bezier()

Merged Aaron Kreuzberg requested to merge ak/develop into develop
2 unresolved threads
@@ -6,6 +6,7 @@
#include <glow-extras/viewer/objects/other/labels.hh>
#include <glow-extras/viewer/traits.hh>
#include <glow-extras/viewer/view.hh>
#include <typed-geometry/feature/bezier.hh>
namespace glow::viewer
{
@@ -1134,6 +1135,80 @@ public:
add_range(_labels, data._labels);
}
template <int D>
line_ref add_bezier(tg::bezier<D, tg::pos3> const& bezier, material const& mat = {})
{
tg::bezier<1, tg::pos3> bezier_start_end_segment = tg::make_bezier(bezier.control_points[0], bezier.control_points[D]);
tg::bezier<D, tg::vec3> bezier_subtract = bezier - bezier_start_end_segment;
auto min = tg::pos3(bezier_subtract.control_points[0]);
auto max = tg::pos3(bezier_subtract.control_points[0]);
for (tg::vec3& c : bezier_subtract.control_points)
{
min.x = tg::min(c.x, min.x);
min.y = tg::min(c.y, min.y);
min.z = tg::min(c.z, min.z);
max.x = tg::max(c.x, max.x);
max.y = tg::max(c.y, max.y);
max.z = tg::max(c.z, max.z);
}
tg::aabb3 bb = tg::aabb3(min, max);
float bb_length_diagonal = tg::length(bb.max - bb.min);
float segment_size;
if (bb_length_diagonal <= (2 * tg::epsilon<float>)) // zero curvature: approximation with single segment
segment_size = 1.0f;
else
segment_size = 0.05f * (1.0f / bb_length_diagonal);
// estimated segment length in world size approximated from 1st segment
float segment_size_world = tg::length(bezier[0] - bezier[segment_size]);
// ratio of in param segment size and world size segment size for back-mapping
float ratio = segment_size / segment_size_world;
if (_state.lines_curr == &_lines_world && segment_size_world < 5 * _state.lines_width)
{
segment_size_world = 5 * _state.lines_width;
// back-mapping to param size
segment_size = segment_size_world * ratio;
}
// segment length larger 1 exceeds bezier parametrization
segment_size = tg::clamp(segment_size, 0.001, 1.0f);
return _add_bezier(bezier, segment_size, mat);
}
template <int D, class PosT>
line_ref _add_bezier(tg::bezier<D, PosT> const& bezier, float segment_length, material const& mat = {})
{
static_assert(tg::is_comp_like<PosT, 3, float>, "value must be a pos3 like type");
auto start_cnt = _state.lines_curr->size();
float current_length = segment_length;
PosT prev_position = bezier.control_points[0];
int segment_counter = 0;
while (current_length <= 1.0f)
{
PosT current_position = bezier[current_length];
add_line(prev_position, current_position, mat);
prev_position = current_position;
current_length += segment_length;
segment_counter++;
}
// add last segment
if ((current_length - segment_length) < 1)
add_line(prev_position, bezier[1], mat);
return {array_view<line>(_state.lines_curr->data() + start_cnt, _state.lines_curr->size() - start_cnt), *this};
}
std::vector<SharedRenderable> create_renderables() const;
void set_name(std::string s) { _state.name = std::move(s); }
Loading