//################################################################################################################################ // PrusaSlicer development only -> !!!TO BE REMOVED!!! #include "libslic3r/Technologies.hpp" //################################################################################################################################ ///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966 ///|/ ///|/ libvgcode is released under the terms of the AGPLv3 or higher ///|/ #include "CogMarker.hpp" #include "OpenGLUtils.hpp" #include "Utils.hpp" #include #include #include //################################################################################################################################ // PrusaSlicer development only -> !!!TO BE REMOVED!!! #if ENABLE_NEW_GCODE_VIEWER //################################################################################################################################ namespace libvgcode { CogMarker::~CogMarker() { if (m_ibo_id != 0) glsafe(glDeleteBuffers(1, &m_ibo_id)); if (m_vbo_id != 0) glsafe(glDeleteBuffers(1, &m_vbo_id)); if (m_vao_id != 0) glsafe(glDeleteVertexArrays(1, &m_vao_id)); } // Geometry: // sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius' void CogMarker::init(uint8_t resolution, float radius) { if (m_vao_id != 0) return; // ensure vertices count does not exceed 65536 resolution = std::clamp(resolution, 4, 105); const uint16_t sector_count = (uint16_t)resolution; const uint16_t stack_count = (uint16_t)resolution; const float sector_step = 2.0f * PI / float(sector_count); const float stack_step = PI / float(stack_count); std::vector vertices; const uint16_t vertices_count = (stack_count - 1) * sector_count + 2; vertices.reserve(6 * vertices_count); m_indices_count = 3 * (2 * (stack_count - 1) * sector_count); std::vector indices; indices.reserve(m_indices_count); // vertices for (uint16_t i = 0; i <= stack_count; ++i) { // from pi/2 to -pi/2 const float stack_angle = 0.5f * PI - stack_step * float(i); const float xy = radius * std::cos(stack_angle); const float z = radius * std::sin(stack_angle); if (i == 0 || i == stack_count) { const Vec3f pos = toVec3f(xy, 0.0f, z); const Vec3f norm = normalize(pos); add_vertex(pos, norm, vertices); } else { for (uint16_t j = 0; j < sector_count; ++j) { // from 0 to 2pi const float sector_angle = sector_step * float(j); const Vec3f pos = toVec3f(xy * std::cos(sector_angle), xy * std::sin(sector_angle), z); const Vec3f norm = normalize(pos); add_vertex(pos, norm, vertices); } } } // indices for (uint16_t i = 0; i < stack_count; ++i) { // Beginning of current stack. uint16_t k1 = (i == 0) ? 0 : (1 + (i - 1) * sector_count); const uint16_t k1_first = k1; // Beginning of next stack. uint16_t k2 = (i == 0) ? 1 : (k1 + sector_count); const uint16_t k2_first = k2; for (uint16_t j = 0; j < sector_count; ++j) { // 2 triangles per sector excluding first and last stacks uint16_t k1_next = k1; uint16_t k2_next = k2; if (i != 0) { k1_next = (j + 1 == sector_count) ? k1_first : (k1 + 1); add_triangle(k1, k2, k1_next, indices); } if (i + 1 != stack_count) { k2_next = (j + 1 == sector_count) ? k2_first : (k2 + 1); add_triangle(k1_next, k2, k2_next, indices); } k1 = k1_next; k2 = k2_next; } } const size_t vertex_stride = 6 * sizeof(float); const size_t position_offset = 0; const size_t normal_offset = 3 * sizeof(float); int curr_vertex_array; glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); int curr_array_buffer; glsafe(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &curr_array_buffer)); glsafe(glGenVertexArrays(1, &m_vao_id)); glsafe(glBindVertexArray(m_vao_id)); glsafe(glGenBuffers(1, &m_vbo_id)); glsafe(glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id)); glsafe(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW)); glsafe(glEnableVertexAttribArray(0)); glsafe(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)position_offset)); glsafe(glEnableVertexAttribArray(1)); glsafe(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_stride, (const void*)normal_offset)); glsafe(glGenBuffers(1, &m_ibo_id)); glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo_id)); glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW)); glsafe(glBindBuffer(GL_ARRAY_BUFFER, curr_array_buffer)); glsafe(glBindVertexArray(curr_vertex_array)); } void CogMarker::render() { if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0) return; int curr_vertex_array; glsafe(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &curr_vertex_array)); glcheck(); glsafe(glBindVertexArray(m_vao_id)); glsafe(glDrawElements(GL_TRIANGLES, m_indices_count, GL_UNSIGNED_SHORT, (const void*)0)); glsafe(glBindVertexArray(curr_vertex_array)); } void CogMarker::update(const Vec3f& position, float mass) { m_total_position = m_total_position + toVec3f(mass * position[0], mass * position[1], mass * position[2]); m_total_mass += mass; } void CogMarker::reset() { m_total_position = toVec3f(0.0f, 0.0f, 0.0f); m_total_mass = 0.0f; } Vec3f CogMarker::get_position() const { assert(m_total_mass > 0.0f); const float inv_total_mass = 1.0f / m_total_mass; return { m_total_position[0] * inv_total_mass, m_total_position[1] * inv_total_mass, m_total_position[2] * inv_total_mass }; } } // namespace libvgcode //################################################################################################################################ // PrusaSlicer development only -> !!!TO BE REMOVED!!! #endif // ENABLE_NEW_GCODE_VIEWER //################################################################################################################################