Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update on annulus plotting #83

Merged
merged 5 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 45 additions & 13 deletions core/include/actsvg/core/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,33 +195,65 @@ point2_type rotate(const point2_type &p_, scalar a_) {
return p_rot;
}

/** Helper method toscala a point3 object
/** Helper method to scale object
*
* @param p0_ the point3 object and @param s_ the scale
* @param p0_ the point object and @param s_ the scale
*
* @return a new point3
* @return a new point_type object
**/
template <typename point3_type>
point3_type scale(const point3_type &p0_, scalar s_) {
point3_type scaled;
template <typename point_type, std::size_t kDIM = 3u>
point_type scale(const point_type &p0_, scalar s_) {
point_type scaled;
scaled[0] = s_ * p0_[0];
scaled[1] = s_ * p0_[1];
scaled[2] = s_ * p0_[2];
if constexpr (kDIM == 3u) {
scaled[2] = s_ * p0_[2];
}
return scaled;
}

/** Helper method for making a unit vector
*
* @param x0_ the starting point
* @param x1_ the ending point
*
* @return the distance
**/
template <typename point_type, std::size_t kDIM = 2u>
point_type unit_direction(const point_type &x0_, const point_type &x1_) {
// 2 dimensional case
if constexpr (kDIM == 2u) {
scalar length = std::sqrt(std::pow(x1_[0] - x0_[0], 2) +
std::pow(x1_[1] - x0_[1], 2));
scalar norml = 1. / length;
return point_type{norml * (x1_[0] - x0_[0]), norml * (x1_[1] - x0_[1])};
}
// 3 dimensional case
if constexpr (kDIM == 3u) {
scalar length = std::sqrt(std::pow(x1_[0] - x0_[0], 2) +
std::pow(x1_[1] - x0_[1], 2) +
std::pow(x1_[2] - x0_[2], 2));
scalar norml = 1. / length;
return point_type{norml * (x1_[0] - x0_[0]), norml * (x1_[1] - x0_[1]),
norml * (x1_[2] - x0_[2])};
}
return point_type{};
}

/** Helper method to add two point3 objects
*
* @param p0_ and @param p1_ the 3D points
* @param p0_ and @param p1_ the points
*
* @return a new point3
* @return a new point_type object
**/
template <typename point3_type>
point3_type add(const point3_type &p0_, const point3_type &p1_) {
point3_type added;
template <typename point_type, std::size_t kDIM = 3u>
point_type add(const point_type &p0_, const point_type &p1_) {
point_type added;
added[0] = p0_[0] + p1_[0];
added[1] = p0_[1] + p1_[1];
added[2] = p0_[2] + p1_[2];
if constexpr (kDIM == 3u) {
added[2] = p0_[2] + p1_[2];
}
return added;
}

Expand Down
4 changes: 3 additions & 1 deletion core/src/core/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,11 @@ svg::object connected_info_box(

auto tebox = polygon(id_ + "_text_box", tec, text_fill_, stroke_);
ib.add_object(tebox);

scalar toffset = text_.size() == 1u ? tih + title_font_._size : tih;
auto te =
text(id_ + "_text",
{p_[0] + title_font_._size, static_cast<scalar>(p_[1] - tih)},
{p_[0] + title_font_._size, static_cast<scalar>(p_[1] - toffset)},
text_, text_font_);
ib.add_object(te);

Expand Down
119 changes: 92 additions & 27 deletions meta/include/actsvg/display/geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,40 @@
#include "actsvg/core.hpp"
#include "actsvg/display/tools.hpp"
#include "actsvg/proto/surface.hpp"
#include "actsvg/styles/defaults.hpp"

namespace actsvg {

using namespace defaults;

namespace display {

struct surface_options {

/// @param _boolean_shape draw the boolean
bool _boolean_shape = true;
/// @param _focus draw at focus
bool _focus = false;
/// @param _draw_at_scale draw at scale
bool _draw_at_scale = false;
/// @param _draw_as_template draw as template
bool _draw_as_template = false;
/// @param _label_measures draw the labels
bool _label_measures = false;
};

/** Draw the surface with a dedicated view
*
* @param id_ the identification of this surface
* @param s_ the surface type
* @param v_ the view type
* @param b_ draw the boolean
* @param fs_ draw at focus
* @param sc_ draw at scale
* @param dt_ draw as template
* @param o_ the options struct
*
* @note template surfaces ignore the view_type::scene range restriction
*/
template <typename surface_type, typename view_type>
svg::object surface(const std::string& id_, const surface_type& s_,
const view_type& v_, bool _b = true, bool fs_ = false,
bool sc_ = false, bool dt_ = false) {
const view_type& v_,
const surface_options& o_ = surface_options{}) {

svg::object s;

Expand All @@ -48,12 +59,12 @@ svg::object surface(const std::string& id_, const surface_type& s_,

style::transform draw_transform = s_._transform;
// No rotation nor shift as template
if (dt_) {
if (o_._draw_as_template) {
draw_transform._tr = {0., 0.};
draw_transform._rot = {0., 0., 0.};
}
// Apply scale or not
if (not sc_) {
if (!o_._draw_at_scale) {
draw_transform._scale = {1., 1.};
}

Expand All @@ -63,7 +74,8 @@ svg::object surface(const std::string& id_, const surface_type& s_,
return s;
}

style::transform draw_transform = fs_ ? style::transform{} : s_._transform;
style::transform draw_transform =
o_._focus ? style::transform{} : s_._transform;
draw_transform._scale = s_._transform._scale;

// Surface directly
Expand All @@ -86,32 +98,86 @@ svg::object surface(const std::string& id_, const surface_type& s_,
annulusCircleIx(origin_x, origin_y, max_r, min_phi_rel);
auto out_left_s_xy =
annulusCircleIx(origin_x, origin_y, max_r, max_phi_rel);

// For drawing, this needs a shift
scalar irx = in_right_s_xy[0] - origin_x;
scalar iry = in_right_s_xy[1] - origin_y;
scalar ilx = in_left_s_xy[0] - origin_x;
scalar ily = in_left_s_xy[1] - origin_y;
scalar orx = out_right_s_xy[0] - origin_x;
scalar ory = out_right_s_xy[1] - origin_y;
scalar olx = out_left_s_xy[0] - origin_x;
scalar oly = out_left_s_xy[1] - origin_y;
// Dedicated path drawing of the annulus bounds
s._tag = "path";
s._id = id_;
std::string path = "M " + std::to_string(in_right_s_xy[0]) + " " +
std::to_string(-in_right_s_xy[1]);
std::string path =
"M " + std::to_string(irx) + " " + std::to_string(-iry);
path += " A " + std::to_string(min_r) + " " + std::to_string(min_r);
path += " 0 0 0 ";
path += std::to_string(in_left_s_xy[0]) + " " +
std::to_string(-in_left_s_xy[1]);
path += " L " + std::to_string(out_left_s_xy[0]) + " " +
std::to_string(-out_left_s_xy[1]);
path += std::to_string(ilx) + " " + std::to_string(-ily);
path += " L " + std::to_string(olx) + " " + std::to_string(-oly);
path += " A " + std::to_string(max_r) + " " + std::to_string(max_r);
path += " 0 0 1 ";
path += std::to_string(out_right_s_xy[0]) + " " +
std::to_string(-out_right_s_xy[1]);
path += " L " + std::to_string(in_right_s_xy[0]) + " " +
std::to_string(-in_right_s_xy[1]);
path += std::to_string(orx) + " " + std::to_string(-ory);
path += " L " + std::to_string(irx) + " " + std::to_string(-iry);
s._attribute_map["d"] = path;
s._fill = s_._fill;
s._stroke = s_._stroke;
s._transform = draw_transform;
if (not fs_) {
if (!o_._focus) {
s._x_range = {-max_r, max_r};
s._y_range = {-max_r, max_r};
}

if (o_._label_measures) {

// make a copy & a group out of the object
auto sc = s;
s = svg::object{};
s._tag = "g";
s._id = id_ + "_labeled_group";
s.add_object(sc);

// Draw min / max circles
s.add_object(draw::circle(id_ + "_inner_circle", {0., 0}, min_r,
style::fill{},
defaults::__bl_dotted_stroke));
s.add_object(draw::circle(id_ + "_outer_circle", {0., 0}, max_r,
style::fill{},
defaults::__bl_dotted_stroke));

// Define the origin of the strip system & draw the lines
point2 origin = {-origin_x, -origin_y};
auto el0 = point2{olx, oly};
auto el1 = point2{orx, ory};
std::array<point2, 2u> lines = {el0, el1};
for (const auto [il, lline] : utils::enumerate(lines)) {
point2 dline = utils::unit_direction<>(origin, lline);
point2 dneg = utils::scale<point2, 2u>(dline, -0.2 * min_r);
point2 dpos = utils::scale<point2, 2u>(dneg, -1.);

auto line = draw::line(id_ + "_line" + std::to_string(il),
utils::add<point2, 2u>(origin, dneg),
utils::add<point2, 2u>(lline, dpos),
defaults::__bl_dotted_stroke);
line._transform = draw_transform;
s.add_object(line);
}
}

// Package into a translated group if we have a surfade transform
if (s_._surface_transform.has_value()) {
const auto& sfg = s_._surface_transform.value();
if (sfg._translation[0] != 0. || sfg._translation[1] != 0.) {
auto tg = s;
s = svg::object{};
s._id = id_ + "_translated";
s._tag = "g";
s._transform._tr = {-sfg._translation[0], sfg._translation[1]};
s.add_object(tg);
}
}

} else if (s_._type == surface_type::type::e_disc) {

// x-y view for discs
Expand Down Expand Up @@ -145,14 +211,14 @@ svg::object surface(const std::string& id_, const surface_type& s_,
s_c_._radii = {0., s_._radii[1u]};

svg::object outer_mask =
surface(id_ + "_mask_surface_outer", s_c_, v_, false);
surface(id_ + "_mask_surface_outer", s_c_, v_, {false});
outer_mask._fill = style::fill{true};
outer_mask._stroke = style::stroke{true};
outer_mask._attribute_map["fill"] = "white";

s_c_._radii = {0., s_._radii[0u]};
svg::object inner_mask =
surface(id_ + "_mask_surface_inner", s_c_, v_, false);
surface(id_ + "_mask_surface_inner", s_c_, v_, {false});
inner_mask._fill = style::fill{true};
inner_mask._stroke = style::stroke{true};
inner_mask._attribute_map["fill"] = "black";
Expand Down Expand Up @@ -216,7 +282,6 @@ svg::object surface(const std::string& id_, const surface_type& s_,
}

} else if (s_._type == surface_type::type::e_straw) {

// xy view
if constexpr (std::is_same_v<view_type, views::x_y>) {
// Skin of the straw
Expand Down Expand Up @@ -395,15 +460,15 @@ svg::object surface(const std::string& id_, const surface_type& s_,
draw_transform);
}

if (_b) {
if (o_._boolean_shape) {
/// Boolean surfaces only supported for x-y view so far
if constexpr (std::is_same_v<view_type, views::x_y>) {
if (s_._boolean_surface.size() == 1u and
s_._boolean_operation == surface_type::boolean::e_subtraction) {
std::string mask_id = id_ + "_mask";
// make a new boolean surface
svg::object outer_mask =
surface(id_ + "_mask_surface_outer", s_, v_, false);
surface(id_ + "_mask_surface_outer", s_, v_, {false});
outer_mask._fill = style::fill{true};
outer_mask._stroke = style::stroke{true};
outer_mask._attribute_map["fill"] = "white";
Expand Down
6 changes: 3 additions & 3 deletions meta/include/actsvg/display/helpers.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This file is part of the actsvg packge.
//
// Copyright (C) 2022 CERN for the benefit of the ACTS project
// Copyright (C) 2022-2024 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -236,8 +236,8 @@ process_modules(const volume_type& v_, const view_type& view_,
}

auto surface_module =
display::surface(draw_surface._name, draw_surface, view_, true,
false, true, false);
display::surface(draw_surface._name, draw_surface, view_,
{true, false, true, false});
modules.push_back(surface_module);
}
all_modules.push_back(modules);
Expand Down
2 changes: 1 addition & 1 deletion meta/include/actsvg/display/sheets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ svg::object surface_sheet_xy(const std::string& id_,
// The boolean parameters are : we draw the surface with booleans, focusses,
// scaled, and as template
auto surface = display::surface(s_._name + "_in_sheet", draw_surface,
x_y_view, true, true, true, true);
x_y_view, {true, true, true, true});
so.add_object(surface);

// disc/annulus may overwrite axis drawing
Expand Down
5 changes: 5 additions & 0 deletions meta/include/actsvg/styles/defaults.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ extern style::stroke __r_stroke;
extern style::fill __bl_fill;
extern style::stroke __bl_stroke;

// Black, dashed stroke
extern style::stroke __bl_dashed_stroke;
// Black, dashed stroke
extern style::stroke __bl_dotted_stroke;

// No fill, no stroke
extern style::fill __nn_fill;
extern style::stroke __nn_stroke;
Expand Down
10 changes: 10 additions & 0 deletions meta/src/styles/defaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ style::fill __r_fill;
style::stroke __r_stroke;
style::fill __bl_fill;
style::stroke __bl_stroke;
style::stroke __bl_dashed_stroke;
style::stroke __bl_dotted_stroke;
style::fill __nn_fill;
style::stroke __nn_stroke;
style::gradient __rgb_gradient;
Expand Down Expand Up @@ -103,6 +105,14 @@ static bool create_defaults() {
__bl_fill._fc._rgb = {0, 0, 0};
__bl_stroke._sc._rgb = {0, 0, 0};

// Black dashed
__bl_dashed_stroke._sc._rgb = {0, 0, 0};
__bl_dashed_stroke._dasharray = {3, 3};

// Black dashed
__bl_dotted_stroke._sc._rgb = {0, 0, 0};
__bl_dotted_stroke._dasharray = {1, 1};

// Nulls
__nn_fill = style::fill();

Expand Down
1 change: 0 additions & 1 deletion python/src/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ void add_core_module(context& ctx) {

/// Draw a gradient box
d.def("gradient_box", &draw::gradient_box);

}
}
} // namespace python
Expand Down
1 change: 0 additions & 1 deletion python/src/dummies/examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#include "../utilities.hpp"


namespace py = pybind11;
using namespace pybind11::literals;

Expand Down
Loading
Loading