Faster gizmos update

This commit is contained in:
Enrico Turri 2018-06-21 08:37:04 +02:00
commit 550f6e307f
40 changed files with 1415 additions and 753 deletions

View file

@ -2,6 +2,8 @@
#include <algorithm>
#include <assert.h>
#include <Eigen/Dense>
namespace Slic3r {
template BoundingBoxBase<Point>::BoundingBoxBase(const std::vector<Point> &points);
@ -251,4 +253,41 @@ void BoundingBox::align_to_grid(const coord_t cell_size)
}
}
BoundingBoxf3 BoundingBoxf3::transformed(const std::vector<float>& matrix) const
{
Eigen::Matrix<float, 3, 8> vertices;
vertices(0, 0) = (float)min.x; vertices(1, 0) = (float)min.y; vertices(2, 0) = (float)min.z;
vertices(0, 1) = (float)max.x; vertices(1, 1) = (float)min.y; vertices(2, 1) = (float)min.z;
vertices(0, 2) = (float)max.x; vertices(1, 2) = (float)max.y; vertices(2, 2) = (float)min.z;
vertices(0, 3) = (float)min.x; vertices(1, 3) = (float)max.y; vertices(2, 3) = (float)min.z;
vertices(0, 4) = (float)min.x; vertices(1, 4) = (float)min.y; vertices(2, 4) = (float)max.z;
vertices(0, 5) = (float)max.x; vertices(1, 5) = (float)min.y; vertices(2, 5) = (float)max.z;
vertices(0, 6) = (float)max.x; vertices(1, 6) = (float)max.y; vertices(2, 6) = (float)max.z;
vertices(0, 7) = (float)min.x; vertices(1, 7) = (float)max.y; vertices(2, 7) = (float)max.z;
Eigen::Transform<float, 3, Eigen::Affine> m;
::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float));
Eigen::Matrix<float, 3, 8> transf_vertices = m * vertices.colwise().homogeneous();
float min_x = transf_vertices(0, 0);
float max_x = transf_vertices(0, 0);
float min_y = transf_vertices(1, 0);
float max_y = transf_vertices(1, 0);
float min_z = transf_vertices(2, 0);
float max_z = transf_vertices(2, 0);
for (int i = 1; i < 8; ++i)
{
min_x = std::min(min_x, transf_vertices(0, i));
max_x = std::max(max_x, transf_vertices(0, i));
min_y = std::min(min_y, transf_vertices(1, i));
max_y = std::max(max_y, transf_vertices(1, i));
min_z = std::min(min_z, transf_vertices(2, i));
max_z = std::max(max_z, transf_vertices(2, i));
}
return BoundingBoxf3(Pointf3((coordf_t)min_x, (coordf_t)min_y, (coordf_t)min_z), Pointf3((coordf_t)max_x, (coordf_t)max_y, (coordf_t)max_z));
}
}

View file

@ -148,6 +148,8 @@ public:
BoundingBoxf3() : BoundingBox3Base<Pointf3>() {};
BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base<Pointf3>(pmin, pmax) {};
BoundingBoxf3(const std::vector<Pointf3> &points) : BoundingBox3Base<Pointf3>(points) {};
BoundingBoxf3 transformed(const std::vector<float>& matrix) const;
};
template<typename VT>

View file

@ -1271,6 +1271,7 @@ namespace Slic3r {
if ((std::abs(sx - sy) > 0.00001) || (std::abs(sx - sz) > 0.00001))
return;
#if 0 // use quaternions
// rotations (extracted using quaternion)
double inv_sx = 1.0 / sx;
double inv_sy = 1.0 / sy;
@ -1331,6 +1332,25 @@ namespace Slic3r {
if (angle_z < 0.0)
angle_z += 2.0 * PI;
}
#else // use eigen library
double inv_sx = 1.0 / sx;
double inv_sy = 1.0 / sy;
double inv_sz = 1.0 / sz;
Eigen::Matrix3d m3x3;
m3x3 << (double)matrix(0, 0) * inv_sx, (double)matrix(0, 1) * inv_sy, (double)matrix(0, 2) * inv_sz,
(double)matrix(1, 0) * inv_sx, (double)matrix(1, 1) * inv_sy, (double)matrix(1, 2) * inv_sz,
(double)matrix(2, 0) * inv_sx, (double)matrix(2, 1) * inv_sy, (double)matrix(2, 2) * inv_sz;
Eigen::AngleAxisd rotation;
rotation.fromRotationMatrix(m3x3);
// invalid rotation axis, we currently handle only rotations around Z axis
if ((rotation.angle() != 0.0) && (rotation.axis() != Eigen::Vector3d::UnitZ()) && (rotation.axis() != -Eigen::Vector3d::UnitZ()))
return;
double angle_z = (rotation.axis() == Eigen::Vector3d::UnitZ()) ? rotation.angle() : -rotation.angle();
#endif
instance.offset.x = offset_x;
instance.offset.y = offset_y;

View file

@ -13,6 +13,7 @@
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/nowide/fstream.hpp>
#include <miniz/miniz_zip.h>
#if 0
@ -666,10 +667,21 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
// If bundle is not a null pointer, updates it if the amf file/archive contains config data
bool load_amf(const char *path, PresetBundle* bundle, Model *model)
{
if (boost::iends_with(path, ".zip.amf"))
return load_amf_archive(path, bundle, model);
else if (boost::iends_with(path, ".amf") || boost::iends_with(path, ".amf.xml"))
if (boost::iends_with(path, ".amf.xml"))
// backward compatibility with older slic3r output
return load_amf_file(path, bundle, model);
else if (boost::iends_with(path, ".amf"))
{
boost::nowide::ifstream file(path, boost::nowide::ifstream::binary);
if (!file.good())
return false;
std::string zip_mask(2, '\0');
file.read(const_cast<char*>(zip_mask.data()), 2);
file.close();
return (zip_mask == "PK") ? load_amf_archive(path, bundle, model) : load_amf_file(path, bundle, model);
}
else
return false;
}

View file

@ -14,6 +14,8 @@
#include <boost/nowide/iostream.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <Eigen/Dense>
namespace Slic3r {
unsigned int Model::s_auto_extruder_id = 1;
@ -603,10 +605,7 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
//========================================================================================================
const BoundingBoxf3& ModelObject::bounding_box() const
//const BoundingBoxf3& ModelObject::bounding_box()
//========================================================================================================
{
if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox;
@ -1048,32 +1047,16 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const
{
// rotate around mesh origin
double c = cos(this->rotation);
double s = sin(this->rotation);
Pointf3 pts[4] = {
bbox.min,
bbox.max,
Pointf3(bbox.min.x, bbox.max.y, bbox.min.z),
Pointf3(bbox.max.x, bbox.min.y, bbox.max.z)
};
BoundingBoxf3 out;
for (int i = 0; i < 4; ++ i) {
Pointf3 &v = pts[i];
double xold = v.x;
double yold = v.y;
v.x = float(c * xold - s * yold);
v.y = float(s * xold + c * yold);
v.x *= this->scaling_factor;
v.y *= this->scaling_factor;
v.z *= this->scaling_factor;
if (! dont_translate) {
v.x += this->offset.x;
v.y += this->offset.y;
}
out.merge(v);
}
return out;
Eigen::Transform<float, 3, Eigen::Affine> matrix = Eigen::Transform<float, 3, Eigen::Affine>::Identity();
if (!dont_translate)
matrix.translate(Eigen::Vector3f((float)offset.x, (float)offset.y, 0.0f));
matrix.rotate(Eigen::AngleAxisf(rotation, Eigen::Vector3f::UnitZ()));
matrix.scale(scaling_factor);
std::vector<float> m(16, 0.0f);
::memcpy((void*)m.data(), (const void*)matrix.data(), 16 * sizeof(float));
return bbox.transformed(m);
}
void ModelInstance::transform_polygon(Polygon* polygon) const

View file

@ -103,10 +103,7 @@ public:
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
// This bounding box is being cached.
//========================================================================================================
const BoundingBoxf3& bounding_box() const;
// const BoundingBoxf3& bounding_box();
//========================================================================================================
void invalidate_bounding_box() { m_bounding_box_valid = false; }
// Returns a snug bounding box of the transformed instances.
// This bounding box is not being cached.
@ -148,10 +145,9 @@ private:
// Parent object, owning this ModelObject.
Model *m_model;
// Bounding box, cached.
//========================================================================================================
mutable BoundingBoxf3 m_bounding_box;
mutable bool m_bounding_box_valid;
//========================================================================================================
};
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.

View file

@ -103,7 +103,7 @@ double Polygon::area() const
double a = 0.;
for (size_t i = 0, j = n - 1; i < n; ++i) {
a += double(points[j].x + points[i].x) * double(points[i].y - points[j].y);
a += ((double)points[j].x + (double)points[i].x) * ((double)points[i].y - (double)points[j].y);
j = i;
}
return 0.5 * a;