mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Added Geometry::Transformation class. Use it into ModelInstance, ModelVolume and GLVolume
This commit is contained in:
		
							parent
							
								
									7f08f460f1
								
							
						
					
					
						commit
						d6d632d4fc
					
				
					 8 changed files with 449 additions and 8 deletions
				
			
		|  | @ -1,3 +1,4 @@ | |||
| #include "libslic3r.h" | ||||
| #include "Geometry.hpp" | ||||
| #include "ClipperUtils.hpp" | ||||
| #include "ExPolygon.hpp" | ||||
|  | @ -369,12 +370,6 @@ contains(const std::vector<T> &vector, const Point &point) | |||
| } | ||||
| template bool contains(const ExPolygons &vector, const Point &point); | ||||
| 
 | ||||
| double | ||||
| rad2deg(double angle) | ||||
| { | ||||
|     return angle / PI * 180.0; | ||||
| } | ||||
| 
 | ||||
| double | ||||
| rad2deg_dir(double angle) | ||||
| { | ||||
|  | @ -1232,4 +1227,161 @@ Vec3d extract_euler_angles(const Transform3d& transform) | |||
|     return extract_euler_angles(m); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
| Transformation::Flags::Flags() | ||||
|     : dont_translate(true) | ||||
|     , dont_rotate(true) | ||||
|     , dont_scale(true) | ||||
| #if ENABLE_MIRROR | ||||
|     , dont_mirror(true) | ||||
| #endif // ENABLE_MIRROR
 | ||||
| { | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
| bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const | ||||
| { | ||||
|     return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror); | ||||
| } | ||||
| 
 | ||||
| void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) | ||||
| { | ||||
|     this->dont_translate = dont_translate; | ||||
|     this->dont_rotate = dont_rotate; | ||||
|     this->dont_scale = dont_scale; | ||||
|     this->dont_mirror = dont_mirror; | ||||
| } | ||||
| #else | ||||
| bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const | ||||
| { | ||||
|     return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale); | ||||
| } | ||||
| 
 | ||||
| void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale) | ||||
| { | ||||
|     this->dont_translate = dont_translate; | ||||
|     this->dont_rotate = dont_rotate; | ||||
|     this->dont_scale = dont_scale; | ||||
| } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
| Transformation::Transformation() | ||||
|     : m_offset(Vec3d::Zero()) | ||||
|     , m_rotation(Vec3d::Zero()) | ||||
|     , m_scaling_factor(Vec3d::Ones()) | ||||
| #if ENABLE_MIRROR | ||||
|     , m_mirror(Vec3d::Ones()) | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     , m_matrix(Transform3d::Identity()) | ||||
|     , m_dirty(false) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_offset(const Vec3d& offset) | ||||
| { | ||||
|     set_offset(X, offset(0)); | ||||
|     set_offset(Y, offset(1)); | ||||
|     set_offset(Z, offset(2)); | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_offset(Axis axis, double offset) | ||||
| { | ||||
|     if (m_offset(axis) != offset) | ||||
|     { | ||||
|         m_offset(axis) = offset; | ||||
|         m_dirty = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_rotation(const Vec3d& rotation) | ||||
| { | ||||
|     set_rotation(X, rotation(0)); | ||||
|     set_rotation(Y, rotation(1)); | ||||
|     set_rotation(Z, rotation(2)); | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_rotation(Axis axis, double rotation) | ||||
| { | ||||
|     rotation = angle_to_0_2PI(rotation); | ||||
| 
 | ||||
|     if (m_rotation(axis) = rotation) | ||||
|     { | ||||
|         m_rotation(axis) = rotation; | ||||
|         m_dirty = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_scaling_factor(const Vec3d& scaling_factor) | ||||
| { | ||||
|     set_scaling_factor(X, scaling_factor(0)); | ||||
|     set_scaling_factor(Y, scaling_factor(1)); | ||||
|     set_scaling_factor(Z, scaling_factor(2)); | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_scaling_factor(Axis axis, double scaling_factor) | ||||
| { | ||||
|     if (m_scaling_factor(axis) != std::abs(scaling_factor)) | ||||
|     { | ||||
|         m_scaling_factor(axis) = std::abs(scaling_factor); | ||||
|         m_dirty = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_mirror(const Vec3d& mirror) | ||||
| { | ||||
|     set_mirror(X, mirror(0)); | ||||
|     set_mirror(Y, mirror(1)); | ||||
|     set_mirror(Z, mirror(2)); | ||||
| } | ||||
| 
 | ||||
| void Transformation::set_mirror(Axis axis, double mirror) | ||||
| { | ||||
|     double abs_mirror = std::abs(mirror); | ||||
|     if (abs_mirror == 0.0) | ||||
|         mirror = 1.0; | ||||
|     else if (abs_mirror != 1.0) | ||||
|         mirror /= abs_mirror; | ||||
| 
 | ||||
|     if (m_mirror(axis) != mirror) | ||||
|     { | ||||
|         m_mirror(axis) = mirror; | ||||
|         m_dirty = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
| const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const | ||||
| #else | ||||
| const Transform3d& Transformation::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const | ||||
| #endif // ENABLE_MIRROR
 | ||||
| { | ||||
| #if ENABLE_MIRROR | ||||
|     if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror)) | ||||
| #else | ||||
|     if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale)) | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     { | ||||
|         Vec3d translation = dont_translate ? Vec3d::Zero() : m_offset; | ||||
|         Vec3d rotation = dont_rotate ? Vec3d::Zero() : m_rotation; | ||||
|         Vec3d scale = dont_scale ? Vec3d::Ones() : m_scaling_factor; | ||||
| #if ENABLE_MIRROR | ||||
|         Vec3d mirror = dont_mirror ? Vec3d::Ones() : m_mirror; | ||||
|         m_matrix = Geometry::assemble_transform(translation, rotation, scale, mirror); | ||||
| #else | ||||
|         m_matrix = Geometry::assemble_transform(translation, rotation, scale); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|         m_flags.set(dont_translate, dont_rotate, dont_scale, dont_mirror); | ||||
| #else | ||||
|         m_flags.set(dont_translate, dont_rotate, dont_scale); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|         m_dirty = false; | ||||
|     } | ||||
| 
 | ||||
|     return m_matrix; | ||||
| } | ||||
| 
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| } } | ||||
|  |  | |||
|  | @ -117,9 +117,23 @@ void chained_path(const Points &points, std::vector<Points::size_type> &retval); | |||
| template<class T> void chained_path_items(Points &points, T &items, T &retval); | ||||
| bool directions_parallel(double angle1, double angle2, double max_diff = 0); | ||||
| template<class T> bool contains(const std::vector<T> &vector, const Point &point); | ||||
| double rad2deg(double angle); | ||||
| template<typename T> T rad2deg(T angle) { return T(180.0) * angle / T(PI); } | ||||
| double rad2deg_dir(double angle); | ||||
| template<typename T> T deg2rad(T angle) { return T(PI) * angle / T(180.0); } | ||||
| template<typename T> T angle_to_0_2PI(T angle) | ||||
| { | ||||
|     static const T TWO_PI = T(2) * T(PI); | ||||
|     while (angle < T(0)) | ||||
|     { | ||||
|         angle += TWO_PI; | ||||
|     } | ||||
|     while (TWO_PI < angle) | ||||
|     { | ||||
|         angle -= TWO_PI; | ||||
|     } | ||||
| 
 | ||||
|     return angle; | ||||
| } | ||||
| void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* retval); | ||||
| 
 | ||||
| double linint(double value, double oldmin, double oldmax, double newmin, double newmax); | ||||
|  | @ -200,6 +214,79 @@ Vec3d extract_euler_angles(const Eigen::Matrix<double, 3, 3, Eigen::DontAlign>& | |||
| // Returns the euler angles extracted from the given affine transform
 | ||||
| // Warning -> The transform should not contain any shear !!!
 | ||||
| Vec3d extract_euler_angles(const Transform3d& transform); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
| class Transformation | ||||
| { | ||||
|     struct Flags | ||||
|     { | ||||
|         bool dont_translate; | ||||
|         bool dont_rotate; | ||||
|         bool dont_scale; | ||||
| #if ENABLE_MIRROR | ||||
|         bool dont_mirror; | ||||
| #endif // ENABLE_MIRROR
 | ||||
| 
 | ||||
|         Flags(); | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|         bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const; | ||||
|         void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror); | ||||
| #else | ||||
|         bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale) const; | ||||
|         void set(bool dont_translate, bool dont_rotate, bool dont_scale); | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     }; | ||||
| 
 | ||||
|     Vec3d m_offset;              // In unscaled coordinates
 | ||||
|     Vec3d m_rotation;            // Rotation around the three axes, in radians around mesh center point
 | ||||
|     Vec3d m_scaling_factor;      // Scaling factors along the three axes
 | ||||
| #if ENABLE_MIRROR | ||||
|     Vec3d m_mirror;              // Mirroring along the three axes
 | ||||
| #endif // ENABLE_MIRROR
 | ||||
|     mutable Transform3d m_matrix; | ||||
| 
 | ||||
|     mutable Flags m_flags; | ||||
|     mutable bool m_dirty; | ||||
| 
 | ||||
| public: | ||||
|     Transformation(); | ||||
| 
 | ||||
|     const Vec3d& get_offset() const { return m_offset; } | ||||
|     double get_offset(Axis axis) const { return m_offset(axis); } | ||||
| 
 | ||||
|     void set_offset(const Vec3d& offset); | ||||
|     void set_offset(Axis axis, double offset); | ||||
| 
 | ||||
|     const Vec3d& get_rotation() const { return m_rotation; } | ||||
|     double get_rotation(Axis axis) const { return m_rotation(axis); } | ||||
| 
 | ||||
|     void set_rotation(const Vec3d& rotation); | ||||
|     void set_rotation(Axis axis, double rotation); | ||||
| 
 | ||||
|     Vec3d get_scaling_factor() const { return m_scaling_factor; } | ||||
|     double get_scaling_factor(Axis axis) const { return m_scaling_factor(axis); } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|     void set_scaling_factor(const Vec3d& scaling_factor); | ||||
|     void set_scaling_factor(Axis axis, double scaling_factor); | ||||
| 
 | ||||
|     const Vec3d& get_mirror() const { return m_mirror; } | ||||
|     double get_mirror(Axis axis) const { return m_mirror(axis); } | ||||
| 
 | ||||
|     void set_mirror(const Vec3d& mirror); | ||||
|     void set_mirror(Axis axis, double mirror); | ||||
| 
 | ||||
|     const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; | ||||
| #else | ||||
|     void set_scaling_factor(const Vec3d& scaling_factor) { m_scaling_factor = scaling_factor; } | ||||
|     void set_scaling_factor(Axis axis, double scaling_factor) { m_scaling_factor(axis) = scaling_factor; } | ||||
| 
 | ||||
|     const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const; | ||||
| #endif // ENABLE_MIRROR
 | ||||
| }; | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| } } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1124,6 +1124,7 @@ size_t ModelVolume::split(unsigned int max_extruders) | |||
|     return idx; | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_MODELVOLUME_TRANSFORM | ||||
| void ModelInstance::set_rotation(const Vec3d& rotation) | ||||
| { | ||||
|     set_rotation(X, rotation(0)); | ||||
|  | @ -1176,6 +1177,7 @@ void ModelInstance::set_mirror(Axis axis, double mirror) | |||
|     m_mirror(axis) = mirror; | ||||
| } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // !ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const | ||||
| { | ||||
|  | @ -1197,17 +1199,29 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes | |||
|         // Scale the bounding box along the three axes.
 | ||||
|         for (unsigned int i = 0; i < 3; ++i) | ||||
|         { | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|             if (std::abs(m_transformation.get_scaling_factor((Axis)i)-1.0) > EPSILON) | ||||
|             { | ||||
|                 bbox.min(i) *= m_transformation.get_scaling_factor((Axis)i); | ||||
|                 bbox.max(i) *= m_transformation.get_scaling_factor((Axis)i); | ||||
| #else | ||||
|             if (std::abs(this->m_scaling_factor(i) - 1.0) > EPSILON) | ||||
|             { | ||||
|                 bbox.min(i) *= this->m_scaling_factor(i); | ||||
|                 bbox.max(i) *= this->m_scaling_factor(i); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Translate the bounding box.
 | ||||
|         if (! dont_translate) { | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|             bbox.min += m_transformation.get_offset(); | ||||
|             bbox.max += m_transformation.get_offset(); | ||||
| #else | ||||
|             bbox.min += this->m_offset; | ||||
|             bbox.max += this->m_offset; | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|         } | ||||
|     } | ||||
|     return bbox; | ||||
|  | @ -1225,12 +1239,20 @@ Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const | |||
| 
 | ||||
| void ModelInstance::transform_polygon(Polygon* polygon) const | ||||
| { | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     // CHECK_ME -> Is the following correct or it should take in account all three rotations ?
 | ||||
|     polygon->rotate(m_transformation.get_rotation(Z)); // rotate around polygon origin
 | ||||
|     // CHECK_ME -> Is the following correct ?
 | ||||
|     polygon->scale(m_transformation.get_scaling_factor(X), m_transformation.get_scaling_factor(Y)); // scale around polygon origin
 | ||||
| #else | ||||
|     // CHECK_ME -> Is the following correct or it should take in account all three rotations ?
 | ||||
|     polygon->rotate(this->m_rotation(2));                // rotate around polygon origin
 | ||||
|     // CHECK_ME -> Is the following correct ?
 | ||||
|     polygon->scale(this->m_scaling_factor(0), this->m_scaling_factor(1));           // scale around polygon origin
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_MODELVOLUME_TRANSFORM | ||||
| #if ENABLE_MIRROR | ||||
| Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const | ||||
| #else | ||||
|  | @ -1247,5 +1269,6 @@ Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, b | |||
|     return Geometry::assemble_transform(translation, rotation, scale); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| } | ||||
| #endif // !ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ | |||
| #include <string> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
| #include "Geometry.hpp" | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -210,6 +213,10 @@ class ModelVolume : public ModelBase | |||
|     // The convex hull of this model's mesh.
 | ||||
|     TriangleMesh        m_convex_hull; | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     Geometry::Transformation m_transformation; | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| public: | ||||
|     std::string         name; | ||||
|     // The triangular model.
 | ||||
|  | @ -257,6 +264,34 @@ public: | |||
|     static Type         type_from_string(const std::string &s); | ||||
|     static std::string  type_to_string(const Type t); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     const Vec3d& get_offset() const { return m_transformation.get_offset(); } | ||||
|     double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } | ||||
| 
 | ||||
|     void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } | ||||
|     void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } | ||||
| 
 | ||||
|     const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } | ||||
|     double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } | ||||
| 
 | ||||
|     void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } | ||||
|     void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } | ||||
| 
 | ||||
|     Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } | ||||
|     double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } | ||||
| 
 | ||||
|     void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } | ||||
|     void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|     const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } | ||||
|     double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } | ||||
| 
 | ||||
|     void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } | ||||
|     void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| private: | ||||
|     // Parent object owning this ModelVolume.
 | ||||
|     ModelObject*            object; | ||||
|  | @ -306,12 +341,16 @@ public: | |||
|     friend class ModelObject; | ||||
| 
 | ||||
| private: | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     Geometry::Transformation m_transformation; | ||||
| #else | ||||
|     Vec3d m_offset;              // in unscaled coordinates
 | ||||
|     Vec3d m_rotation;            // Rotation around the three axes, in radians around mesh center point
 | ||||
|     Vec3d m_scaling_factor;      // Scaling factors along the three axes
 | ||||
| #if ENABLE_MIRROR | ||||
|     Vec3d m_mirror;              // Mirroring along the three axes
 | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| public: | ||||
|     // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state())
 | ||||
|  | @ -319,6 +358,36 @@ public: | |||
| 
 | ||||
|     ModelObject* get_object() const { return this->object; } | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     const Geometry::Transformation& get_transformation() const { return m_transformation; } | ||||
|     void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } | ||||
| 
 | ||||
|     const Vec3d& get_offset() const { return m_transformation.get_offset(); } | ||||
|     double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } | ||||
| 
 | ||||
|     void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } | ||||
|     void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } | ||||
| 
 | ||||
|     const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } | ||||
|     double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } | ||||
| 
 | ||||
|     void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } | ||||
|     void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } | ||||
| 
 | ||||
|     Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } | ||||
|     double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } | ||||
| 
 | ||||
|     void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } | ||||
|     void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|     const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } | ||||
|     double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } | ||||
| 
 | ||||
|     void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } | ||||
|     void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #else | ||||
|     const Vec3d& get_offset() const { return m_offset; } | ||||
|     double get_offset(Axis axis) const { return m_offset(axis); } | ||||
| 
 | ||||
|  | @ -349,6 +418,7 @@ public: | |||
|     void set_mirror(const Vec3d& mirror); | ||||
|     void set_mirror(Axis axis, double mirror); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     // To be called on an external mesh
 | ||||
|     void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const; | ||||
|  | @ -361,11 +431,19 @@ public: | |||
|     // To be called on an external polygon. It does not translate the polygon, only rotates and scales.
 | ||||
|     void transform_polygon(Polygon* polygon) const; | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
| #if ENABLE_MIRROR | ||||
|     const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } | ||||
| #else | ||||
|     const Transform3d& world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const { return m_transformation.world_matrix(dont_translate, dont_rotate, dont_scale); } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #else | ||||
| #if ENABLE_MIRROR | ||||
|     Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; | ||||
| #else | ||||
|     Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const; | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     bool is_printable() const { return print_volume_state == PVS_Inside; } | ||||
| 
 | ||||
|  | @ -373,6 +451,11 @@ private: | |||
|     // Parent object, owning this instance.
 | ||||
|     ModelObject* object; | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     ModelInstance(ModelObject *object) : object(object), print_volume_state(PVS_Inside) {} | ||||
|     ModelInstance(ModelObject *object, const ModelInstance &other) : | ||||
|         m_transformation(other.m_transformation), object(object), print_volume_state(PVS_Inside) {} | ||||
| #else | ||||
| #if ENABLE_MIRROR | ||||
|     ModelInstance(ModelObject *object) : m_offset(Vec3d::Zero()), m_rotation(Vec3d::Zero()), m_scaling_factor(Vec3d::Ones()), m_mirror(Vec3d::Ones()), object(object), print_volume_state(PVS_Inside) {} | ||||
|     ModelInstance(ModelObject *object, const ModelInstance &other) : | ||||
|  | @ -382,6 +465,7 @@ private: | |||
|     ModelInstance(ModelObject *object, const ModelInstance &other) : | ||||
|         m_rotation(other.m_rotation), m_scaling_factor(other.m_scaling_factor), m_offset(other.m_offset), object(object), print_volume_state(PVS_Inside) {} | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     explicit ModelInstance(ModelInstance &rhs) = delete; | ||||
|     ModelInstance& operator=(ModelInstance &rhs) = delete; | ||||
|  |  | |||
|  | @ -24,6 +24,8 @@ | |||
| #define ENABLE_MIRROR (1 && ENABLE_1_42_0) | ||||
| // Modified camera target behavior
 | ||||
| #define ENABLE_MODIFIED_CAMERA_TARGET (1 && ENABLE_1_42_0) | ||||
| // Add Geometry::Transformation class and use it into ModelInstance, ModelVolume and GLVolume
 | ||||
| #define ENABLE_MODELVOLUME_TRANSFORM (1 && ENABLE_1_42_0) | ||||
| 
 | ||||
| #endif // _technologies_h_
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -195,6 +195,9 @@ const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f }; | |||
| const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f }; | ||||
| 
 | ||||
| GLVolume::GLVolume(float r, float g, float b, float a) | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     : m_transformed_bounding_box_dirty(true) | ||||
| #else | ||||
|     : m_offset(Vec3d::Zero()) | ||||
|     , m_rotation(Vec3d::Zero()) | ||||
|     , m_scaling_factor(Vec3d::Ones()) | ||||
|  | @ -204,6 +207,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) | |||
|     , m_world_matrix(Transform3f::Identity()) | ||||
|     , m_world_matrix_dirty(true) | ||||
|     , m_transformed_bounding_box_dirty(true) | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|     , m_transformed_convex_hull_bounding_box_dirty(true) | ||||
|     , m_convex_hull(nullptr) | ||||
|     , composite_id(-1) | ||||
|  | @ -260,6 +264,7 @@ void GLVolume::set_render_color() | |||
|         set_render_color(color, 4); | ||||
| } | ||||
| 
 | ||||
| #if !ENABLE_MODELVOLUME_TRANSFORM | ||||
| const Vec3d& GLVolume::get_rotation() const | ||||
| { | ||||
|     return m_rotation; | ||||
|  | @ -360,6 +365,7 @@ void GLVolume::set_mirror(Axis axis, double mirror) | |||
|     } | ||||
| } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // !ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| void GLVolume::set_convex_hull(const TriangleMesh& convex_hull) | ||||
| { | ||||
|  | @ -386,6 +392,7 @@ void GLVolume::set_drag_group_id(const std::string& drag_by) | |||
| } | ||||
| #endif // !ENABLE_EXTENDED_SELECTION
 | ||||
| 
 | ||||
| #if !ENABLE_MODELVOLUME_TRANSFORM | ||||
| const Transform3f& GLVolume::world_matrix() const | ||||
| { | ||||
|     if (m_world_matrix_dirty) | ||||
|  | @ -399,12 +406,17 @@ const Transform3f& GLVolume::world_matrix() const | |||
|     } | ||||
|     return m_world_matrix; | ||||
| } | ||||
| #endif // !ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| const BoundingBoxf3& GLVolume::transformed_bounding_box() const | ||||
| { | ||||
|     if (m_transformed_bounding_box_dirty) | ||||
|     { | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|         m_transformed_bounding_box = bounding_box.transformed(world_matrix()); | ||||
| #else | ||||
|         m_transformed_bounding_box = bounding_box.transformed(world_matrix().cast<double>()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|         m_transformed_bounding_box_dirty = false; | ||||
|     } | ||||
| 
 | ||||
|  | @ -415,10 +427,17 @@ const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const | |||
| { | ||||
|     if (m_transformed_convex_hull_bounding_box_dirty) | ||||
|     { | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|         if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) | ||||
|             m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix()); | ||||
|         else | ||||
|             m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix()); | ||||
| #else | ||||
|         if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0)) | ||||
|             m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix().cast<double>()); | ||||
|         else | ||||
|             m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix().cast<double>()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|         m_transformed_convex_hull_bounding_box_dirty = false; | ||||
|     } | ||||
|  | @ -469,7 +488,11 @@ void GLVolume::render() const | |||
|     ::glCullFace(GL_BACK); | ||||
|     ::glPushMatrix(); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     ::glMultMatrixd(world_matrix().data()); | ||||
| #else | ||||
|     ::glMultMatrixf(world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|     if (this->indexed_vertex_array.indexed()) | ||||
|         this->indexed_vertex_array.render(this->tverts_range, this->qverts_range); | ||||
|     else | ||||
|  | @ -507,7 +530,11 @@ void GLVolume::render_using_layer_height() const | |||
|         glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width); | ||||
| 
 | ||||
|     if (world_matrix_id >= 0) | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|         ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()); | ||||
| #else | ||||
|         ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     GLsizei w = (GLsizei)layer_height_texture_width(); | ||||
|     GLsizei h = (GLsizei)layer_height_texture_height(); | ||||
|  | @ -567,7 +594,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c | |||
|             ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); | ||||
| 
 | ||||
|         if (worldmatrix_id != -1) | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|             ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()); | ||||
| #else | ||||
|             ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|         render(); | ||||
| 
 | ||||
|  | @ -586,7 +617,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c | |||
|         ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0); | ||||
| 
 | ||||
|     if (worldmatrix_id != -1) | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|         ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()); | ||||
| #else | ||||
|         ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); | ||||
|     ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); | ||||
|  | @ -594,7 +629,11 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c | |||
| 
 | ||||
|     ::glPushMatrix(); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     ::glMultMatrixd(world_matrix().data()); | ||||
| #else | ||||
|     ::glMultMatrixf(world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     if (n_triangles > 0) | ||||
|     { | ||||
|  | @ -638,7 +677,11 @@ void GLVolume::render_legacy() const | |||
| 
 | ||||
|     ::glPushMatrix(); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     ::glMultMatrixd(world_matrix().data()); | ||||
| #else | ||||
|     ::glMultMatrixf(world_matrix().data()); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     if (n_triangles > 0) | ||||
|         ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first); | ||||
|  | @ -767,12 +810,16 @@ std::vector<int> GLVolumeCollection::load_object( | |||
|             } | ||||
|             v.is_modifier = ! model_volume->is_model_part(); | ||||
|             v.shader_outside_printer_detection_enabled = model_volume->is_model_part(); | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|             v.set_transformation(instance->get_transformation()); | ||||
| #else | ||||
|             v.set_offset(instance->get_offset()); | ||||
|             v.set_rotation(instance->get_rotation()); | ||||
|             v.set_scaling_factor(instance->get_scaling_factor()); | ||||
| #if ENABLE_MIRROR | ||||
|             v.set_mirror(instance->get_mirror()); | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  |  | |||
|  | @ -254,6 +254,9 @@ public: | |||
|     GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {} | ||||
| 
 | ||||
| private: | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     Geometry::Transformation m_transformation; | ||||
| #else | ||||
|     // Offset of the volume to be rendered.
 | ||||
|     Vec3d                 m_offset; | ||||
|     // Rotation around three axes of the volume to be rendered.
 | ||||
|  | @ -268,6 +271,7 @@ private: | |||
|     mutable Transform3f   m_world_matrix; | ||||
|     // Whether or not is needed to recalculate the world matrix.
 | ||||
|     mutable bool          m_world_matrix_dirty; | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|     // Bounding box of this volume, in unscaled coordinates.
 | ||||
|     mutable BoundingBoxf3 m_transformed_bounding_box; | ||||
|     // Whether or not is needed to recalculate the transformed bounding box.
 | ||||
|  | @ -280,7 +284,6 @@ private: | |||
|     mutable bool          m_transformed_convex_hull_bounding_box_dirty; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     // Bounding box of this volume, in unscaled coordinates.
 | ||||
|     BoundingBoxf3       bounding_box; | ||||
|     // Color of the triangles / quads held by this volume.
 | ||||
|  | @ -333,6 +336,36 @@ public: | |||
|     // Sets render color in dependence of current state
 | ||||
|     void set_render_color(); | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     const Geometry::Transformation& get_transformation() const { return m_transformation; } | ||||
|     void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; set_bounding_boxes_as_dirty(); } | ||||
| 
 | ||||
|     const Vec3d& get_offset() const { return m_transformation.get_offset(); } | ||||
|     double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } | ||||
| 
 | ||||
|     void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); } | ||||
|     void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); } | ||||
| 
 | ||||
|     const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } | ||||
|     double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } | ||||
| 
 | ||||
|     void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); } | ||||
|     void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); } | ||||
| 
 | ||||
|     Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } | ||||
|     double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } | ||||
| 
 | ||||
|     void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); } | ||||
|     void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); } | ||||
| 
 | ||||
| #if ENABLE_MIRROR | ||||
|     const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } | ||||
|     double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } | ||||
| 
 | ||||
|     void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); } | ||||
|     void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); set_bounding_boxes_as_dirty(); } | ||||
| #endif // ENABLE_MIRROR
 | ||||
| #else | ||||
|     const Vec3d& get_rotation() const; | ||||
|     void set_rotation(const Vec3d& rotation); | ||||
| 
 | ||||
|  | @ -350,6 +383,7 @@ public: | |||
| 
 | ||||
|     const Vec3d& get_offset() const; | ||||
|     void set_offset(const Vec3d& offset); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|     void set_convex_hull(const TriangleMesh& convex_hull); | ||||
| 
 | ||||
|  | @ -362,7 +396,11 @@ public: | |||
|     int                 volume_idx() const { return (this->composite_id / 1000) % 1000; } | ||||
|     int                 instance_idx() const { return this->composite_id % 1000; } | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     const Transform3d&   world_matrix() const { return m_transformation.world_matrix(); } | ||||
| #else | ||||
|     const Transform3f&   world_matrix() const; | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
|     const BoundingBoxf3& transformed_bounding_box() const; | ||||
|     const BoundingBoxf3& transformed_convex_hull_bounding_box() const; | ||||
| 
 | ||||
|  | @ -412,6 +450,10 @@ public: | |||
|     } | ||||
| 
 | ||||
|     void reset_layer_height_texture_data() { layer_height_texture_data.reset(); } | ||||
| 
 | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; } | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| }; | ||||
| 
 | ||||
| #if ENABLE_EXTENDED_SELECTION | ||||
|  |  | |||
|  | @ -926,7 +926,11 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const | |||
| 
 | ||||
|         // gets transform from first selected volume
 | ||||
|         const GLVolume* v = selection.get_volume(*idxs.begin()); | ||||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|         transform = v->world_matrix(); | ||||
| #else | ||||
|         transform = v->world_matrix().cast<double>(); | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
|         // gets angles from first selected volume
 | ||||
|         angles = v->get_rotation(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri