Thu, 15 Jun 2023 16:18:03 +0300
Refactor, make selecting elements from the model select the corresponding line from the editor as well
#pragma once #include "src/basics.h" #include "src/documentmanager.h" #include "src/types/boundingbox.h" #include "src/gl/common.h" #include "src/gl/compiler.h" #include <QOpenGLWidget> class PartRenderer final : public QOpenGLWidget { Q_OBJECT QTextDocument* const model; DocumentManager* const documents; const ColorTable& colorTable; BoundingBox boundingBox; gl::ModelShaders shaders; ModelId highlighted = {0}; glm::mat4 projectionMatrix; glm::mat4 viewMatrix; glm::mat4 modelMatrix; glm::vec4 viewportVector; glm::quat modelQuaternion; glm::vec3 modelViewOrigin = {0, 0, 0}; QPoint lastMousePosition; int totalMouseMove = 0; double zoom = 1.0; bool initialized = false; bool needBuild = true; std::vector<RenderLayer*> activeRenderLayers; std::vector<RenderLayer*> inactiveRenderLayers; std::chrono::time_point<std::chrono::steady_clock> lastClickTime; bool frozen = false; public: static const gl::RenderPreferences default_render_preferences; static const gl::build_preferences default_build_preferences; const gl::RenderPreferences* render_preferences = &PartRenderer::default_render_preferences; const gl::build_preferences* build_preferences = &PartRenderer::default_build_preferences; PartRenderer( QTextDocument* model, DocumentManager* documents, const ColorTable& colorTable, QWidget* parent = nullptr); ~PartRenderer() override; ModelId getHighlightedObject() const; void addRenderLayer(RenderLayer* layer); void setLayerEnabled(RenderLayer* layer, bool enabled); std::optional<glm::vec3> screenToModelCoordinates(const QPointF& point, const Plane& plane) const; QPointF modelToScreenCoordinates(const glm::vec3& point) const; bool isDark() const; std::int32_t pick(QPoint where); void setSelection(const QSet<std::int32_t>& selectedIds); glm::vec3 cameraVector(const QPointF& point) const; Line<3> cameraLine(const QPointF& point) const; Q_SLOT void setModelViewOrigin(const glm::vec3& newViewOrigin); Q_SLOT void build(); Q_SIGNALS: void projectionMatrixChanged(const glm::mat4& newMatrix); void modelMatrixChanged(const glm::mat4& newMatrix); void viewMatrixChanged(const glm::mat4& newMatrix); void message(const Message& message); private: void initializeGL() override; void resizeGL(int width, int height) override; void paintGL() override; void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; void wheelEvent(QWheelEvent* event) override; glm::vec3 unproject(const glm::vec3& win) const; void setFragmentStyle(gl::FragmentStyle fragStyle); void renderScene(const gl::RenderPreferences* preferences); void updateViewMatrix(); void updateModelMatrix(); void renderVao(const gl::ArrayClass arrayClass, const GLenum glType); template<gl::ArrayClass arrayClass> void renderVao(); void checkForGLErrors(); }; inline constexpr opt<GLenum> getGlTypeForArrayClass(const gl::ArrayClass vboClass) { switch (vboClass) { case gl::ArrayClass::Lines: case gl::ArrayClass::ConditionalLines: return GL_LINES; case gl::ArrayClass::Triangles: return GL_TRIANGLES; case gl::ArrayClass::Quads: return GL_QUADS; } return {}; } template<gl::ArrayClass arrayClass> void PartRenderer::renderVao() { constexpr opt<GLenum> glType = getGlTypeForArrayClass(arrayClass); static_assert(glType.has_value()); this->renderVao(arrayClass, *glType); } inline QVector<QPointF> convertWorldPointsToScreenPoints( const std::vector<glm::vec3> &worldPoints, const PartRenderer* renderer) { QVector<QPointF> points2d; points2d.reserve(static_cast<int>(worldPoints.size())); for (const glm::vec3& point : worldPoints) { points2d.push_back(renderer->modelToScreenCoordinates(point)); } return points2d; } inline winding_e worldPolygonWinding( const std::vector<glm::vec3> &points, const PartRenderer* renderer) { return calculate_polygon_winding(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); } inline void drawWorldPoint( QPainter* painter, const glm::vec3& worldPoint, const PartRenderer* renderer) { const QPointF center = renderer->modelToScreenCoordinates(worldPoint); painter->drawEllipse(inscribe(CircleF{center, 5})); } inline void drawWorldPolyline( QPainter *painter, const std::vector<glm::vec3> &points, const PartRenderer* renderer) { painter->drawPolyline(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); } inline void drawWorldPolygon( QPainter* painter, const std::vector<glm::vec3> &points, const PartRenderer* renderer) { painter->drawPolygon(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); }