mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge remote-tracking branch 'origin/dev' into new_main_page_ui
This commit is contained in:
		
						commit
						b1d418a799
					
				
					 16 changed files with 287 additions and 585 deletions
				
			
		| 
						 | 
				
			
			@ -772,9 +772,9 @@ add_executable(slic3r EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slic3r.cpp)
 | 
			
		|||
target_include_directories(XS PRIVATE src src/libslic3r)
 | 
			
		||||
target_link_libraries(slic3r libslic3r libslic3r_gui admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES})
 | 
			
		||||
 | 
			
		||||
add_executable(slabasebed ${PROJECT_SOURCE_DIR}/src/slabasebed.cpp)
 | 
			
		||||
add_executable(slabasebed EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slabasebed.cpp)
 | 
			
		||||
target_include_directories(slabasebed PRIVATE src src/libslic3r)
 | 
			
		||||
target_link_libraries(slabasebed libslic3r libslic3r_gui qhull admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES})
 | 
			
		||||
target_link_libraries(slabasebed libslic3r libslic3r_gui qhull admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES} ${CMAKE_DL_LIBS})
 | 
			
		||||
 | 
			
		||||
if(SLIC3R_PROFILE)
 | 
			
		||||
    target_link_libraries(Shiny)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,8 +87,6 @@ const char* INVALID_OBJECT_TYPES[] =
 | 
			
		|||
    "other"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef Eigen::Matrix<float, 4, 4, Eigen::RowMajor> Matrix4x4;
 | 
			
		||||
 | 
			
		||||
const char* get_attribute_value_charptr(const char** attributes, unsigned int attributes_size, const char* attribute_key)
 | 
			
		||||
{
 | 
			
		||||
    if ((attributes == nullptr) || (attributes_size == 0) || (attributes_size % 2 != 0) || (attribute_key == nullptr))
 | 
			
		||||
| 
						 | 
				
			
			@ -121,11 +119,11 @@ int get_attribute_value_int(const char** attributes, unsigned int attributes_siz
 | 
			
		|||
    return (text != nullptr) ? ::atoi(text) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Matrix4x4 get_matrix_from_string(const std::string& mat_str)
 | 
			
		||||
Slic3r::Transform3d get_transform_from_string(const std::string& mat_str)
 | 
			
		||||
{
 | 
			
		||||
    if (mat_str.empty())
 | 
			
		||||
        // empty string means default identity matrix
 | 
			
		||||
        return Matrix4x4::Identity();
 | 
			
		||||
        return Slic3r::Transform3d::Identity();
 | 
			
		||||
 | 
			
		||||
    std::vector<std::string> mat_elements_str;
 | 
			
		||||
    boost::split(mat_elements_str, mat_str, boost::is_any_of(" "), boost::token_compress_on);
 | 
			
		||||
| 
						 | 
				
			
			@ -133,9 +131,9 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str)
 | 
			
		|||
    unsigned int size = (unsigned int)mat_elements_str.size();
 | 
			
		||||
    if (size != 12)
 | 
			
		||||
        // invalid data, return identity matrix
 | 
			
		||||
        return Matrix4x4::Identity();
 | 
			
		||||
        return Slic3r::Transform3d::Identity();
 | 
			
		||||
 | 
			
		||||
    Matrix4x4 ret = Matrix4x4::Identity();
 | 
			
		||||
    Slic3r::Transform3d ret = Slic3r::Transform3d::Identity();
 | 
			
		||||
    unsigned int i = 0;
 | 
			
		||||
    // matrices are stored into 3mf files as 4x3
 | 
			
		||||
    // we need to transpose them
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +141,7 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str)
 | 
			
		|||
    {
 | 
			
		||||
        for (unsigned int r = 0; r < 3; ++r)
 | 
			
		||||
        {
 | 
			
		||||
            ret(r, c) = (float)::atof(mat_elements_str[i++].c_str());
 | 
			
		||||
            ret(r, c) = ::atof(mat_elements_str[i++].c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -209,17 +207,17 @@ namespace Slic3r {
 | 
			
		|||
        struct Component
 | 
			
		||||
        {
 | 
			
		||||
            int object_id;
 | 
			
		||||
            Matrix4x4 matrix;
 | 
			
		||||
            Transform3d transform;
 | 
			
		||||
 | 
			
		||||
            explicit Component(int object_id)
 | 
			
		||||
                : object_id(object_id)
 | 
			
		||||
                , matrix(Matrix4x4::Identity())
 | 
			
		||||
                , transform(Transform3d::Identity())
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Component(int object_id, const Matrix4x4& matrix)
 | 
			
		||||
            Component(int object_id, const Transform3d& transform)
 | 
			
		||||
                : object_id(object_id)
 | 
			
		||||
                , matrix(matrix)
 | 
			
		||||
                , transform(transform)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -273,11 +271,11 @@ namespace Slic3r {
 | 
			
		|||
        struct Instance
 | 
			
		||||
        {
 | 
			
		||||
            ModelInstance* instance;
 | 
			
		||||
            Matrix4x4 matrix;
 | 
			
		||||
            Transform3d transform;
 | 
			
		||||
 | 
			
		||||
            Instance(ModelInstance* instance, const Matrix4x4& matrix)
 | 
			
		||||
            Instance(ModelInstance* instance, const Transform3d& transform)
 | 
			
		||||
                : instance(instance)
 | 
			
		||||
                , matrix(matrix)
 | 
			
		||||
                , transform(transform)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -405,9 +403,9 @@ namespace Slic3r {
 | 
			
		|||
        bool _handle_start_metadata(const char** attributes, unsigned int num_attributes);
 | 
			
		||||
        bool _handle_end_metadata();
 | 
			
		||||
 | 
			
		||||
        bool _create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter);
 | 
			
		||||
        bool _create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter);
 | 
			
		||||
 | 
			
		||||
        void _apply_transform(ModelInstance& instance, const Matrix4x4& matrix);
 | 
			
		||||
        void _apply_transform(ModelInstance& instance, const Transform3d& transform);
 | 
			
		||||
 | 
			
		||||
        bool _handle_start_config(const char** attributes, unsigned int num_attributes);
 | 
			
		||||
        bool _handle_end_config();
 | 
			
		||||
| 
						 | 
				
			
			@ -934,8 +932,8 @@ namespace Slic3r {
 | 
			
		|||
                ModelObject* object = instance.instance->get_object();
 | 
			
		||||
                if (object != nullptr)
 | 
			
		||||
                {
 | 
			
		||||
                    // apply the matrix to the instance
 | 
			
		||||
                    _apply_transform(*instance.instance, instance.matrix);
 | 
			
		||||
                    // apply the transform to the instance
 | 
			
		||||
                    _apply_transform(*instance.instance, instance.transform);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1119,7 +1117,7 @@ namespace Slic3r {
 | 
			
		|||
    bool _3MF_Importer::_handle_start_component(const char** attributes, unsigned int num_attributes)
 | 
			
		||||
    {
 | 
			
		||||
        int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
 | 
			
		||||
        Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
 | 
			
		||||
        Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
 | 
			
		||||
 | 
			
		||||
        IdToModelObjectMap::iterator object_item = m_objects.find(object_id);
 | 
			
		||||
        if (object_item == m_objects.end())
 | 
			
		||||
| 
						 | 
				
			
			@ -1132,7 +1130,7 @@ namespace Slic3r {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_curr_object.components.emplace_back(object_id, matrix);
 | 
			
		||||
        m_curr_object.components.emplace_back(object_id, transform);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1165,9 +1163,9 @@ namespace Slic3r {
 | 
			
		|||
        // see specifications
 | 
			
		||||
 | 
			
		||||
        int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
 | 
			
		||||
        Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
 | 
			
		||||
        Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
 | 
			
		||||
 | 
			
		||||
        return _create_object_instance(object_id, matrix, 1);
 | 
			
		||||
        return _create_object_instance(object_id, transform, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _3MF_Importer::_handle_end_item()
 | 
			
		||||
| 
						 | 
				
			
			@ -1195,7 +1193,7 @@ namespace Slic3r {
 | 
			
		|||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool _3MF_Importer::_create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter)
 | 
			
		||||
    bool _3MF_Importer::_create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter)
 | 
			
		||||
    {
 | 
			
		||||
        static const unsigned int MAX_RECURSIONS = 10;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1232,7 +1230,7 @@ namespace Slic3r {
 | 
			
		|||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_instances.emplace_back(instance, matrix);
 | 
			
		||||
                m_instances.emplace_back(instance, transform);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -1240,7 +1238,7 @@ namespace Slic3r {
 | 
			
		|||
            // recursively process nested components
 | 
			
		||||
            for (const Component& component : it->second)
 | 
			
		||||
            {
 | 
			
		||||
                if (!_create_object_instance(component.object_id, matrix * component.matrix, recur_counter + 1))
 | 
			
		||||
                if (!_create_object_instance(component.object_id, transform * component.transform, recur_counter + 1))
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -1248,20 +1246,20 @@ namespace Slic3r {
 | 
			
		|||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _3MF_Importer::_apply_transform(ModelInstance& instance, const Matrix4x4& matrix)
 | 
			
		||||
    void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform)
 | 
			
		||||
    {
 | 
			
		||||
        // slic3r ModelInstance cannot be transformed using a matrix
 | 
			
		||||
        // we extract from the given matrix only the values currently used
 | 
			
		||||
 | 
			
		||||
        // translation
 | 
			
		||||
        double offset_x = (double)matrix(0, 3);
 | 
			
		||||
        double offset_y = (double)matrix(1, 3);
 | 
			
		||||
        double offset_z = (double)matrix(2, 3);
 | 
			
		||||
        double offset_x = transform(0, 3);
 | 
			
		||||
        double offset_y = transform(1, 3);
 | 
			
		||||
        double offset_z = transform(2, 3);
 | 
			
		||||
 | 
			
		||||
        // scale
 | 
			
		||||
        double sx = ::sqrt(sqr((double)matrix(0, 0)) + sqr((double)matrix(1, 0)) + sqr((double)matrix(2, 0)));
 | 
			
		||||
        double sy = ::sqrt(sqr((double)matrix(0, 1)) + sqr((double)matrix(1, 1)) + sqr((double)matrix(2, 1)));
 | 
			
		||||
        double sz = ::sqrt(sqr((double)matrix(0, 2)) + sqr((double)matrix(1, 2)) + sqr((double)matrix(2, 2)));
 | 
			
		||||
        double sx = ::sqrt(sqr(transform(0, 0)) + sqr(transform(1, 0)) + sqr(transform(2, 0)));
 | 
			
		||||
        double sy = ::sqrt(sqr(transform(0, 1)) + sqr(transform(1, 1)) + sqr(transform(2, 1)));
 | 
			
		||||
        double sz = ::sqrt(sqr(transform(0, 2)) + sqr(transform(1, 2)) + sqr(transform(2, 2)));
 | 
			
		||||
 | 
			
		||||
        // invalid scale value, return
 | 
			
		||||
        if ((sx == 0.0) || (sy == 0.0) || (sz == 0.0))
 | 
			
		||||
| 
						 | 
				
			
			@ -1271,86 +1269,23 @@ 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;
 | 
			
		||||
        double inv_sz = 1.0 / sz;
 | 
			
		||||
        
 | 
			
		||||
        Eigen::Matrix<double, 3, 3, Eigen::RowMajor> 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;
 | 
			
		||||
 | 
			
		||||
        double qw = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) + m3x3(1, 1) + m3x3(2, 2)));
 | 
			
		||||
        double qx = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) - m3x3(1, 1) - m3x3(2, 2)));
 | 
			
		||||
        double qy = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) + m3x3(1, 1) - m3x3(2, 2)));
 | 
			
		||||
        double qz = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) - m3x3(1, 1) + m3x3(2, 2)));
 | 
			
		||||
 | 
			
		||||
        double q_magnitude = ::sqrt(sqr(qw) + sqr(qx) + sqr(qy) + sqr(qz));
 | 
			
		||||
 | 
			
		||||
        // invalid length, return
 | 
			
		||||
        if (q_magnitude == 0.0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        double inv_q_magnitude = 1.0 / q_magnitude;
 | 
			
		||||
 | 
			
		||||
        qw *= inv_q_magnitude;
 | 
			
		||||
        qx *= inv_q_magnitude;
 | 
			
		||||
        qy *= inv_q_magnitude;
 | 
			
		||||
        qz *= inv_q_magnitude;
 | 
			
		||||
 | 
			
		||||
        double test = qx * qy + qz * qw;
 | 
			
		||||
        double angle_x, angle_y, angle_z;
 | 
			
		||||
 | 
			
		||||
        if (test > 0.499)
 | 
			
		||||
        {
 | 
			
		||||
            // singularity at north pole
 | 
			
		||||
            angle_x = 0.0;
 | 
			
		||||
            angle_y = 2.0 * ::atan2(qx, qw);
 | 
			
		||||
            angle_z = 0.5 * PI;
 | 
			
		||||
        }
 | 
			
		||||
        else if (test < -0.499)
 | 
			
		||||
        {
 | 
			
		||||
            // singularity at south pole
 | 
			
		||||
            angle_x = 0.0;
 | 
			
		||||
            angle_y = -2.0 * ::atan2(qx, qw);
 | 
			
		||||
            angle_z = -0.5 * PI;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            angle_x = ::atan2(2.0 * qx * qw - 2.0 * qy * qz, 1.0 - 2.0 * sqr(qx) - 2.0 * sqr(qz));
 | 
			
		||||
            angle_y = ::atan2(2.0 * qy * qw - 2.0 * qx * qz, 1.0 - 2.0 * sqr(qy) - 2.0 * sqr(qz));
 | 
			
		||||
            angle_z = ::asin(2.0 * qx * qy + 2.0 * qz * qw);
 | 
			
		||||
 | 
			
		||||
            if (angle_x < 0.0)
 | 
			
		||||
                angle_x += 2.0 * PI;
 | 
			
		||||
 | 
			
		||||
            if (angle_y < 0.0)
 | 
			
		||||
                angle_y += 2.0 * PI;
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
        m3x3 << transform(0, 0) * inv_sx, transform(0, 1) * inv_sy, transform(0, 2) * inv_sz,
 | 
			
		||||
                transform(1, 0) * inv_sx, transform(1, 1) * inv_sy, transform(1, 2) * inv_sz,
 | 
			
		||||
                transform(2, 0) * inv_sx, transform(2, 1) * inv_sy, transform(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()))
 | 
			
		||||
        if ((rotation.angle() != 0.0) && (rotation.axis() != Vec3d::UnitZ()) && (rotation.axis() != -Vec3d::UnitZ()))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        double angle_z = (rotation.axis() == Eigen::Vector3d::UnitZ()) ? rotation.angle() : -rotation.angle();
 | 
			
		||||
#endif 
 | 
			
		||||
        double angle_z = (rotation.axis() == Vec3d::UnitZ()) ? rotation.angle() : -rotation.angle();
 | 
			
		||||
 | 
			
		||||
        instance.offset(0) = offset_x;
 | 
			
		||||
        instance.offset(1) = offset_y;
 | 
			
		||||
| 
						 | 
				
			
			@ -1548,11 +1483,11 @@ namespace Slic3r {
 | 
			
		|||
        struct BuildItem
 | 
			
		||||
        {
 | 
			
		||||
            unsigned int id;
 | 
			
		||||
            Matrix4x4 matrix;
 | 
			
		||||
            Transform3d transform;
 | 
			
		||||
 | 
			
		||||
            BuildItem(unsigned int id, const Matrix4x4& matrix)
 | 
			
		||||
            BuildItem(unsigned int id, const Transform3d& transform)
 | 
			
		||||
                : id(id)
 | 
			
		||||
                , matrix(matrix)
 | 
			
		||||
                , transform(transform)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -1801,9 +1736,11 @@ namespace Slic3r {
 | 
			
		|||
                stream << "   </" << COMPONENTS_TAG << ">\n";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Eigen::Affine3f transform;
 | 
			
		||||
            transform = Eigen::Translation3f((float)instance->offset(0), (float)instance->offset(1), 0.0f) * Eigen::AngleAxisf((float)instance->rotation, Eigen::Vector3f::UnitZ()) * Eigen::Scaling((float)instance->scaling_factor);
 | 
			
		||||
            build_items.emplace_back(instance_id, transform.matrix());
 | 
			
		||||
            Transform3d t = Transform3d::Identity();
 | 
			
		||||
            t.translate(Vec3d(instance->offset(0), instance->offset(1), 0.0));
 | 
			
		||||
            t.rotate(Eigen::AngleAxisd(instance->rotation, Vec3d::UnitZ()));
 | 
			
		||||
            t.scale(instance->scaling_factor);
 | 
			
		||||
            build_items.emplace_back(instance_id, t);
 | 
			
		||||
 | 
			
		||||
            stream << "  </" << OBJECT_TAG << ">\n";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1904,7 +1841,7 @@ namespace Slic3r {
 | 
			
		|||
            {
 | 
			
		||||
                for (unsigned r = 0; r < 3; ++r)
 | 
			
		||||
                {
 | 
			
		||||
                    stream << item.matrix(r, c);
 | 
			
		||||
                    stream << item.transform(r, c);
 | 
			
		||||
                    if ((r != 2) || (c != 3))
 | 
			
		||||
                        stream << " ";
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -743,21 +743,6 @@ void ModelObject::rotate(float angle, const Vec3d& axis)
 | 
			
		|||
    this->invalidate_bounding_box();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModelObject::transform(const float* matrix3x4)
 | 
			
		||||
{
 | 
			
		||||
    if (matrix3x4 == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    for (ModelVolume* v : volumes)
 | 
			
		||||
    {
 | 
			
		||||
        v->mesh.transform(matrix3x4);
 | 
			
		||||
        v->m_convex_hull.transform(matrix3x4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->origin_translation = Vec3d::Zero();
 | 
			
		||||
    this->invalidate_bounding_box();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ModelObject::mirror(const Axis &axis)
 | 
			
		||||
{
 | 
			
		||||
    for (ModelVolume *v : this->volumes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,7 +122,6 @@ public:
 | 
			
		|||
    void scale(const Vec3d &versor);
 | 
			
		||||
    void rotate(float angle, const Axis &axis);
 | 
			
		||||
    void rotate(float angle, const Vec3d& axis);
 | 
			
		||||
    void transform(const float* matrix3x4); // <<<<<<<<< FIXME (using eigen)
 | 
			
		||||
    void mirror(const Axis &axis);
 | 
			
		||||
    size_t materials_count() const;
 | 
			
		||||
    size_t facets_count() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -294,6 +294,8 @@ inline Contour3D inner_bed(const ExPolygon& poly, double depth_mm,
 | 
			
		|||
 | 
			
		||||
/// Unification of polygons (with clipper) preserving holes as well.
 | 
			
		||||
inline ExPolygons unify(const ExPolygons& shapes) {
 | 
			
		||||
    using ClipperLib::ptSubject;
 | 
			
		||||
 | 
			
		||||
    ExPolygons retv;
 | 
			
		||||
 | 
			
		||||
    bool closed = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -303,11 +305,15 @@ inline ExPolygons unify(const ExPolygons& shapes) {
 | 
			
		|||
 | 
			
		||||
    for(auto& path : shapes) {
 | 
			
		||||
        auto clipperpath = Slic3rMultiPoint_to_ClipperPath(path.contour);
 | 
			
		||||
        valid &= clipper.AddPath(clipperpath, ClipperLib::ptSubject, closed);
 | 
			
		||||
 | 
			
		||||
        if(!clipperpath.empty())
 | 
			
		||||
            valid &= clipper.AddPath(clipperpath, ptSubject, closed);
 | 
			
		||||
 | 
			
		||||
        auto clipperholes = Slic3rMultiPoints_to_ClipperPaths(path.holes);
 | 
			
		||||
 | 
			
		||||
        for(auto& hole : clipperholes) {
 | 
			
		||||
            valid &= clipper.AddPath(hole, ClipperLib::ptSubject, closed);
 | 
			
		||||
            if(!hole.empty())
 | 
			
		||||
                valid &= clipper.AddPath(hole, ptSubject, closed);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -382,7 +388,7 @@ inline Point centroid(const ExPolygon& poly) {
 | 
			
		|||
/// with explicit bridges. Bridges are generated from each shape's centroid
 | 
			
		||||
/// to the center of the "scene" which is the centroid calculated from the shape
 | 
			
		||||
/// centroids (a star is created...)
 | 
			
		||||
inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0)
 | 
			
		||||
inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 50)
 | 
			
		||||
{
 | 
			
		||||
    if(polys.empty()) return ExPolygons();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -408,8 +414,9 @@ inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0)
 | 
			
		|||
        double dx = x(c) - x(cc), dy = y(c) - y(cc);
 | 
			
		||||
        double l = std::sqrt(dx * dx + dy * dy);
 | 
			
		||||
        double nx = dx / l, ny = dy / l;
 | 
			
		||||
        double max_dist = mm(max_dist_mm);
 | 
			
		||||
 | 
			
		||||
        if(l < max_dist_mm) return ExPolygon();
 | 
			
		||||
        if(l > max_dist) return ExPolygon();
 | 
			
		||||
 | 
			
		||||
        ExPolygon r;
 | 
			
		||||
        auto& ctour = r.contour.points;
 | 
			
		||||
| 
						 | 
				
			
			@ -427,9 +434,6 @@ inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 0)
 | 
			
		|||
 | 
			
		||||
    punion = unify(punion);
 | 
			
		||||
 | 
			
		||||
    if(punion.size() != 1)
 | 
			
		||||
        BOOST_LOG_TRIVIAL(error) << "Cannot generate correct SLA base pool!";
 | 
			
		||||
 | 
			
		||||
    return punion;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -449,9 +453,10 @@ void ground_layer(const TriangleMesh &mesh, ExPolygons &output, float h)
 | 
			
		|||
 | 
			
		||||
void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out,
 | 
			
		||||
                      double min_wall_thickness_mm,
 | 
			
		||||
                      double min_wall_height_mm)
 | 
			
		||||
                      double min_wall_height_mm,
 | 
			
		||||
                      double max_merge_distance_mm)
 | 
			
		||||
{
 | 
			
		||||
    auto concavehs = concave_hull(ground_layer);
 | 
			
		||||
    auto concavehs = concave_hull(ground_layer, max_merge_distance_mm);
 | 
			
		||||
    for(ExPolygon& concaveh : concavehs) {
 | 
			
		||||
        if(concaveh.contour.points.empty()) return;
 | 
			
		||||
        concaveh.holes.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -460,7 +465,7 @@ void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out,
 | 
			
		|||
        coord_t w = x(bb.max) - x(bb.min);
 | 
			
		||||
        coord_t h = y(bb.max) - y(bb.min);
 | 
			
		||||
 | 
			
		||||
        auto wall_thickness = coord_t(std::pow((w+h)*0.1, 0.8));
 | 
			
		||||
        auto wall_thickness = coord_t((w+h)*0.01);
 | 
			
		||||
 | 
			
		||||
        const coord_t WALL_THICKNESS = mm(min_wall_thickness_mm) +
 | 
			
		||||
                                       wall_thickness;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,9 @@ void ground_layer(const TriangleMesh& mesh,
 | 
			
		|||
/// Calculate the pool for the mesh for SLA printing
 | 
			
		||||
void create_base_pool(const ExPolygons& ground_layer,
 | 
			
		||||
                      TriangleMesh& output_mesh,
 | 
			
		||||
                      double min_wall_thickness_mm = 4,
 | 
			
		||||
                      double min_wall_height_mm = 5
 | 
			
		||||
                      double min_wall_thickness_mm = 2,
 | 
			
		||||
                      double min_wall_height_mm = 5,
 | 
			
		||||
                      double max_merge_distance_mm = 50
 | 
			
		||||
                      );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,15 +279,6 @@ void TriangleMesh::mirror(const Axis &axis)
 | 
			
		|||
    stl_invalidate_shared_vertices(&this->stl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::transform(const float* matrix3x4)
 | 
			
		||||
{
 | 
			
		||||
    if (matrix3x4 == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    stl_transform(&stl, const_cast<float*>(matrix3x4));
 | 
			
		||||
    stl_invalidate_shared_vertices(&stl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TriangleMesh::align_to_origin()
 | 
			
		||||
{
 | 
			
		||||
    this->translate(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,6 @@ public:
 | 
			
		|||
    void mirror_x() { this->mirror(X); }
 | 
			
		||||
    void mirror_y() { this->mirror(Y); }
 | 
			
		||||
    void mirror_z() { this->mirror(Z); }
 | 
			
		||||
    void transform(const float* matrix3x4);
 | 
			
		||||
    void align_to_origin();
 | 
			
		||||
    void rotate(double angle, Point* center);
 | 
			
		||||
    TriangleMeshPtrs split() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,6 +214,35 @@ void PrintController::gen_support_material(PrintObject *pobj)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PrintController::PngExportData
 | 
			
		||||
PrintController::query_png_export_data(const DynamicPrintConfig& conf)
 | 
			
		||||
{
 | 
			
		||||
    PngExportData ret;
 | 
			
		||||
 | 
			
		||||
    auto zippath = query_destination_path("Output zip file", "*.zip", "out");
 | 
			
		||||
 | 
			
		||||
    ret.zippath = zippath;
 | 
			
		||||
 | 
			
		||||
    ret.width_mm = conf.opt_float("display_width");
 | 
			
		||||
    ret.height_mm = conf.opt_float("display_height");
 | 
			
		||||
 | 
			
		||||
    ret.width_px = conf.opt_int("display_pixels_x");
 | 
			
		||||
    ret.height_px = conf.opt_int("display_pixels_y");
 | 
			
		||||
 | 
			
		||||
    auto opt_corr = conf.opt<ConfigOptionFloats>("printer_correction");
 | 
			
		||||
 | 
			
		||||
    if(opt_corr) {
 | 
			
		||||
        ret.corr_x = opt_corr->values[0];
 | 
			
		||||
        ret.corr_y = opt_corr->values[1];
 | 
			
		||||
        ret.corr_z = opt_corr->values[2];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret.exp_time_first_s = conf.opt_float("initial_exposure_time");
 | 
			
		||||
    ret.exp_time_s = conf.opt_float("exposure_time");
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
 | 
			
		||||
{
 | 
			
		||||
    auto st = pri->state();
 | 
			
		||||
| 
						 | 
				
			
			@ -262,18 +291,23 @@ void PrintController::slice_to_png()
 | 
			
		|||
{
 | 
			
		||||
    using Pointf3 = Vec3d;
 | 
			
		||||
 | 
			
		||||
    auto exd = query_png_export_data();
 | 
			
		||||
 | 
			
		||||
    if(exd.zippath.empty()) return;
 | 
			
		||||
 | 
			
		||||
    auto presetbundle = GUI::get_preset_bundle();
 | 
			
		||||
 | 
			
		||||
    assert(presetbundle);
 | 
			
		||||
 | 
			
		||||
    auto conf = presetbundle->full_config();
 | 
			
		||||
    auto pt = presetbundle->printers.get_selected_preset().printer_technology();
 | 
			
		||||
    if(pt != ptSLA) {
 | 
			
		||||
        report_issue(IssueType::ERR, _("Printer technology is not SLA!"),
 | 
			
		||||
                     _("Error"));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto conf = presetbundle->full_config();
 | 
			
		||||
    conf.validate();
 | 
			
		||||
 | 
			
		||||
    auto exd = query_png_export_data(conf);
 | 
			
		||||
    if(exd.zippath.empty()) return;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        print_->apply_config(conf);
 | 
			
		||||
        print_->validate();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ protected:
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    // Should display a dialog with the input fields for printing to png
 | 
			
		||||
    PngExportData query_png_export_data();
 | 
			
		||||
    PngExportData query_png_export_data(const DynamicPrintConfig&);
 | 
			
		||||
 | 
			
		||||
    // The previous export data, to pre-populate the dialog
 | 
			
		||||
    PngExportData prev_expdata_;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -309,120 +309,120 @@ void AppController::set_global_progress_indicator(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PrintController::PngExportData PrintController::query_png_export_data()
 | 
			
		||||
{
 | 
			
		||||
//PrintController::PngExportData PrintController::collect_png_export_data()
 | 
			
		||||
//{
 | 
			
		||||
 | 
			
		||||
    // Implement the logic of the PngExportDialog
 | 
			
		||||
    class PngExportView: public PngExportDialog {
 | 
			
		||||
        double ratio_, bs_ratio_;
 | 
			
		||||
        PrintController& ctl_;
 | 
			
		||||
    public:
 | 
			
		||||
//    // Implement the logic of the PngExportDialog
 | 
			
		||||
//    class PngExportView: public PngExportDialog {
 | 
			
		||||
//        double ratio_, bs_ratio_;
 | 
			
		||||
//        PrintController& ctl_;
 | 
			
		||||
//    public:
 | 
			
		||||
 | 
			
		||||
        PngExportView(PrintController& ctl):
 | 
			
		||||
            PngExportDialog(wxTheApp->GetTopWindow()), ctl_(ctl)
 | 
			
		||||
        {
 | 
			
		||||
            ratio_ = double(spin_reso_width_->GetValue()) /
 | 
			
		||||
                    spin_reso_height_->GetValue();
 | 
			
		||||
//        PngExportView(PrintController& ctl):
 | 
			
		||||
//            PngExportDialog(wxTheApp->GetTopWindow()), ctl_(ctl)
 | 
			
		||||
//        {
 | 
			
		||||
//            ratio_ = double(spin_reso_width_->GetValue()) /
 | 
			
		||||
//                    spin_reso_height_->GetValue();
 | 
			
		||||
 | 
			
		||||
            bs_ratio_ = bed_width_spin_->GetValue() /
 | 
			
		||||
                    bed_height_spin_->GetValue();
 | 
			
		||||
        }
 | 
			
		||||
//            bs_ratio_ = bed_width_spin_->GetValue() /
 | 
			
		||||
//                    bed_height_spin_->GetValue();
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        PngExportData export_data() const {
 | 
			
		||||
            PrintController::PngExportData ret;
 | 
			
		||||
            ret.zippath = filepick_ctl_->GetPath();
 | 
			
		||||
            ret.width_px = spin_reso_width_->GetValue();
 | 
			
		||||
            ret.height_px = spin_reso_height_->GetValue();
 | 
			
		||||
            ret.width_mm = bed_width_spin_->GetValue();
 | 
			
		||||
            ret.height_mm = bed_height_spin_->GetValue();
 | 
			
		||||
            ret.exp_time_s = exptime_spin_->GetValue();
 | 
			
		||||
            ret.exp_time_first_s = exptime_first_spin_->GetValue();
 | 
			
		||||
            ret.corr_x = corr_spin_x_->GetValue();
 | 
			
		||||
            ret.corr_y = corr_spin_y_->GetValue();
 | 
			
		||||
            ret.corr_z = corr_spin_z_->GetValue();
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
//        PngExportData export_data() const {
 | 
			
		||||
//            PrintController::PngExportData ret;
 | 
			
		||||
//            ret.zippath = filepick_ctl_->GetPath();
 | 
			
		||||
//            ret.width_px = spin_reso_width_->GetValue();
 | 
			
		||||
//            ret.height_px = spin_reso_height_->GetValue();
 | 
			
		||||
//            ret.width_mm = bed_width_spin_->GetValue();
 | 
			
		||||
//            ret.height_mm = bed_height_spin_->GetValue();
 | 
			
		||||
//            ret.exp_time_s = exptime_spin_->GetValue();
 | 
			
		||||
//            ret.exp_time_first_s = exptime_first_spin_->GetValue();
 | 
			
		||||
//            ret.corr_x = corr_spin_x_->GetValue();
 | 
			
		||||
//            ret.corr_y = corr_spin_y_->GetValue();
 | 
			
		||||
//            ret.corr_z = corr_spin_z_->GetValue();
 | 
			
		||||
//            return ret;
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        void prefill(const PngExportData& data) {
 | 
			
		||||
            filepick_ctl_->SetPath(data.zippath);
 | 
			
		||||
            spin_reso_width_->SetValue(data.width_px);
 | 
			
		||||
            spin_reso_height_->SetValue(data.height_px);
 | 
			
		||||
            bed_width_spin_->SetValue(data.width_mm);
 | 
			
		||||
            bed_height_spin_->SetValue(data.height_mm);
 | 
			
		||||
            exptime_spin_->SetValue(data.exp_time_s);
 | 
			
		||||
            exptime_first_spin_->SetValue(data.exp_time_first_s);
 | 
			
		||||
            corr_spin_x_->SetValue(data.corr_x);
 | 
			
		||||
            corr_spin_y_->SetValue(data.corr_y);
 | 
			
		||||
            corr_spin_z_->SetValue(data.corr_z);
 | 
			
		||||
            if(data.zippath.empty()) export_btn_->Disable();
 | 
			
		||||
            else export_btn_->Enable();
 | 
			
		||||
        }
 | 
			
		||||
//        void prefill(const PngExportData& data) {
 | 
			
		||||
//            filepick_ctl_->SetPath(data.zippath);
 | 
			
		||||
//            spin_reso_width_->SetValue(data.width_px);
 | 
			
		||||
//            spin_reso_height_->SetValue(data.height_px);
 | 
			
		||||
//            bed_width_spin_->SetValue(data.width_mm);
 | 
			
		||||
//            bed_height_spin_->SetValue(data.height_mm);
 | 
			
		||||
//            exptime_spin_->SetValue(data.exp_time_s);
 | 
			
		||||
//            exptime_first_spin_->SetValue(data.exp_time_first_s);
 | 
			
		||||
//            corr_spin_x_->SetValue(data.corr_x);
 | 
			
		||||
//            corr_spin_y_->SetValue(data.corr_y);
 | 
			
		||||
//            corr_spin_z_->SetValue(data.corr_z);
 | 
			
		||||
//            if(data.zippath.empty()) export_btn_->Disable();
 | 
			
		||||
//            else export_btn_->Enable();
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void ResoLock( wxCommandEvent& /*event*/ ) override {
 | 
			
		||||
            ratio_ = double(spin_reso_width_->GetValue()) /
 | 
			
		||||
                    double(spin_reso_height_->GetValue());
 | 
			
		||||
        }
 | 
			
		||||
//        virtual void ResoLock( wxCommandEvent& /*event*/ ) override {
 | 
			
		||||
//            ratio_ = double(spin_reso_width_->GetValue()) /
 | 
			
		||||
//                    double(spin_reso_height_->GetValue());
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void BedsizeLock( wxCommandEvent& /*event*/ ) override {
 | 
			
		||||
            bs_ratio_ = bed_width_spin_->GetValue() /
 | 
			
		||||
                    bed_height_spin_->GetValue();
 | 
			
		||||
        }
 | 
			
		||||
//        virtual void BedsizeLock( wxCommandEvent& /*event*/ ) override {
 | 
			
		||||
//            bs_ratio_ = bed_width_spin_->GetValue() /
 | 
			
		||||
//                    bed_height_spin_->GetValue();
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void EvalResoSpin( wxCommandEvent& event ) override {
 | 
			
		||||
            if(reso_lock_btn_->GetValue()) {
 | 
			
		||||
                if(event.GetId() == spin_reso_width_->GetId()) {
 | 
			
		||||
                    spin_reso_height_->SetValue(
 | 
			
		||||
                            std::round(spin_reso_width_->GetValue()/ratio_));
 | 
			
		||||
                    spin_reso_height_->Update();
 | 
			
		||||
                } else {
 | 
			
		||||
                    spin_reso_width_->SetValue(
 | 
			
		||||
                            std::round(spin_reso_height_->GetValue()*ratio_));
 | 
			
		||||
                    spin_reso_width_->Update();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
//        virtual void EvalResoSpin( wxCommandEvent& event ) override {
 | 
			
		||||
//            if(reso_lock_btn_->GetValue()) {
 | 
			
		||||
//                if(event.GetId() == spin_reso_width_->GetId()) {
 | 
			
		||||
//                    spin_reso_height_->SetValue(
 | 
			
		||||
//                            std::round(spin_reso_width_->GetValue()/ratio_));
 | 
			
		||||
//                    spin_reso_height_->Update();
 | 
			
		||||
//                } else {
 | 
			
		||||
//                    spin_reso_width_->SetValue(
 | 
			
		||||
//                            std::round(spin_reso_height_->GetValue()*ratio_));
 | 
			
		||||
//                    spin_reso_width_->Update();
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void EvalBedSpin( wxCommandEvent& event ) override {
 | 
			
		||||
            if(bedsize_lock_btn_->GetValue()) {
 | 
			
		||||
                if(event.GetId() == bed_width_spin_->GetId()) {
 | 
			
		||||
                    bed_height_spin_->SetValue(
 | 
			
		||||
                            std::round(bed_width_spin_->GetValue()/bs_ratio_));
 | 
			
		||||
                    bed_height_spin_->Update();
 | 
			
		||||
                } else {
 | 
			
		||||
                    bed_width_spin_->SetValue(
 | 
			
		||||
                            std::round(bed_height_spin_->GetValue()*bs_ratio_));
 | 
			
		||||
                    bed_width_spin_->Update();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
//        virtual void EvalBedSpin( wxCommandEvent& event ) override {
 | 
			
		||||
//            if(bedsize_lock_btn_->GetValue()) {
 | 
			
		||||
//                if(event.GetId() == bed_width_spin_->GetId()) {
 | 
			
		||||
//                    bed_height_spin_->SetValue(
 | 
			
		||||
//                            std::round(bed_width_spin_->GetValue()/bs_ratio_));
 | 
			
		||||
//                    bed_height_spin_->Update();
 | 
			
		||||
//                } else {
 | 
			
		||||
//                    bed_width_spin_->SetValue(
 | 
			
		||||
//                            std::round(bed_height_spin_->GetValue()*bs_ratio_));
 | 
			
		||||
//                    bed_width_spin_->Update();
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void onFileChanged( wxFileDirPickerEvent& event ) {
 | 
			
		||||
            if(filepick_ctl_->GetPath().IsEmpty()) export_btn_->Disable();
 | 
			
		||||
            else export_btn_->Enable();
 | 
			
		||||
        }
 | 
			
		||||
//        virtual void onFileChanged( wxFileDirPickerEvent& event ) {
 | 
			
		||||
//            if(filepick_ctl_->GetPath().IsEmpty()) export_btn_->Disable();
 | 
			
		||||
//            else export_btn_->Enable();
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        virtual void Close( wxCommandEvent& /*event*/ ) {
 | 
			
		||||
            auto ret = wxID_OK;
 | 
			
		||||
//        virtual void Close( wxCommandEvent& /*event*/ ) {
 | 
			
		||||
//            auto ret = wxID_OK;
 | 
			
		||||
 | 
			
		||||
            if(wxFileName(filepick_ctl_->GetPath()).Exists())
 | 
			
		||||
                if(!ctl_.report_issue(PrintController::IssueType::WARN_Q,
 | 
			
		||||
                                  _(L("File already exists. Overwrite?")),
 | 
			
		||||
                                  _(L("Warning")))) ret = wxID_CANCEL;
 | 
			
		||||
            EndModal(ret);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
//            if(wxFileName(filepick_ctl_->GetPath()).Exists())
 | 
			
		||||
//                if(!ctl_.report_issue(PrintController::IssueType::WARN_Q,
 | 
			
		||||
//                                  _(L("File already exists. Overwrite?")),
 | 
			
		||||
//                                  _(L("Warning")))) ret = wxID_CANCEL;
 | 
			
		||||
//            EndModal(ret);
 | 
			
		||||
//        }
 | 
			
		||||
//    };
 | 
			
		||||
 | 
			
		||||
    PngExportView exdlg(*this);
 | 
			
		||||
//    PngExportView exdlg(*this);
 | 
			
		||||
 | 
			
		||||
    exdlg.prefill(prev_expdata_);
 | 
			
		||||
//    exdlg.prefill(prev_expdata_);
 | 
			
		||||
 | 
			
		||||
    auto r = exdlg.ShowModal();
 | 
			
		||||
//    auto r = exdlg.ShowModal();
 | 
			
		||||
 | 
			
		||||
    auto ret = exdlg.export_data();
 | 
			
		||||
    prev_expdata_ = ret;
 | 
			
		||||
//    auto ret = exdlg.export_data();
 | 
			
		||||
//    prev_expdata_ = ret;
 | 
			
		||||
 | 
			
		||||
    if(r != wxID_OK) ret.zippath.clear();
 | 
			
		||||
//    if(r != wxID_OK) ret.zippath.clear();
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
//    return ret;
 | 
			
		||||
//}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,8 @@ GLVolume::GLVolume(float r, float g, float b, float a)
 | 
			
		|||
    : m_origin(0, 0, 0)
 | 
			
		||||
    , m_angle_z(0.0f)
 | 
			
		||||
    , m_scale_factor(1.0f)
 | 
			
		||||
    , m_world_matrix(Transform3f::Identity())
 | 
			
		||||
    , m_world_matrix_dirty(true)
 | 
			
		||||
    , m_transformed_bounding_box_dirty(true)
 | 
			
		||||
    , m_transformed_convex_hull_bounding_box_dirty(true)
 | 
			
		||||
    , m_convex_hull(nullptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +270,7 @@ void GLVolume::set_origin(const Vec3d& origin)
 | 
			
		|||
    if (m_origin != origin)
 | 
			
		||||
    {
 | 
			
		||||
        m_origin = origin;
 | 
			
		||||
        m_world_matrix_dirty = true;
 | 
			
		||||
        m_transformed_bounding_box_dirty = true;
 | 
			
		||||
        m_transformed_convex_hull_bounding_box_dirty = true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -278,6 +281,7 @@ void GLVolume::set_angle_z(float angle_z)
 | 
			
		|||
    if (m_angle_z != angle_z)
 | 
			
		||||
    {
 | 
			
		||||
        m_angle_z = angle_z;
 | 
			
		||||
        m_world_matrix_dirty = true;
 | 
			
		||||
        m_transformed_bounding_box_dirty = true;
 | 
			
		||||
        m_transformed_convex_hull_bounding_box_dirty = true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -288,6 +292,7 @@ void GLVolume::set_scale_factor(float scale_factor)
 | 
			
		|||
    if (m_scale_factor != scale_factor)
 | 
			
		||||
    {
 | 
			
		||||
        m_scale_factor = scale_factor;
 | 
			
		||||
        m_world_matrix_dirty = true;
 | 
			
		||||
        m_transformed_bounding_box_dirty = true;
 | 
			
		||||
        m_transformed_convex_hull_bounding_box_dirty = true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -298,16 +303,20 @@ void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
 | 
			
		|||
    m_convex_hull = &convex_hull;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Transform3f GLVolume::world_matrix() const
 | 
			
		||||
const Transform3f& GLVolume::world_matrix() const
 | 
			
		||||
{
 | 
			
		||||
    Transform3f matrix = Transform3f::Identity();
 | 
			
		||||
    matrix.translate(Vec3f((float)m_origin(0), (float)m_origin(1), (float)m_origin(2)));
 | 
			
		||||
    matrix.rotate(Eigen::AngleAxisf(m_angle_z, Vec3f::UnitZ()));
 | 
			
		||||
    matrix.scale(m_scale_factor);
 | 
			
		||||
    return matrix;
 | 
			
		||||
    if (m_world_matrix_dirty)
 | 
			
		||||
    {
 | 
			
		||||
        m_world_matrix = Transform3f::Identity();
 | 
			
		||||
        m_world_matrix.translate(Vec3f((float)m_origin(0), (float)m_origin(1), (float)m_origin(2)));
 | 
			
		||||
        m_world_matrix.rotate(Eigen::AngleAxisf(m_angle_z, Vec3f::UnitZ()));
 | 
			
		||||
        m_world_matrix.scale(m_scale_factor);
 | 
			
		||||
        m_world_matrix_dirty = false;
 | 
			
		||||
    }
 | 
			
		||||
    return m_world_matrix;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BoundingBoxf3 GLVolume::transformed_bounding_box() const
 | 
			
		||||
const BoundingBoxf3& GLVolume::transformed_bounding_box() const
 | 
			
		||||
{
 | 
			
		||||
    if (m_transformed_bounding_box_dirty)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +327,7 @@ BoundingBoxf3 GLVolume::transformed_bounding_box() const
 | 
			
		|||
    return m_transformed_bounding_box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BoundingBoxf3 GLVolume::transformed_convex_hull_bounding_box() const
 | 
			
		||||
const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
 | 
			
		||||
{
 | 
			
		||||
    if (m_transformed_convex_hull_bounding_box_dirty)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,6 +260,10 @@ private:
 | 
			
		|||
    float                 m_angle_z;
 | 
			
		||||
    // Scale factor of the volume to be rendered.
 | 
			
		||||
    float                 m_scale_factor;
 | 
			
		||||
    // World matrix of the volume to be rendered.
 | 
			
		||||
    mutable Transform3f   m_world_matrix;
 | 
			
		||||
    // Whether or not is needed to recalculate the world matrix.
 | 
			
		||||
    mutable bool          m_world_matrix_dirty;
 | 
			
		||||
    // 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.
 | 
			
		||||
| 
						 | 
				
			
			@ -334,9 +338,9 @@ public:
 | 
			
		|||
    int                 volume_idx() const { return (this->composite_id / 1000) % 1000; }
 | 
			
		||||
    int                 instance_idx() const { return this->composite_id % 1000; }
 | 
			
		||||
 | 
			
		||||
    Transform3f         world_matrix() const;
 | 
			
		||||
    BoundingBoxf3       transformed_bounding_box() const;
 | 
			
		||||
    BoundingBoxf3       transformed_convex_hull_bounding_box() const;
 | 
			
		||||
    const Transform3f&   world_matrix() const;
 | 
			
		||||
    const BoundingBoxf3& transformed_bounding_box() const;
 | 
			
		||||
    const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
 | 
			
		||||
 | 
			
		||||
    bool                empty() const { return this->indexed_vertex_array.empty(); }
 | 
			
		||||
    bool                indexed() const { return this->indexed_vertex_array.indexed(); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1134,11 +1134,7 @@ GLCanvas3D::Gizmos::~Gizmos()
 | 
			
		|||
 | 
			
		||||
bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
 | 
			
		||||
{
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    GLGizmoBase* gizmo = new GLGizmoScale3D(parent);
 | 
			
		||||
#else
 | 
			
		||||
    GLGizmoBase* gizmo = new GLGizmoScale(parent);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
    if (gizmo == nullptr)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1147,11 +1143,7 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
 | 
			
		|||
 | 
			
		||||
    m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    gizmo = new GLGizmoRotate3D(parent);
 | 
			
		||||
#else
 | 
			
		||||
    gizmo = new GLGizmoRotate(parent, GLGizmoRotate::Z);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
    if (gizmo == nullptr)
 | 
			
		||||
    {
 | 
			
		||||
        _reset();
 | 
			
		||||
| 
						 | 
				
			
			@ -1379,11 +1371,7 @@ float GLCanvas3D::Gizmos::get_scale() const
 | 
			
		|||
        return 1.0f;
 | 
			
		||||
 | 
			
		||||
    GizmosMap::const_iterator it = m_gizmos.find(Scale);
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoScale3D*>(it->second)->get_scale_x() : 1.0f;
 | 
			
		||||
#else
 | 
			
		||||
    return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoScale*>(it->second)->get_scale() : 1.0f;
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLCanvas3D::Gizmos::set_scale(float scale)
 | 
			
		||||
| 
						 | 
				
			
			@ -1393,11 +1381,7 @@ void GLCanvas3D::Gizmos::set_scale(float scale)
 | 
			
		|||
 | 
			
		||||
    GizmosMap::const_iterator it = m_gizmos.find(Scale);
 | 
			
		||||
    if (it != m_gizmos.end())
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
        reinterpret_cast<GLGizmoScale3D*>(it->second)->set_scale(scale);
 | 
			
		||||
#else
 | 
			
		||||
        reinterpret_cast<GLGizmoScale*>(it->second)->set_scale(scale);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float GLCanvas3D::Gizmos::get_angle_z() const
 | 
			
		||||
| 
						 | 
				
			
			@ -1406,11 +1390,7 @@ float GLCanvas3D::Gizmos::get_angle_z() const
 | 
			
		|||
        return 0.0f;
 | 
			
		||||
 | 
			
		||||
    GizmosMap::const_iterator it = m_gizmos.find(Rotate);
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoRotate3D*>(it->second)->get_angle_z() : 0.0f;
 | 
			
		||||
#else
 | 
			
		||||
    return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoRotate*>(it->second)->get_angle() : 0.0f;
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLCanvas3D::Gizmos::set_angle_z(float angle_z)
 | 
			
		||||
| 
						 | 
				
			
			@ -1420,11 +1400,7 @@ void GLCanvas3D::Gizmos::set_angle_z(float angle_z)
 | 
			
		|||
 | 
			
		||||
    GizmosMap::const_iterator it = m_gizmos.find(Rotate);
 | 
			
		||||
    if (it != m_gizmos.end())
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
reinterpret_cast<GLGizmoRotate3D*>(it->second)->set_angle_z(angle_z);
 | 
			
		||||
#else
 | 
			
		||||
        reinterpret_cast<GLGizmoRotate*>(it->second)->set_angle(angle_z);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
        reinterpret_cast<GLGizmoRotate3D*>(it->second)->set_angle_z(angle_z);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec3d GLCanvas3D::Gizmos::get_flattening_normal() const
 | 
			
		||||
| 
						 | 
				
			
			@ -2487,10 +2463,12 @@ void GLCanvas3D::reload_scene(bool force)
 | 
			
		|||
    // 1st call to reset if no objects left
 | 
			
		||||
    update_gizmos_data();
 | 
			
		||||
    update_volumes_selection(m_objects_selections);
 | 
			
		||||
    // 2nd call to restore if something selected
 | 
			
		||||
    // 2nd call to restore selection, if any
 | 
			
		||||
    if (!m_objects_selections.empty())
 | 
			
		||||
        update_gizmos_data();
 | 
			
		||||
 | 
			
		||||
    m_gizmos.refresh();
 | 
			
		||||
 | 
			
		||||
    if (m_config->has("nozzle_diameter"))
 | 
			
		||||
    {
 | 
			
		||||
        // Should the wipe tower be visualized ?
 | 
			
		||||
| 
						 | 
				
			
			@ -3157,7 +3135,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
 | 
			
		|||
    }
 | 
			
		||||
    else if (evt.Dragging() && m_gizmos.is_dragging())
 | 
			
		||||
    {
 | 
			
		||||
        m_canvas->CaptureMouse();
 | 
			
		||||
        if (!m_canvas->HasCapture())
 | 
			
		||||
            m_canvas->CaptureMouse();
 | 
			
		||||
 | 
			
		||||
        m_mouse.dragging = true;
 | 
			
		||||
        m_gizmos.update(mouse_ray(pos));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,8 @@ const float GLGizmoBase::Grabber::HalfSize = 2.0f;
 | 
			
		|||
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
 | 
			
		||||
 | 
			
		||||
GLGizmoBase::Grabber::Grabber()
 | 
			
		||||
    : center(0.0, 0.0, 0.0)
 | 
			
		||||
    , angle_x(0.0f)
 | 
			
		||||
    , angle_y(0.0f)
 | 
			
		||||
    , angle_z(0.0f)
 | 
			
		||||
    : center(Vec3d::Zero())
 | 
			
		||||
    , angles(Vec3d::Zero())
 | 
			
		||||
    , dragging(false)
 | 
			
		||||
{
 | 
			
		||||
    color[0] = 1.0f;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,29 +47,14 @@ void GLGizmoBase::Grabber::render(bool hover) const
 | 
			
		|||
    else
 | 
			
		||||
        ::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float));
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    render(render_color, true);
 | 
			
		||||
#else
 | 
			
		||||
    render(render_color);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
void GLGizmoBase::Grabber::render(const float* render_color, bool use_lighting) const
 | 
			
		||||
#else
 | 
			
		||||
void GLGizmoBase::Grabber::render(const float* render_color) const
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
{
 | 
			
		||||
    float half_size = dragging ? HalfSize * DraggingScaleFactor : HalfSize;
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    if (use_lighting)
 | 
			
		||||
        ::glEnable(GL_LIGHTING);
 | 
			
		||||
#else
 | 
			
		||||
    float min_x = -half_size;
 | 
			
		||||
    float max_x = +half_size;
 | 
			
		||||
    float min_y = -half_size;
 | 
			
		||||
    float max_y = +half_size;
 | 
			
		||||
#endif // !ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,11 +62,10 @@ void GLGizmoBase::Grabber::render(const float* render_color) const
 | 
			
		|||
    ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2));
 | 
			
		||||
 | 
			
		||||
    float rad_to_deg = 180.0f / (GLfloat)PI;
 | 
			
		||||
    ::glRotatef((GLfloat)angle_x * rad_to_deg, 1.0f, 0.0f, 0.0f);
 | 
			
		||||
    ::glRotatef((GLfloat)angle_y * rad_to_deg, 0.0f, 1.0f, 0.0f);
 | 
			
		||||
    ::glRotatef((GLfloat)angle_z * rad_to_deg, 0.0f, 0.0f, 1.0f);
 | 
			
		||||
    ::glRotatef((GLfloat)angles(0) * rad_to_deg, 1.0f, 0.0f, 0.0f);
 | 
			
		||||
    ::glRotatef((GLfloat)angles(1) * rad_to_deg, 0.0f, 1.0f, 0.0f);
 | 
			
		||||
    ::glRotatef((GLfloat)angles(2) * rad_to_deg, 0.0f, 0.0f, 1.0f);
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    // face min x
 | 
			
		||||
    ::glPushMatrix();
 | 
			
		||||
    ::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f);
 | 
			
		||||
| 
						 | 
				
			
			@ -124,28 +106,13 @@ void GLGizmoBase::Grabber::render(const float* render_color) const
 | 
			
		|||
    ::glTranslatef(0.0f, 0.0f, (GLfloat)half_size);
 | 
			
		||||
    render_face(half_size);
 | 
			
		||||
    ::glPopMatrix();
 | 
			
		||||
#else
 | 
			
		||||
    ::glDisable(GL_CULL_FACE);
 | 
			
		||||
    ::glBegin(GL_TRIANGLES);
 | 
			
		||||
    ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f);
 | 
			
		||||
    ::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f);
 | 
			
		||||
    ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f);
 | 
			
		||||
    ::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f);
 | 
			
		||||
    ::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f);
 | 
			
		||||
    ::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f);
 | 
			
		||||
    ::glEnd();
 | 
			
		||||
    ::glEnable(GL_CULL_FACE);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    ::glPopMatrix();
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    if (use_lighting)
 | 
			
		||||
        ::glDisable(GL_LIGHTING);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
void GLGizmoBase::Grabber::render_face(float half_size) const
 | 
			
		||||
{
 | 
			
		||||
    ::glBegin(GL_TRIANGLES);
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +125,6 @@ void GLGizmoBase::Grabber::render_face(float half_size) const
 | 
			
		|||
    ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f);
 | 
			
		||||
    ::glEnd();
 | 
			
		||||
}
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent)
 | 
			
		||||
    : m_parent(parent)
 | 
			
		||||
| 
						 | 
				
			
			@ -265,41 +231,24 @@ const float GLGizmoRotate::GrabberOffset = 5.0f;
 | 
			
		|||
GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
 | 
			
		||||
    : GLGizmoBase(parent)
 | 
			
		||||
    , m_axis(axis)
 | 
			
		||||
    , m_angle(0.0f)
 | 
			
		||||
    , m_angle(0.0)
 | 
			
		||||
    , m_center(0.0, 0.0, 0.0)
 | 
			
		||||
    , m_radius(0.0f)
 | 
			
		||||
    , m_keep_initial_values(false)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoRotate::set_angle(float angle)
 | 
			
		||||
void GLGizmoRotate::set_angle(double angle)
 | 
			
		||||
{
 | 
			
		||||
    if (std::abs(angle - 2.0f * PI) < EPSILON)
 | 
			
		||||
        angle = 0.0f;
 | 
			
		||||
    if (std::abs(angle - 2.0 * (double)PI) < EPSILON)
 | 
			
		||||
        angle = 0.0;
 | 
			
		||||
 | 
			
		||||
    m_angle = angle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLGizmoRotate::on_init()
 | 
			
		||||
{
 | 
			
		||||
#if !ENABLE_GIZMOS_3D
 | 
			
		||||
    std::string path = resources_dir() + "/icons/overlay/";
 | 
			
		||||
 | 
			
		||||
    std::string filename = path + "rotate_off.png";
 | 
			
		||||
    if (!m_textures[Off].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
    
 | 
			
		||||
    filename = path + "rotate_hover.png";
 | 
			
		||||
    if (!m_textures[Hover].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
    
 | 
			
		||||
    filename = path + "rotate_on.png";
 | 
			
		||||
    if (!m_textures[On].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
#endif // !ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    m_grabbers.push_back(Grabber());
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +288,7 @@ void GLGizmoRotate::on_update(const Linef3& mouse_ray)
 | 
			
		|||
    if (theta == 2.0 * (double)PI)
 | 
			
		||||
        theta = 0.0;
 | 
			
		||||
 | 
			
		||||
    m_angle = (float)theta;
 | 
			
		||||
    m_angle = theta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
 | 
			
		||||
| 
						 | 
				
			
			@ -347,55 +296,33 @@ void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
 | 
			
		|||
    if (m_grabbers[0].dragging)
 | 
			
		||||
        set_tooltip(format(m_angle * 180.0f / (float)PI, 4));
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    ::glEnable(GL_DEPTH_TEST);
 | 
			
		||||
#else
 | 
			
		||||
    ::glDisable(GL_DEPTH_TEST);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    if (!m_keep_initial_values)
 | 
			
		||||
    {
 | 
			
		||||
        m_center = box.center();
 | 
			
		||||
#if !ENABLE_GIZMOS_3D
 | 
			
		||||
        const Vec3d& size = box.size();
 | 
			
		||||
        m_center(2) = 0.0;
 | 
			
		||||
#endif // !ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
        m_radius = Offset + box.radius();
 | 
			
		||||
#else
 | 
			
		||||
        m_radius = Offset + ::sqrt(sqr(0.5f * (float)size(0)) + sqr(0.5f * (float)size(1)));
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
        m_keep_initial_values = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::glPushMatrix();
 | 
			
		||||
    transform_to_local();
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
 | 
			
		||||
    ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
 | 
			
		||||
#else
 | 
			
		||||
    ::glLineWidth(2.0f);
 | 
			
		||||
    ::glColor3fv(m_drag_color);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    render_circle();
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    if (m_hover_id != -1)
 | 
			
		||||
    {
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
        render_scale();
 | 
			
		||||
        render_snap_radii();
 | 
			
		||||
        render_reference_radius();
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    }
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    ::glColor3fv(m_highlight_color);
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    if (m_hover_id != -1)
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
        render_angle();
 | 
			
		||||
 | 
			
		||||
    render_grabber();
 | 
			
		||||
| 
						 | 
				
			
			@ -491,7 +418,7 @@ void GLGizmoRotate::render_reference_radius() const
 | 
			
		|||
 | 
			
		||||
void GLGizmoRotate::render_angle() const
 | 
			
		||||
{
 | 
			
		||||
    float step_angle = m_angle / AngleResolution;
 | 
			
		||||
    float step_angle = (float)m_angle / AngleResolution;
 | 
			
		||||
    float ex_radius = m_radius + GrabberOffset;
 | 
			
		||||
 | 
			
		||||
    ::glBegin(GL_LINE_STRIP);
 | 
			
		||||
| 
						 | 
				
			
			@ -508,15 +435,11 @@ void GLGizmoRotate::render_angle() const
 | 
			
		|||
 | 
			
		||||
void GLGizmoRotate::render_grabber() const
 | 
			
		||||
{
 | 
			
		||||
    float grabber_radius = m_radius + GrabberOffset;
 | 
			
		||||
    double grabber_radius = (double)(m_radius + GrabberOffset);
 | 
			
		||||
    m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
 | 
			
		||||
    m_grabbers[0].angle_z = m_angle;
 | 
			
		||||
    m_grabbers[0].angles(2) = m_angle;
 | 
			
		||||
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
    ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
 | 
			
		||||
#else
 | 
			
		||||
    ::glColor3fv(m_drag_color);
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    ::glBegin(GL_LINES);
 | 
			
		||||
    ::glVertex3f(0.0f, 0.0f, 0.0f);
 | 
			
		||||
| 
						 | 
				
			
			@ -584,17 +507,7 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) cons
 | 
			
		|||
 | 
			
		||||
    m.translate(-m_center);
 | 
			
		||||
 | 
			
		||||
    Eigen::Matrix<double, 3, 2> world_ray;
 | 
			
		||||
    Eigen::Matrix<double, 3, 2> local_ray;
 | 
			
		||||
    world_ray(0, 0) = mouse_ray.a(0);
 | 
			
		||||
    world_ray(1, 0) = mouse_ray.a(1);
 | 
			
		||||
    world_ray(2, 0) = mouse_ray.a(2);
 | 
			
		||||
    world_ray(0, 1) = mouse_ray.b(0);
 | 
			
		||||
    world_ray(1, 1) = mouse_ray.b(1);
 | 
			
		||||
    world_ray(2, 1) = mouse_ray.b(2);
 | 
			
		||||
    local_ray = m * world_ray.colwise().homogeneous();
 | 
			
		||||
 | 
			
		||||
    return Linef3(Vec3d(local_ray(0, 0), local_ray(1, 0), local_ray(2, 0)), Vec3d(local_ray(0, 1), local_ray(1, 1), local_ray(2, 1))).intersect_plane(0.0);
 | 
			
		||||
    return transform(mouse_ray, m).intersect_plane(0.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent)
 | 
			
		||||
| 
						 | 
				
			
			@ -698,116 +611,13 @@ void GLGizmoRotate3D::on_render(const BoundingBoxf3& box) const
 | 
			
		|||
        m_z.render(box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const float GLGizmoScale::Offset = 5.0f;
 | 
			
		||||
 | 
			
		||||
GLGizmoScale::GLGizmoScale(GLCanvas3D& parent)
 | 
			
		||||
    : GLGizmoBase(parent)
 | 
			
		||||
    , m_scale(1.0f)
 | 
			
		||||
    , m_starting_scale(1.0f)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLGizmoScale::on_init()
 | 
			
		||||
{
 | 
			
		||||
    std::string path = resources_dir() + "/icons/overlay/";
 | 
			
		||||
 | 
			
		||||
    std::string filename = path + "scale_off.png";
 | 
			
		||||
    if (!m_textures[Off].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    filename = path + "scale_hover.png";
 | 
			
		||||
    if (!m_textures[Hover].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    filename = path + "scale_on.png";
 | 
			
		||||
    if (!m_textures[On].load_from_file(filename, false))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        m_grabbers.push_back(Grabber());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale::on_start_dragging()
 | 
			
		||||
{
 | 
			
		||||
    if (m_hover_id != -1)
 | 
			
		||||
        m_starting_drag_position = to_2d(m_grabbers[m_hover_id].center);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale::on_update(const Linef3& mouse_ray)
 | 
			
		||||
{
 | 
			
		||||
    Vec2d mouse_pos = to_2d(mouse_ray.intersect_plane(0.0));
 | 
			
		||||
    Vec2d center(0.5 * (m_grabbers[1].center(0) + m_grabbers[0].center(0)), 0.5 * (m_grabbers[3].center(1) + m_grabbers[0].center(1)));
 | 
			
		||||
 | 
			
		||||
    double orig_len = (m_starting_drag_position - center).norm();
 | 
			
		||||
    double new_len = (mouse_pos - center).norm();
 | 
			
		||||
    double ratio = (orig_len != 0.0) ? new_len / orig_len : 1.0;
 | 
			
		||||
 | 
			
		||||
    m_scale = m_starting_scale * (float)ratio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale::on_render(const BoundingBoxf3& box) const
 | 
			
		||||
{
 | 
			
		||||
    if (m_grabbers[0].dragging || m_grabbers[1].dragging || m_grabbers[2].dragging || m_grabbers[3].dragging)
 | 
			
		||||
        set_tooltip(format(100.0f * m_scale, 4) + "%");
 | 
			
		||||
 | 
			
		||||
    ::glDisable(GL_DEPTH_TEST);
 | 
			
		||||
 | 
			
		||||
    double min_x = box.min(0) - (double)Offset;
 | 
			
		||||
    double max_x = box.max(0) + (double)Offset;
 | 
			
		||||
    double min_y = box.min(1) - (double)Offset;
 | 
			
		||||
    double max_y = box.max(1) + (double)Offset;
 | 
			
		||||
 | 
			
		||||
    m_grabbers[0].center = Vec3d(min_x, min_y, 0.0);
 | 
			
		||||
    m_grabbers[1].center = Vec3d(max_x, min_y, 0.0);
 | 
			
		||||
    m_grabbers[2].center = Vec3d(max_x, max_y, 0.0);
 | 
			
		||||
    m_grabbers[3].center = Vec3d(min_x, max_y, 0.0);
 | 
			
		||||
 | 
			
		||||
    ::glLineWidth(2.0f);
 | 
			
		||||
    ::glColor3fv(m_drag_color);
 | 
			
		||||
 | 
			
		||||
    // draw outline
 | 
			
		||||
    ::glBegin(GL_LINE_LOOP);
 | 
			
		||||
    for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        ::glVertex3f((GLfloat)m_grabbers[i].center(0), (GLfloat)m_grabbers[i].center(1), 0.0f);
 | 
			
		||||
    }
 | 
			
		||||
    ::glEnd();
 | 
			
		||||
 | 
			
		||||
    // draw grabbers
 | 
			
		||||
    for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 3 * sizeof(float));
 | 
			
		||||
    }
 | 
			
		||||
    render_grabbers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale::on_render_for_picking(const BoundingBoxf3& box) const
 | 
			
		||||
{
 | 
			
		||||
    ::glDisable(GL_DEPTH_TEST);
 | 
			
		||||
 | 
			
		||||
    for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        m_grabbers[i].color[0] = 1.0f;
 | 
			
		||||
        m_grabbers[i].color[1] = 1.0f;
 | 
			
		||||
        m_grabbers[i].color[2] = picking_color_component(i);
 | 
			
		||||
    }
 | 
			
		||||
    render_grabbers_for_picking();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const float GLGizmoScale3D::Offset = 5.0f;
 | 
			
		||||
 | 
			
		||||
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent)
 | 
			
		||||
    : GLGizmoBase(parent)
 | 
			
		||||
    , m_scale_x(1.0f)
 | 
			
		||||
    , m_scale_y(1.0f)
 | 
			
		||||
    , m_scale_z(1.0f)
 | 
			
		||||
    , m_starting_scale_x(1.0f)
 | 
			
		||||
    , m_starting_scale_y(1.0f)
 | 
			
		||||
    , m_starting_scale_z(1.0f)
 | 
			
		||||
    , m_scale(Vec3d::Ones())
 | 
			
		||||
    , m_starting_scale(Vec3d::Ones())
 | 
			
		||||
    , m_starting_center(Vec3d::Zero())
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -832,15 +642,15 @@ bool GLGizmoScale3D::on_init()
 | 
			
		|||
        m_grabbers.push_back(Grabber());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    float half_pi = 0.5f * (float)PI;
 | 
			
		||||
    double half_pi = 0.5 * (double)PI;
 | 
			
		||||
 | 
			
		||||
    // x axis
 | 
			
		||||
    m_grabbers[0].angle_y = half_pi;
 | 
			
		||||
    m_grabbers[1].angle_y = half_pi;
 | 
			
		||||
    m_grabbers[0].angles(1) = half_pi;
 | 
			
		||||
    m_grabbers[1].angles(1) = half_pi;
 | 
			
		||||
 | 
			
		||||
    // y axis
 | 
			
		||||
    m_grabbers[2].angle_x = half_pi;
 | 
			
		||||
    m_grabbers[3].angle_x = half_pi;
 | 
			
		||||
    m_grabbers[2].angles(0) = half_pi;
 | 
			
		||||
    m_grabbers[3].angles(0) = half_pi;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -869,16 +679,16 @@ void GLGizmoScale3D::on_update(const Linef3& mouse_ray)
 | 
			
		|||
void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
 | 
			
		||||
{
 | 
			
		||||
    if (m_grabbers[0].dragging || m_grabbers[1].dragging)
 | 
			
		||||
        set_tooltip("X: " + format(100.0f * m_scale_x, 4) + "%");
 | 
			
		||||
        set_tooltip("X: " + format(100.0f * m_scale(0), 4) + "%");
 | 
			
		||||
    else if (m_grabbers[2].dragging || m_grabbers[3].dragging)
 | 
			
		||||
        set_tooltip("Y: " + format(100.0f * m_scale_y, 4) + "%");
 | 
			
		||||
        set_tooltip("Y: " + format(100.0f * m_scale(1), 4) + "%");
 | 
			
		||||
    else if (m_grabbers[4].dragging || m_grabbers[5].dragging)
 | 
			
		||||
        set_tooltip("Z: " + format(100.0f * m_scale_z, 4) + "%");
 | 
			
		||||
        set_tooltip("Z: " + format(100.0f * m_scale(2), 4) + "%");
 | 
			
		||||
    else if (m_grabbers[6].dragging || m_grabbers[7].dragging || m_grabbers[8].dragging || m_grabbers[9].dragging)
 | 
			
		||||
    {
 | 
			
		||||
        std::string tooltip = "X: " + format(100.0f * m_scale_x, 4) + "%\n";
 | 
			
		||||
        tooltip += "Y: " + format(100.0f * m_scale_y, 4) + "%\n";
 | 
			
		||||
        tooltip += "Z: " + format(100.0f * m_scale_z, 4) + "%";
 | 
			
		||||
        std::string tooltip = "X: " + format(100.0f * m_scale(0), 4) + "%\n";
 | 
			
		||||
        tooltip += "Y: " + format(100.0f * m_scale(1), 4) + "%\n";
 | 
			
		||||
        tooltip += "Z: " + format(100.0f * m_scale(2), 4) + "%";
 | 
			
		||||
        set_tooltip(tooltip);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1025,7 +835,7 @@ void GLGizmoScale3D::do_scale_x(const Linef3& mouse_ray)
 | 
			
		|||
    double ratio = calc_ratio(1, mouse_ray, m_starting_center);
 | 
			
		||||
 | 
			
		||||
    if (ratio > 0.0)
 | 
			
		||||
        m_scale_x = m_starting_scale_x * (float)ratio;
 | 
			
		||||
        m_scale(0) = m_starting_scale(0) * ratio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray)
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,8 +843,8 @@ void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray)
 | 
			
		|||
    double ratio = calc_ratio(2, mouse_ray, m_starting_center);
 | 
			
		||||
 | 
			
		||||
    if (ratio > 0.0)
 | 
			
		||||
        m_scale_x = m_starting_scale_y * (float)ratio; // << this is temporary
 | 
			
		||||
//        m_scale_y = m_starting_scale_y * (float)ratio;
 | 
			
		||||
        m_scale(0) = m_starting_scale(1) * ratio; // << this is temporary
 | 
			
		||||
//        m_scale(1) = m_starting_scale(1) * ratio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray)
 | 
			
		||||
| 
						 | 
				
			
			@ -1042,8 +852,8 @@ void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray)
 | 
			
		|||
    double ratio = calc_ratio(1, mouse_ray, m_starting_center);
 | 
			
		||||
 | 
			
		||||
    if (ratio > 0.0)
 | 
			
		||||
        m_scale_x = m_starting_scale_z * (float)ratio; // << this is temporary
 | 
			
		||||
//        m_scale_z = m_starting_scale_z * (float)ratio;
 | 
			
		||||
        m_scale(0) = m_starting_scale(2) * ratio; // << this is temporary
 | 
			
		||||
//        m_scale(2) = m_starting_scale(2) * ratio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLGizmoScale3D::do_scale_uniform(const Linef3& mouse_ray)
 | 
			
		||||
| 
						 | 
				
			
			@ -1053,11 +863,7 @@ void GLGizmoScale3D::do_scale_uniform(const Linef3& mouse_ray)
 | 
			
		|||
    double ratio = calc_ratio(0, mouse_ray, center);
 | 
			
		||||
 | 
			
		||||
    if (ratio > 0.0)
 | 
			
		||||
    {
 | 
			
		||||
        m_scale_x = m_starting_scale_x * (float)ratio;
 | 
			
		||||
        m_scale_y = m_starting_scale_y * (float)ratio;
 | 
			
		||||
        m_scale_z = m_starting_scale_z * (float)ratio;
 | 
			
		||||
    }
 | 
			
		||||
        m_scale = m_starting_scale * ratio;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double GLGizmoScale3D::calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,6 @@
 | 
			
		|||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#define ENABLE_GIZMOS_3D 1
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
class BoundingBoxf3;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,30 +26,18 @@ protected:
 | 
			
		|||
        static const float DraggingScaleFactor;
 | 
			
		||||
 | 
			
		||||
        Vec3d center;
 | 
			
		||||
        float angle_x;
 | 
			
		||||
        float angle_y;
 | 
			
		||||
        float angle_z;
 | 
			
		||||
        Vec3d angles;
 | 
			
		||||
        float color[3];
 | 
			
		||||
        bool dragging;
 | 
			
		||||
 | 
			
		||||
        Grabber();
 | 
			
		||||
 | 
			
		||||
        void render(bool hover) const;
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
        void render_for_picking() const { render(color, false); }
 | 
			
		||||
#else
 | 
			
		||||
        void render_for_picking() const { render(color); }
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
        void render(const float* render_color, bool use_lighting) const;
 | 
			
		||||
#else
 | 
			
		||||
        void render(const float* render_color) const;
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
#if ENABLE_GIZMOS_3D
 | 
			
		||||
        void render_face(float half_size) const;
 | 
			
		||||
#endif // ENABLE_GIZMOS_3D
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +132,7 @@ public:
 | 
			
		|||
 | 
			
		||||
private:
 | 
			
		||||
    Axis m_axis;
 | 
			
		||||
    float m_angle;
 | 
			
		||||
    double m_angle;
 | 
			
		||||
 | 
			
		||||
    mutable Vec3d m_center;
 | 
			
		||||
    mutable float m_radius;
 | 
			
		||||
| 
						 | 
				
			
			@ -155,8 +141,8 @@ private:
 | 
			
		|||
public:
 | 
			
		||||
    GLGizmoRotate(GLCanvas3D& parent, Axis axis);
 | 
			
		||||
 | 
			
		||||
    float get_angle() const { return m_angle; }
 | 
			
		||||
    void set_angle(float angle);
 | 
			
		||||
    double get_angle() const { return m_angle; }
 | 
			
		||||
    void set_angle(double angle);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual bool on_init();
 | 
			
		||||
| 
						 | 
				
			
			@ -188,14 +174,14 @@ class GLGizmoRotate3D : public GLGizmoBase
 | 
			
		|||
public:
 | 
			
		||||
    explicit GLGizmoRotate3D(GLCanvas3D& parent);
 | 
			
		||||
 | 
			
		||||
    float get_angle_x() const { return m_x.get_angle(); }
 | 
			
		||||
    void set_angle_x(float angle) { m_x.set_angle(angle); }
 | 
			
		||||
    double get_angle_x() const { return m_x.get_angle(); }
 | 
			
		||||
    void set_angle_x(double angle) { m_x.set_angle(angle); }
 | 
			
		||||
 | 
			
		||||
    float get_angle_y() const { return m_y.get_angle(); }
 | 
			
		||||
    void set_angle_y(float angle) { m_y.set_angle(angle); }
 | 
			
		||||
    double get_angle_y() const { return m_y.get_angle(); }
 | 
			
		||||
    void set_angle_y(double angle) { m_y.set_angle(angle); }
 | 
			
		||||
 | 
			
		||||
    float get_angle_z() const { return m_z.get_angle(); }
 | 
			
		||||
    void set_angle_z(float angle) { m_z.set_angle(angle); }
 | 
			
		||||
    double get_angle_z() const { return m_z.get_angle(); }
 | 
			
		||||
    void set_angle_z(double angle) { m_z.set_angle(angle); }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual bool on_init();
 | 
			
		||||
| 
						 | 
				
			
			@ -234,64 +220,31 @@ protected:
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GLGizmoScale : public GLGizmoBase
 | 
			
		||||
{
 | 
			
		||||
    static const float Offset;
 | 
			
		||||
 | 
			
		||||
    float m_scale;
 | 
			
		||||
    float m_starting_scale;
 | 
			
		||||
 | 
			
		||||
    Vec2d m_starting_drag_position;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit GLGizmoScale(GLCanvas3D& parent);
 | 
			
		||||
 | 
			
		||||
    float get_scale() const { return m_scale; }
 | 
			
		||||
    void set_scale(float scale) { m_starting_scale = scale; }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual bool on_init();
 | 
			
		||||
    virtual void on_start_dragging();
 | 
			
		||||
    virtual void on_update(const Linef3& mouse_ray);
 | 
			
		||||
    virtual void on_render(const BoundingBoxf3& box) const;
 | 
			
		||||
    virtual void on_render_for_picking(const BoundingBoxf3& box) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GLGizmoScale3D : public GLGizmoBase
 | 
			
		||||
{
 | 
			
		||||
    static const float Offset;
 | 
			
		||||
 | 
			
		||||
    mutable BoundingBoxf3 m_box;
 | 
			
		||||
 | 
			
		||||
    float m_scale_x;
 | 
			
		||||
    float m_scale_y;
 | 
			
		||||
    float m_scale_z;
 | 
			
		||||
 | 
			
		||||
    float m_starting_scale_x;
 | 
			
		||||
    float m_starting_scale_y;
 | 
			
		||||
    float m_starting_scale_z;
 | 
			
		||||
    Vec3d m_scale;
 | 
			
		||||
 | 
			
		||||
    Vec3d m_starting_scale;
 | 
			
		||||
    Vec3d m_starting_drag_position;
 | 
			
		||||
    Vec3d m_starting_center;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit GLGizmoScale3D(GLCanvas3D& parent);
 | 
			
		||||
 | 
			
		||||
    float get_scale_x() const { return m_scale_x; }
 | 
			
		||||
    void set_scale_x(float scale) { m_starting_scale_x = scale; }
 | 
			
		||||
    double get_scale_x() const { return m_scale(0); }
 | 
			
		||||
    void set_scale_x(double scale) { m_starting_scale(0) = scale; }
 | 
			
		||||
 | 
			
		||||
    float get_scale_y() const { return m_scale_y; }
 | 
			
		||||
    void set_scale_y(float scale) { m_starting_scale_y = scale; }
 | 
			
		||||
    double get_scale_y() const { return m_scale(1); }
 | 
			
		||||
    void set_scale_y(double scale) { m_starting_scale(1) = scale; }
 | 
			
		||||
 | 
			
		||||
    float get_scale_z() const { return m_scale_z; }
 | 
			
		||||
    void set_scale_z(float scale) { m_starting_scale_z = scale; }
 | 
			
		||||
    double get_scale_z() const { return m_scale(2); }
 | 
			
		||||
    void set_scale_z(double scale) { m_starting_scale(2) = scale; }
 | 
			
		||||
 | 
			
		||||
    void set_scale(float scale)
 | 
			
		||||
    {
 | 
			
		||||
        m_starting_scale_x = scale;
 | 
			
		||||
        m_starting_scale_y = scale;
 | 
			
		||||
        m_starting_scale_z = scale;
 | 
			
		||||
    }
 | 
			
		||||
    void set_scale(double scale) { m_starting_scale = scale * Vec3d::Ones(); }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual bool on_init();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue