Code structure - DigitalHolography/Holovibes GitHub Wiki
It's where all computation are done.
Some logic must be done only once in the pipe (like allocation/deallocation of buffers when changing batch size or the accumulation window size).
Requests are declared in the enum ICompute::Setting
. A macro ICS
(stands for ICompute Settings) is used to access request easily: ICS::YourRequest
.
Usage:
auto pipe = ... // Get an instance of the pipe
// Request YourRequest and request a pipe_refresh
pipe.request(ICS::YourRequest);
// Set YourRequest to false but do not discard the pipe_refresh
pipe.clear_request(ICS::YourRequest);
// Request (or discard if false) YourRequest without requesting a pipe_refresh
pipe.set_requested(ICS::YourRequest, true);
pipe.is_requested(ICS::YourRequest); // true
Add a field in ICompute::Setting
, it muse be before Count
:
enum class Setting
{
...
YourRequest,
...
Count
};
Add the logic in Pipe::make_requests
. A macro can be used for one line request:
HANDLE_REQUEST(ICS::YourRequest, "Log String", ...);
// Will be expanded to
if (is_requested(ICS::YourRequest))
{
LOG_DEBUG("Log String");
...
clear_request(ICS::YourRequest);
}
Note
- Requests are handled at the beginning of each pipe refresh (if requested)
- There are internally handled with an array of atomic bool.
Each settings is a struct holding a single variable value
. There are defined in settings.hh
using a macro. Usage:
// Declare a new settings of type NewSetting that will hold a size_t
DECLARE_SETTING(NewSetting, size_t);
These settings are then stored into a settings container (defined in settings_container.hh
. There are two containers:
-
RealtimeSettingsContainer
: used to store settings that will be updated immediately (for real time). -
DelayedSettingsContainer
: used to store initial settings value and keep track of what should be updated. The modification are delayed (for pipe refresh).
Usage:
- To create a new container pass a
std::tuple
of the initial values to the constructor and all the settings as template parameters (remember a setting is a type). It's recommended to declare the list of type as a macro (seeicompute.hh
). - To update settings in real time, use
RealtimeSettingsContainer::update_setting
. - To update settings with a delay, use
DelayedSettingsContainer::update_setting
and apply delayed updates withDelayedSettingsContainer::apply_updates
. - To get the value of a setting, use
SettingsContainer::get
. - To check if a setting is in a container, use the trait
has_setting
orholovibes::has_setting_v
.
Code example:
// Create a RealtimeSettingsContainer
RealtimeSettingsContainer settings<std::string, int, float>(std::make_tuple("Hello", 9, 3.14));
settings.update_setting(42);
settings.get<int>(); // 42
// Check if a setting is in the container
has_setting_v<int, settings> // returns true
has_setting<int, settings>::value == has_setting_v<int, settings>; // True
// Create a DelayedSettingsContainer
DelayedSettingsContainer delayed_settings<std::string, int, float>(std::make_tuple("Hello", 9, 3.14));
delayed_settings.update_setting(42);
delayed_settings.get<int>(); // 9
has_setting_v<int, delayed_settings> // returns true
delayed_settings.apply_updates();
delayed_settings.get<int>(); // 42
All settings are stored in a RealtimeSettingsContainer
inside holovibes.hh
. Default values are given to them in the ctor.
The pipe stores some of these settings in three containers (defined in icompute.hh
):
-
realtime_settings_
: stores settings that don't need a refresh of the pipe -
pipe_refresh_settings_
: stores settings that are updated solely on pipe refresh (like space transform, add/remove a computation step, allocate/deallocate a buffer). -
onrestart_settings_
: stores settings that need a restart of the pipe to be applied (like the record queue location or the output buffer size).
Other computation steps (Analysis, Post process, Rendering, ...) also have containers.
- If you are in the pipe (
pipe.cc
or other computation step) to get the value of a setting you MUST callthis->setting<T>()
and you MUST never callthis->update_setting(T value)
norapi::get_xxx
andapi::set_xxx
. - In all other places you MUST call the appropriate function of the API (
api::get_xxx
andapi::set_xxx
). - You MUST never modify directly settings stored in
holovibes
nor callGET_SETTING
,UPDATE_SETTING
andSET_SETTING
(these macros get and set settings stored inholovibes
) except if you are inAPI.hxx
and inall_struct.cc
.
When a setting T
is updated in the API, this will call Holovibes::update_setting
then if ICompute
has T
call ICompute::update_setting(T)
, then call update_setting
for each computation step if they contain T
.
Note
Overlays are UI elements rendered on top of displayed images. There is also some logic and controls associated with them.
There are drawn using modern OpenGL (Vao).
- Zoom: select an area with your mouse on the main display (XY view) by clicking left and then drag to select the zone (a green overlay will appear). Click right to return to default zoom.
- For the 3D cuts: press Space on the main display and move your mouse where you want, a red cross overlay will follow your mouse (the will automatically set the
X
andY
settings). Press Space again to fix the position. On the slice (YZ and XZ windows) a rectangular red overlay show on which frequency the calculus are made (it's theZ
setting). You can press Space you move the rectangle and Space again to fix its position. - Charts: When in charts recording mode you can select two zones, the signal zone and the noise one. These overlays work the same as the Zoom one
- Reticle: When clicking on display reticle a red outlined square overlay will appear.
Class hierarchy | Description | Variables |
---|---|---|
Overlay |
Base class |
color_ : the fill and border color.alpha_ : the opacity of the border.zone_ : have a src point and a dst point.translation_ : in OpenGL clip space [-1, 1] where (-1,-1) is the top left corner and (1,1) the bottom right one. Default at (0,0) the center.scale_ : in the range [0,1].In the end zone_ will be converted to translation_ and scale_ . |
RectOverlay -> Overlay
|
an outlined rectangular overlay. | |
FilledRectOverlay -> RectOverlay
|
a filled rectangular overlay with borders. |
fill_alpha_ : the opacity of the background. |
SquareOverlay -> FilledRectOverlay
|
a filled square overlay | |
CircOverlay -> Overlay
|
an outlined circular overlay |
resolution_ : the number of line segments generated to approximate the circle shape.radius_ : the radius of the circle.zone_.src() : the center of the circle |
- Add a new entry in the
KindOfOverlay
enum located in theOverlay.hh
file. - Create a new class that inherits from one of the class above.
- In the constructor specify the properties of the overlay (
color_
,alpha_
, ...). - If you want to move the overlay change the value of whether
zone_
ortranslation_
/scale_
in thesetBuffer
method. - In
overlay_manager.cc
create a new overload of the templated functioncreate_overlay
.
// Display the overlay `OverlayKind`
UserInterfaceDescriptor::instance().mainDisplay->getOverlayManager().create_overlay<gui::OverlayKind>();
// Hide the overlay `OverlayKind`
UserInterfaceDescriptor::instance().mainDisplay->getOverlayManager().disable_all(gui::OverlayKind);