Horizon
canvas3d.hpp
1 #pragma once
2 #include "background.hpp"
3 #include "canvas/canvas_patch.hpp"
4 #include "clipper/clipper.hpp"
5 #include "common/common.hpp"
6 #include "cover.hpp"
7 #include "face.hpp"
8 #include "wall.hpp"
9 #include <epoxy/gl.h>
10 #include <glm/glm.hpp>
11 #include <gtkmm.h>
12 #include <unordered_map>
13 
14 namespace horizon {
15 class Canvas3D : public Gtk::GLArea, public CanvasPatch {
16 public:
17  friend CoverRenderer;
18  friend WallRenderer;
19  friend FaceRenderer;
20  friend BackgroundRenderer;
21  Canvas3D();
22 
23  float cam_azimuth = 90;
24  float cam_elevation = 45;
25  float cam_distance = 20;
26  float cam_fov = 45;
27 
28  float far;
29  float near;
30 
31  float explode = 0;
32  Color solder_mask_color;
33  bool show_solder_mask = true;
34  bool show_silkscreen = true;
35  bool show_substrate = true;
36  bool show_models = true;
37 
38  Color background_top_color;
39  Color background_bottom_color;
40 
41  void request_push();
42  void update2(const class Board &brd);
43  void prepare();
44 
45  void set_msaa(unsigned int samples);
46 
47  void load_models_async(class Pool *pool);
48 
49  void load_3d_model(const std::string &filename, const std::string &base_path);
50  void clear_3d_models();
51 
52  typedef sigc::signal<void, bool> type_signal_models_loading;
53  type_signal_models_loading signal_models_loading()
54  {
55  return s_signal_models_loading;
56  }
57 
58  class Layer3D {
59  public:
60  class Vertex {
61  public:
62  Vertex(float ix, float iy) : x(ix), y(iy)
63  {
64  }
65 
66  float x, y;
67  };
68  std::vector<Vertex> tris;
69  std::vector<Vertex> walls;
70  float offset = 0;
71  float thickness = 0.035;
72  float alpha = 1;
73  float explode_mul = 0;
74  Color color;
75  };
76 
77  class FaceVertex {
78  public:
79  FaceVertex(float ix, float iy, float iz, uint8_t ir, uint8_t ig, uint8_t ib)
80  : x(ix), y(iy), z(iz), r(ir), g(ig), b(ib), _pad(0)
81  {
82  }
83  float x;
84  float y;
85  float z;
86 
87  uint8_t r;
88  uint8_t g;
89  uint8_t b;
90  uint8_t _pad;
91  } __attribute__((packed));
92 
94  public:
95  ModelTransform(float ix, float iy, float a, bool f) : x(ix), y(iy), angle(a), flip(f)
96  {
97  }
98  float x;
99  float y;
100  uint16_t angle;
101  int16_t flip;
102 
103  float model_x = 0;
104  float model_y = 0;
105  float model_z = 0;
106  uint16_t model_roll = 0;
107  uint16_t model_pitch = 0;
108  uint16_t model_yaw = 0;
109  } __attribute__((packed));
110 
111 private:
112  float width;
113  float height;
114  void push();
115  bool needs_push = false;
116 
117  CoverRenderer cover_renderer;
118  WallRenderer wall_renderer;
119  FaceRenderer face_renderer;
120  BackgroundRenderer background_renderer;
121 
122  void on_size_allocate(Gtk::Allocation &alloc) override;
123  void on_realize() override;
124  bool on_render(const Glib::RefPtr<Gdk::GLContext> &context) override;
125  bool on_button_press_event(GdkEventButton *button_event) override;
126  bool on_motion_notify_event(GdkEventMotion *motion_event) override;
127  bool on_button_release_event(GdkEventButton *button_event) override;
128  bool on_scroll_event(GdkEventScroll *scroll_event) override;
129 
130  glm::vec2 pointer_pos_orig;
131  float cam_azimuth_orig;
132  float cam_elevation_orig;
133 
134  glm::vec2 center;
135  glm::vec2 center_orig;
136  glm::vec3 cam_normal;
137 
138  std::pair<glm::vec3, glm::vec3> bbox;
139  float package_height_max = 0;
140 
141  enum class PanMode { NONE, MOVE, ROTATE };
142  PanMode pan_mode = PanMode::NONE;
143 
144  glm::mat4 viewmat;
145  glm::mat4 projmat;
146 
147  GLuint renderbuffer;
148  GLuint fbo;
149  GLuint depthrenderbuffer;
150  unsigned int num_samples = 1;
151  bool needs_resize = false;
152 
153  void resize_buffers();
154 
155  void polynode_to_tris(const ClipperLib::PolyNode *node, int layer);
156 
157  void prepare_layer(int layer);
158  void prepare_soldermask(int layer);
159  void prepare_packages();
160  float get_layer_offset(int layer);
161  const class Board *brd = nullptr;
162  void add_path(int layer, const ClipperLib::Path &path);
163 
164  void load_models_thread(std::set<std::string> model_filenames, std::string base_path);
165 
166  std::unordered_map<int, Layer3D> layers;
167 
168  std::mutex models_loading_mutex;
169  std::vector<FaceVertex> face_vertex_buffer; // vertices of all models, sequentially
170  std::vector<unsigned int> face_index_buffer; // indexes face_vertex_buffer to form triangles
171  std::map<std::string, std::pair<size_t, size_t>> models; // key: filename value: first: offset in face_index_buffer
172  // second: no of indexes
173  Glib::Dispatcher models_loading_dispatcher;
174 
175  std::vector<ModelTransform> package_transforms; // position and rotation of
176  // all board packages,
177  // grouped by package
178  std::map<std::string, std::pair<size_t, size_t>>
179  package_transform_idxs; // key: model filename: value: first: offset
180  // in package_transforms second: no of items
181 
182  type_signal_models_loading s_signal_models_loading;
183 };
184 } // namespace horizon
Definition: cover.hpp:6
Definition: wall.hpp:6
Definition: canvas_patch.hpp:6
Definition: canvas3d.hpp:58
Definition: clipper.hpp:136
Definition: canvas3d.hpp:93
Definition: canvas3d.hpp:77
Definition: board.hpp:28
Definition: face.hpp:6
Definition: canvas3d.hpp:60
Stores objects (Unit, Entity, Symbol, Part, etc.) from the pool.
Definition: pool.hpp:18
Definition: block.cpp:7
Definition: canvas3d.hpp:15
Definition: common.hpp:205
Definition: background.hpp:5