2013-07-16 19:04:14 +00:00
|
|
|
#include "Point.hpp"
|
2013-11-06 22:08:03 +00:00
|
|
|
#include "Line.hpp"
|
2014-05-21 18:08:21 +00:00
|
|
|
#include "MultiPoint.hpp"
|
2018-05-17 08:37:26 +00:00
|
|
|
#include "Int128.hpp"
|
2020-11-20 14:19:49 +00:00
|
|
|
#include "BoundingBox.hpp"
|
2015-01-03 14:03:53 +00:00
|
|
|
#include <algorithm>
|
2013-07-16 19:04:14 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
|
2018-08-28 07:03:03 +00:00
|
|
|
std::vector<Vec3f> transform(const std::vector<Vec3f>& points, const Transform3f& t)
|
|
|
|
{
|
|
|
|
unsigned int vertices_count = (unsigned int)points.size();
|
|
|
|
if (vertices_count == 0)
|
|
|
|
return std::vector<Vec3f>();
|
|
|
|
|
|
|
|
unsigned int data_size = 3 * vertices_count * sizeof(float);
|
|
|
|
|
|
|
|
Eigen::MatrixXf src(3, vertices_count);
|
|
|
|
::memcpy((void*)src.data(), (const void*)points.data(), data_size);
|
|
|
|
|
|
|
|
Eigen::MatrixXf dst(3, vertices_count);
|
|
|
|
dst = t * src.colwise().homogeneous();
|
|
|
|
|
|
|
|
std::vector<Vec3f> ret_points(vertices_count, Vec3f::Zero());
|
|
|
|
::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size);
|
|
|
|
return ret_points;
|
|
|
|
}
|
|
|
|
|
|
|
|
Pointf3s transform(const Pointf3s& points, const Transform3d& t)
|
|
|
|
{
|
|
|
|
unsigned int vertices_count = (unsigned int)points.size();
|
|
|
|
if (vertices_count == 0)
|
|
|
|
return Pointf3s();
|
|
|
|
|
|
|
|
unsigned int data_size = 3 * vertices_count * sizeof(double);
|
|
|
|
|
|
|
|
Eigen::MatrixXd src(3, vertices_count);
|
|
|
|
::memcpy((void*)src.data(), (const void*)points.data(), data_size);
|
|
|
|
|
|
|
|
Eigen::MatrixXd dst(3, vertices_count);
|
|
|
|
dst = t * src.colwise().homogeneous();
|
|
|
|
|
|
|
|
Pointf3s ret_points(vertices_count, Vec3d::Zero());
|
|
|
|
::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size);
|
|
|
|
return ret_points;
|
|
|
|
}
|
|
|
|
|
2018-08-14 19:33:41 +00:00
|
|
|
void Point::rotate(double angle, const Point ¢er)
|
2013-07-16 19:04:14 +00:00
|
|
|
{
|
2018-08-17 13:53:43 +00:00
|
|
|
double cur_x = (double)(*this)(0);
|
|
|
|
double cur_y = (double)(*this)(1);
|
2018-08-15 11:51:40 +00:00
|
|
|
double s = ::sin(angle);
|
|
|
|
double c = ::cos(angle);
|
2018-08-17 13:53:43 +00:00
|
|
|
double dx = cur_x - (double)center(0);
|
|
|
|
double dy = cur_y - (double)center(1);
|
|
|
|
(*this)(0) = (coord_t)round( (double)center(0) + c * dx - s * dy );
|
|
|
|
(*this)(1) = (coord_t)round( (double)center(1) + c * dy + s * dx );
|
2013-07-16 19:04:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-24 12:07:46 +00:00
|
|
|
bool has_duplicate_points(std::vector<Point> &&pts)
|
|
|
|
{
|
|
|
|
std::sort(pts.begin(), pts.end());
|
|
|
|
for (size_t i = 1; i < pts.size(); ++ i)
|
|
|
|
if (pts[i - 1] == pts[i])
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-11-29 12:52:47 +00:00
|
|
|
Points collect_duplicates(Points pts /* Copy */)
|
2022-08-25 11:28:10 +00:00
|
|
|
{
|
2022-11-29 12:58:41 +00:00
|
|
|
std::sort(pts.begin(), pts.end());
|
2022-08-25 11:28:10 +00:00
|
|
|
Points duplicits;
|
|
|
|
const Point *prev = &pts.front();
|
|
|
|
for (size_t i = 1; i < pts.size(); ++i) {
|
|
|
|
const Point *act = &pts[i];
|
|
|
|
if (*prev == *act) {
|
|
|
|
// duplicit point
|
|
|
|
if (!duplicits.empty() && duplicits.back() == *act)
|
|
|
|
continue; // only unique duplicits
|
|
|
|
duplicits.push_back(*act);
|
|
|
|
}
|
|
|
|
prev = act;
|
|
|
|
}
|
|
|
|
return duplicits;
|
|
|
|
}
|
|
|
|
|
2020-11-16 09:20:47 +00:00
|
|
|
BoundingBox get_extents(const Points &pts)
|
|
|
|
{
|
|
|
|
return BoundingBox(pts);
|
|
|
|
}
|
|
|
|
|
|
|
|
BoundingBox get_extents(const std::vector<Points> &pts)
|
|
|
|
{
|
|
|
|
BoundingBox bbox;
|
|
|
|
for (const Points &p : pts)
|
|
|
|
bbox.merge(get_extents(p));
|
|
|
|
return bbox;
|
|
|
|
}
|
|
|
|
|
New BuildVolume class was created, which detects build volume type (rectangular,
circular, convex, concave) and performs efficient collision detection agains these build
volumes. As of now, collision detection is performed against a convex
hull of a concave build volume for efficency.
GCodeProcessor::Result renamed out of GCodeProcessor to GCodeProcessorResult,
so it could be forward declared.
Plater newly exports BuildVolume, not Bed3D. Bed3D is a rendering class,
while BuildVolume is a purely geometric class.
Reduced usage of global wxGetApp, the Bed3D is passed as a parameter
to View3D/Preview/GLCanvas.
Convex hull code was extracted from Geometry.cpp/hpp to Geometry/ConvexHulll.cpp,hpp.
New test inside_convex_polygon().
New efficent point inside polygon test: Decompose convex hull
to bottom / top parts and use the decomposition to detect point inside
a convex polygon in O(log n). decompose_convex_polygon_top_bottom(),
inside_convex_polygon().
New Circle constructing functions: circle_ransac() and circle_taubin_newton().
New polygon_is_convex() test with unit tests.
2021-11-16 09:15:51 +00:00
|
|
|
BoundingBoxf get_extents(const std::vector<Vec2d> &pts)
|
|
|
|
{
|
|
|
|
BoundingBoxf bbox;
|
|
|
|
for (const Vec2d &p : pts)
|
|
|
|
bbox.merge(p);
|
|
|
|
return bbox;
|
|
|
|
}
|
|
|
|
|
2022-11-14 18:01:17 +00:00
|
|
|
int nearest_point_index(const Points &points, const Point &pt)
|
|
|
|
{
|
|
|
|
int64_t distance = std::numeric_limits<int64_t>::max();
|
|
|
|
int idx = -1;
|
|
|
|
|
|
|
|
for (const Point &pt2 : points) {
|
|
|
|
// If the X distance of the candidate is > than the total distance of the
|
|
|
|
// best previous candidate, we know we don't want it.
|
|
|
|
int64_t d = sqr<int64_t>(pt2.x() - pt.x());
|
|
|
|
if (d < distance) {
|
|
|
|
// If the Y distance of the candidate is > than the total distance of the
|
|
|
|
// best previous candidate, we know we don't want it.
|
|
|
|
d += sqr<int64_t>(pt2.y() - pt.y());
|
|
|
|
if (d < distance) {
|
|
|
|
idx = &pt2 - points.data();
|
|
|
|
distance = d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
2018-08-21 19:05:24 +00:00
|
|
|
std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf)
|
2015-05-02 19:43:22 +00:00
|
|
|
{
|
2018-08-17 13:53:43 +00:00
|
|
|
return stm << pointf(0) << "," << pointf(1);
|
2015-05-02 19:43:22 +00:00
|
|
|
}
|
|
|
|
|
2018-05-17 08:37:26 +00:00
|
|
|
namespace int128 {
|
|
|
|
|
2018-08-17 14:54:07 +00:00
|
|
|
int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3)
|
2018-05-17 08:37:26 +00:00
|
|
|
{
|
|
|
|
Slic3r::Vector v1(p2 - p1);
|
|
|
|
Slic3r::Vector v2(p3 - p1);
|
2021-05-19 10:01:30 +00:00
|
|
|
return Int128::sign_determinant_2x2_filtered(v1.x(), v1.y(), v2.x(), v2.y());
|
2018-05-17 08:37:26 +00:00
|
|
|
}
|
|
|
|
|
2018-08-17 14:54:07 +00:00
|
|
|
int cross(const Vec2crd &v1, const Vec2crd &v2)
|
2018-05-17 08:37:26 +00:00
|
|
|
{
|
2021-05-19 10:01:30 +00:00
|
|
|
return Int128::sign_determinant_2x2_filtered(v1.x(), v1.y(), v2.x(), v2.y());
|
2018-05-17 08:37:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-07-16 19:04:14 +00:00
|
|
|
}
|