BRL-CAD
dbi.h
Go to the documentation of this file.
1 /* D B I . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2008-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup ged_defines
21  *
22  * Experimental
23  *
24  * Geometry EDiting Library structures for reflecting the state of
25  * the database and views.
26  *
27  * These are used to provide a fast, explicit expression in memory of the
28  * database and view states, to allow applications to quickly display
29  * hierarchical information and manipulate view data.
30  *
31  * We want this to be visible to C++ APIs like libqtcad, so they can reflect
32  * the state of the .g hierarchy in their own structures without us or them
33  * having to make copies of the data. Pattern this on how we handle ON_Brep
34  */
35 /** @{ */
36 /** @file ged/defines.h */
37 
38 #ifndef GED_DBI_H
39 #define GED_DBI_H
40 
41 #include "common.h"
42 #include "bu/vls.h"
43 
44 #ifdef __cplusplus
45 #include <set>
46 #include <unordered_map>
47 #include <unordered_set>
48 #include <string>
49 #include <vector>
50 
51 class GED_EXPORT DbiState;
52 
53 class GED_EXPORT BSelectState {
54  public:
56 
57  bool select_path(const char *path, bool update);
58  bool select_hpath(std::vector<unsigned long long> &hpath);
59 
60  bool deselect_path(const char *path, bool update);
61  bool deselect_hpath(std::vector<unsigned long long> &hpath);
62 
63  void clear();
64 
65  bool is_selected(unsigned long long);
66  bool is_active(unsigned long long);
67  bool is_active_parent(unsigned long long);
68  bool is_parent_obj(unsigned long long);
69  bool is_immediate_parent_obj(unsigned long long);
70  bool is_grand_parent_obj(unsigned long long);
71 
72  std::vector<std::string> list_selected_paths();
73 
74  void expand();
75  void collapse();
76 
77  void refresh();
78  bool draw_sync();
79 
80  unsigned long long state_hash();
81 
82  std::unordered_map<unsigned long long, std::vector<unsigned long long>> selected;
83  std::unordered_set<unsigned long long> active_paths; // Solid paths to illuminate
84  std::unordered_set<unsigned long long> active_parents; // Paths above selection
85  // To support highlighting closed paths that have selected primitives
86  // below them, we need more information. This is different than
87  // highlighting only the paths related to the specific selected full
88  // path - in this situation, the application wants to know about all
89  // paths that are above the leaf *object* that is selected, in whatever
90  // portion of the database. Immediate parents are combs whose
91  // immediate child is the selected leaf; grand parents are higher level
92  // combs above immediate parents
93  std::unordered_set<unsigned long long> immediate_parents;
94  std::unordered_set<unsigned long long> grand_parents;
95 
96  void characterize();
97 
98  private:
99  DbiState *dbis;
100 
101  void add_paths(
102  unsigned long long c_hash,
103  std::vector<unsigned long long> &path_hashes
104  );
105 
106  void clear_paths(
107  unsigned long long c_hash,
108  std::vector<unsigned long long> &path_hashes
109  );
110 
111  void expand_paths(
112  std::vector<std::vector<unsigned long long>> &out_paths,
113  unsigned long long c_hash,
114  std::vector<unsigned long long> &path_hashes
115  );
116 
117  void collapse_paths(
118  std::vector<std::vector<unsigned long long>> &out_paths
119  );
120 
121  void clear_paths(std::vector<unsigned long long> &path_hashes, unsigned long long c_hash);
122 };
123 
124 
125 class GED_EXPORT BViewState {
126  public:
128 
129 
130  // Adds path to the BViewState container, but doesn't trigger a re-draw - that
131  // should be done once all paths to be added in a given draw cycle are added.
132  // The actual drawing (and mode specifications) are done with redraw and a
133  // supplied bv_obj_settings structure.
134  void add_path(const char *path);
135  void add_hpath(std::vector<unsigned long long> &path_hashes);
136 
137  // Erases paths from the view for the given mode. If mode < 0, all
138  // matching paths are erased. For modes that are un-evaluated, all
139  // paths that are subsets of the specified path are removed. For
140  // evaluated modes like 3 (bigE) that generate an evaluated visual
141  // specific to that path, only precise path matches are removed
142  void erase_path(int mode, int argc, const char **argv);
143  void erase_hpath(int mode, unsigned long long c_hash, std::vector<unsigned long long> &path_hashes, bool cache_collapse = true);
144 
145  // Return a sorted vector of strings encoding the drawn paths in the
146  // view. If mode == -1 list all paths, otherwise list those specific
147  // to the mode. If list_collapsed is true, return the minimal path set
148  // that captures what is drawn - otherwise, return the direct list of
149  // scene objects
150  std::vector<std::string> list_drawn_paths(int mode, bool list_collapsed);
151 
152  // Get a count of the drawn paths
153  size_t count_drawn_paths(int mode, bool list_collapsed);
154 
155  // Report if a path hash is drawn - 0 == not drawn, 1 == fully drawn, 2 == partially drawn
156  int is_hdrawn(int mode, unsigned long long phash);
157 
158  // Clear all drawn objects (TODO - should allow mode specification here)
159  void clear();
160 
161  // A View State refresh regenerates already drawn objects.
162  unsigned long long refresh(struct bview *v, int argc, const char **argv);
163 
164  // A View State redraw can impact multiple views with a shared state - most of
165  // the elements will be the same, but adaptive plotting will be view specific even
166  // with otherwise common objects - we must update accordingly.
167  unsigned long long redraw(struct bv_obj_settings *vs, std::unordered_set<struct bview *> &views, int no_autoview);
168 
169  // Allow callers to calculate the drawing hash of a path
170  unsigned long long path_hash(std::vector<unsigned long long> &path, size_t max_len);
171 
172  // Debugging methods for printing out current states - the use of hashes
173  // means direct inspection of most data isn't informative, so we provide
174  // convenience methods that decode it to user-comprehensible info.
175  void print_view_state(struct bu_vls *o = NULL);
176 
177  private:
178  // Sets defining all drawn solid paths (including invalid paths). The
179  // s_keys holds the ordered individual keys of each drawn solid path - it
180  // is the latter that allows for the collapse operation to populate
181  // drawn_paths. s_map uses the same key as s_keys to map instances to
182  // actual scene objects. Because objects may be represented by more than
183  // one type of scene object (shaded, wireframe, evaluated, etc.) the mapping of
184  // key to scene object is not unique - we must also take scene object type
185  // into account.
186  std::unordered_map<unsigned long long, std::unordered_map<int, struct bv_scene_obj *>> s_map;
187  std::unordered_map<unsigned long long, std::vector<unsigned long long>> s_keys;
188 
189  // Called when the parent Db context is getting ready to update the data
190  // structures - we may need to redraw, so we save any necessary information
191  // ahead of the changes. Although this is a public function of the BViewState,
192  // it is practically speaking an implementation detail
193  void cache_collapsed();
194 
195  DbiState *dbis;
196 
197  int check_status(
198  std::unordered_set<unsigned long long> *invalid_objects,
199  std::unordered_set<unsigned long long> *changed_paths,
200  unsigned long long path_hash,
201  std::vector<unsigned long long> &cpath,
202  bool leaf_expand
203  );
204 
205  void walk_tree(
206  std::unordered_set<struct bv_scene_obj *> &objs,
207  unsigned long long chash,
208  int curr_mode,
209  struct bview *v,
210  struct bv_obj_settings *vs,
211  matp_t m,
212  std::vector<unsigned long long> &path_hashes,
213  std::unordered_set<struct bview *> &views,
214  unsigned long long *ret
215  );
216 
217  void gather_paths(
218  std::unordered_set<struct bv_scene_obj *> &objs,
219  unsigned long long c_hash,
220  int curr_mode,
221  struct bview *v,
222  struct bv_obj_settings *vs,
223  matp_t m,
224  matp_t lm,
225  std::vector<unsigned long long> &path_hashes,
226  std::unordered_set<struct bview *> &views,
227  unsigned long long *ret
228  );
229 
230  struct bv_scene_obj * scene_obj(
231  std::unordered_set<struct bv_scene_obj *> &objs,
232  int curr_mode,
233  struct bv_obj_settings *vs,
234  matp_t m,
235  std::vector<unsigned long long> &path_hashes,
236  std::unordered_set<struct bview *> &views,
237  struct bview *v
238  );
239 
240  int leaf_check(unsigned long long chash, std::vector<unsigned long long> &path_hashes);
241 
242  // Paths supplied by commands to be incorporated into the drawn state by redraw method
243  std::vector<std::vector<unsigned long long>> staged;
244 
245  // The collapsed drawn paths from the previous db state, organized
246  // by drawn mode
247  void depth_group_collapse(
248  std::vector<std::vector<unsigned long long>> &collapsed,
249  std::unordered_set<unsigned long long> &d_paths,
250  std::unordered_set<unsigned long long> &p_d_paths,
251  std::map<size_t, std::unordered_set<unsigned long long>> &depth_groups
252  );
253  std::unordered_map<int, std::vector<std::vector<unsigned long long>>> mode_collapsed;
254  std::vector<std::vector<unsigned long long>> all_collapsed;
255 
256  // Set of hashes of all drawn paths and subpaths, constructed during the collapse
257  // operation from the set of drawn solid paths. This allows calling codes to
258  // spot check any path to see if it is active, without having to interrogate
259  // other data structures or walk down the tree.
260  std::unordered_map<int, std::unordered_set<unsigned long long>> drawn_paths;
261  std::unordered_set<unsigned long long> all_drawn_paths;
262 
263  // Set of partially drawn paths, constructed during the collapse operation.
264  // This holds the paths that should return 2 for is_hdrawn
265  std::unordered_map<int, std::unordered_set<unsigned long long>> partially_drawn_paths;
266  std::unordered_set<unsigned long long> all_partially_drawn_paths;
267 
268  friend class BSelectState;
269 };
270 
271 #define GED_DBISTATE_DB_CHANGE 0x01
272 #define GED_DBISTATE_VIEW_CHANGE 0x02
273 
274 struct ged_draw_cache;
275 
276 class GED_EXPORT DbiState {
277  public:
278  DbiState(struct ged *);
280 
281  unsigned long long update();
282 
283  std::vector<unsigned long long> tops(bool show_cyclic);
284 
285  bool path_color(struct bu_color *c, std::vector<unsigned long long> &elements);
286 
287  bool path_is_subtraction(std::vector<unsigned long long> &elements);
288  db_op_t bool_op(unsigned long long, unsigned long long);
289 
290  bool get_matrix(matp_t m, unsigned long long p_key, unsigned long long i_key);
291  bool get_path_matrix(matp_t m, std::vector<unsigned long long> &elements);
292 
293  bool get_bbox(point_t *bbmin, point_t *bbmax, matp_t curr_mat, unsigned long long hash);
294  bool get_path_bbox(point_t *bbmin, point_t *bbmax, std::vector<unsigned long long> &elements);
295 
296  bool valid_hash(unsigned long long phash);
297  bool valid_hash_path(std::vector<unsigned long long> &phashes);
298  bool print_hash(struct bu_vls *opath, unsigned long long phash);
299  void print_path(struct bu_vls *opath, std::vector<unsigned long long> &path, size_t pmax = 0, int verbsose = 0);
300 
301  const char *pathstr(std::vector<unsigned long long> &path, size_t pmax = 0);
302  const char *hashstr(unsigned long long);
303 
304  std::vector<unsigned long long> digest_path(const char *path);
305 
306  unsigned long long path_hash(std::vector<unsigned long long> &path, size_t max_len);
307 
308  void clear_cache(struct directory *dp);
309 
310  BViewState *get_view_state(struct bview *);
311 
312  std::vector<BSelectState *> get_selected_states(const char *sname);
313  BSelectState * find_selected_state(const char *sname);
314 
315  void put_selected_state(const char *sname);
316  std::vector<std::string> list_selection_sets();
317 
318  // These maps are the ".g ground truth" of the comb structures - the set
319  // associated with each hash contains all the child hashes from the comb
320  // definition in the database for quick lookup, and the vector preserves
321  // the comb ordering for listing.
322  std::unordered_map<unsigned long long, std::unordered_set<unsigned long long>> p_c;
323  // Note: to match MGED's 'l' printing you need to use a reverse_iterator
324  std::unordered_map<unsigned long long, std::vector<unsigned long long>> p_v;
325 
326  // Translate individual object hashes to their directory names. This map must
327  // be updated any time a database object changes to remain valid.
328  struct directory *get_hdp(unsigned long long);
329  std::unordered_map<unsigned long long, struct directory *> d_map;
330 
331  // For invalid comb entry strings, we can't point to a directory pointer. This
332  // map must also be updated after every db change - if a directory pointer hash
333  // maps to an entry in this map it needs to be removed, and newly invalid entries
334  // need to be added.
335  std::unordered_map<unsigned long long, std::string> invalid_entry_map;
336 
337  // This is a map of non-uniquely named child instances (i.e. instances that must be
338  // numbered) to the .g database name associated with those instances. Allows for
339  // one unique entry in p_c rather than requiring per-instance duplication
340  std::unordered_map<unsigned long long, unsigned long long> i_map;
341  std::unordered_map<unsigned long long, std::string> i_str;
342 
343  // Matrices above comb instances are critical to geometry placement. For non-identity
344  // matrices, we store them locally so they may be accessed without having to unpack
345  // the comb from disk.
346  std::unordered_map<unsigned long long, std::unordered_map<unsigned long long, std::vector<fastf_t>>> matrices;
347 
348  // Similar to matrices, store non-union bool ops for instances
349  std::unordered_map<unsigned long long, std::unordered_map<unsigned long long, size_t>> i_bool;
350 
351 
352  // Bounding boxes for each solid. To calculate the bbox for a comb, the
353  // children are walked combining the bboxes. The idea is to be able to
354  // retrieve solid bboxes and calculate comb bboxes without having to touch
355  // the disk beyond the initial per-solid calculations, which may be done
356  // once per load and/or dimensional change.
357  std::unordered_map<unsigned long long, std::vector<fastf_t>> bboxes;
358 
359 
360  // We also have a number of standard attributes that can impact drawing,
361  // which are normally only accessible by loading in the attributes of
362  // the object. We stash them in maps to have the information available
363  // without having to interrogate the disk
364  std::unordered_map<unsigned long long, int> c_inherit; // color inheritance flag
365  std::unordered_map<unsigned long long, unsigned int> rgb; // color RGB value (r + (g << 8) + (b << 16))
366  std::unordered_map<unsigned long long, int> region_id; // region_id
367 
368 
369  // Data to be used by callbacks
370  std::unordered_set<struct directory *> added;
371  std::unordered_set<struct directory *> changed;
372  std::unordered_set<unsigned long long> changed_hashes;
373  std::unordered_set<unsigned long long> removed;
374  std::unordered_map<unsigned long long, std::string> old_names;
375 
376  // The shared view is common to multiple views, so we always update it.
377  // For other associated views (if any), we track their drawn states
378  // separately, but they too need to update in response to database
379  // changes (as well as draw/erase commands).
380  BViewState *shared_vs = NULL;
381  std::unordered_map<struct bview *, BViewState *> view_states;
382 
383  // We have a "default" selection state that is always available,
384  // and applications may define other named selection states.
385  BSelectState *default_selected;
386  std::unordered_map<std::string, BSelectState *> selected_sets;
387 
388  // Database Instance associated with this container
389  struct ged *gedp = NULL;
390  struct db_i *dbip = NULL;
391 
392  bool need_update_nref = true;
393 
394  // Debugging methods for printing out current states - the use of hashes
395  // means direct inspection of most data isn't informative, so we provide
396  // convenience methods that decode it to user-comprehensible info.
397  void print_dbi_state(struct bu_vls *o = NULL, bool report_view_states = false);
398 
399  private:
400  void gather_cyclic(
401  std::unordered_set<unsigned long long> &cyclic,
402  unsigned long long c_hash,
403  std::vector<unsigned long long> &path_hashes
404  );
405  void print_leaves(
406  std::set<std::string> &leaves,
407  unsigned long long c_hash,
408  std::vector<unsigned long long> &path_hashes
409  );
410 
411  void populate_maps(struct directory *dp, unsigned long long phash, int reset);
412  unsigned long long update_dp(struct directory *dp, int reset);
413  unsigned int color_int(struct bu_color *);
414  int int_color(struct bu_color *c, unsigned int);
415  struct resource *res = NULL;
416  struct ged_draw_cache *dcache = NULL;
417  struct bu_vls hash_string = BU_VLS_INIT_ZERO;
418  struct bu_vls path_string = BU_VLS_INIT_ZERO;
419 };
420 
421 
422 #else
423 
424 /* Placeholders to allow for compilation when we're included in a C file */
425 typedef struct _dbi_state {
426  int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */
427 } DbiState;
428 typedef struct _bview_state {
429  int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */
430 } BViewState;
431 typedef struct _bselect_state {
432  int dummy; /* MS Visual C hack which can be removed if the struct contains something meaningful */
433 } BSelectState;
434 
435 #endif
436 
437 #endif /* GED_DBI_H */
438 
439 /** @} */
440 
441 /*
442  * Local Variables:
443  * tab-width: 8
444  * mode: C
445  * indent-tabs-mode: t
446  * c-file-style: "stroustrup"
447  * End:
448  * ex: shiftwidth=4 tabstop=8
449  */
void characterize()
std::unordered_set< unsigned long long > grand_parents
Definition: dbi.h:94
std::unordered_set< unsigned long long > active_parents
Definition: dbi.h:84
bool select_hpath(std::vector< unsigned long long > &hpath)
bool deselect_hpath(std::vector< unsigned long long > &hpath)
void collapse()
void refresh()
bool is_selected(unsigned long long)
std::unordered_map< unsigned long long, std::vector< unsigned long long > > selected
Definition: dbi.h:82
bool draw_sync()
bool is_active(unsigned long long)
unsigned long long state_hash()
std::unordered_set< unsigned long long > active_paths
Definition: dbi.h:83
std::unordered_set< unsigned long long > immediate_parents
Definition: dbi.h:93
bool is_active_parent(unsigned long long)
std::vector< std::string > list_selected_paths()
bool deselect_path(const char *path, bool update)
bool is_parent_obj(unsigned long long)
bool is_grand_parent_obj(unsigned long long)
BSelectState(DbiState *)
bool select_path(const char *path, bool update)
bool is_immediate_parent_obj(unsigned long long)
BViewState(DbiState *)
void erase_path(int mode, int argc, const char **argv)
void erase_hpath(int mode, unsigned long long c_hash, std::vector< unsigned long long > &path_hashes, bool cache_collapse=true)
size_t count_drawn_paths(int mode, bool list_collapsed)
void add_hpath(std::vector< unsigned long long > &path_hashes)
int is_hdrawn(int mode, unsigned long long phash)
void add_path(const char *path)
std::vector< std::string > list_drawn_paths(int mode, bool list_collapsed)
Definition: dbi.h:277
Header file for the BRL-CAD common definitions.
#define BU_VLS_INIT_ZERO
Definition: vls.h:81
void int * elements
Definition: tig.h:178
void int char * mode
Definition: tig.h:179
void int * c
Definition: tig.h:139
fastf_t * matp_t
pointer to a 4x4 matrix
Definition: vmath.h:373
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:355
db_op_t
Definition: op.h:55
Definition: color.h:54
Definition: vls.h:53
Definition: defines.h:489
Definition: defines.h:205