- Jan 09, 2025
-
-
Flavien BRIDAULT authored
Geometry libraries were refactored. - `sight::geometry::glm` becomes `sight::geometry` - `sight::geometry::data` now only contains functions relative to `sight::data` objects Several types were renamed or moved: * `fw_matrix4x4`: removed, replaced by `glm::dmat4` * `fw_plane`: replaced by `sight::geometry::plane_t`, moved all related code to `sight::geometry` * `fw_line`: redefined either by `sight::geometry::ray_t` or `sight::geometry::line_t` which both refers to `std::pair<glm::dvec3, glm::dvec3>`. Moved all related code to `sight::geometry` * `fw_vector_index` and `fw_vector_position`: all related code was removed Also `sight::data::image::world_to_image()` and `sight::data::image::image_to_world()` were moved from `sight::data` to `sight::geometry::data`. They were internally rewritten to be more "SIMD" friendly and new functions were added to get the raw transforms: - `sight::data::image::world_to_image_transform()` - `sight::data::image::image_to_world_transform()` This is especially useful in tight loops to avoid recomputing these matrices for each point/voxel.
-
- Dec 19, 2024
-
-
-
This change ensures image orientation is used in filtering and visualisation. To help with the process and to factorize some code, the `sight::data::image` class now has two functions `data::image::image_to_world()` and `data::image::world_to_image()` that convert image coordinates from/to world coordinates. They use internally `data::image::m_orientation`, `data::image::m_origin` and `data::image::m_spacing` and they are templated, so you can use any container that holds 3d coordinates, without having to use `{x, y, z}` construct to convert from/to Ogre, ITK, ... Notable modified classes/helpers: - volume_renderer - ray_tracing_volume_renderer - scene - negato3d - negato2d - negato2d_camera - medical_image - plane - image_extruder - resampler - ITK (reader, writer, converter) - VTK (reader, writer, converter) - image_center - propagator - slice_index_position_editor - ruler - shape - point
-
- Dec 13, 2024
-
-
Marc SCHWEITZER authored
-
- Dec 12, 2024
-
-
Flavien BRIDAULT authored
-
- Dec 11, 2024
-
-
Flavien BRIDAULT authored
It is now possible to pass optional objects with default values in XML configurations: ```xml <extension implements="sight::app::extension::config"> <id>...</id> <parameters> <!-- valid, if not passed, returns the object returned by the default constructor --> <object uid="model_series" type="sight::data::model_series" optional="true" /> <!-- valid, if not passed, returns false --> <object uid="vr_visibility" type="sight::data::boolean" optional="true" value="false" /> <!-- invalid because model_series is not a string_serializable --> <object uid="model_series" type="sight::data::model_series" optional="true" value="..." /> <!-- invalid, "optional" must always be specified. --> <object uid="vr_visibility" type="sight::data::boolean" value="false" /> </parameters> ... </extension> ``` However, the keyword `optional` was already used before to pass deferred objects. To get something harmonized with local objects declaration, the `src` attribute is now deprecated and you must now use `deferred=true` at both places. Similarly, use `preference="true"` instead of `src="preference`. ```xml <extension implements="sight::app::extension::config"> <id>...</id> <parameters> <!-- valid, if not passed, returns the object returned by the default constructor --> <object uid="model_series" type="sight::data::model_series" deferred="true" /> </parameters> <config> <object uid="image" type="sight::data::image_series" deferred="true" /> <object uid="bool" type="sight::data::boolean" value="true" preference="true" /> </config> ... </extension> ```
-
Flavien BRIDAULT authored
The pages deployment must be done in a single job, otherwise they can delete each other content.
-
- Dec 10, 2024
-
-
Shamim SEDGHI authored
-
Shamim SEDGHI authored
-
Flavien BRIDAULT authored
-
-
Flavien BRIDAULT authored
It appears we suffer from a known bug with files larger than 9999 lines. Until we upgrade gcov, we exclude those big files.
-
- Dec 09, 2024
-
-
Flavien BRIDAULT authored
Now, when an incompatibility is found between the signal and the slot, the exception is caught in the proxy and an error is returned. The config can still run, but it will not crash when closing. Also, an important bug was found when trying to match signal and slot signature. We can indeed omit part of the arguments of a signal when connecting a slot, but of course from the right. We can connect for instance: - (int, int) -> (int) - (int, int) -> () But of course we refuse the inverse (we throw `sight::core::com::exception::bad_slot`): - (int) -> (int, int) - () -> (int, int) This mechanism works recursively but was broken when argument types were different like: - (int, int) -> (string) This led to a stack overflow.
😕 This is now fixed and throw `sight::core::com::exception::bad_slot` as well. -
Added variables SIGHT_APP_VENDOR and SIGHT_APP_VENDOR_URL, use them both for the QCoreApplication (runtime) and also for CPACK_PACKAGE_VENDOR (installer).
-
- Dec 06, 2024
-
-
Flavien BRIDAULT authored
misc: p
-
- Dec 03, 2024
-
-
Flavien BRIDAULT authored
-
Flavien BRIDAULT authored
This fixes a regression introduced in c7a5a369 and prevented some graphic resources to be updated properly.
-
- Dec 02, 2024
-
-
Flavien BRIDAULT authored
-
Flavien BRIDAULT authored
-
Flavien BRIDAULT authored
-
- Nov 28, 2024
-
-
- Nov 25, 2024
-
-
## Description The API to send a signal has been simplified for all data objects, including properties. Indeed the `sight::core::com::has_signals` interface brings four new functions: ```cpp template<typename ... A> void emit(const signals::signal_key_type& _key, A ... _a) const; template<typename ... A> void emit(com::has_slots* _caller, const signals::signal_key_type& _key, A ... _a) const; template<typename ... A> void async_emit(const signals::signal_key_type& _key, A ... _a) const; template<typename ... A> void async_emit(com::has_slots* _caller, const signals::signal_key_type& _key, A ... _a) const; ``` They allow any signal holder to send a signal, synchronously or asynchronously, with a one-liner. The signature with a `com::has_slots` parameter allows to block all slots of the caller connected with the signal, preventing an infinite loop. Thus, instead of writing something like: ```cpp auto sig = object->signal<data::object::modified_signal_t>(data::object::MODIFIED_SIG); core::com::connection::blocker block(sig->get_connection(slot(service::slots::UPDATE))); sig->async_emit(); ``` You can call: ``` object->async_emit(this, data::object::MODIFIED_SIG); ``` Besides this major change, the XML configuration parser has been improved to ensure variables substitutions inside data containers. Example: ```xml <object uid="properties_map" type="sight::data::map"> <item key="integer"> <object uid="sub_object" type="sight::data::integer" value="45" /> </item> </object> <service uid="..." type="example::service"> <properties integer="${sub_object}" /> </service> ``` Before this merge-requests, the example service could not find the `sub_object` because the variable substitution was simply not performed.
-
-
- Nov 22, 2024
-
-
Didier WECKMANN authored
Rename `enum sight::data::image::pixel_format` to `sight::data::image::pixel_format_t` to avoid ambiguities with ` sight::data::image::pixel_format()` It also makes VS Code happier.
-
- Nov 19, 2024
-
-
Flavien BRIDAULT authored
-
- Nov 15, 2024
-
-
Flavien BRIDAULT authored
- move the PACS configuration in a module so that it can be used in other apps - the image is now an input and not an inout in the `module::ui::qt::image::window_level` service - adjust the range of `module::ui::qt::image::window_level` depending on the image range - remove the static label in the color widget of `module::ui::qt::settings` - `sight::data::helper::medical_image::get_min_max()` now returns its values as a pair to avoid a wrong initialisation in the caller code. - fix mixed rendering with binary transparent objects
-
- Add unit tests - Fix wrong return type in matrix4::position() and matrix4::orientation()
-
- Nov 14, 2024
-
-
Flavien BRIDAULT authored
Auto-connections were correctly configured and honored only by the config manager, thus required, a XML configuration. This was annoying for unit-tests and overall, that was not the proper place to do it. This is now done directly in the service code itself.
-
Flavien BRIDAULT authored
The naming of the unit test target is used to deduce the name of the module to be tested, which is then auto loaded. This mechanism was broken for sub-repositories. It is now fixed, and if the naming of the target is not correct, an error is reported to the user.
-
- Nov 13, 2024
-
-
Didier WECKMANN authored
Fixed: - illegal access to deleted objects - memory leaks - visibility badly applied - desynchronization of ogre object and fiducials - race conditions on signal / slot handling - too many wrappers and clumsy code
-
- Nov 07, 2024
-
-
Marc SCHWEITZER authored
Allow to call slot="start" or slot="stop" within an update_sequence. This ensure to call start/stop in a specific order. Example: ```xml <sequence uid="toggle_dev_mode"> <service uid="video_grabber" slot="stop"/> <service uid="dummy_grabber" slot="start"/> </sequence> <sequence uid="toggle_prod_mode"> <service uid="dummy_grabber" slot="stop"/> <service uid="video_grabber" slot="start"/> </sequence> ```
-
- Nov 03, 2024
-
-
Flavien BRIDAULT authored
- use malloc policy for images shared with ITK - send signals when action property is set - init text of combo box when using keys/values - do not autoconnect map properties to avoid spurious warnings when the service is used in an update loop - model_series adaptor was accidentally unregistered while updating - jobs::observer should not allow to report done work when finished
-
- Oct 30, 2024
-
-
Marc SCHWEITZER authored
when the service is "disabled" the configured key-sequence is ignored. The classic behavior is kept with the "enabled" mode.
-
- Oct 21, 2024
-
-
Didier WECKMANN authored
- Only use fiducial data from source image_series, not intermediate point_list - Remove opencv "drawing" and only rely on ogre - Simplify / remove unneeded code
-
- Oct 18, 2024
-
-
Luis MENDOZA authored
- Tab widgets are now transparent and hand the noctura theme correctly - Toolboxes have now a configurable expand icon color - unify hove/pressed effects on buttons
-
- Oct 17, 2024
-
-
This uses the native `timeBeginPeriod` function to force timer precision on Windows to be around the millisecond, otherwise, we can't go down below 1/64s.
-
- Oct 16, 2024
-
-
Flavien BRIDAULT authored
Chaining service updates in Sight live applications has always been tough. To circumvent all related issues with event-based chaining, we introduce an explicit approach allowing to specify update sequence and execute them all at once. It used to be possible to specify which services to update **once** once after start: ```xml <update uid="service1"> <update uid="service2"> <update uid="service3"> ``` This section is now modified and allows specifying these single-shot updates, but also the ability to define an update loop: ```xml <start uid="update_loop"> <update> <service uid="service1"/> <service uid="service2"/> <sequence uid="update_loop" loop="true"> <service uid="service3" /> <service uid="service4" /> </sequence> </update> ``` In this example, `service1` and `service2` are updated once after start, while `service3` and `service4` are continuously updated. The sequence `update_loop`is identified with an uid, so it can be started and stopped like any other service. Doing this, the update sequence is not dependent on the updated() signal. This is much more robust because this means any other, maybe unwanted updates triggered from somewhere else do not affect the sequence. This new syntax also allows chaining update sequences between XML configurations. As the manner of UI registries and `wid`, it is possible to reserve a slot for another update sequence defined in another configuration: ```xml <!-- Main loop --> <update> <sequence uid="update_loop" loop="true"> <service uid="service1" /> <updater uid="sub_updater" /> <service uid="service2" slot="modify" /> </sequence> </update> <!-- In a sub-configuration, passing the parameter "sub_updater" --> <update> <sequence parent="${sub_updater}"> <service uid="..." /> <service uid="..." /> </sequence> </update> ``` Note that here the `uid` of the sequence is omitted because no interaction is required inside this XML. The sequence is played automatically by the root updater after `service1::update()` and `service2::modify` slots. It is also possible to execute services in parallel. Mixing sequences and parallel are allowed with the syntax: ```xml <!-- Main loop --> <update> <sequence uid="update_loop" loop="true"> <service uid="service1" /> <parallel> <service uid="service2" /> <updater uid="sub_updater" /> <sequence> <service uid="service3" /> <service uid="service4" /> </sequence> <parallel/> <service uid="service5" /> </sequence> </update> <!-- In a sub-configuration, passing the parameter "sub_updater" --> <update> <sequence parent="${sub_updater}"> <service uid="..." /> <service uid="..." /> </sequence> </update> ``` In this example, `service1`updates first, then `service2`, the whole update sequence in the sub-configuration, and the sequence of `service3` and `service4` are executed in parallel. When they are executed, whether or not they are on different workers, `service5` is executed. The solution proposed above could be sufficient. However, managing `sight::viz::scene3d::render` could become tedious. Correctly using auto-connections, and maintaining the list of all adaptors in the update can be tedious and error-prone. Developers usually expect that a single call to the \`update()\` of the renderer manages the update of the adaptors properly, which is the case in auto mode when we do interactive rendering, but not in manual mode, in "live" applications. To solve this, we introduced a generic update interface `sight::core::updater` that will be inherited by the adaptors. This interface allows to defer the update of the adaptor required by their data. In manual mode, the adaptors just flag which part of their update process they should process. When the update is actually called, they will really perform it and unflag it. The render only requires to interrogate the adaptors before rendering to know if they need to update or not. To sum up, updating a generic scene in manual mode is now much easier and not error-prone regarding synchronisation. For example, if we imagine an application reading a video, extracting a feature and then display it in overlay over the video, the update loop could look like: ```xml <!-- Main loop --> <update> <sequence uid="main_loop" loop="true"> <service uid="video_grabber_srv" /> <service uid="extract_position_srv" /> <service uid="compute_position_srv" /> <service uid="render_srv" /> <!-- Update all adaptors, only those required if their data have changed --> </sequence> </update> ```
-
- Oct 15, 2024
-
-
Luis MENDOZA authored
- new camera parser that uses either sight resources path or an absolute file system path to default the camera to video file playing - update ex_video_recorder to use that parser feat(test): unitary test of camera parser
-
Didier WECKMANN authored
Roughly 10X speedup, measured with a big xml "configuration": - Debug build: - Before: 419.446 ms - After: 42.868 ms. - Release build: - Before: 35.768 ms - After: 4.716 ms
-