Horizon
canvas3d_base.hpp
1 #pragma once
2 #include <glm/glm.hpp>
3 #include "common/common.hpp"
4 #include "canvas_mesh.hpp"
5 #include "canvas/appearance.hpp"
6 #include "util/uuid.hpp"
7 #include <mutex>
8 #include "cover_renderer.hpp"
9 #include "face_renderer.hpp"
10 #include "wall_renderer.hpp"
11 #include "background_renderer.hpp"
12 #include "point_renderer.hpp"
13 #include "import_step/import.hpp"
14 #include "point.hpp"
15 #include <sigc++/sigc++.h>
16 #include <variant>
17 
18 namespace horizon {
19 
20 class Canvas3DBase {
21 public:
22  Canvas3DBase();
23  friend class CoverRenderer;
24  friend class WallRenderer;
25  friend class FaceRenderer;
26  friend class BackgroundRenderer;
27  friend class PointRenderer;
28  Color get_layer_color(int layer) const;
29 
30  enum class Projection { PERSP, ORTHO };
31 
32 #define GET_SET_X(x_, t_, f_) \
33  const auto &get_##x_() const \
34  { \
35  return x_; \
36  } \
37  void set_##x_(const t_ &c) \
38  { \
39  x_ = c; \
40  redraw(); \
41  f_ \
42  }
43 
44 #define GET_SET(x_, t_) GET_SET_X(x_, t_, )
45 #define GET_SET_PICK(x_, t_) GET_SET_X(x_, t_, invalidate_pick();)
46 
47  GET_SET(background_top_color, Color)
48  GET_SET(background_bottom_color, Color)
49  GET_SET_PICK(show_solder_mask, bool)
50  GET_SET_PICK(show_silkscreen, bool)
51  GET_SET_PICK(show_substrate, bool)
52  GET_SET_PICK(show_models, bool)
53  GET_SET_PICK(show_dnp_models, bool)
54  GET_SET_PICK(show_solder_paste, bool)
55  GET_SET_PICK(show_copper, bool)
56  GET_SET_PICK(show_points, bool)
57  GET_SET(use_layer_colors, bool)
58  GET_SET(solder_mask_color, Color)
59  GET_SET(silkscreen_color, Color)
60  GET_SET(substrate_color, Color)
61  GET_SET_PICK(explode, float)
62  GET_SET_PICK(cam_distance, float)
63  GET_SET_PICK(cam_fov, float)
64  GET_SET_PICK(center, glm::vec2)
65  GET_SET_PICK(projection, Projection)
66 
67 #undef GET_SET
68 #undef GET_SET_X
69 #undef GET_SET_PICK
70 
71  const float &get_cam_elevation() const
72  {
73  return cam_elevation;
74  }
75  void set_cam_elevation(const float &ele);
76 
77  const float &get_cam_azimuth() const
78  {
79  return cam_azimuth;
80  }
81  void set_cam_azimuth(const float &az);
82 
83  struct ViewParams {
84  float cx;
85  float cy;
86  float cam_distance;
87  float cam_azimuth;
88  float cam_elevation;
89  };
90  std::optional<ViewParams> get_view_all_params() const;
91  void view_all();
92 
93  void clear_3d_models();
94  void set_point_transform(const glm::dmat4 &mat);
95  void set_points(const std::vector<Point3D> &points);
96 
97  struct BBox {
98  float xl, yl, zl, xh, yh, zh;
99  };
100 
101  BBox get_model_bbox(const std::string &filename) const;
102 
103  typedef sigc::signal<void> type_signal_view_changed;
104  type_signal_view_changed signal_view_changed()
105  {
106  return s_signal_view_changed;
107  }
108 
109  bool model_is_loaded(const std::string &filename);
110 
111 protected:
112  CanvasMesh ca;
113 
114  Appearance appearance;
115 
116  Color background_top_color;
117  Color background_bottom_color;
118  bool show_solder_mask = true;
119  bool show_silkscreen = true;
120  bool show_substrate = true;
121  bool show_models = true;
122  bool show_dnp_models = false;
123  bool show_solder_paste = true;
124  bool use_layer_colors = false;
125  bool show_copper = true;
126  bool show_points = false;
127  Color solder_mask_color = {0, .5, 0};
128  Color silkscreen_color = {1, 1, 1};
129  Color substrate_color = {.2, .15, 0};
130  float explode = 0;
131  float highlight_intensity = .5;
132 
133  float cam_azimuth = 90;
134  float cam_elevation = 45;
135  float cam_distance = 20;
136  float cam_fov = 45;
137  glm::vec2 center;
138 
139  Projection projection = Projection::PERSP;
140 
141 
142  int width = 100;
143  int height = 100;
144 
145  CoverRenderer cover_renderer;
146  WallRenderer wall_renderer;
147  FaceRenderer face_renderer;
148  BackgroundRenderer background_renderer;
149  PointRenderer point_renderer;
150 
151  void a_realize();
152  void resize_buffers();
153  void push();
154  enum class RenderBackground { YES, NO };
155  void render(RenderBackground mode = RenderBackground::YES);
156  virtual int a_get_scale_factor() const;
157  virtual void redraw()
158  {
159  }
160  void invalidate_pick();
161  void prepare();
162  void prepare_packages();
163 
164  unsigned int num_samples = 1;
165 
166  const class Board *brd = nullptr;
167 
168  std::set<UUID> packages_highlight;
169 
170  void load_3d_model(const std::string &filename, const std::string &filename_abs);
171 
172  std::map<std::string, std::string> get_model_filenames(class IPool &pool);
173 
174  std::mutex models_loading_mutex;
175 
176  void update_max_package_height();
177 
178  void queue_pick();
179  typedef sigc::signal<void> type_signal_pick_ready;
180  type_signal_pick_ready signal_pick_ready()
181  {
182  return s_signal_pick_ready;
183  }
184  std::variant<UUID, glm::dvec3> pick_package_or_point(unsigned int x, unsigned int y) const;
185 
186  virtual STEPImporter::Faces import_step(const std::string &filename_rel, const std::string &filename_abs);
187 
188  virtual std::optional<std::pair<std::string, std::string>> get_model_filename(const class BoardPackage &pkg,
189  IPool &pool);
190 
191  virtual const std::map<int, CanvasMesh::Layer3D> &get_layers() const;
192  const CanvasMesh::Layer3D &get_layer(int layer) const;
193 
194 private:
195  class FaceVertex {
196  public:
197  FaceVertex(float ix, float iy, float iz, float inx, float iny, float inz, uint8_t ir, uint8_t ig, uint8_t ib)
198  : x(ix), y(iy), z(iz), nx(inx), ny(iny), nz(inz), r(ir), g(ig), b(ib), _pad(0)
199  {
200  }
201  float x;
202  float y;
203  float z;
204  float nx;
205  float ny;
206  float nz;
207 
208  uint8_t r;
209  uint8_t g;
210  uint8_t b;
211  uint8_t _pad;
212  } __attribute__((packed));
213 
214  class ModelTransform {
215  public:
216  ModelTransform(float ix, float iy, float a, bool flip, bool highlight)
217  : x(ix), y(iy), angle(a), flags(flip | (highlight << 1))
218  {
219  }
220  float x;
221  float y;
222  uint16_t angle;
223  uint16_t flags;
224 
225  float model_x = 0;
226  float model_y = 0;
227  float model_z = 0;
228  uint16_t model_roll = 0;
229  uint16_t model_pitch = 0;
230  uint16_t model_yaw = 0;
231  } __attribute__((packed));
232 
233  float get_layer_offset(int layer) const;
234  float get_layer_thickness(int layer) const;
235  bool layer_is_visible(int layer) const;
236 
237  std::pair<glm::vec3, glm::vec3> bbox;
238 
239  GLuint renderbuffer;
240  GLuint fbo;
241  GLuint depthrenderbuffer;
242  GLuint pickrenderbuffer;
243 
244  GLuint fbo_downsampled;
245  GLuint pickrenderbuffer_downsampled;
246 
247  enum class PickState { QUEUED, CURRENT, INVALID };
248  PickState pick_state = PickState::INVALID;
249 
250  glm::mat4 viewmat;
251  glm::mat4 projmat;
252  glm::vec3 cam_normal;
253 
254  float package_height_max = 0;
255  std::vector<FaceVertex> face_vertex_buffer; // vertices of all models, sequentially
256  std::vector<unsigned int> face_index_buffer; // indexes face_vertex_buffer to form triangles
257 
258  class ModelInfo {
259  public:
260  ModelInfo(size_t o, size_t n) : face_index_offset(o), count(n)
261  {
262  }
263  const size_t face_index_offset; // offset in face_index_buffer
264  const size_t count; // number of items in face_index_buffer
265  bool pushed = false;
266  };
267  std::map<std::string, ModelInfo> models; // key: filename
268 
269  std::vector<ModelTransform> package_transforms; // position and rotation of
270  // all board packages,
271  // grouped by package
272 
273  struct PackageInfo {
274  size_t offset; // in package_transforms
275  size_t n_packages;
276  unsigned int pick_base;
277  std::vector<UUID> pkg;
278  };
279 
280  std::map<std::pair<std::string, bool>, PackageInfo> package_infos; // key: first: model filename second: nopopulate
281  std::vector<uint16_t> pick_buf;
282 
283  uint16_t point_pick_base = 0;
284  std::vector<Point3D> points;
285  glm::dmat4 point_mat;
286  size_t n_points = 0;
287 
288  float get_magic_number() const;
289 
290  type_signal_pick_ready s_signal_pick_ready;
291  type_signal_view_changed s_signal_view_changed;
292 };
293 
294 } // namespace horizon
Definition: appearance.hpp:7
Definition: background_renderer.hpp:5
Definition: canvas3d_base.hpp:20
Definition: canvas_mesh.hpp:8
Definition: common.hpp:270
Definition: cover_renderer.hpp:7
Definition: face_renderer.hpp:6
Definition: point_renderer.hpp:6
Definition: wall_renderer.hpp:7
Definition: canvas3d_base.hpp:97
Definition: canvas3d_base.hpp:83