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