8#include <kernel/geometry/atlas/chart.hpp>
42 template<
typename Mesh_>
44 public ChartCRTP<Bezier<Mesh_>, Mesh_, BezierTraits>
99 const std::deque<std::size_t>& vtx_ptr,
100 const std::deque<WorldPoint>& world,
101 const std::deque<ParamPoint>& param,
112 XASSERTM(
_vtx_ptr.size() > std::size_t(1),
"Bezier needs at least 2 points");
116 XASSERTM(
_vtx_ptr.front() == std::size_t(0),
"invalid vertex pointer array");
120 for(std::size_t i(0); (i+1) <
_vtx_ptr.size(); ++i)
170 this->_param.push_back(param);
178 this->_closed =
true;
210 this->_orientation = ori;
267 if constexpr(Mesh_::shape_dim == 2)
278 pt.set_mat_vec_mult(rot, tmp) += offset;
283 XABORTM(
"Trying to call Bezier Chart routines for a 3d mesh");
298 ASSERTM((i+1) <
Index(this->_vtx_ptr.size()),
"invalid segment index");
306 if(n == std::size_t(1))
317 for(std::size_t k(0); k <= n; ++k)
323 for(std::size_t j(0); j < n; ++j)
325 for(std::size_t k(0); (k+j) < n; ++k)
328 (v[k] *= t1) += (t * v[k+1]);
350 ASSERTM((i+1) <
Index(this->_vtx_ptr.size()),
"invalid segment index");
359 if(n == std::size_t(1))
373 for(std::size_t k(0); k <= n; ++k)
382 for(std::size_t j(0); j < n; ++j)
384 for(std::size_t k(0); (k+j) < n; ++k)
388 (((der1[k] *= t1) += (t * der1[k+1])) -= vals[k]) += vals[k+1];
392 (vals[k] *= t1) += (t * vals[k+1]);
419 ASSERTM((i+1) <
Index(this->_vtx_ptr.size()),
"invalid segment index");
425 if(n == std::size_t(1))
444 const std::size_t ke =
_vtx_ptr[i+1];
451 if(ps.norm_euclid_sqr() < pe.norm_euclid_sqr())
455 for(std::size_t k(ks + 1); k < ke; ++k)
467 for(std::size_t k(ks + 1); k < ke; ++k)
518 if(n <= std::size_t(3))
544 for(
int iter(0); iter < 10; ++iter)
550 for(std::size_t k(0); k <= n; ++k)
557 for(std::size_t j(0); j < n; ++j)
559 for(std::size_t k(0); (k+j) < n; ++k)
563 (((der2[k] *= t1) += (t * der2[k+1])) -=
DataType(2)*der1[k]) +=
DataType(2)*der1[k+1];
567 (((der1[k] *= t1) += (t * der1[k+1])) -= vals[k]) += vals[k+1];
571 (vals[k] *= t1) += (t * vals[k+1]);
576 DataType vpx = vals[0][0] - point[0];
577 DataType vpy = vals[0][1] - point[1];
593 DataType fd = (d2x*vpx + d2y*vpy + d1x*d1x + d1y*d1y);
627 XASSERTM(!this->_param.empty(),
"Bezier has no parameters");
630 const Index i =
Index(this->find_param(param[0]));
633 const DataType t = (param[0] - this->_param[i][0]) / (this->_param[i+1][0] - this->_param[i][0]);
651 point = this->_world.front();
652 DataType min_dist = (inpoint - point).norm_euclid_sqr();
653 for(std::size_t i(1); i < this->_vtx_ptr.size(); ++i)
655 DataType distance = (inpoint - this->_world.at(this->_vtx_ptr[i])).norm_euclid_sqr();
656 if(distance < min_dist)
658 point = this->_world.at(this->_vtx_ptr[i]);
667 for(
Index i(0); (i+1) <
Index(this->_vtx_ptr.size()); ++i)
679 for(std::size_t k(this->_vtx_ptr[i]); k <= this->_vtx_ptr[i+1]; ++k)
682 const WorldPoint p = this->_world.at(k) - inpoint;
685 gt_x0 = gt_x0 || (p[0] > -min_dist);
686 lt_x1 = lt_x1 || (p[0] < +min_dist);
687 gt_y0 = gt_y0 || (p[1] > -min_dist);
688 lt_y1 = lt_y1 || (p[1] < +min_dist);
692 if(!(gt_x0 && lt_x1 && gt_y0 && lt_y1))
702 DataType distance = (x - inpoint).norm_euclid();
705 if(distance < min_dist)
726 auto& vtx = mesh.get_vertex_set();
727 const auto& target_vtx = meshpart.template get_target_set<0>();
740 return (projected - point).norm_euclid();
749 grad_dist = (projected - point);
751 return grad_dist.norm_euclid();
767 DataType best_distance_sqr(Math::huge<DataType>());
777 for(
Index i(0); (i+1) <
Index(this->_vtx_ptr.size()); ++i)
788 DataType my_distance_sqr(difference.norm_euclid_sqr());
793 if(my_distance_sqr <= sqr_eps)
798 best_is_vertex =
~Index(0);
803 if(i ==
Index(0) || (my_distance_sqr < best_distance_sqr))
805 best_distance_sqr = my_distance_sqr;
809 grad_dist = difference;
815 best_is_vertex = i+1;
817 best_is_vertex =
~Index(0);
831 XASSERT(this->_vtx_ptr.size() >= std::size_t(3));
835 if(best_is_vertex ==
Index(0))
836 prev_seg =
Index(this->_vtx_ptr.size()-2u);
838 prev_seg = best_is_vertex - 1u;
842 if(best_is_vertex ==
Index(this->_vtx_ptr.size()-1u))
845 next_seg = best_is_vertex;
880 WorldPoint prev_tangent({-prev_normal[1], prev_normal[0]});
901 if((best_distance_sqr > sqr_eps) && best_sign !=
DataType(0))
903 grad_dist.normalize();
904 grad_dist *= -best_sign;
911 grad_dist.normalize();
916 return best_sign *
Math::sqrt(best_distance_sqr);
920 virtual void write(std::ostream& os,
const String& sindent)
const override
922 String sind(sindent), sind2(sindent);
929 os << sindent <<
"<Bezier dim=\"2\" size=\"" << this->_vtx_ptr.size() <<
"\"";
930 os <<
" type=\"" << (this->_closed ?
"closed" :
"open") <<
"\"";
934 os << sind <<
"<Points>\n";
942 for(std::size_t i(1); i <
_vtx_ptr.size(); ++i)
949 os <<
" " <<
_world[k][j];
952 os << sind <<
"</Points>\n";
957 os << sind <<
"<Params>\n";
958 for(std::size_t i(0); i <
_param.size(); ++i)
959 os << sind2 <<
_param[i][0] <<
'\n';
960 os << sind <<
"</Params>\n";
964 os << sindent <<
"</Bezier>\n";
968 std::size_t find_param(
const DataType x)
const
973 if(x <=
_param.front()[0])
974 return std::size_t(0);
976 return _param.size()-std::size_t(2);
979 std::size_t il(0), ir(
_param.size()-1);
983 std::size_t im = (il+ir)/2;
996 return (il+1 <
_param.size() ? il : (
_param.size() - std::size_t(2)));
1000 template<
typename Mesh_>
1012 _bezier(bezier), _size(size), _read(0)
1016 virtual bool attribs(std::map<String,bool>&)
const override
1021 virtual void create(
int iline,
const String& sline,
const String&,
const std::map<String, String>&,
bool closed)
override
1050 std::size_t num_ctrl(0);
1051 if(!scoords.front().parse(num_ctrl))
1055 if((_read ==
Index(0)) && (num_ctrl > std::size_t(0)))
1065 for(
int k(0); k < int(num_ctrl); ++k)
1070 throw Xml::ContentError(iline, sline,
"Failed to parse control point coordinate");
1080 throw Xml::ContentError(iline, sline,
"Failed to parse vertex point coordinate");
1093 template<
typename Mesh_>
1105 _bezier(bezier), _size(size), _read(0)
1109 virtual bool attribs(std::map<String,bool>&)
const override
1114 virtual void create(
int iline,
const String& sline,
const String&,
const std::map<String, String>&,
bool closed)
override
1142 if(!sline.
parse(point[0]))
1155 template<
typename Mesh_,
typename ChartReturn_ = ChartBase<Mesh_>>
1162 std::unique_ptr<ChartReturn_>& _chart;
1163 std::unique_ptr<Bezier<Mesh_>> _bezier;
1174 virtual bool attribs(std::map<String,bool>& attrs)
const override
1176 attrs.emplace(
"dim",
true);
1177 attrs.emplace(
"size",
true);
1178 attrs.emplace(
"type",
false);
1179 attrs.emplace(
"orientation",
false);
1187 const std::map<String, String>& attrs,
1188 bool closed)
override
1197 if(!attrs.find(
"dim")->second.parse(dim))
1203 if(!attrs.find(
"size")->second.parse(_size))
1205 if(_size <
Index(2))
1209 bool poly_closed(
false);
1210 auto it = attrs.find(
"type");
1211 if(it != attrs.end())
1213 String stype = it->second;
1214 if(it->second ==
"closed")
1216 else if (it->second !=
"open")
1217 throw Xml::ContentError(iline, sline,
"Invalid Bezier type; must be either 'closed' or 'open'");
1220 DataType orientation(1);
1221 it = attrs.find(
"orientation");
1222 if(it != attrs.end())
1223 it->second.parse(orientation);
1226 _bezier.reset(
new ChartType(poly_closed, orientation));
1232 _chart = std::move(_bezier);
1242 if(name ==
"Points")
return std::make_shared<BezierPointsParser<Mesh_>>(*_bezier, _size);
1243 if(name ==
"Params")
return std::make_shared<BezierParamsParser<Mesh_>>(*_bezier, _size);
#define XABORTM(msg)
Abortion macro definition with custom message.
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
virtual bool content(int, const String &) override
Called to process a content line.
virtual void close(int, const String &) override
Closes this markup parser node.
virtual std::shared_ptr< Xml::MarkupParser > markup(int, const String &, const String &name) override
Called to process a child markup node.
virtual void create(int iline, const String &sline, const String &, const std::map< String, String > &attrs, bool closed) override
Creates this markup parser node.
virtual bool attribs(std::map< String, bool > &attrs) const override
Specifies the mandatory and optional attributes.
Bezier chart class template.
void push_close()
Marks the Bezier chart as closed.
void push_param(const ParamPoint ¶m)
Pushes a new parameter to the spline.
WorldPoint map_on_segment(const Index i, const DataType t) const
Maps a local segment parameter point.
bool _closed
Specifies whether the spline is closed.
const std::deque< WorldPoint > & get_world_points() const
Returns a (const) reference to the internal world points deque.
Bezier(bool closed=false, DataType orientation=DataType(1))
default CTOR
std::deque< ParamPoint > _param
The parameter values for these world points.
void project_point(WorldPoint &point) const
Projects a single world point.
DataType compute_dist(const WorldPoint &point, WorldPoint &grad_dist) const
Computes the distance of a point to this chart.
std::deque< WorldPoint > _world
The vertex and control points for the spline.
virtual bool can_explicit() const override
Specifies whether the chart can perform explicit projection.
DataType compute_signed_dist(const WorldPoint &point) const
Computes the signed distance of a point to this chart.
virtual void transform(const WorldPoint &origin, const WorldPoint &angles, const WorldPoint &offset) override
BaseClass::ParamPoint ParamPoint
Vector type for parameter points aka. domain points.
DataType _orientation
Specifies if the chart is to be oriented negatively or not.
DataType compute_signed_dist(const WorldPoint &point, WorldPoint &grad_dist) const
Computes the signed distance of a point to this chart.
Bezier(const std::deque< std::size_t > &vtx_ptr, const std::deque< WorldPoint > &world, const std::deque< ParamPoint > ¶m, bool closed, DataType orientation=DataType(1))
Constructor.
void set_orientation(int ori)
Sets the orientation code for the curve.
void project_meshpart(Mesh_ &mesh, const MeshPart< Mesh_ > &meshpart) const
Projects all mesh points identified by a meshpart.
BaseClass::CoordType DataType
Floating point type for coordinates.
BaseClass::WorldPoint WorldPoint
Vector type for world points aka. image points.
virtual void write(std::ostream &os, const String &sindent) const override
Writes the Chart into a stream in XML format.
WorldPoint get_normal_on_segment(const Index i, const DataType t) const
Computes the outer unit normal in a single point.
DataType compute_dist(const WorldPoint &point) const
Computes the distance of a point to this chart.
DataType project_on_segment(const Index i, const WorldPoint &point) const
Projects a point onto one segment of the spline.
const std::deque< std::size_t > & get_vertex_pointers() const
Returns a (const) reference to the internal vertex pointers deque.
void push_control(const WorldPoint &point)
Pushes a new control point to the spline.
std::deque< std::size_t > _vtx_ptr
The vertex point pointer array.
static constexpr int max_degree
maximum allowed spline degree
ChartCRTP< Bezier< Mesh_ >, Mesh_, BezierTraits > BaseClass
The CRTP base class.
virtual String get_type() const override
Writes the type as String.
bool is_closed() const
Checks whether the curve is open or closed.
int get_orientation() const
Returns the orientation code for the curve.
void push_vertex(const WorldPoint &point)
Pushes a new vertex point to the spline.
void map_param(WorldPoint &point, const ParamPoint ¶m) const
Maps a single parameter point.
std::deque< WorldPoint > & get_world_points()
Returns a (const) reference to the internal world points deque.
std::deque< std::size_t > & get_vertex_pointers()
Returns a (const) reference to the internal vertex pointers deque.
virtual bool content(int iline, const String &sline) override
Called to process a content line.
virtual void close(int iline, const String &sline) override
Closes this markup parser node.
virtual bool attribs(std::map< String, bool > &) const override
Specifies the mandatory and optional attributes.
virtual void create(int iline, const String &sline, const String &, const std::map< String, String > &, bool closed) override
Creates this markup parser node.
virtual std::shared_ptr< MarkupParser > markup(int, const String &, const String &) override
Called to process a child markup node.
virtual void create(int iline, const String &sline, const String &, const std::map< String, String > &, bool closed) override
Creates this markup parser node.
virtual bool attribs(std::map< String, bool > &) const override
Specifies the mandatory and optional attributes.
virtual void close(int iline, const String &sline) override
Closes this markup parser node.
virtual std::shared_ptr< MarkupParser > markup(int, const String &, const String &) override
Called to process a child markup node.
virtual bool content(int iline, const String &sline) override
Called to process a content line.
Chart CRTP base-class template.
static constexpr int world_dim
the world dimension of this chart
BaseClass::WorldPoint WorldPoint
our world point type
VertexSetType::CoordType CoordType
coordinate type
Class template for partial meshes.
Index get_num_entities(int dim) const
Returns the number of entities.
String class implementation.
bool parse(T_ &t) const
Parses the string and stores its value in the provided variable.
std::deque< String > split_by_whitespaces() const
Splits the string by white-spaces.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_rotation_2d(T_ angle)
Sets this matrix to a 2D rotation matrix.
Tiny Vector class template.
XML Markup Parser interface.
T_ sqrt(T_ x)
Returns the square-root of a value.
T_ abs(T_ x)
Returns the absolute value.
T_ clamp(T_ x, T_ a, T_ b)
Clamps a value to a range.
T_ sqr(T_ x)
Returns the square of a value.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ signum(T_ x)
Returns the sign of a value.
CUDA_HOST_DEVICE T_ dot(const T_ &a, const T_ &b)
Computes the dot-product of two scalars.
std::uint64_t Index
Index data type.
static constexpr bool is_explicit
we support explicit map
static constexpr int world_dim
this is a 2D object
static constexpr bool is_implicit
we don't support implicit project
static constexpr int param_dim
we have 1D parameters