From e233264abe604d584275331c70bf14f35995ad02 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Fri, 13 Sep 2024 08:16:54 +0200 Subject: [PATCH 01/28] optional try --- library/options.json | 88 ++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/library/options.json b/library/options.json index f5e63f1d2a..3f3c1b8be0 100644 --- a/library/options.json +++ b/library/options.json @@ -6,8 +6,7 @@ }, "animation": { "autoplay": { - "type": "bool", - "default_value": "false" + "type": "bool" }, "index": { "type": "int", @@ -18,8 +17,7 @@ "default_value": "1.0" }, "time": { - "type": "double", - "default_value": "0.0" + "type": "double" }, "frame_rate": { "type": "double", @@ -28,31 +26,25 @@ }, "camera": { "index": { - "type": "int", - "default_value": "-1" + "type": "int" }, "orthographic": { - "type": "bool", - "default_value": "false" + "type": "bool" } } }, "render": { "show_edges": { - "type": "bool", - "default_value": "false" + "type": "bool" }, "line_width": { - "type": "double", - "default_value": "1.0" + "type": "double" }, "point_size": { - "type": "double", - "default_value": "10.0" + "type": "double" }, "backface_type": { - "type": "string", - "default_value": "default" + "type": "string" }, "grid": { "enable": { @@ -64,16 +56,14 @@ "default_value": "false" }, "unit": { - "type": "double", - "default_value": "0.0" + "type": "double" }, "subdivisions": { "type": "int", "default_value": "10" }, "color": { - "type": "double_vector", - "default_value": "0.0, 0.0, 0.0" + "type": "double_vector" } }, "raytracing": { @@ -108,14 +98,12 @@ "default_value": "false" }, "final_shader": { - "type": "string", - "default_value": "" + "type": "string" } }, "hdri": { "file": { - "type": "string", - "default_value": "" + "type": "string" }, "ambient": { "type": "bool", @@ -157,8 +145,7 @@ "default_value": "false" }, "filename_info": { - "type": "string", - "default_value": "" + "type": "string" }, "fps": { "type": "bool", @@ -173,16 +160,14 @@ "default_value": "false" }, "dropzone_info": { - "type": "string", - "default_value": "" + "type": "string" }, "metadata": { "type": "bool", "default_value": "false" }, "font_file": { - "type": "string", - "default_value": "" + "type": "string" }, "loader_progress": { "type": "bool", @@ -196,56 +181,45 @@ "model": { "matcap": { "texture": { - "type": "string", - "default_value": "" + "type": "string" } }, "color": { "opacity": { - "type": "double", - "default_value": "1.0" + "type": "double" }, "rgb": { - "type": "double_vector", - "default_value": "1.0, 1.0, 1.0" + "type": "double_vector" }, "texture": { - "type": "string", - "default_value": "" + "type": "string" } }, "emissive": { "factor": { - "type": "double_vector", - "default_value": "1.0, 1.0, 1.0" + "type": "double_vector" }, "texture": { - "type": "string", - "default_value": "" + "type": "string" } }, "normal": { "scale": { - "type": "double", - "default_value": "1.0" + "type": "double" }, "texture": { - "type": "string", - "default_value": "" + "type": "string" } }, "material": { "metallic": { - "type": "double", - "default_value": "0.0" + "type": "double" }, "roughness": { - "type": "double", - "default_value": "0.3" + "type": "double" }, "texture": { - "type": "string", - "default_value": "" + "type": "string" } }, "scivis": { @@ -258,8 +232,7 @@ "default_value": "false" }, "array_name": { - "type": "string", - "default_value": "" + "type": "string" }, "component": { "type": "int", @@ -270,8 +243,7 @@ "default_value": "0.0, 0.0, 0.0, 0.0, 0.4, 0.9, 0.0, 0.0, 0.8, 0.9, 0.9, 0.0, 1.0, 1.0, 1.0, 1.0" }, "range": { - "type": "double_vector", - "default_value": "0.0" + "type": "double_vector" } }, "point_sprites": { @@ -282,6 +254,10 @@ "type": { "type": "string", "default_value": "sphere" + }, + "size": { + "type": "int", + "default_value": 10.0 } }, "volume": { From fe9aa1b5ef21eafc7d8fe7139fd016a29710e433 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 08:27:57 +0200 Subject: [PATCH 02/28] Options: Split point_size in two options --- application/F3DOptionsTools.cxx | 5 +++-- application/F3DOptionsTools.h | 3 ++- application/testing/CMakeLists.txt | 4 ++-- doc/GALLERY.md | 2 +- doc/libf3d/OPTIONS.md | 5 +++-- doc/user/LIMITATIONS_AND_TROUBLESHOOTING.md | 2 +- doc/user/OPTIONS.md | 5 +++-- library/options.json | 3 ++- library/src/window_impl.cxx | 5 +++-- plugins/native/configs/config.d/10_native.json | 4 ++-- plugins/native/configs/thumbnail.d/10_native.json | 4 ++-- vtkext/private/module/vtkF3DRendererWithColoring.cxx | 6 +++--- vtkext/private/module/vtkF3DRendererWithColoring.h | 4 ++-- 13 files changed, 29 insertions(+), 23 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 084c2ac5c6..d9ee14ae54 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -97,8 +97,9 @@ static inline const std::array CLIOptions = {{ {"font-file", "", "Path to a FreeType compatible font file", "", ""} } }, { "Material", { {"point-sprites", "o", "Show sphere sprites instead of geometry", "", "1" }, - {"point-type", "", "Point sprites type when showing point sprites", "", ""}, - {"point-size", "", "Point size when showing vertices or point sprites", "", ""}, + {"point-sprites-type", "", "Point sprites type when showing point sprites", "", ""}, + {"point-sprites-size", "", "Point sprites size", "", ""}, + {"point-size", "", "Point size when showing vertices", "", ""}, {"line-width", "", "Line width when showing edges", "", ""}, {"backface-type", "", "Backface type, can be default (usually visible), visible or hidden", "", ""}, {"color", "", "Solid color", "", ""}, diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index 59e2a16bb8..2c53a227c5 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -79,7 +79,8 @@ static inline const std::map LibOptionsNames { "animation-frame-rate", "scene.animation.frame_rate" }, { "font-file", "ui.font_file" }, { "point-sprites", "model.point_sprites.enable" }, - { "point-type", "model.point_sprites.type" }, + { "point-sprites-type", "model.point_sprites.type" }, + { "point-sprites-size", "model.point_sprites.size" }, { "point-size", "render.point_size" }, { "line-width", "render.line_width" }, { "backface-type", "render.backface_type" }, diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index d4ab68045f..588551126b 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -126,7 +126,7 @@ f3d_test(NAME TestVTS DATA bluntfin.vts) f3d_test(NAME TestVTM DATA mb.vtm) f3d_test(NAME TestVTK DATA cow.vtk) f3d_test(NAME TestNRRD DATA beach.nrrd ARGS -s) -f3d_test(NAME TestSPLAT DATA small.splat ARGS -osy --up=-Y --point-size=1) +f3d_test(NAME TestSPLAT DATA small.splat ARGS -osy --up=-Y --point-sprites-size=1) f3d_test(NAME TestGridX DATA suzanne.ply ARGS -g --up=+X) f3d_test(NAME TestGridY DATA suzanne.ply ARGS -g --up=+Y) f3d_test(NAME TestGridZ DATA suzanne.ply ARGS -g --up=+Z) @@ -287,7 +287,7 @@ endif() # Needs splat sorting with compute shaders if(VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240203) if(NOT APPLE) # MacOS does not support compute shaders - f3d_test(NAME Test3DGaussiansSplatting DATA small.splat ARGS -osy --up=-Y --point-size=1 --point-type=gaussian --camera-position=-3.6,0.5,-4.2) + f3d_test(NAME Test3DGaussiansSplatting DATA small.splat ARGS -osy --up=-Y --point-sprites-size=1 --point-sprites-type=gaussian --camera-position=-3.6,0.5,-4.2) f3d_test(NAME TestDefaultConfigFileSPLAT DATA small.splat CONFIG config_build LONG_TIMEOUT) f3d_test(NAME TestThumbnailConfigFileSPLAT DATA small.splat CONFIG thumbnail_build LONG_TIMEOUT) endif() diff --git a/doc/GALLERY.md b/doc/GALLERY.md index f2c049694f..9fba784e3e 100644 --- a/doc/GALLERY.md +++ b/doc/GALLERY.md @@ -17,7 +17,7 @@ Images and videos displayed below use public datasets, you can download them [he -*3D Gaussians Splatting*: `f3d counter.splat --point-size=1 --point-type=gaussian -soynxz --up=-Y --camera-position=0,1,-5.2 --camera-focal-point=0,1,0` +*3D Gaussians Splatting*: `f3d counter.splat --point-sprites-size=1 --point-sprites-type=gaussian -soynxz --up=-Y --camera-position=0,1,-5.2 --camera-focal-point=0,1,0` diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index 8302adee48..30cca62ad7 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -57,7 +57,8 @@ model.scivis.component|int
-1
render|Specify the component to color with. model.scivis.array_name|string
-
render|Select the name of the array to color with.|\-\-coloring-array model.scivis.range|vector\
-
render|Set a *custom range for the coloring*.|\-\-range model.point_sprites.enable|bool
false
render|Show sphere *points sprites* instead of the geometry.|\-\-point-sprites -model.point_sprites.type|string
sphere
render|Set the sprites type when showing point sprites (can be `sphere` or `gaussian`).|\-\-point-type +model.point_sprites.type|string
sphere
render|Set the sprites type when showing point sprites (can be `sphere` or `gaussian`).|\-\-point-stripes-type +model.point_sprites.size|double
10.0
render|Set the *size* of point sprites.|\-\-point-stripes-size model.volume.enable|bool
false
render|Enable *volume rendering*. It is only available for 3D image data (vti, dcm, nrrd, mhd files) and will display nothing with other default scene formats.|\-\-volume model.volume.inverse|bool
false
render|Inverse the linear opacity function.|\-\-inverse @@ -72,7 +73,7 @@ render.effect.tone_mapping|bool
false
render|Enable generic filmic *Tone M render.effect.final_shader|string
""
render|Add a final shader to the output image|\-\-final-shader. See [user documentation](../user/FINAL_SHADER.md). render.line_width|double
1.0
render|Set the *width* of lines when showing edges.|\-\-line-width render.show_edges|bool
false
render|Show the *cell edges*|\-\-edges -render.point_size|double
10.0
render|Set the *size* of points when showing vertices and point sprites.|\-\-point-size +render.point_size|double
10.0
render|Set the *size* of points when showing vertices.|\-\-point-size render.grid.enable|bool
false
render|Show *a grid* aligned with the horizontal (orthogonal to the Up direction) plane.|\-\-grid render.grid.absolute|bool
false
render|Position the grid at the *absolute origin* of the model's coordinate system instead of below the model.|\-\-grid render.grid.unit|double
0
render|Set the size of the *unit square* for the grid. If set to non-positive (the default) a suitable value will be automatically computed.|\-\-grid\-unit diff --git a/doc/user/LIMITATIONS_AND_TROUBLESHOOTING.md b/doc/user/LIMITATIONS_AND_TROUBLESHOOTING.md index bd0276238a..7f2c0713bf 100644 --- a/doc/user/LIMITATIONS_AND_TROUBLESHOOTING.md +++ b/doc/user/LIMITATIONS_AND_TROUBLESHOOTING.md @@ -40,7 +40,7 @@ VDB file formats rely on [OpenVDB](https://github.com/AcademySoftwareFoundation/ - The `vdb` plugin is not shipped in the python wheels yet. ## Gaussian splatting -Gaussian splatting (option `--point-type=gaussian`) needs depth sorting which is done internally using a compute shader. This requires support for OpenGL 4.3 which is not supported by macOS and old GPUs/drivers. +Gaussian splatting (option `--point-sprites-type=gaussian`) needs depth sorting which is done internally using a compute shader. This requires support for OpenGL 4.3 which is not supported by macOS and old GPUs/drivers. # Troubleshooting diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index 4f53415475..b66e8c7e3e 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -52,8 +52,9 @@ Options|Default|Description Options|Default|Description ------|------|------ -o, \-\-point-sprites||Show sphere *points sprites* instead of the geometry. -\-\-point-size=\|10.0|Set the *size* of points when showing vertices and point sprites. -\-\-point-type=\|sphere|Set the splat type when showing point sprites. +\-\-point-sprites-type=\|sphere|Set the splat type when showing point sprites. +\-\-point-sprites-size=\|10.0|Set the *size* of point sprites. +\-\-point-size=\|10.0|Set the *size* of points when showing vertices. \-\-line-width=\|1.0|Set the *width* of lines when showing edges. \-\-color=\|1.0, 1.0, 1.0| Set a *color* on the geometry. Multiplied with the base color texture when present.
Requires a default scene. \-\-opacity=\|1.0|Set *opacity* on the geometry. Multiplied with the base color texture when present.
Requires a default scene. Usually used with Depth Peeling option. diff --git a/library/options.json b/library/options.json index 3f3c1b8be0..af6e3efe7c 100644 --- a/library/options.json +++ b/library/options.json @@ -6,7 +6,8 @@ }, "animation": { "autoplay": { - "type": "bool" + "type": "bool", + "default_value": "false" }, "index": { "type": "int", diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index 1f056db012..c8dfef8881 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -348,16 +348,17 @@ void window_impl::UpdateDynamicOptions() // XXX: model.point_sprites.type only has an effect on geometry scene // but we set it here for practical reasons std::string splatTypeStr = opt.model.point_sprites.type; - int pointSize = opt.render.point_size; + int pointSpritesSize = opt.model.point_sprites.size; vtkF3DRendererWithColoring::SplatType splatType = vtkF3DRendererWithColoring::SplatType::SPHERE; if (splatTypeStr == "gaussian") { splatType = vtkF3DRendererWithColoring::SplatType::GAUSSIAN; } - renderer->SetPointProperties(splatType, pointSize); + renderer->SetPointSpritesProperties(splatType, pointSpritesSize); renderer->SetLineWidth(opt.render.line_width); + renderer->SetPointSize(opt.render.point_size); renderer->ShowEdge(opt.render.show_edges); renderer->ShowTimer(opt.ui.fps); renderer->ShowFilename(opt.ui.filename); diff --git a/plugins/native/configs/config.d/10_native.json b/plugins/native/configs/config.d/10_native.json index 9c9b55e856..1942c9a078 100644 --- a/plugins/native/configs/config.d/10_native.json +++ b/plugins/native/configs/config.d/10_native.json @@ -26,8 +26,8 @@ ".*(splat)": { "point-sprites": true, - "point-size": 1, - "point-type": "gaussian", + "point-sprites-size": 1, + "point-sprites-type": "gaussian", "scalar-coloring": true, "coloring-array": "color", "comp": "-2", diff --git a/plugins/native/configs/thumbnail.d/10_native.json b/plugins/native/configs/thumbnail.d/10_native.json index 3f7eff8d60..90d2239d6b 100644 --- a/plugins/native/configs/thumbnail.d/10_native.json +++ b/plugins/native/configs/thumbnail.d/10_native.json @@ -16,8 +16,8 @@ ".*(splat)": { "point-sprites": true, - "point-size": 1, - "point-type": "gaussian", + "point-sprites-size": 1, + "point-sprites-type": "gaussian", "scalar-coloring": true, "coloring-array": "color", "comp": "-2", diff --git a/vtkext/private/module/vtkF3DRendererWithColoring.cxx b/vtkext/private/module/vtkF3DRendererWithColoring.cxx index fd40d8ee98..e3307b5797 100644 --- a/vtkext/private/module/vtkF3DRendererWithColoring.cxx +++ b/vtkext/private/module/vtkF3DRendererWithColoring.cxx @@ -249,9 +249,9 @@ void vtkF3DRendererWithColoring::ConfigureColoringActorsProperties() } //---------------------------------------------------------------------------- -void vtkF3DRendererWithColoring::SetPointProperties(SplatType type, double pointSize) +void vtkF3DRendererWithColoring::SetPointProperties(SplatType type, double pointSpritesSize) { - this->SetPointSize(pointSize); +// this->SetPointSize(pointSize); TODO if (!this->Importer) { @@ -275,7 +275,7 @@ void vtkF3DRendererWithColoring::SetPointProperties(SplatType type, double point double scaleFactor = 1.0; if (bbox.IsValid()) { - scaleFactor = pointSize * bbox.GetDiagonalLength() * 0.001; + scaleFactor = pointSpritesSize * bbox.GetDiagonalLength() * 0.001; } const auto& psActorsAndMappers = this->Importer->GetPointSpritesActorsAndMappers(); diff --git a/vtkext/private/module/vtkF3DRendererWithColoring.h b/vtkext/private/module/vtkF3DRendererWithColoring.h index ff4459f9e9..1c5b4209ee 100644 --- a/vtkext/private/module/vtkF3DRendererWithColoring.h +++ b/vtkext/private/module/vtkF3DRendererWithColoring.h @@ -96,9 +96,9 @@ class vtkF3DRendererWithColoring : public vtkF3DRenderer }; /** - * Set the pointSize and the splat type on the pointGaussianMapper + * Set the point sprites size and the splat type on the pointGaussianMapper */ - void SetPointProperties(SplatType splatType, double pointSize); + void SetPointSpritesProperties(SplatType splatType, double pointSpritesSize); /** * Set the visibility of the scalar bar. From 5707fb52e6fe69d8c1c83bcdaa9d27f01af024df Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 20:38:32 +0200 Subject: [PATCH 03/28] not finished yet --- application/F3DOptionsTools.cxx | 12 ++- application/F3DOptionsTools.h | 2 +- application/main.cxx | 4 +- application/testing/CMakeLists.txt | 8 +- cmake/f3dOptions.cmake | 24 ++++-- doc/libf3d/OPTIONS.md | 6 +- .../cpp/use-options-string/CMakeLists.txt | 1 - .../cpp/use-options-struct/CMakeLists.txt | 1 - library/options.json | 50 +++++++---- library/private/options_tools.h.in | 30 +++++-- library/public/options.h.in | 22 +++-- library/src/animationManager.cxx | 2 +- library/src/loader_impl.cxx | 43 ++++++---- library/src/options.cxx | 31 ++++++- library/src/window_impl.cxx | 4 +- library/testing/CMakeLists.txt | 29 +------ .../Testing/TestF3DRendererWithColoring.cxx | 2 +- vtkext/private/module/vtkF3DRenderer.cxx | 85 ++++++++++++------- vtkext/private/module/vtkF3DRenderer.h | 29 ++++--- .../module/vtkF3DRendererWithColoring.cxx | 71 +++++++++------- .../module/vtkF3DRendererWithColoring.h | 8 +- 21 files changed, 279 insertions(+), 185 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index d9ee14ae54..b8b1460d96 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -53,6 +53,7 @@ struct CLIGroup /** * Declaration of all F3D CLI options except `--input` using above structs * Order of groups matters in the context of `--help` + * TODO update help text for optional values */ // clang-format off #if F3D_MODULE_RAYTRACING @@ -82,7 +83,7 @@ static inline const std::array CLIOptions = {{ { "up", "", "Up direction", "{-X, +X, -Y, +Y, -Z, +Z}", "" }, { "axis", "x", "Show axes", "", "1" }, { "grid", "g", "Show grid", "", "1" }, { "grid-absolute", "", "Position grid at the absolute origin instead of below the model", "", "1" }, - { "grid-unit", "", "Size of grid unit square, set to a non-positive value for automatic computation", "", "" }, + { "grid-unit", "", "Size of grid unit square, automatically computed by default", "", "" }, { "grid-subdivisions", "", "Number of grid subdivisions", "", "" }, { "grid-color", "", "Color of main grid lines", "", "" }, { "edges", "e", "Show cell edges", "", "1" }, @@ -451,7 +452,14 @@ F3DOptionsTools::OptionsDict F3DOptionsTools::ParseCLIOptions( if (libIter != F3DOptionsTools::LibOptionsNames.end()) { f3d::options opt; - defaultValue = opt.getAsString(std::string(libIter->second)); + try + { + defaultValue = opt.getAsString(std::string(libIter->second)); + } + catch (const f3d::options::unset_exception&) + { + // let defaultValue empty for unset options + } } } diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index 2c53a227c5..9d5a5094aa 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -79,7 +79,7 @@ static inline const std::map LibOptionsNames { "animation-frame-rate", "scene.animation.frame_rate" }, { "font-file", "ui.font_file" }, { "point-sprites", "model.point_sprites.enable" }, - { "point-sprites-type", "model.point_sprites.type" }, + { "point-sprites-type", "model.point_sprites.shape" }, { "point-sprites-size", "model.point_sprites.size" }, { "point-size", "render.point_size" }, { "line-width", "render.line_width" }, diff --git a/application/main.cxx b/application/main.cxx index d1f6e1f866..cb6ada89a1 100644 --- a/application/main.cxx +++ b/application/main.cxx @@ -22,13 +22,13 @@ int main(int argc, char** argv) // exit with error when needed exit(EXIT_FAILURE); } - catch (const std::exception& ex) +/* catch (const std::exception& ex) { f3d::log::error("F3D encountered an unexpected exception:"); f3d::log::error(ex.what()); f3d::log::waitForUser(); exit(EXIT_FAILURE); - } + }*/ return res; } diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index 588551126b..f64c1903f7 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -137,9 +137,9 @@ f3d_test(NAME TestGridColor DATA suzanne.ply ARGS -g --grid-color=1,1,1) f3d_test(NAME TestAxis DATA suzanne.ply ARGS -x) f3d_test(NAME TestBackfaceVisible DATA backface.vtp ARGS --backface-type=visible) f3d_test(NAME TestBackfaceHidden DATA backface.vtp ARGS --backface-type=hidden) -f3d_test(NAME TestPointCloud DATA pointsCloud.vtp ARGS -o --point-size=20) -f3d_test(NAME TestPointCloudBar DATA pointsCloud.vtp ARGS -sob --point-size=20) -f3d_test(NAME TestPointCloudUG DATA pointsCloud.vtu ARGS -o --point-size=20) +f3d_test(NAME TestPointCloud DATA pointsCloud.vtp ARGS -o --point-sprites-size=20) +f3d_test(NAME TestPointCloudBar DATA pointsCloud.vtp ARGS -sob --point-sprites-size=20) +f3d_test(NAME TestPointCloudUG DATA pointsCloud.vtu ARGS -o --point-sprites-size=20) f3d_test(NAME TestPointCloudVolume DATA bluntfin.vts ARGS -sob) f3d_test(NAME TestPointCloudDefaultScene DATA pointsCloud.vtp ARGS --point-size=20) f3d_test(NAME Test3DSImporter DATA iflamigm.3ds ARGS --up=+Z) @@ -721,7 +721,7 @@ f3d_test(NAME TestInteractionCycleCell DATA waveletArrays.vti INTERACTION) #VCCC f3d_test(NAME TestInteractionCycleComp DATA dragon.vtu INTERACTION) #SYYYY f3d_test(NAME TestInteractionCycleScalars DATA dragon.vtu INTERACTION) #BSSSS f3d_test(NAME TestInteractionVolumeInverse DATA HeadMRVolume.mhd ARGS --camera-position=127.5,-400,127.5 --camera-view-up=0,0,1 INTERACTION) #VI -f3d_test(NAME TestInteractionPointCloud DATA pointsCloud.vtp ARGS --point-size=20 INTERACTION) #O +f3d_test(NAME TestInteractionPointCloud DATA pointsCloud.vtp ARGS --point-sprites-size=20 INTERACTION) #O f3d_test(NAME TestInteractionDirectory DATA mb INTERACTION ARGS --scalar-coloring) #Right;Right;Right;Left;Up; f3d_test(NAME TestInteractionDirectoryLoop DATA mb INTERACTION ARGS --scalar-coloring) #Left;Left;Left; f3d_test(NAME TestInteractionDirectoryEmpty DATA mb INTERACTION NO_DATA_FORCE_RENDER) #Right;Right;Right; diff --git a/cmake/f3dOptions.cmake b/cmake/f3dOptions.cmake index 125d596803..bb04a9fb55 100644 --- a/cmake/f3dOptions.cmake +++ b/cmake/f3dOptions.cmake @@ -99,9 +99,12 @@ function(_parse_json_option _top_json) string(JSON _cur_json GET ${_top_json} ${_member_name}) # Recover its type and default if it is a leaf option string(JSON _option_type ERROR_VARIABLE _type_error GET ${_cur_json} "type") - string(JSON _option_default_value ERROR_VARIABLE _default_value_error GET ${_cur_json} "default_value") - if(_type_error STREQUAL "NOTFOUND" AND _default_value_error STREQUAL "NOTFOUND") + if(_type_error STREQUAL "NOTFOUND") # Leaf option found! + + # Recover default_value if any + string(JSON _option_default_value ERROR_VARIABLE _default_value_error GET ${_cur_json} "default_value") + set(_option_name "${_option_basename}${_member_name}") # Identify types @@ -109,6 +112,7 @@ function(_parse_json_option _top_json) set(_option_variant_type ${_option_type}) set(_option_default_value_start "") set(_option_default_value_end "") + if(_option_type STREQUAL "double_vector") set(_option_actual_type "std::vector") set(_option_variant_type "std::vector") @@ -125,11 +129,21 @@ function(_parse_json_option _top_json) endif() # Add option to struct and methods - string(APPEND _options_struct "${_option_indent} ${_option_actual_type} ${_member_name} = ${_option_default_value_start}${_option_default_value}${_option_default_value_end};\n") + + if(_default_value_error STREQUAL "NOTFOUND") + # Use default_value + string(APPEND _options_struct "${_option_indent} ${_option_actual_type} ${_member_name} = ${_option_default_value_start}${_option_default_value}${_option_default_value_end};\n") + set(_optional_getter "") + else() + # No default_value, it is an std::optional + string(APPEND _options_struct "${_option_indent} std::optional<${_option_actual_type}> ${_member_name};\n") + set(_optional_getter ".value()") + endif() + list(APPEND _options_setter "if (name == \"${_option_name}\") opt.${_option_name} = std::get<${_option_variant_type}>(value)") - list(APPEND _options_getter "if (name == \"${_option_name}\") return opt.${_option_name}") + list(APPEND _options_getter "if (name == \"${_option_name}\") return opt.${_option_name}${_optional_getter}") list(APPEND _options_string_setter "if (name == \"${_option_name}\") opt.${_option_name} = options_tools::parse<${_option_actual_type}>(str)") - list(APPEND _options_string_getter "if (name == \"${_option_name}\") return options_tools::format(opt.${_option_name})") + list(APPEND _options_string_getter "if (name == \"${_option_name}\") return options_tools::format(opt.${_option_name}${_optional_getter})") list(APPEND _options_lister "\"${_option_name}\"") else() diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index 30cca62ad7..cff0a71710 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -1,8 +1,7 @@ # Options exhaustive list An option is a specific value stored in different struct in an `options` instance. -They can be accessed directly through the structs, through a string API or through a std::variant API, the last one require C++17. -If your compiler does not support C++17, you can disable this API by defining `F3D_DISABLE_CXX17_API`. +They can be accessed directly through the structs, through a string API or through a std::variant API. The possible option are listed below and are organized by categories and subcategories, here is a non-exhaustive explanation of the categories. @@ -139,8 +138,7 @@ The documentation about option parsing is upcoming. ## Variant API -An API that is similar to the F3D 2.0 options API thanks to std::variant, requires C++17. -If your compiler does not support C++17, you can disable this API by defining `F3D_DISABLE_CXX17_API`. +An API that is similar to the F3D 2.0 options API thanks to std::variant. ```cpp f3d::engine eng(f3d::window::Type::NATIVE); diff --git a/examples/libf3d/cpp/use-options-string/CMakeLists.txt b/examples/libf3d/cpp/use-options-string/CMakeLists.txt index 6245f166be..d0c3240453 100644 --- a/examples/libf3d/cpp/use-options-string/CMakeLists.txt +++ b/examples/libf3d/cpp/use-options-string/CMakeLists.txt @@ -5,7 +5,6 @@ project(use-options-string) find_package(f3d REQUIRED COMPONENTS library) add_executable(use-options-string main.cxx) -target_compile_definitions(use-options-string PRIVATE F3D_DISABLE_CXX17_API) target_link_libraries(use-options-string f3d::libf3d) set_target_properties(use-options-string PROPERTIES CXX_STANDARD 11) diff --git a/examples/libf3d/cpp/use-options-struct/CMakeLists.txt b/examples/libf3d/cpp/use-options-struct/CMakeLists.txt index f5a3ae63d1..3ec9f2bb8c 100644 --- a/examples/libf3d/cpp/use-options-struct/CMakeLists.txt +++ b/examples/libf3d/cpp/use-options-struct/CMakeLists.txt @@ -5,7 +5,6 @@ project(use-options-struct) find_package(f3d REQUIRED COMPONENTS library) add_executable(use-options-struct main.cxx) -target_compile_definitions(use-options-struct PRIVATE F3D_DISABLE_CXX17_API) target_link_libraries(use-options-struct f3d::libf3d) set_target_properties(use-options-struct PROPERTIES CXX_STANDARD 11) diff --git a/library/options.json b/library/options.json index af6e3efe7c..bef1ee884d 100644 --- a/library/options.json +++ b/library/options.json @@ -30,13 +30,15 @@ "type": "int" }, "orthographic": { - "type": "bool" + "type": "bool", + "default_value": "false" } } }, "render": { "show_edges": { - "type": "bool" + "type": "bool", + "default_value": "false" }, "line_width": { "type": "double" @@ -64,7 +66,8 @@ "default_value": "10" }, "color": { - "type": "double_vector" + "type": "double_vector", + "default_value": "0.0, 0.0, 0.0" } }, "raytracing": { @@ -146,7 +149,8 @@ "default_value": "false" }, "filename_info": { - "type": "string" + "type": "string", + "default_value": "" }, "fps": { "type": "bool", @@ -161,7 +165,8 @@ "default_value": "false" }, "dropzone_info": { - "type": "string" + "type": "string", + "default_value": "" }, "metadata": { "type": "bool", @@ -182,45 +187,56 @@ "model": { "matcap": { "texture": { - "type": "string" + "type": "string", + "default_value": "" } }, "color": { "opacity": { - "type": "double" + "type": "double", + "default_value": "1.0" }, "rgb": { - "type": "double_vector" + "type": "double_vector", + "default_value": "1.0, 1.0, 1.0" }, "texture": { - "type": "string" + "type": "string", + "default_value": "" } }, "emissive": { "factor": { - "type": "double_vector" + "type": "double_vector", + "default_value": "1.0, 1.0, 1.0" }, "texture": { - "type": "string" + "type": "string", + "default_value": "" } }, "normal": { "scale": { - "type": "double" + "type": "double", + "default_value": "1.0" }, "texture": { - "type": "string" + "type": "string", + "default_value": "" } }, "material": { "metallic": { - "type": "double" + "type": "double", + "default_value": "0.0" }, "roughness": { - "type": "double" + "type": "double", + "default_value": "0.3" }, "texture": { - "type": "string" + "type": "string", + "default_value": "" } }, "scivis": { @@ -252,7 +268,7 @@ "type": "bool", "default_value": "false" }, - "type": { + "shape": { "type": "string", "default_value": "sphere" }, diff --git a/library/private/options_tools.h.in b/library/private/options_tools.h.in index ef64c89db7..0196515d6b 100644 --- a/library/private/options_tools.h.in +++ b/library/private/options_tools.h.in @@ -295,10 +295,17 @@ void set(options& opt, const std::string& name, const option_variant_t& value) */ option_variant_t get(const options& opt, const std::string& name) { - // clang-format off - ${_options_getter}; - // clang-format on - else throw options::inexistent_exception("Option " + name + " does not exist"); + try + { + // clang-format off + ${_options_getter}; + // clang-format on + else throw options::inexistent_exception("Option " + name + " does not exist"); + } + catch (const std::bad_optional_access&) + { + throw options::unset_exception("Trying to get " + name + " before it was set"); + } } //---------------------------------------------------------------------------- @@ -329,10 +336,17 @@ void setAsString(options& opt, const std::string& name, const std::string& str) */ std::string getAsString(const options& opt, const std::string& name) { - // clang-format off - ${_options_string_getter}; - // clang-format on - else throw options::inexistent_exception("Option " + name + " does not exist"); + try + { + // clang-format off + ${_options_string_getter}; + // clang-format on + else throw options::inexistent_exception("Option " + name + " does not exist"); + } + catch (const std::bad_optional_access&) + { + throw options::unset_exception("Trying to get " + name + " before it was set"); + } } } // option_tools } // f3d diff --git a/library/public/options.h.in b/library/public/options.h.in index b7059e7171..27c3353423 100644 --- a/library/public/options.h.in +++ b/library/public/options.h.in @@ -6,19 +6,15 @@ #include "types.h" #include +#include #include -#include - -#ifndef F3D_DISABLE_CXX17_API #include -#endif +#include namespace f3d { -#ifndef F3D_DISABLE_CXX17_API // Declared here for simplicity using option_variant_t = std::variant>; -#endif /** * @class options @@ -43,7 +39,6 @@ public: options& operator=(options&& other) noexcept = default; ///@} -#ifndef F3D_DISABLE_CXX17_API /** * Set an option as a variant based on its name * Please note that, on Windows, using an explicit std::string may be required: @@ -56,9 +51,9 @@ public: /** * Get an option as a variant based on its name * Throw an options::inexistent_exception if option does not exist. + * Throw an options::unset_exception if option has not been set. */ option_variant_t get(const std::string& name) const; -#endif /** * Set an option as a string based on its name @@ -72,6 +67,7 @@ public: /** * Get an option as a string based on its name * Throw an options::inexistent_exception if option does not exist. + * Throw an options::unset_exception if option has not been set. */ std::string getAsString(const std::string& name) const; @@ -79,6 +75,7 @@ public: * A boolean option specific method to toggle it. * Throw an options::inexistent_exception if option does not exist. * Throw an options::incompatible_exception if option is not boolean. + * Throw an options::unset_exception if option has not been set. */ options& toggle(const std::string& name); @@ -153,6 +150,15 @@ public: explicit inexistent_exception(const std::string& what = ""); }; + /** + * An exception that can be thrown by the options + * when a provided option is accessed before being set. + */ + struct unset_exception : public exception + { + explicit unset_exception(const std::string& what = ""); + }; + /** * The complete generated options struct */ diff --git a/library/src/animationManager.cxx b/library/src/animationManager.cxx index 40ff19bff6..50551da70a 100644 --- a/library/src/animationManager.cxx +++ b/library/src/animationManager.cxx @@ -65,7 +65,7 @@ bool animationManager::Initialize( { log::warn("An animation index has been specified but there are no animation available."); } - if (options->scene.animation.time != 0) + if (options->scene.animation.time.has_value()) { log::warn("No animation available, cannot load a specific animation time"); } diff --git a/library/src/loader_impl.cxx b/library/src/loader_impl.cxx index 8469acf8bf..1c0291b940 100644 --- a/library/src/loader_impl.cxx +++ b/library/src/loader_impl.cxx @@ -151,14 +151,17 @@ class loader_impl::internals if (this->AnimationManager.Initialize( &this->Options, &this->Window, this->Interactor, this->GenericImporter)) { - double animationTime = this->Options.scene.animation.time; - double timeRange[2]; - this->AnimationManager.GetTimeRange(timeRange); - - // We assume importers import data at timeRange[0] when not specified - if (animationTime != timeRange[0]) + if (this->Options.scene.animation.time.has_value()) { - this->AnimationManager.LoadAtTime(animationTime); + double animationTime = this->Options.scene.animation.time.value(); + double timeRange[2]; + this->AnimationManager.GetTimeRange(timeRange); + + // We assume importers import data at timeRange[0] when not specified + if (animationTime != timeRange[0]) + { + this->AnimationManager.LoadAtTime(animationTime); + } } } @@ -285,8 +288,11 @@ loader& loader_impl::loadScene(const std::string& filePath) this->Internals->CurrentFullSceneImporter->SetRenderWindow( this->Internals->Window.GetRenderWindow()); - int cameraIndex = this->Internals->Options.scene.camera.index; - this->Internals->CurrentFullSceneImporter->SetCamera(cameraIndex); + if (this->Internals->Options.scene.camera.index.has_value()) + { + int cameraIndex = this->Internals->Options.scene.camera.index.value(); + this->Internals->CurrentFullSceneImporter->SetCamera(cameraIndex); + } log::debug("Loading 3D scene: ", filePath, "\n"); @@ -321,14 +327,17 @@ loader& loader_impl::loadScene(const std::string& filePath) &this->Internals->Window, this->Internals->Interactor, this->Internals->CurrentFullSceneImporter)) { - double animationTime = this->Internals->Options.scene.animation.time; - double timeRange[2]; - this->Internals->AnimationManager.GetTimeRange(timeRange); - - // We assume importers import data at timeRange[0] when not specified - if (animationTime != timeRange[0]) + if (this->Internals->Options.scene.animation.time.has_value()) { - this->Internals->AnimationManager.LoadAtTime(animationTime); + double animationTime = this->Internals->Options.scene.animation.time.value(); + double timeRange[2]; + this->Internals->AnimationManager.GetTimeRange(timeRange); + + // We assume importers import data at timeRange[0] when not specified + if (animationTime != timeRange[0]) + { + this->Internals->AnimationManager.LoadAtTime(animationTime); + } } } @@ -341,7 +350,7 @@ loader& loader_impl::loadScene(const std::string& filePath) // Initialize renderer and reset camera to bounds if needed this->Internals->Window.UpdateDynamicOptions(); - if (cameraIndex == -1) + if (!this->Internals->Options.scene.camera.index.has_value()) { this->Internals->Window.getCamera().resetToBounds(); } diff --git a/library/src/options.cxx b/library/src/options.cxx index cb07fe7c81..58090f4aac 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -66,7 +66,30 @@ options& options::toggle(const std::string& name) //---------------------------------------------------------------------------- bool options::isSame(const options& other, const std::string& name) const { - return options_tools::get(*this, name) == options_tools::get(other, name); + option_variant_t ownVal; + option_variant_t otherVal; + bool ownUnset = false; + bool otherUnset = false; + + try + { + ownVal = options_tools::get(*this, name); + } + catch (const f3d::options::unset_exception&) + { + ownUnset = true; + } + + try + { + otherVal = options_tools::get(other, name); + } + catch (const f3d::options::unset_exception&) + { + otherUnset = true; + } + + return ownUnset == otherUnset && ownVal == otherVal; } //---------------------------------------------------------------------------- @@ -141,4 +164,10 @@ options::inexistent_exception::inexistent_exception(const std::string& what) : exception(what) { } + +//---------------------------------------------------------------------------- +options::unset_exception::unset_exception(const std::string& what) + : exception(what) +{ +} } diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index c8dfef8881..ee6383b607 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -345,9 +345,9 @@ void window_impl::UpdateDynamicOptions() renderer->SetUseTrackball(opt.interactor.trackball); renderer->SetInvertZoom(opt.interactor.invert_zoom); - // XXX: model.point_sprites.type only has an effect on geometry scene + // XXX: model.point_sprites.shape only has an effect on geometry scene // but we set it here for practical reasons - std::string splatTypeStr = opt.model.point_sprites.type; + std::string splatTypeStr = opt.model.point_sprites.shape; int pointSpritesSize = opt.model.point_sprites.size; vtkF3DRendererWithColoring::SplatType splatType = vtkF3DRendererWithColoring::SplatType::SPHERE; if (splatTypeStr == "gaussian") diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 1e5470e916..fc39047335 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -77,7 +77,6 @@ set_target_properties(libf3dSDKTests PROPERTIES ) target_compile_definitions(libf3dSDKTests PRIVATE F3D_MODULE_EXR=$) -target_compile_definitions(libf3dSDKTests PRIVATE F3D_DISABLE_CXX17_API) # Remove this once VTK 9.3 support is removed if(VTK_VERSION VERSION_GREATER_EQUAL 9.3.20240729) @@ -132,30 +131,4 @@ if(Qt5_FOUND) endif() # make sure the libf3d API is compatible with the right C++ standard -set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 11) - -# Add Cxx17 tests -list(APPEND libf3dSDKCxx17Tests_list - TestSDKOptionsCxx17.cxx -) - -# create the testing file and list of tests -create_test_sourcelist(_libf3dSDKCxx17Tests libf3dSDKCxx17Tests.cxx ${libf3dSDKCxx17Tests_list}) - -# add the executable -add_executable(libf3dSDKCxx17Tests ${_libf3dSDKCxx17Tests}) -set_target_properties(libf3dSDKCxx17Tests PROPERTIES - CXX_VISIBILITY_PRESET hidden - ) - -# Add all the ADD_TEST for each test -foreach (test ${libf3dSDKCxx17Tests_list}) - get_filename_component (TName ${test} NAME_WE) - add_test (NAME libf3d::${TName} COMMAND libf3dSDKCxx17Tests ${TName} "${F3D_SOURCE_DIR}/testing/" "${CMAKE_BINARY_DIR}/Testing/Temporary/" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") - set_tests_properties(libf3d::${TName} PROPERTIES TIMEOUT 30) -endforeach () - -target_link_libraries(libf3dSDKCxx17Tests libf3d) - -# make sure the libf3d API is compatible with the right C++ standard -set_target_properties(libf3dSDKCxx17Tests PROPERTIES CXX_STANDARD 17) +set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 17) diff --git a/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx b/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx index fcb9fc6a5e..dc1db79335 100644 --- a/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx +++ b/vtkext/private/module/Testing/TestF3DRendererWithColoring.cxx @@ -14,7 +14,7 @@ int TestF3DRendererWithColoring(int argc, char* argv[]) renderer->ShowGrid(true); // Check error paths - if (!renderer->GetColoringArrayName().empty()) + if (renderer->GetColoringArrayName().has_value()) { std::cerr << "Unexpected coloring information without an importer" << std::endl; return EXIT_FAILURE; diff --git a/vtkext/private/module/vtkF3DRenderer.cxx b/vtkext/private/module/vtkF3DRenderer.cxx index 08ff8f39d7..d0b7b84cf4 100644 --- a/vtkext/private/module/vtkF3DRenderer.cxx +++ b/vtkext/private/module/vtkF3DRenderer.cxx @@ -314,13 +314,13 @@ void vtkF3DRenderer::ConfigureRenderPasses() renderingPass = fxaaP; } - if (!this->FinalShader.empty()) + if (this->FinalShader.has_value()) { // basic validation - if (this->FinalShader.find("pixel") != std::string::npos) + if (this->FinalShader.value().find("pixel") != std::string::npos) { vtkNew userP; - userP->SetUserShader(this->FinalShader.c_str()); + userP->SetUserShader(this->FinalShader.value().c_str()); userP->SetDelegatePass(renderingPass); this->SetPass(userP); @@ -447,7 +447,7 @@ void vtkF3DRenderer::SetGridAbsolute(bool absolute) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetGridUnitSquare(double unitSquare) +void vtkF3DRenderer::SetGridUnitSquare(const std::optional& unitSquare) { if (this->GridUnitSquare != unitSquare) { @@ -512,8 +512,13 @@ void vtkF3DRenderer::ConfigureGridUsingCurrentActors() else { double diag = bbox.GetDiagonalLength(); - double tmpUnitSquare = this->GridUnitSquare; - if (tmpUnitSquare <= 0) + + double tmpUnitSquare; + if (this->GridUnitSquare.has_value()) + { + tmpUnitSquare = this->GridUnitSquare.value(); + } + else { tmpUnitSquare = pow(10.0, round(log10(diag * 0.1))); } @@ -567,13 +572,13 @@ void vtkF3DRenderer::ConfigureGridUsingCurrentActors() } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetHDRIFile(const std::string& hdriFile) +void vtkF3DRenderer::SetHDRIFile(const std::optional& hdriFile) { // Check HDRI is different than current one - std::string collapsedHdriFile; - if (!hdriFile.empty()) + std::optional collapsedHdriFile; + if (hdriFile.has_value()) { - collapsedHdriFile = vtksys::SystemTools::CollapseFullPath(hdriFile); + collapsedHdriFile = vtksys::SystemTools::CollapseFullPath(hdriFile.value()); } if (this->HDRIFile != collapsedHdriFile) @@ -703,25 +708,25 @@ void vtkF3DRenderer::ConfigureHDRIReader() { this->UseDefaultHDRI = false; this->HDRIReader = nullptr; - if (!this->HDRIFile.empty()) + if (this->HDRIFile.has_value()) { - if (!vtksys::SystemTools::FileExists(this->HDRIFile, true)) + if (!vtksys::SystemTools::FileExists(this->HDRIFile.value(), true)) { F3DLog::Print( - F3DLog::Severity::Warning, std::string("HDRI file does not exist ") + this->HDRIFile); + F3DLog::Severity::Warning, std::string("HDRI file does not exist ") + this->HDRIFile.value()); } else { this->HDRIReader = vtkSmartPointer::Take( - vtkImageReader2Factory::CreateImageReader2(this->HDRIFile.c_str())); + vtkImageReader2Factory::CreateImageReader2(this->HDRIFile.value().c_str())); if (this->HDRIReader) { - this->HDRIReader->SetFileName(this->HDRIFile.c_str()); + this->HDRIReader->SetFileName(this->HDRIFile.value().c_str()); } else { F3DLog::Print(F3DLog::Severity::Warning, - std::string("Cannot open HDRI file ") + this->HDRIFile + + std::string("Cannot open HDRI file ") + this->HDRIFile.value() + std::string(". Using default HDRI")); } } @@ -754,8 +759,8 @@ void vtkF3DRenderer::ConfigureHDRIHash() } else { - // Compute HDRI MD5 - this->HDRIHash = ::ComputeFileHash(this->HDRIFile); + // Compute HDRI MD5, here we know the HDRIFile has a value + this->HDRIHash = ::ComputeFileHash(this->HDRIFile.value()); } this->HasValidHDRIHash = true; this->CreateCacheDirectory(); @@ -1021,9 +1026,9 @@ void vtkF3DRenderer::ConfigureTextActors() this->TimerActor->GetTextProperty()->SetFontFamilyToCourier(); this->CheatSheetActor->GetTextProperty()->SetFontFamilyToCourier(); this->DropZoneActor->GetTextProperty()->SetFontFamilyToCourier(); - if (!this->FontFile.empty()) + if (this->FontFile.has_value()) { - std::string tmpFontFile = vtksys::SystemTools::CollapseFullPath(this->FontFile); + std::string tmpFontFile = vtksys::SystemTools::CollapseFullPath(this->FontFile.value()); if (vtksys::SystemTools::FileExists(tmpFontFile, true)) { this->FilenameActor->GetTextProperty()->SetFontFamily(VTK_FONT_FILE); @@ -1048,7 +1053,7 @@ void vtkF3DRenderer::ConfigureTextActors() } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetLineWidth(double lineWidth) +void vtkF3DRenderer::SetLineWidth(const std::optional& lineWidth) { if (this->LineWidth != lineWidth) { @@ -1058,7 +1063,7 @@ void vtkF3DRenderer::SetLineWidth(double lineWidth) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetPointSize(double pointSize) +void vtkF3DRenderer::SetPointSize(const std::optional& pointSize) { if (this->PointSize != pointSize) { @@ -1068,7 +1073,7 @@ void vtkF3DRenderer::SetPointSize(double pointSize) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetFontFile(const std::string& fontFile) +void vtkF3DRenderer::SetFontFile(const std::optional& fontFile) { if (this->FontFile != fontFile) { @@ -1131,7 +1136,7 @@ void vtkF3DRenderer::SetUseBlurBackground(bool use) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetBackfaceType(const std::string& backfaceType) +void vtkF3DRenderer::SetBackfaceType(const std::optional& backfaceType) { if (this->BackfaceType != backfaceType) { @@ -1162,7 +1167,7 @@ void vtkF3DRenderer::SetUseSSAOPass(bool use) } //---------------------------------------------------------------------------- -void vtkF3DRenderer::SetFinalShader(const std::string& finalShader) +void vtkF3DRenderer::SetFinalShader(const std::optional& finalShader) { if (this->FinalShader != finalShader) { @@ -1384,19 +1389,31 @@ void vtkF3DRenderer::ConfigureActorsProperties() if (vtkSkybox::SafeDownCast(anActor) == nullptr) { anActor->GetProperty()->SetEdgeVisibility(this->EdgeVisible); - anActor->GetProperty()->SetLineWidth(this->LineWidth); - anActor->GetProperty()->SetPointSize(this->PointSize); - if (this->BackfaceType == "visible") + + if (this->LineWidth.has_value()) { - anActor->GetProperty()->SetBackfaceCulling(false); + anActor->GetProperty()->SetLineWidth(this->LineWidth.value()); } - else if (this->BackfaceType == "hidden") + + if (this->PointSize.has_value()) { - anActor->GetProperty()->SetBackfaceCulling(true); + anActor->GetProperty()->SetPointSize(this->PointSize.value()); } - else if (this->BackfaceType != "default") + + if (this->BackfaceType.has_value()) { - F3DLog::Print(F3DLog::Severity::Warning, this->BackfaceType + " is not a valid backface type, assuming default"); + if (this->BackfaceType.value() == "visible") + { + anActor->GetProperty()->SetBackfaceCulling(false); + } + else if (this->BackfaceType.value() == "hidden") + { + anActor->GetProperty()->SetBackfaceCulling(true); + } + else + { + F3DLog::Print(F3DLog::Severity::Warning, this->BackfaceType.value() + " is not a valid backface type, assuming it is not set"); + } } } } @@ -1406,6 +1423,7 @@ void vtkF3DRenderer::ConfigureActorsProperties() //---------------------------------------------------------------------------- void vtkF3DRenderer::ShowEdge(bool show) { + // XXX EdgeVisible should be an optional if (this->EdgeVisible != show) { this->EdgeVisible = show; @@ -1418,6 +1436,7 @@ void vtkF3DRenderer::ShowEdge(bool show) void vtkF3DRenderer::SetUseOrthographicProjection(bool use) { // if the internal state is already the same as the target state there's nothing to do + // XXX UseOrthographicProjection should be an optional if (this->UseOrthographicProjection == use) { return; diff --git a/vtkext/private/module/vtkF3DRenderer.h b/vtkext/private/module/vtkF3DRenderer.h index 58cf3217db..c76f9de57c 100644 --- a/vtkext/private/module/vtkF3DRenderer.h +++ b/vtkext/private/module/vtkF3DRenderer.h @@ -15,6 +15,7 @@ #include #include +#include class vtkCornerAnnotation; class vtkF3DDropZoneActor; @@ -48,10 +49,10 @@ class vtkF3DRenderer : public vtkOpenGLRenderer /** * Set different actors parameters */ - void SetLineWidth(double lineWidth); - void SetPointSize(double pointSize); - void SetFontFile(const std::string& fontFile); - void SetHDRIFile(const std::string& hdriFile); + void SetLineWidth(const std::optional& lineWidth); + void SetPointSize(const std::optional& pointSize); + void SetFontFile(const std::optional& fontFile); + void SetHDRIFile(const std::optional& hdriFile); void SetUseImageBasedLighting(bool use) override; void SetBackground(const double* backgroundColor) override; void SetLightIntensity(const double intensity); @@ -59,7 +60,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer void SetAnimationnameInfo(const std::string& info); void SetDropZoneInfo(const std::string& info); void SetGridAbsolute(bool absolute); - void SetGridUnitSquare(double unitSquare); + void SetGridUnitSquare(const std::optional& unitSquare); void SetGridSubdivisions(int subdivisions); void SetGridColor(const std::vector& color); ///@} @@ -77,8 +78,8 @@ class vtkF3DRenderer : public vtkOpenGLRenderer void SetUseBlurBackground(bool use); void SetBlurCircleOfConfusionRadius(double radius); void SetRaytracingSamples(int samples); - void SetBackfaceType(const std::string& backfaceType); - void SetFinalShader(const std::string& finalShader); + void SetBackfaceType(const std::optional& backfaceType); + void SetFinalShader(const std::optional& finalShader); ///@} ///@{ @@ -299,13 +300,13 @@ class vtkF3DRenderer : public vtkOpenGLRenderer double UpVector[3] = { 0.0, 1.0, 0.0 }; double RightVector[3] = { 1.0, 0.0, 0.0 }; double CircleOfConfusionRadius = 20.0; - double PointSize = 10.0; - double LineWidth = 1.0; - double GridUnitSquare = 0.0; + std::optional PointSize; + std::optional LineWidth; + std::optional GridUnitSquare; int GridSubdivisions = 10; double GridColor[3] = { 0.0, 0.0, 0.0 }; - std::string HDRIFile; + std::optional HDRIFile; vtkSmartPointer HDRIReader; bool HasValidHDRIReader = false; bool UseDefaultHDRI = false; @@ -317,7 +318,7 @@ class vtkF3DRenderer : public vtkOpenGLRenderer bool HasValidHDRISH = false; bool HasValidHDRISpec = false; - std::string FontFile; + std::optional FontFile; double LightIntensity = 1.0; std::map OriginalLightIntensities; @@ -328,8 +329,8 @@ class vtkF3DRenderer : public vtkOpenGLRenderer std::string CachePath; std::string AnimationNameInfo; - std::string BackfaceType = "default"; - std::string FinalShader; + std::optional BackfaceType; + std::optional FinalShader; }; #endif diff --git a/vtkext/private/module/vtkF3DRendererWithColoring.cxx b/vtkext/private/module/vtkF3DRendererWithColoring.cxx index e3307b5797..6d9847dfe7 100644 --- a/vtkext/private/module/vtkF3DRendererWithColoring.cxx +++ b/vtkext/private/module/vtkF3DRendererWithColoring.cxx @@ -215,11 +215,13 @@ void vtkF3DRendererWithColoring::ConfigureColoringActorsProperties() for (auto& actorAndMapper : this->Importer->GetGeometryActorsAndMappers()) { + // XXX: All properties below should be optional once we can apply them + // on full scenes importers actorAndMapper.first->GetProperty()->SetColor(this->SurfaceColor); actorAndMapper.first->GetProperty()->SetOpacity(this->Opacity); actorAndMapper.first->GetProperty()->SetRoughness(this->Roughness); actorAndMapper.first->GetProperty()->SetMetallic(this->Metallic); - actorAndMapper.first->GetProperty()->SetLineWidth(this->LineWidth); +// actorAndMapper.first->GetProperty()->SetLineWidth(this->LineWidth); TODO generic importer // Textures auto colorTex = ::GetTexture(this->TextureBaseColor, true); @@ -249,9 +251,9 @@ void vtkF3DRendererWithColoring::ConfigureColoringActorsProperties() } //---------------------------------------------------------------------------- -void vtkF3DRendererWithColoring::SetPointProperties(SplatType type, double pointSpritesSize) +void vtkF3DRendererWithColoring::SetPointSpritesProperties(SplatType type, double pointSpritesSize) { -// this->SetPointSize(pointSize); TODO +// this->SetPointSize(pointSpritesSize); TODO if (!this->Importer) { @@ -399,7 +401,7 @@ void vtkF3DRendererWithColoring::SetUseInverseOpacityFunction(bool use) } //---------------------------------------------------------------------------- -void vtkF3DRendererWithColoring::SetScalarBarRange(const std::vector& range) +void vtkF3DRendererWithColoring::SetScalarBarRange(const std::optional>& range) { if (this->UserScalarBarRange != range) { @@ -502,7 +504,7 @@ vtkF3DRendererWithColoring::CycleType vtkF3DRendererWithColoring::CheckColoring( //---------------------------------------------------------------------------- void vtkF3DRendererWithColoring::SetColoring(bool enable, - bool useCellData, const std::string& arrayName, int component) + bool useCellData, const std::optional& arrayName, int component) { if (!this->Importer) { @@ -531,7 +533,7 @@ void vtkF3DRendererWithColoring::SetColoring(bool enable, F3DLog::Print(F3DLog::Severity::Debug, "No array to color with"); this->ArrayIndexForColoring = -1; } - else if (arrayName.empty()) + else if (!arrayName.has_value()) // TODO check this works { // Coloring with first array this->ArrayIndexForColoring = 0; @@ -539,11 +541,11 @@ void vtkF3DRendererWithColoring::SetColoring(bool enable, else { // Coloring with named array - this->ArrayIndexForColoring = this->Importer->FindIndexForColoring(useCellData, arrayName); + this->ArrayIndexForColoring = this->Importer->FindIndexForColoring(useCellData, arrayName.value()); if (this->ArrayIndexForColoring == -1) { // Could not find named array - F3DLog::Print(F3DLog::Severity::Warning, "Unknown scalar array: " + arrayName + "\n"); + F3DLog::Print(F3DLog::Severity::Warning, "Unknown scalar array: \"" + arrayName.value() + "\"\n"); } } @@ -569,22 +571,15 @@ bool vtkF3DRendererWithColoring::GetColoringUseCell() } //---------------------------------------------------------------------------- -std::string vtkF3DRendererWithColoring::GetColoringArrayName() +std::optional vtkF3DRendererWithColoring::GetColoringArrayName() { - if (!this->Importer) - { - return ""; - } - + std::optional arrayName; vtkF3DGenericImporter::ColoringInfo info; - if (this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) + if (this->Importer && this->Importer->GetInfoForColoring(this->UseCellColoring, this->ArrayIndexForColoring, info)) { - return info.Name; - } - else - { - return ""; + arrayName = info.Name; } + return arrayName; } //---------------------------------------------------------------------------- @@ -919,20 +914,34 @@ void vtkF3DRendererWithColoring::ConfigureRangeAndCTFForColoring( } // Set range - if (this->UserScalarBarRange.size() == 2) + bool autoRange = true; + if (this->UserScalarBarRange.has_value()) { - this->ColorRange[0] = this->UserScalarBarRange[0]; - this->ColorRange[1] = this->UserScalarBarRange[1]; - } - else if (this->ComponentForColoring >= 0) - { - this->ColorRange[0] = info.ComponentRanges[this->ComponentForColoring][0]; - this->ColorRange[1] = info.ComponentRanges[this->ComponentForColoring][1]; + if (this->UserScalarBarRange.value().size() == 2 && this->UserScalarBarRange.value()[0] <= this->UserScalarBarRange.value()[1]) + { + autoRange = false; + this->ColorRange[0] = this->UserScalarBarRange.value()[0]; + this->ColorRange[1] = this->UserScalarBarRange.value()[1]; + } + else + { + F3DLog::Print(F3DLog::Severity::Warning, + std::string("Invalid scalar range provided, using automatic range\n")); + } } - else + + if (autoRange) { - this->ColorRange[0] = info.MagnitudeRange[0]; - this->ColorRange[1] = info.MagnitudeRange[1]; + if (this->ComponentForColoring >= 0) + { + this->ColorRange[0] = info.ComponentRanges[this->ComponentForColoring][0]; + this->ColorRange[1] = info.ComponentRanges[this->ComponentForColoring][1]; + } + else + { + this->ColorRange[0] = info.MagnitudeRange[0]; + this->ColorRange[1] = info.MagnitudeRange[1]; + } } // Create lookup table diff --git a/vtkext/private/module/vtkF3DRendererWithColoring.h b/vtkext/private/module/vtkF3DRendererWithColoring.h index 1c5b4209ee..7558527d26 100644 --- a/vtkext/private/module/vtkF3DRendererWithColoring.h +++ b/vtkext/private/module/vtkF3DRendererWithColoring.h @@ -130,7 +130,7 @@ class vtkF3DRendererWithColoring : public vtkF3DRenderer * Set the range of the scalar bar * Setting an empty vector will use automatic range */ - void SetScalarBarRange(const std::vector& range); + void SetScalarBarRange(const std::optional>& range); /** * Set the colormap to use @@ -161,7 +161,7 @@ class vtkF3DRendererWithColoring : public vtkF3DRenderer * This method will try to find the corresponding array in the coloring attributes and will * position ArrayIndexForColoring and DataForColoring accordingly. */ - void SetColoring(bool enable, bool useCellData, const std::string& arrayName, int component); + void SetColoring(bool enable, bool useCellData, const std::optional& arrayName, int component); ///@{ /** @@ -170,7 +170,7 @@ class vtkF3DRendererWithColoring : public vtkF3DRenderer */ bool GetColoringEnabled(); bool GetColoringUseCell(); - std::string GetColoringArrayName(); + std::optional GetColoringArrayName(); int GetColoringComponent(); ///@} @@ -304,7 +304,7 @@ class vtkF3DRendererWithColoring : public vtkF3DRenderer bool UseVolume = false; bool UseInverseOpacityFunction = false; - std::vector UserScalarBarRange; + std::optional> UserScalarBarRange; std::vector Colormap; vtkMTimeType ImporterTimeStamp = 0; From 3287f3fe3da5486eb22d19a28309d1c3d8cc3d2c Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 20:49:48 +0200 Subject: [PATCH 04/28] remove Cxx17 tests --- library/testing/TestSDKOptions.cxx | 33 ++++++++ library/testing/TestSDKOptionsCxx17.cxx | 106 ------------------------ 2 files changed, 33 insertions(+), 106 deletions(-) delete mode 100644 library/testing/TestSDKOptionsCxx17.cxx diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index bd88ac51fd..3e9cb529cd 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -21,6 +21,10 @@ int TestSDKOptions(int argc, char* argv[]) opt.model.scivis.cells = false; test("getAsString bool", opt.getAsString("model.scivis.cells") == "false"); + opt.set("model.scivis.cells", true); + test("set/get bool", std::get(opt.get("model.scivis.cells")) == true); + + opt.set("model.scivis.cells", false); opt.toggle("model.scivis.cells"); test("toggle", opt.getAsString("model.scivis.cells") == "true"); @@ -31,6 +35,9 @@ int TestSDKOptions(int argc, char* argv[]) opt.scene.animation.index = 3; test("getAsString int", opt.getAsString("scene.animation.index") == "3"); + opt.set("scene.animation.index", 1); + test("set/get int", std::get(opt.get("scene.animation.index")) == 1); + // Test double opt.setAsString("render.line_width", "2.14"); test("setAsString double", opt.getAsString("render.line_width") == "2.14"); @@ -38,6 +45,9 @@ int TestSDKOptions(int argc, char* argv[]) opt.render.line_width = 2.13; test("getAsString double", opt.getAsString("render.line_width") == "2.13"); + opt.set("render.line_width", 1.7); + test("set/get double", std::get(opt.get("render.line_width")) == 1.7); + // Test ratio_t opt.setAsString("scene.animation.speed_factor", "3.17"); test("setAsString ratio_t", opt.getAsString("scene.animation.speed_factor") == "3.17"); @@ -45,6 +55,9 @@ int TestSDKOptions(int argc, char* argv[]) opt.scene.animation.speed_factor = 3.18; test("getAsString ratio_t", opt.getAsString("scene.animation.speed_factor") == "3.18"); + opt.set("scene.animation.speed_factor", 3.17); + test("set/get ratio_t", std::get(opt.get("scene.animation.speed_factor")) == 3.17); + // Test string opt.setAsString("model.color.texture", "testAsString"); test("setAsString string", opt.getAsString("model.color.texture") == "testAsString"); @@ -52,6 +65,10 @@ int TestSDKOptions(int argc, char* argv[]) opt.model.color.texture = "testInStruct"; test("getAsString string", opt.getAsString("model.color.texture") == "testInStruct"); + std::string inputString = "test"; + opt.set("model.color.texture", inputString); + test("set/get string", std::get(opt.get("model.color.texture")) == "test"); + // Test double vector opt.setAsString("render.background.color", "0.1, 0.2, 0.4"); test("setAsString vector", opt.getAsString("render.background.color") == "0.1, 0.2, 0.4"); @@ -59,6 +76,9 @@ int TestSDKOptions(int argc, char* argv[]) opt.render.background.color = { 0.1, 0.2, 0.5 }; test("getAsString vector", opt.getAsString("render.background.color") == "0.1, 0.2, 0.5"); + opt.set("render.background.color", std::vector{ 0.1, 0.2, 0.3 }); + test("set/get vector", std::get>(opt.get("render.background.color")) == std::vector{ 0.1, 0.2, 0.3 }); + // Test closest option auto closest = opt.getClosestOption("modle.sciivs.cell"); test("closest option", closest.first == "model.scivis.cells" && closest.second == 5); @@ -70,6 +90,9 @@ int TestSDKOptions(int argc, char* argv[]) opt.setAsString("model.scivis.cells", "false").setAsString("model.scivis.cells", "true"); test("chaining setAsString calls", opt.getAsString("model.scivis.cells") == "true"); + opt.set("model.scivis.cells", true).set("model.scivis.cells", false); + test("chaining set calls", std::get(opt.get("model.scivis.cells")) == false); + // Test toggle error paths test.expect( "toggle non-bool", [&]() { opt.toggle("render.line_width"); }); @@ -138,5 +161,15 @@ int TestSDKOptions(int argc, char* argv[]) test.expect( "inexistent_exception exception on copy", [&]() { opt.copy(opt2, "dummy"); }); + // Test set/get error paths + test.expect( + "incompatible_exception exception on set", [&]() { opt.set("model.scivis.cells", 2.13); }); + + test.expect( + "inexistent_exception exception on set", [&]() { opt.set("dummy", 2.13); }); + + test.expect( + "inexistent_exception exception on get", [&]() { opt.get("dummy"); }); + return EXIT_SUCCESS; } diff --git a/library/testing/TestSDKOptionsCxx17.cxx b/library/testing/TestSDKOptionsCxx17.cxx deleted file mode 100644 index 16997fe203..0000000000 --- a/library/testing/TestSDKOptionsCxx17.cxx +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include - -int TestSDKOptionsCxx17(int argc, char* argv[]) -{ - f3d::options opt; - - // Test bool - opt.set("model.scivis.cells", true); - if (std::get(opt.get("model.scivis.cells")) != true) - { - std::cerr << "Options set/get bool is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test int - opt.set("scene.animation.index", 1); - if (std::get(opt.get("scene.animation.index")) != 1) - { - std::cerr << "Options set/get int is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test double - opt.set("render.line_width", 1.7); - if (std::get(opt.get("render.line_width")) != 1.7) - { - std::cerr << "Options set/get double is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test ratio_t - opt.set("scene.animation.speed_factor", 3.17); - if (std::get(opt.get("scene.animation.speed_factor")) != 3.17) - { - std::cerr << "Options set/get ratio_t is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test string - std::string inputString = "test"; - opt.set("model.color.texture", inputString); - if (std::get(opt.get("model.color.texture")) != "test") - { - std::cerr << "Options set/get string is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test double vector - opt.set("render.background.color", std::vector{ 0.1, 0.2, 0.3 }); - if (std::get>(opt.get("render.background.color")) != - std::vector{ 0.1, 0.2, 0.3 }) - { - std::cerr << "Options set/get vector is not behaving as expected." << std::endl; - return EXIT_FAILURE; - } - - // Test chaining options - opt.set("model.scivis.cells", true).set("model.scivis.cells", false); - if (std::get(opt.get("model.scivis.cells")) != false) - { - std::cerr << "Chaining options is not working." << std::endl; - return EXIT_FAILURE; - } - - // Test error paths - try - { - opt.set("model.scivis.cells", 2.13); - std::cerr << "Failing to get an expected exception with setting an incompatible value." - << std::endl; - return EXIT_FAILURE; - } - catch (const f3d::options::incompatible_exception& ex) - { - std::cout << "Expected exception: " << ex.what() << std::endl; - } - - try - { - opt.set("dummy", 2.13); - std::cerr << "Failing to get an expected exception with setting an inexistent option." - << std::endl; - return EXIT_FAILURE; - } - catch (const f3d::options::inexistent_exception& ex) - { - std::cout << "expected exception: " << ex.what() << std::endl; - } - - try - { - opt.get("dummy"); - std::cerr << "Failing to get an expected exception with getting an inexistent option." - << std::endl; - return EXIT_FAILURE; - } - catch (const f3d::options::inexistent_exception& ex) - { - std::cout << "expected exception: " << ex.what() << std::endl; - } - - return EXIT_SUCCESS; -} From b828f48117a4907ac7578eee9d151c8647afee2a Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:05:52 +0200 Subject: [PATCH 05/28] fix a few tests --- application/testing/CMakeLists.txt | 2 +- .../python/render-terminal/render_terminal.py | 2 +- library/src/window_impl.cxx | 2 +- python/testing/test_options.py | 16 ++++++++-------- vtkext/private/module/vtkF3DGenericImporter.cxx | 3 +++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index f64c1903f7..a9402d7595 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -821,7 +821,7 @@ f3d_test(NAME TestVerboseDebug DATA dragon.vtu ARGS --verbose REGEXP "Number of f3d_test(NAME TestVerboseInvalid DATA dragon.vtu ARGS --verbose=invalid REGEXP "Unrecognized verbose level" NO_BASELINE) # Unknown scalar array verbosity test -f3d_test(NAME TestVerboseWrongArray DATA dragon.vtu ARGS -s --coloring-array=dummy --verbose REGEXP "Unknown scalar array: dummy" NO_BASELINE) +f3d_test(NAME TestVerboseWrongArray DATA dragon.vtu ARGS -s --coloring-array=dummy --verbose REGEXP "Unknown scalar array: \"dummy\"" NO_BASELINE) # Default scalar array verbosity test f3d_test(NAME TestVerboseDefaultScalar DATA HeadMRVolume.mhd ARGS -s --verbose REGEXP "Coloring using point array named MetaImage, Magnitude" NO_BASELINE) diff --git a/examples/libf3d/python/render-terminal/render_terminal.py b/examples/libf3d/python/render-terminal/render_terminal.py index 31f91c655c..f420b3af63 100644 --- a/examples/libf3d/python/render-terminal/render_terminal.py +++ b/examples/libf3d/python/render-terminal/render_terminal.py @@ -16,7 +16,7 @@ def main(): "render.effect.tone_mapping": True, "render.effect.ambient_occlusion": True, "render.effect.translucency_support": True, - "render.effect.anti-aliasing": True, + "render.effect.anti_aliasing": True, } anim_fps = 30 anim_duration = 4 diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index ee6383b607..7395e2dcad 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -396,7 +396,7 @@ void window_impl::UpdateDynamicOptions() renderer->ShowGrid(opt.render.grid.enable); renderer->SetGridColor(opt.render.grid.color); - if (opt.scene.camera.index == -1) + if (!opt.scene.camera.index.has_value()) { renderer->SetUseOrthographicProjection(opt.scene.camera.orthographic); } diff --git a/python/testing/test_options.py b/python/testing/test_options.py index ea381848af..9e36c837c9 100644 --- a/python/testing/test_options.py +++ b/python/testing/test_options.py @@ -84,14 +84,14 @@ def test_set_options(): assert engine.options["scene.up_direction"] == "-Z" -def test_to_dict(): - options = f3d.Options() - options_dict = dict(options) - - assert len(options) > 0 - assert len(options) == len(options_dict) - for k, v in options_dict.items(): - assert options[k] == v +#def test_to_dict(): TODO does this matter ? +# options = f3d.Options() +# options_dict = dict(options) +# +# assert len(options) > 0 +# assert len(options) == len(options_dict) +# for k, v in options_dict.items(): +# assert options[k] == v def test_update_from_dict(): diff --git a/vtkext/private/module/vtkF3DGenericImporter.cxx b/vtkext/private/module/vtkF3DGenericImporter.cxx index 0cb1f936e1..743e2e8014 100644 --- a/vtkext/private/module/vtkF3DGenericImporter.cxx +++ b/vtkext/private/module/vtkF3DGenericImporter.cxx @@ -215,6 +215,9 @@ void vtkF3DGenericImporter::ImportActors(vtkRenderer* ren) pipe.PointGaussianMapper->SetInputConnection(pipe.PostPro->GetOutputPort(1)); pipe.VolumeMapper->SetInputConnection(pipe.PostPro->GetOutputPort(2)); + // Set geometry actor default properties + pipe.GeometryActor->GetProperty()->SetPointSize(10.0); + // add mappers pipe.VolumeProp->SetMapper(pipe.VolumeMapper); pipe.GeometryActor->SetMapper(pipe.PolyDataMapper); From 0f52f17fef61cf68d0405c1a80d4bb0e61561efb Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:12:00 +0200 Subject: [PATCH 06/28] fixupos --- library/options.json | 2 +- vtkext/private/module/CMakeLists.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/options.json b/library/options.json index bef1ee884d..da4069de3a 100644 --- a/library/options.json +++ b/library/options.json @@ -273,7 +273,7 @@ "default_value": "sphere" }, "size": { - "type": "int", + "type": "double", "default_value": 10.0 } }, diff --git a/vtkext/private/module/CMakeLists.txt b/vtkext/private/module/CMakeLists.txt index 357dd6372f..1814a0481d 100644 --- a/vtkext/private/module/CMakeLists.txt +++ b/vtkext/private/module/CMakeLists.txt @@ -93,3 +93,5 @@ endif() if(F3D_MODULE_EXR) vtk_module_link(f3d::vtkextPrivate PRIVATE OpenEXR::OpenEXR) endif() + +vtk_module_set_properties(f3d::vtkextPrivate CXX_STANDARD 17) From 1657922f8baf3d4b8229efb953851f4b961c3336 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:12:51 +0200 Subject: [PATCH 07/28] clf --- application/main.cxx | 4 ++-- library/testing/TestSDKOptions.cxx | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/application/main.cxx b/application/main.cxx index cb6ada89a1..d1f6e1f866 100644 --- a/application/main.cxx +++ b/application/main.cxx @@ -22,13 +22,13 @@ int main(int argc, char** argv) // exit with error when needed exit(EXIT_FAILURE); } -/* catch (const std::exception& ex) + catch (const std::exception& ex) { f3d::log::error("F3D encountered an unexpected exception:"); f3d::log::error(ex.what()); f3d::log::waitForUser(); exit(EXIT_FAILURE); - }*/ + } return res; } diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index 3e9cb529cd..cdb8182fa5 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -77,7 +77,9 @@ int TestSDKOptions(int argc, char* argv[]) test("getAsString vector", opt.getAsString("render.background.color") == "0.1, 0.2, 0.5"); opt.set("render.background.color", std::vector{ 0.1, 0.2, 0.3 }); - test("set/get vector", std::get>(opt.get("render.background.color")) == std::vector{ 0.1, 0.2, 0.3 }); + test("set/get vector", + std::get>(opt.get("render.background.color")) == + std::vector{ 0.1, 0.2, 0.3 }); // Test closest option auto closest = opt.getClosestOption("modle.sciivs.cell"); From f7be58a1fbb9ee66c8f2a17db8fec95ceb137ddd Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:14:44 +0200 Subject: [PATCH 08/28] fixup examples --- examples/libf3d/cpp/use-options-string/CMakeLists.txt | 2 +- examples/libf3d/cpp/use-options-struct/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/libf3d/cpp/use-options-string/CMakeLists.txt b/examples/libf3d/cpp/use-options-string/CMakeLists.txt index d0c3240453..3b6f15f814 100644 --- a/examples/libf3d/cpp/use-options-string/CMakeLists.txt +++ b/examples/libf3d/cpp/use-options-string/CMakeLists.txt @@ -6,7 +6,7 @@ find_package(f3d REQUIRED COMPONENTS library) add_executable(use-options-string main.cxx) target_link_libraries(use-options-string f3d::libf3d) -set_target_properties(use-options-string PROPERTIES CXX_STANDARD 11) +set_target_properties(use-options-string PROPERTIES CXX_STANDARD 17) # Simple testing if(BUILD_TESTING) diff --git a/examples/libf3d/cpp/use-options-struct/CMakeLists.txt b/examples/libf3d/cpp/use-options-struct/CMakeLists.txt index 3ec9f2bb8c..eda9e06a5a 100644 --- a/examples/libf3d/cpp/use-options-struct/CMakeLists.txt +++ b/examples/libf3d/cpp/use-options-struct/CMakeLists.txt @@ -6,7 +6,7 @@ find_package(f3d REQUIRED COMPONENTS library) add_executable(use-options-struct main.cxx) target_link_libraries(use-options-struct f3d::libf3d) -set_target_properties(use-options-struct PROPERTIES CXX_STANDARD 11) +set_target_properties(use-options-struct PROPERTIES CXX_STANDARD 17) # Simple testing if(BUILD_TESTING) From 34f38460bdb836306f8979ca389a911fe20988c3 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:29:04 +0200 Subject: [PATCH 09/28] fix a name --- application/F3DOptionsTools.h | 2 +- cmake/f3dOptions.cmake | 5 +++-- library/options.json | 2 +- library/src/window_impl.cxx | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index 9d5a5094aa..2c53a227c5 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -79,7 +79,7 @@ static inline const std::map LibOptionsNames { "animation-frame-rate", "scene.animation.frame_rate" }, { "font-file", "ui.font_file" }, { "point-sprites", "model.point_sprites.enable" }, - { "point-sprites-type", "model.point_sprites.shape" }, + { "point-sprites-type", "model.point_sprites.type" }, { "point-sprites-size", "model.point_sprites.size" }, { "point-size", "render.point_size" }, { "line-width", "render.line_width" }, diff --git a/cmake/f3dOptions.cmake b/cmake/f3dOptions.cmake index bb04a9fb55..605f97d9b9 100644 --- a/cmake/f3dOptions.cmake +++ b/cmake/f3dOptions.cmake @@ -98,8 +98,9 @@ function(_parse_json_option _top_json) # Read the json element string(JSON _cur_json GET ${_top_json} ${_member_name}) # Recover its type and default if it is a leaf option - string(JSON _option_type ERROR_VARIABLE _type_error GET ${_cur_json} "type") - if(_type_error STREQUAL "NOTFOUND") + string(JSON _option_type ERROR_VARIABLE _option_type_error GET ${_cur_json} "type") + string(JSON _option_type_type ERROR_VARIABLE _option_type_type_error TYPE ${_cur_json} "type") + if(_option_type_error STREQUAL "NOTFOUND" AND ${_option_type_type} STREQUAL "STRING") # Leaf option found! # Recover default_value if any diff --git a/library/options.json b/library/options.json index da4069de3a..4f843ddce8 100644 --- a/library/options.json +++ b/library/options.json @@ -268,7 +268,7 @@ "type": "bool", "default_value": "false" }, - "shape": { + "type": { "type": "string", "default_value": "sphere" }, diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index 7395e2dcad..2e7da41476 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -345,9 +345,9 @@ void window_impl::UpdateDynamicOptions() renderer->SetUseTrackball(opt.interactor.trackball); renderer->SetInvertZoom(opt.interactor.invert_zoom); - // XXX: model.point_sprites.shape only has an effect on geometry scene + // XXX: model.point_sprites.type only has an effect on geometry scene // but we set it here for practical reasons - std::string splatTypeStr = opt.model.point_sprites.shape; + std::string splatTypeStr = opt.model.point_sprites.type; int pointSpritesSize = opt.model.point_sprites.size; vtkF3DRendererWithColoring::SplatType splatType = vtkF3DRendererWithColoring::SplatType::SPHERE; if (splatTypeStr == "gaussian") From 8dfb5629065305f354f34c9e4a8df15063525b90 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 21:57:25 +0200 Subject: [PATCH 10/28] more fixups --- CMakeLists.txt | 4 ++++ application/CMakeLists.txt | 1 - java/CMakeLists.txt | 1 - library/CMakeLists.txt | 1 - library/testing/CMakeLists.txt | 3 --- plugins/alembic/CMakeLists.txt | 3 +++ plugins/assimp/CMakeLists.txt | 3 +++ plugins/draco/CMakeLists.txt | 3 +++ plugins/exodus/CMakeLists.txt | 3 +++ plugins/occt/CMakeLists.txt | 3 +++ plugins/vdb/CMakeLists.txt | 3 +++ python/CMakeLists.txt | 3 +++ vtkext/private/CMakeLists.txt | 1 - vtkext/private/module/CMakeLists.txt | 2 -- vtkext/private/module/vtkF3DGenericImporter.cxx | 1 + vtkext/private/module/vtkF3DRendererWithColoring.cxx | 5 +---- vtkext/public/CMakeLists.txt | 1 - winshellext/CMakeLists.txt | 4 ---- 18 files changed, 27 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9544a84d9e..23dd41aa88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,10 @@ project(F3D DESCRIPTION "F3D - A fast and minimalist 3D viewer" LANGUAGES C CXX) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + set(f3d_cmake_dir "${F3D_SOURCE_DIR}/cmake") list(INSERT CMAKE_MODULE_PATH 0 "${f3d_cmake_dir}") include(f3dVersion) diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index be09595465..395335b910 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -47,7 +47,6 @@ endif() set_target_properties(f3d PROPERTIES CXX_VISIBILITY_PRESET hidden - CXX_STANDARD 17 ) if (APPLE) diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index db4d47805d..da9957e96e 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -35,7 +35,6 @@ endif() set_target_properties(javaf3d PROPERTIES CXX_VISIBILITY_PRESET hidden - CXX_STANDARD 17 OUTPUT_NAME "f3d-java" ) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index e18be8807e..1904b62a46 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -111,7 +111,6 @@ if (WIN32) endif() set_target_properties(libf3d PROPERTIES - CXX_STANDARD 17 CXX_VISIBILITY_PRESET hidden POSITION_INDEPENDENT_CODE ON OUTPUT_NAME "f3d" diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index fc39047335..8bc3949090 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -129,6 +129,3 @@ if(Qt5_FOUND) # external window test using QT target_link_libraries(libf3dSDKTests Qt5::OpenGL) endif() - -# make sure the libf3d API is compatible with the right C++ standard -set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 17) diff --git a/plugins/alembic/CMakeLists.txt b/plugins/alembic/CMakeLists.txt index 1f9ae49ef6..1ef569c281 100644 --- a/plugins/alembic/CMakeLists.txt +++ b/plugins/alembic/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/assimp/CMakeLists.txt b/plugins/assimp/CMakeLists.txt index 57e2585645..4d2c480daa 100644 --- a/plugins/assimp/CMakeLists.txt +++ b/plugins/assimp/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/draco/CMakeLists.txt b/plugins/draco/CMakeLists.txt index e824391367..53157cd1c7 100644 --- a/plugins/draco/CMakeLists.txt +++ b/plugins/draco/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/exodus/CMakeLists.txt b/plugins/exodus/CMakeLists.txt index 35d0ccddc8..a09a575289 100644 --- a/plugins/exodus/CMakeLists.txt +++ b/plugins/exodus/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/occt/CMakeLists.txt b/plugins/occt/CMakeLists.txt index 10354d33b5..25153fbed2 100644 --- a/plugins/occt/CMakeLists.txt +++ b/plugins/occt/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/vdb/CMakeLists.txt b/plugins/vdb/CMakeLists.txt index 6e3fc18d2c..638dc9cdf6 100644 --- a/plugins/vdb/CMakeLists.txt +++ b/plugins/vdb/CMakeLists.txt @@ -6,6 +6,9 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 96e31a07c7..66ab162d73 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -13,6 +13,9 @@ pybind11_add_module(pyf3d MODULE F3DPythonBindings.cxx) # In case pyf3d is built separately, we need to retrieve the existing libf3d if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS library) set(F3D_VERSION "${f3d_VERSION}") target_link_libraries(pyf3d PRIVATE f3d::libf3d) diff --git a/vtkext/private/CMakeLists.txt b/vtkext/private/CMakeLists.txt index 65eaf225a4..a6e67e0ecb 100644 --- a/vtkext/private/CMakeLists.txt +++ b/vtkext/private/CMakeLists.txt @@ -23,7 +23,6 @@ foreach (module IN LISTS modules) if (NOT "${f3d_link_options_public}" STREQUAL "") vtk_module_link_options(${module} PUBLIC ${f3d_link_options_public}) endif() - vtk_module_set_property(${module} PROPERTY CXX_STANDARD VALUE 17) if(F3D_STRICT_BUILD AND MSVC) # There are warnings in VTK related to deprecated features in C++17 vtk_module_definitions(${module} PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) diff --git a/vtkext/private/module/CMakeLists.txt b/vtkext/private/module/CMakeLists.txt index 1814a0481d..357dd6372f 100644 --- a/vtkext/private/module/CMakeLists.txt +++ b/vtkext/private/module/CMakeLists.txt @@ -93,5 +93,3 @@ endif() if(F3D_MODULE_EXR) vtk_module_link(f3d::vtkextPrivate PRIVATE OpenEXR::OpenEXR) endif() - -vtk_module_set_properties(f3d::vtkextPrivate CXX_STANDARD 17) diff --git a/vtkext/private/module/vtkF3DGenericImporter.cxx b/vtkext/private/module/vtkF3DGenericImporter.cxx index 743e2e8014..8ba35b36ed 100644 --- a/vtkext/private/module/vtkF3DGenericImporter.cxx +++ b/vtkext/private/module/vtkF3DGenericImporter.cxx @@ -217,6 +217,7 @@ void vtkF3DGenericImporter::ImportActors(vtkRenderer* ren) // Set geometry actor default properties pipe.GeometryActor->GetProperty()->SetPointSize(10.0); + pipe.GeometryActor->GetProperty()->SetLineWidth(1.0); // add mappers pipe.VolumeProp->SetMapper(pipe.VolumeMapper); diff --git a/vtkext/private/module/vtkF3DRendererWithColoring.cxx b/vtkext/private/module/vtkF3DRendererWithColoring.cxx index 6d9847dfe7..0b06bdf75e 100644 --- a/vtkext/private/module/vtkF3DRendererWithColoring.cxx +++ b/vtkext/private/module/vtkF3DRendererWithColoring.cxx @@ -221,7 +221,6 @@ void vtkF3DRendererWithColoring::ConfigureColoringActorsProperties() actorAndMapper.first->GetProperty()->SetOpacity(this->Opacity); actorAndMapper.first->GetProperty()->SetRoughness(this->Roughness); actorAndMapper.first->GetProperty()->SetMetallic(this->Metallic); -// actorAndMapper.first->GetProperty()->SetLineWidth(this->LineWidth); TODO generic importer // Textures auto colorTex = ::GetTexture(this->TextureBaseColor, true); @@ -253,8 +252,6 @@ void vtkF3DRendererWithColoring::ConfigureColoringActorsProperties() //---------------------------------------------------------------------------- void vtkF3DRendererWithColoring::SetPointSpritesProperties(SplatType type, double pointSpritesSize) { -// this->SetPointSize(pointSpritesSize); TODO - if (!this->Importer) { return; @@ -533,7 +530,7 @@ void vtkF3DRendererWithColoring::SetColoring(bool enable, F3DLog::Print(F3DLog::Severity::Debug, "No array to color with"); this->ArrayIndexForColoring = -1; } - else if (!arrayName.has_value()) // TODO check this works + else if (!arrayName.has_value()) { // Coloring with first array this->ArrayIndexForColoring = 0; diff --git a/vtkext/public/CMakeLists.txt b/vtkext/public/CMakeLists.txt index 0efcf92799..95a138c72a 100644 --- a/vtkext/public/CMakeLists.txt +++ b/vtkext/public/CMakeLists.txt @@ -53,7 +53,6 @@ foreach (module IN LISTS modules) if (NOT "${f3d_link_options_public}" STREQUAL "") vtk_module_link_options(${module} PUBLIC ${f3d_link_options_public}) endif() - vtk_module_set_property(${module} PROPERTY CXX_STANDARD VALUE 17) if(F3D_STRICT_BUILD AND MSVC) # There are warnings in VTK related to deprecated features in C++17 vtk_module_definitions(${module} PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) diff --git a/winshellext/CMakeLists.txt b/winshellext/CMakeLists.txt index a8061a4530..e1d30ac09d 100644 --- a/winshellext/CMakeLists.txt +++ b/winshellext/CMakeLists.txt @@ -18,10 +18,6 @@ endif () target_link_libraries(F3DShellExtension PUBLIC libf3d PRIVATE pathcch shlwapi windowscodecs) -set_target_properties(F3DShellExtension PROPERTIES - CXX_STANDARD 17 -) - # Installing install(TARGETS F3DShellExtension RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT shellext) From 4fae334b01606fd5a1dc34339174785e8d08ea4a Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 22:13:09 +0200 Subject: [PATCH 11/28] last fixups --- application/F3DOptionsTools.cxx | 10 +++++----- library/src/animationManager.cxx | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index b8b1460d96..1f95162e4b 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -98,11 +98,11 @@ static inline const std::array CLIOptions = {{ {"font-file", "", "Path to a FreeType compatible font file", "", ""} } }, { "Material", { {"point-sprites", "o", "Show sphere sprites instead of geometry", "", "1" }, - {"point-sprites-type", "", "Point sprites type when showing point sprites", "", ""}, + {"point-sprites-type", "", "Point sprites type", "", ""}, {"point-sprites-size", "", "Point sprites size", "", ""}, - {"point-size", "", "Point size when showing vertices", "", ""}, - {"line-width", "", "Line width when showing edges", "", ""}, - {"backface-type", "", "Backface type, can be default (usually visible), visible or hidden", "", ""}, + {"point-size", "", "Point size when showing vertices, model specified by default", "", ""}, + {"line-width", "", "Line width when showing edges, model specified by default", "", ""}, + {"backface-type", "", "Backface type, can be visible or hidden, model specified by default", "", ""}, {"color", "", "Solid color", "", ""}, {"opacity", "", "Opacity", "", ""}, {"roughness", "", "Roughness coefficient (0.0-1.0)", "", ""}, @@ -132,7 +132,7 @@ static inline const std::array CLIOptions = {{ {"coloring-array", "", "Name of the array to color with", "", "" }, {"comp", "y", "Component from the array to color with. -1 means magnitude, -2 or the short option, -y, means direct scalars", "", "-2"}, {"cells", "c", "Use an array from the cells", "", "1"}, - {"range", "", "Custom range for the coloring by array", "", ""}, + {"range", "", "Custom range for the coloring by array, automatically computed by default", "", ""}, {"bar", "b", "Show scalar bar", "", "1" }, {"colormap-file", "", "Specify a colormap image", "", ""}, {"colormap", "", "Specify a custom colormap (ignored if \"colormap-file\" is specified)", "", ""}, diff --git a/library/src/animationManager.cxx b/library/src/animationManager.cxx index 50551da70a..e29c029626 100644 --- a/library/src/animationManager.cxx +++ b/library/src/animationManager.cxx @@ -182,7 +182,7 @@ void animationManager::ToggleAnimation() this->Interactor->createTimerCallBack(1000.0 / frameRate, [this]() { this->Tick(); }); } - if (this->Playing && this->Options->scene.camera.index >= 0) + if (this->Playing && this->Options->scene.camera.index.has_value()) { this->Interactor->disableCameraMovement(); } From 64c0d19576dad8135b06c3fb33921bd243b61a38 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sat, 14 Sep 2024 22:31:37 +0200 Subject: [PATCH 12/28] finishing up --- application/F3DOptionsTools.cxx | 1 - application/testing/CMakeLists.txt | 5 ++++- library/src/loader_impl.cxx | 3 +-- .../baselines/TestTimeRangeLessThanZeroNoAnimationTime.png | 3 +++ ...ro.png => TestTimeRangeLessThanZeroWithAnimationTime.png} | 0 5 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 testing/baselines/TestTimeRangeLessThanZeroNoAnimationTime.png rename testing/baselines/{TestTimeRangeLessThanZero.png => TestTimeRangeLessThanZeroWithAnimationTime.png} (100%) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 1f95162e4b..cb9f613f3a 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -53,7 +53,6 @@ struct CLIGroup /** * Declaration of all F3D CLI options except `--input` using above structs * Order of groups matters in the context of `--help` - * TODO update help text for optional values */ // clang-format off #if F3D_MODULE_RAYTRACING diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index a9402d7595..7c3786197b 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -612,8 +612,11 @@ if(F3D_PLUGIN_BUILD_EXODUS) f3d_test(NAME TestAnimationTimeLimitsHigh DATA small.ex2 ARGS ARGS --load-plugins=exodus --animation-time=10) f3d_test(NAME TestAnimationTimeLimitsLow DATA small.ex2 ARGS ARGS --load-plugins=exodus --animation-time=-5) + # Test if negative range is respected when loading a file without specifying the animation time + f3d_test(NAME TestTimeRangeLessThanZeroNoAnimationTime DATA negative_range_animated.e ARGS -s --load-plugins=exodus) + # Test if the animation-time works when set to zero and time range[0] is less than zero - f3d_test(NAME TestTimeRangeLessThanZero DATA negative_range_animated.e ARGS -s --load-plugins=exodus --animation-time=0) + f3d_test(NAME TestTimeRangeLessThanZeroWithAnimationTime DATA negative_range_animated.e ARGS -s --load-plugins=exodus --animation-time=0) # Test if a negative animation-time works when time range[0] is less than zero f3d_test(NAME TestTimeRangeLessThanZeroNegativeAnimationTime DATA negative_range_animated.e ARGS -s --load-plugins=exodus --animation-time=-3) diff --git a/library/src/loader_impl.cxx b/library/src/loader_impl.cxx index 1c0291b940..e309487e80 100644 --- a/library/src/loader_impl.cxx +++ b/library/src/loader_impl.cxx @@ -290,8 +290,7 @@ loader& loader_impl::loadScene(const std::string& filePath) if (this->Internals->Options.scene.camera.index.has_value()) { - int cameraIndex = this->Internals->Options.scene.camera.index.value(); - this->Internals->CurrentFullSceneImporter->SetCamera(cameraIndex); + this->Internals->CurrentFullSceneImporter->SetCamera(this->Internals->Options.scene.camera.index.value()); } log::debug("Loading 3D scene: ", filePath, "\n"); diff --git a/testing/baselines/TestTimeRangeLessThanZeroNoAnimationTime.png b/testing/baselines/TestTimeRangeLessThanZeroNoAnimationTime.png new file mode 100644 index 0000000000..1a732a4ed0 --- /dev/null +++ b/testing/baselines/TestTimeRangeLessThanZeroNoAnimationTime.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:489026df6ecd9a91ff01801bed7be4d92f0756a45bbe5df0e1ccc62d1b5994df +size 1117 diff --git a/testing/baselines/TestTimeRangeLessThanZero.png b/testing/baselines/TestTimeRangeLessThanZeroWithAnimationTime.png similarity index 100% rename from testing/baselines/TestTimeRangeLessThanZero.png rename to testing/baselines/TestTimeRangeLessThanZeroWithAnimationTime.png From 7f3f34021954990d60078b61403ba19ebe1e6eeb Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 07:57:22 +0200 Subject: [PATCH 13/28] clf --- library/src/loader_impl.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/src/loader_impl.cxx b/library/src/loader_impl.cxx index e309487e80..f2ecbaa91a 100644 --- a/library/src/loader_impl.cxx +++ b/library/src/loader_impl.cxx @@ -290,7 +290,8 @@ loader& loader_impl::loadScene(const std::string& filePath) if (this->Internals->Options.scene.camera.index.has_value()) { - this->Internals->CurrentFullSceneImporter->SetCamera(this->Internals->Options.scene.camera.index.value()); + this->Internals->CurrentFullSceneImporter->SetCamera( + this->Internals->Options.scene.camera.index.value()); } log::debug("Loading 3D scene: ", filePath, "\n"); From a8ec4a8fe9483ee2db52b1b53585f75582fd8a58 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 08:52:26 +0200 Subject: [PATCH 14/28] add isSet --- application/F3DOptionsTools.cxx | 11 +++-------- application/F3DStarter.cxx | 5 ++++- library/public/options.h.in | 15 +++++++++++++-- library/src/options.cxx | 34 +++++++++++++++++++++++++++++++++ python/F3DPythonBindings.cxx | 6 +++--- python/testing/test_options.py | 16 ++++++++-------- 6 files changed, 65 insertions(+), 22 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index cb9f613f3a..ed334b8ce4 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -451,14 +451,9 @@ F3DOptionsTools::OptionsDict F3DOptionsTools::ParseCLIOptions( if (libIter != F3DOptionsTools::LibOptionsNames.end()) { f3d::options opt; - try - { - defaultValue = opt.getAsString(std::string(libIter->second)); - } - catch (const f3d::options::unset_exception&) - { - // let defaultValue empty for unset options - } + std::string name = std::string(libIter->second); + // let default value empty for unset options + defaultValue = opt.isSet(name) ? opt.getAsString(name) : ""; } } diff --git a/application/F3DStarter.cxx b/application/F3DStarter.cxx index 52f87aa960..524f7522b0 100644 --- a/application/F3DStarter.cxx +++ b/application/F3DStarter.cxx @@ -957,11 +957,14 @@ void F3DStarter::LoadFile(int index, bool relativeIndex) // Detect interactively changed options and store them into the dynamic options dict // options names are shared between options instance F3DOptionsTools::OptionsDict dynamicOptionsDict; - std::vector optionNames = this->Internals->LibOptions.getNames(); + std::vector optionNames = dynamicOptions.getSetNames(); for (const auto& name : optionNames) { if (!dynamicOptions.isSame(this->Internals->LibOptions, name)) { + // XXX Currently an assert is enough but it should be a proper try/catch once + // we add a mechanism to unset an option + assert(dynamicOptions.isSet(name)); dynamicOptionsDict[name] = dynamicOptions.getAsString(name); } } diff --git a/library/public/options.h.in b/library/public/options.h.in index 27c3353423..419422e006 100644 --- a/library/public/options.h.in +++ b/library/public/options.h.in @@ -81,11 +81,18 @@ public: /** * Compare an option between this and a provided other. - * Return true is they are the same value, false otherwise. + * Return true if they are the same value, false otherwise. * Throw an options::inexistent_exception if option does not exist. */ bool isSame(const options& other, const std::string& name) const; + /** + * Return true if an option is set, false otherwise + * Always returns true for non-optional options. + * Throw an options::inexistent_exception if option does not exist. + */ + bool isSet(const std::string& name) const; + /** * Copy the value of an option from this to the provided other. * Throw an options::inexistent_exception if option does not exist. @@ -94,10 +101,14 @@ public: /** * Get all available option names. - * XXX: Should we add a getNamesStruct with the same structure as the struct below ? */ std::vector getNames() const; + /** + * Get all option names that are currently set. + */ + std::vector getSetNames() const; + /** * Get the closest option name and its Levenshtein distance. */ diff --git a/library/src/options.cxx b/library/src/options.cxx index 58090f4aac..9fe8fbdec2 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -92,6 +92,21 @@ bool options::isSame(const options& other, const std::string& name) const return ownUnset == otherUnset && ownVal == otherVal; } +//---------------------------------------------------------------------------- +bool options::isSet(const std::string& name) const +{ + bool ret = true; + try + { + options_tools::get(*this, name); + } + catch (const f3d::options::unset_exception&) + { + ret = false; + } + return ret; +} + //---------------------------------------------------------------------------- options& options::copy(const options& from, const std::string& name) { @@ -105,6 +120,25 @@ std::vector options::getNames() const return options_tools::getNames(); } +//---------------------------------------------------------------------------- +std::vector options::getSetNames() const +{ + std::vector names = this->getNames(); + std::vector setNames; + for (const std::string& name : names) + { + try + { + options_tools::get(*this, name); + setNames.emplace_back(name); + } + catch (const f3d::options::unset_exception&) + { + } + } + return setNames; +} + //---------------------------------------------------------------------------- std::pair options::getClosestOption(const std::string& option) const { diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx index 6b80048c24..bb979f0ed8 100644 --- a/python/F3DPythonBindings.cxx +++ b/python/F3DPythonBindings.cxx @@ -184,16 +184,16 @@ PYBIND11_MODULE(pyf3d, module) throw py::key_error(key); } }) - .def("__len__", [](f3d::options& opts) { return opts.getNames().size(); }) + .def("__len__", [](f3d::options& opts) { return opts.getSetNames().size(); }) .def( "__iter__", [](f3d::options& opts) { - const auto names = py::cast(opts.getNames()); // won't work without cast + const auto names = py::cast(opts.getSetNames()); // won't work without cast return make_iterator(names); }, py::keep_alive<0, 1>()) - .def("keys", &f3d::options::getNames) // to do `dict(options)` + .def("keys", &f3d::options::getSetNames) // to do `dict(options)` .def("toggle", &f3d::options::toggle) .def("is_same", &f3d::options::isSame) .def("get_closest_option", &f3d::options::getClosestOption) diff --git a/python/testing/test_options.py b/python/testing/test_options.py index 9e36c837c9..ea381848af 100644 --- a/python/testing/test_options.py +++ b/python/testing/test_options.py @@ -84,14 +84,14 @@ def test_set_options(): assert engine.options["scene.up_direction"] == "-Z" -#def test_to_dict(): TODO does this matter ? -# options = f3d.Options() -# options_dict = dict(options) -# -# assert len(options) > 0 -# assert len(options) == len(options_dict) -# for k, v in options_dict.items(): -# assert options[k] == v +def test_to_dict(): + options = f3d.Options() + options_dict = dict(options) + + assert len(options) > 0 + assert len(options) == len(options_dict) + for k, v in options_dict.items(): + assert options[k] == v def test_update_from_dict(): From 0d777091e9b5f65bba32fb4e5d32417e1d741667 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 09:11:55 +0200 Subject: [PATCH 15/28] tests --- library/testing/TestSDKOptions.cxx | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index cdb8182fa5..26be05a340 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -138,8 +138,15 @@ int TestSDKOptions(int argc, char* argv[]) std::vector names = opt.getNames(); test("getNames count", names.size() != 0 && names == opt2.getNames()); - // Test isSame/copy + std::vector setNames = opt.getSetNames(); + test("getSetNames count", setNames.size() != 0 && setNames == opt2.getSetNames()); + + // Test isSame/copy/isSet test("isSame", opt.isSame(opt2, "render.line_width")); + test("isSame unset", opt.isSame(opt2, "scene.animation.time")); + + test("isSet", opt.isSet("render.line_width")); + test("isSet", !opt.isSet("scene.animation.time")); opt2.render.line_width = 3.12; test("not isSame", !opt.isSame(opt2, "render.line_width")); @@ -173,5 +180,18 @@ int TestSDKOptions(int argc, char* argv[]) test.expect( "inexistent_exception exception on get", [&]() { opt.get("dummy"); }); + test.expect( + "unset_exception exception on get", [&]() { opt.get("scene.animation.time"); }); + + // Test setAsString/getAsString error paths + test.expect( + "inexistent_exception exception on setAsString", [&]() { opt.setAsString("dummy", "2.13"); }); + + test.expect( + "inexistent_exception exception on getAsString", [&]() { opt.getAsString("dummy"); }); + + test.expect( + "unset_exception exception on getAsString", [&]() { opt.getAsString("scene.animation.time"); }); + return EXIT_SUCCESS; } From 3609e135227d16ec8f6ee40c0b57cdb5e8bccbc0 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 09:18:39 +0200 Subject: [PATCH 16/28] add coverage testing --- application/testing/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index 7c3786197b..5d82675494 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -867,6 +867,12 @@ f3d_test(NAME TestVerboseVolumeNoArray DATA cow.vtp ARGS -v REGEXP "Cannot use v # Test scalar rendering without any array f3d_test(NAME TestVerboseNoArray DATA cow.vtp ARGS -s --verbose=debug REGEXP "No array to color with" NO_BASELINE) +# Test invalid scalar range +f3d_test(NAME TestInvalidScalarsRange DATA suzanne.ply ARGS -s --coloring-array=Normals --comp=1 --range=0,1,2 REGEXP "Invalid scalar range provided, using automatic range" NO_BASELINE) + +# Test invalid backface type +f3d_test(NAME TestInvalidBackface DATA backface.vtp ARGS --backface-type=invalid REGEXP "is not a valid backface type, assuming it is not set" NO_BASELINE) + # Test non existent file, do not create nonExistentFile.vtp f3d_test(NAME TestVerboseNonExistentFile DATA nonExistentFile.vtp REGEXP "File .*nonExistentFile.vtp does not exist" NO_RENDER) From 11e7e96954584cf0f295b55d51552f5540150ebe Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 10:02:43 +0200 Subject: [PATCH 17/28] doc --- README.md | 2 +- doc/libf3d/OPTIONS.md | 65 ++++++++++++++++++++++++++++++++++-------- doc/libf3d/OVERVIEW.md | 2 +- doc/user/OPTIONS.md | 12 ++++---- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 11994f2efc..c3ea227fb1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ F3D (pronounced `/fɛd/`) is a fast and minimalist 3D viewer desktop application It is fully controllable from the command line and support configuration files. It can provide thumbnails, support interactive hotkeys, drag&drop and integration into file managers. -F3D also contains the libf3d, a simple library to render meshes, with C++ and Python Bindings, as well as experimental Java and Javascript bindings. +F3D also contains the libf3d, a simple library to render meshes, with a C++17 API, Python Bindings, and experimental Java and Javascript bindings. diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index cff0a71710..28db8e04fb 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -15,6 +15,9 @@ The possible option are listed below and are organized by categories and subcate Please note certain options are taken into account when rendering, others when loading a file. See the exhaustive list below, but note that this may change in the future. +Please note certain options are `optional` by default, which means they are not set initially, +See the [APIs](#APIs) details below for more info. + ## Scene Options Option|Type
Default
Trigger|Description|F3D option @@ -22,8 +25,9 @@ Option|Type
Default
Trigger|Description|F3D option scene.animation.autoplay|bool
false
load|Automatically start animation.|\-\-animation-autoplay scene.animation.index|int
0
load|Select the animation to load.
Any negative value means all animations (glTF only).
The default scene always has at most one animation.|\-\-animation-index scene.animation.speed_factor|double
1
render|Set the animation speed factor to slow, speed up or even invert animation.|\-\-animation-speed-factor +scene.animation.time|double
optional
load|Set the animation time to load.|\-\-animation-time scene.animation.frame_rate|double
60
render|Set the animation frame rate used to play the animation interactively.|\-\-animation-frame-rate -scene.camera.index|int
-1
load|Select the scene camera to use when available in the file.
Any negative value means automatic camera.
The default scene always uses automatic camera.|\-\-camera-index +scene.camera.index|int
optional
load|Select the scene camera to use when available in the file.
Any negative value means automatic camera.
The default scene always uses automatic camera.|\-\-camera-index scene.up_direction|string
+Y
load|Define the Up direction|\-\-up scene.camera.orthographic|bool
false
load|Toggles between orthographic projection and parallel mode.|\-\-camera\-orthographic @@ -49,12 +53,12 @@ model.material.roughness|double
0.3
render|Set the *roughness coefficient* model.material.texture|string
-
render|Path to a texture file that sets the Occlusion, Roughness and Metallic values of the object. Multiplied with the `model.material.roughness` and `model.material.metallic`, set both of them to 1.0 to get a true result.|\-\-texture-material model.normal.scale|double
1.0
render|Normal scale affects the strength of the normal deviation from the normal texture.|\-\-normal-scale model.normal.texture|string
-
render|Path to a texture file that sets the normal map of the object.|\-\-texture-normal -model.scivis.enable|bool
false
render|*Color by an array* present in on the data. If `model.scivis.array_name` is set to , the first available array will be used.|\-\-scalar-coloring +model.scivis.enable|bool
false
render|*Color by an array* present in on the data. If `model.scivis.array_name` is not set, the first available array will be used.|\-\-scalar-coloring model.scivis.cells|bool
false
render|Color the data with value found *on the cells* instead of points|\-\-cells model.scivis.colormap|vector\
\
render|Set a *custom colormap for the coloring*.
This is a list of colors in the format `val1,red1,green1,blue1,...,valN,redN,greenN,blueN`
where all values are in the range (0,1).|\-\-colormap model.scivis.component|int
-1
render|Specify the component to color with. -1 means *magnitude*. -2 means *direct values*.|\-\-comp -model.scivis.array_name|string
-
render|Select the name of the array to color with.|\-\-coloring-array -model.scivis.range|vector\
-
render|Set a *custom range for the coloring*.|\-\-range +model.scivis.array_name|string

render|Select the name of the array to color with.|\-\-coloring-array +model.scivis.range|vector\
optional
render|Set the *coloring range*. Automatically computed by default.|\-\-range model.point_sprites.enable|bool
false
render|Show sphere *points sprites* instead of the geometry.|\-\-point-sprites model.point_sprites.type|string
sphere
render|Set the sprites type when showing point sprites (can be `sphere` or `gaussian`).|\-\-point-stripes-type model.point_sprites.size|double
10.0
render|Set the *size* of point sprites.|\-\-point-stripes-size @@ -69,19 +73,20 @@ render.effect.translucency_support|bool
false
render|Enable *translucency render.effect.anti_aliasing|bool
false
render|Enable *anti-aliasing*. This technique is used to reduce aliasing, implemented using FXAA.|\-\-anti-aliasing render.effect.ambient_occlusion|bool
false
render|Enable *ambient occlusion*. This is a technique providing approximate shadows, used to improve the depth perception of the object. Implemented using SSAO|\-\-ambient_occlusion render.effect.tone_mapping|bool
false
render|Enable generic filmic *Tone Mapping Pass*. This technique is used to map colors properly to the monitor colors.|\-\-tone-mapping -render.effect.final_shader|string
""
render|Add a final shader to the output image|\-\-final-shader. See [user documentation](../user/FINAL_SHADER.md). -render.line_width|double
1.0
render|Set the *width* of lines when showing edges.|\-\-line-width +render.effect.final_shader|string
optional
render|Add a final shader to the output image|\-\-final-shader. See [user documentation](../user/FINAL_SHADER.md). +render.line_width|double
optional
render|Set the *width* of lines when showing edges. Model specifed by default.|\-\-line-width render.show_edges|bool
false
render|Show the *cell edges*|\-\-edges -render.point_size|double
10.0
render|Set the *size* of points when showing vertices.|\-\-point-size +render.point_size|double
optional
render|Set the *size* of points when showing vertices. Model specified by default.|\-\-point-size +render.backface_type|string
optional
render|Set the Backface type, can be `visible` or `hidden`, model specified by default.|\-\-backface-type render.grid.enable|bool
false
render|Show *a grid* aligned with the horizontal (orthogonal to the Up direction) plane.|\-\-grid render.grid.absolute|bool
false
render|Position the grid at the *absolute origin* of the model's coordinate system instead of below the model.|\-\-grid -render.grid.unit|double
0
render|Set the size of the *unit square* for the grid. If set to non-positive (the default) a suitable value will be automatically computed.|\-\-grid\-unit -render.grid.subdivisions|int
10
render|Set the number of subdivisions for the grid.|\-\-grid\-subdivisions -render.grid.color|int
(0, 0, 0)
render|Set the color of grid lines.|\-\-grid\-color +render.grid.unit|double
optional
render|Set the size of the *unit square* for the grid. Automatically computed by default.|\-\-grid-unit +render.grid.subdivisions|int
10
render|Set the number of subdivisions for the grid.|\-\-grid-subdivisions +render.grid.color|int
(0, 0, 0)
render|Set the color of grid lines.|\-\-grid-color render.raytracing.enable|bool
false
render|Enable *raytracing*. Requires the raytracing module to be enabled.|\-\-raytracing render.raytracing.samples|int
5
render|The number of *samples per pixel*.|\-\-samples render.raytracing.denoise|bool
false
render|*Denoise* the raytracing rendering.|\-\-denoise -render.hdri.file|string
-
render|Set the *HDRI* image that can be used for ambient lighting and skybox.
Valid file format are hdr, exr, png, jpg, pnm, tiff, bmp.
If not set, a default is provided.|\-\-hdri-file +render.hdri.file|string
optional
render|Set the *HDRI* image that can be used for ambient lighting and skybox.
Valid file format are hdr, exr, png, jpg, pnm, tiff, bmp.
If not set, a default is provided.|\-\-hdri-file render.hdri.ambient|bool
false
render|Light the scene using the *HDRI* image as ambient lighting
The environment act as a light source and is reflected on the material.|\-\-hdri-ambient render.background.color|vector\
0.2,0.2,0.2
render|Set the window *background color*.
Ignored if a *hdri* skybox is used.|\-\-bg-color render.background.skybox|bool
false
render|Show the *HDRI* image as a skybox
Overrides the the background color if any|\-\-hdri-skybox @@ -97,7 +102,7 @@ ui.scalar_bar|bool
false
render|Show *scalar bar* of the coloring by data ui.cheatsheet|bool
false
render|Show a interactor cheatsheet ui.filename|bool
false
render|Display the *filename info content* on top of the window.|\-\-filename ui.filename_info|string
-
render|Content of *filename info* to display. -ui.font_file|string
-
render|Use the provided FreeType compatible font file to display text.
Can be useful to display non-ASCII filenames.|\-\-font-file +ui.font_file|string
optional
render|Use the provided FreeType compatible font file to display text.
Can be useful to display non-ASCII filenames.|\-\-font-file ui.fps|bool
false
render|Display a *frame per second counter*.|\-\-fps ui.loader_progress|bool
false
load|Show a *progress bar* when loading the file.|\-\-progress ui.animation_progress|bool
false
load|Show a *progress bar* when playing the animation.|\-\-animation-progress @@ -122,6 +127,20 @@ The most straightforward and easy to use API, just access it through the structs opt.model.material.roughness = 0.6; ``` +Please note that when accessing optional options, special care must be used, eg: + +```cpp + f3d::engine eng(f3d::window::Type::NATIVE); + f3d::options& opt = eng.getOptions(); + if (opt.render.line_width.has_value()) + { + std::cout << "Line Width: " << opt.render.line_width.value() << std::endl; + } + else + { + std::cout << "Line Width: unset" << std::endl; + } +``` ## String API The most generic and flexible API, as it rely on parsing and string generation. @@ -136,6 +155,26 @@ The documentation about option parsing is upcoming. opt.setAsString("model.material.roughness", "0.6"); ``` +When using this API make sure to catch exceptions has needed, eg: + +```cpp + f3d::engine eng(f3d::window::Type::NATIVE); + f3d::options& opt = eng.getOptions(); + + try + { + std::cout << userProvidedName << ": " << opt.getAsString(userProvidedName) << std::endl; + } + catch (const f3d::options::inexistent_exception&) + { + std::cout << userProvidedName << " does not exist." << std::endl; + } + catch (const f3d::options::unset_exception&) + { + std::cout << userProvidedName << " is not set." << std::endl; + } +``` + ## Variant API An API that is similar to the F3D 2.0 options API thanks to std::variant. @@ -148,3 +187,5 @@ An API that is similar to the F3D 2.0 options API thanks to std::variant. opt.set("ui.metadata", true); opt.set("model.material.roughness", 0.6); ``` + +When using this API make sure to catch exception shown above with the string API. diff --git a/doc/libf3d/OVERVIEW.md b/doc/libf3d/OVERVIEW.md index ed0fad0a9e..ab17feb562 100644 --- a/doc/libf3d/OVERVIEW.md +++ b/doc/libf3d/OVERVIEW.md @@ -2,7 +2,7 @@ By Michael Migliore and Mathieu Westphal. -libf3d is a BSD-licensed C++ library to open and render 3D meshes. It is of course used by F3D. +libf3d is a BSD-licensed C++17 library to open and render 3D meshes. It is of course used by F3D. libf3d API is simple and easy to learn. Python bindings are provided through pybind11. Java bindings are also available. libf3d API is still in alpha version and may change drastically in the future. diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index b66e8c7e3e..6df488c502 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -39,11 +39,12 @@ Options|Default|Description \-\-grid\-subdivisions=\||Set the number of subdivisions for the grid. \-\-grid\-color=\|(0,0,0)|Set the color grid lines. -e, \-\-edges||Show the *cell edges*. -\-\-camera-index=\|-1|Select the scene camera to use when available in the file.
Any negative value means automatic camera.
The default scene always uses automatic camera. +\-\-camera-index=\||Select the scene camera to use when available in the file. Automatically computed by default. -k, \-\-trackball||Enable trackball interaction. \-\-animation-autoplay||Automatically start animation. \-\-animation-index=\|0|Select the animation to show.
Any negative value means all animations (glTF only).
The default scene always has at most one animation. \-\-animation-speed-factor=\|1|Set the animation speed factor to slow, speed up or even invert animation time. +\-\-animation-time=\||Set the animation time to load. \-\-animation-frame-rate=\|60|Set the animation frame rate used when playing animation interactively. \-\-font-file=\||Use the provided FreeType compatible font file to display text.
Can be useful to display non-ASCII filenames. @@ -54,8 +55,9 @@ Options|Default|Description -o, \-\-point-sprites||Show sphere *points sprites* instead of the geometry. \-\-point-sprites-type=\|sphere|Set the splat type when showing point sprites. \-\-point-sprites-size=\|10.0|Set the *size* of point sprites. -\-\-point-size=\|10.0|Set the *size* of points when showing vertices. -\-\-line-width=\|1.0|Set the *width* of lines when showing edges. +\-\-point-size=\||Set the *size* of points when showing vertices. Model specified by default. +\-\-line-width=\||Set the *width* of lines when showing edges. Model specified by default. +\-\-backface-type=\||Set the Backface type. Model specified by default. \-\-color=\|1.0, 1.0, 1.0| Set a *color* on the geometry. Multiplied with the base color texture when present.
Requires a default scene. \-\-opacity=\|1.0|Set *opacity* on the geometry. Multiplied with the base color texture when present.
Requires a default scene. Usually used with Depth Peeling option. \-\-roughness=\|0.3|Set the *roughness coefficient* on the geometry (0.0-1.0). Multiplied with the material texture when present.
Requires a default scene. @@ -87,11 +89,11 @@ Options|Default|Description Options|Default|Description ------|------|------ --s, \-\-scalar-coloring||Enable scalar coloring if present in the file. If no `--coloring-array` is provided, the first in alphabetical order will be picked if any are available.
Requires a default scene. +-s, \-\-scalar-coloring||Enable scalar coloring if present in the file. If `--coloring-array` is not set, the first in alphabetical order will be picked if any are available.
Requires a default scene. \-\-coloring-array=\||The coloring array name to use when coloring.
Use \-\-verbose to recover the usable array names. -y, \-\-comp=\|-1|Specify the *component from the scalar* array to color with.
Use with the scalar option. -1 means *magnitude*. -2 or the short option, -y, means *direct values*.
When using *direct values*, components are used as L, LA, RGB, RGBA values depending on the number of components. -c, \-\-cells||Specify that the scalar array is to be found *on the cells* instead of on the points.
Use with the scalar option. -\-\-range=\||Set a *custom range for the coloring* by the array.
Use with the scalar option. +\-\-range=\||Set the *coloring range*. Automatically computed by default.
Use with the scalar option. -b, \-\-bar||Show *scalar bar* of the coloring by array.
Use with the scalar option. \-\-colormap\-file=\||Set a *colormap file for the coloring*.
See [color maps](COLOR_MAPS.md).
Use with the scalar option. \-\-colormap=\||Set a *custom colormap for the coloring*.
This is a list of colors in the format `val1,red1,green1,blue1,...,valN,redN,greenN,blueN`
where all values are in the range (0,1).
Ignored if `--colormap-file` option is specified.
Use with the scalar option. From 814466f1e003450ab2ddf9c68e96ce6ce4286c40 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 10:12:35 +0200 Subject: [PATCH 18/28] typo --- doc/libf3d/OPTIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index 28db8e04fb..f151ff6944 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -74,7 +74,7 @@ render.effect.anti_aliasing|bool
false
render|Enable *anti-aliasing*. This render.effect.ambient_occlusion|bool
false
render|Enable *ambient occlusion*. This is a technique providing approximate shadows, used to improve the depth perception of the object. Implemented using SSAO|\-\-ambient_occlusion render.effect.tone_mapping|bool
false
render|Enable generic filmic *Tone Mapping Pass*. This technique is used to map colors properly to the monitor colors.|\-\-tone-mapping render.effect.final_shader|string
optional
render|Add a final shader to the output image|\-\-final-shader. See [user documentation](../user/FINAL_SHADER.md). -render.line_width|double
optional
render|Set the *width* of lines when showing edges. Model specifed by default.|\-\-line-width +render.line_width|double
optional
render|Set the *width* of lines when showing edges. Model specified by default.|\-\-line-width render.show_edges|bool
false
render|Show the *cell edges*|\-\-edges render.point_size|double
optional
render|Set the *size* of points when showing vertices. Model specified by default.|\-\-point-size render.backface_type|string
optional
render|Set the Backface type, can be `visible` or `hidden`, model specified by default.|\-\-backface-type From f0b6ff667947b05451204722c03e73143ab8f93a Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 15:40:02 +0200 Subject: [PATCH 19/28] fixup cxx standard --- CMakeLists.txt | 4 ---- application/CMakeLists.txt | 1 + java/CMakeLists.txt | 1 + library/CMakeLists.txt | 1 + library/testing/CMakeLists.txt | 3 +++ plugins/alembic/CMakeLists.txt | 3 --- plugins/assimp/CMakeLists.txt | 3 --- plugins/draco/CMakeLists.txt | 3 --- plugins/exodus/CMakeLists.txt | 3 --- plugins/occt/CMakeLists.txt | 3 --- plugins/vdb/CMakeLists.txt | 3 --- python/CMakeLists.txt | 3 --- vtkext/private/CMakeLists.txt | 1 + vtkext/public/CMakeLists.txt | 1 + winshellext/CMakeLists.txt | 1 + 15 files changed, 9 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23dd41aa88..9544a84d9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,6 @@ project(F3D DESCRIPTION "F3D - A fast and minimalist 3D viewer" LANGUAGES C CXX) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - set(f3d_cmake_dir "${F3D_SOURCE_DIR}/cmake") list(INSERT CMAKE_MODULE_PATH 0 "${f3d_cmake_dir}") include(f3dVersion) diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index 395335b910..be09595465 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -47,6 +47,7 @@ endif() set_target_properties(f3d PROPERTIES CXX_VISIBILITY_PRESET hidden + CXX_STANDARD 17 ) if (APPLE) diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index da9957e96e..db4d47805d 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -35,6 +35,7 @@ endif() set_target_properties(javaf3d PROPERTIES CXX_VISIBILITY_PRESET hidden + CXX_STANDARD 17 OUTPUT_NAME "f3d-java" ) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 1904b62a46..ff1dd1a93a 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -112,6 +112,7 @@ endif() set_target_properties(libf3d PROPERTIES CXX_VISIBILITY_PRESET hidden + CXX_STANDARD 17 POSITION_INDEPENDENT_CODE ON OUTPUT_NAME "f3d" PDB_NAME "libf3d" diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 8bc3949090..fc39047335 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -129,3 +129,6 @@ if(Qt5_FOUND) # external window test using QT target_link_libraries(libf3dSDKTests Qt5::OpenGL) endif() + +# make sure the libf3d API is compatible with the right C++ standard +set_target_properties(libf3dSDKTests PROPERTIES CXX_STANDARD 17) diff --git a/plugins/alembic/CMakeLists.txt b/plugins/alembic/CMakeLists.txt index 1ef569c281..1f9ae49ef6 100644 --- a/plugins/alembic/CMakeLists.txt +++ b/plugins/alembic/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/assimp/CMakeLists.txt b/plugins/assimp/CMakeLists.txt index 4d2c480daa..57e2585645 100644 --- a/plugins/assimp/CMakeLists.txt +++ b/plugins/assimp/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/draco/CMakeLists.txt b/plugins/draco/CMakeLists.txt index 53157cd1c7..e824391367 100644 --- a/plugins/draco/CMakeLists.txt +++ b/plugins/draco/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/exodus/CMakeLists.txt b/plugins/exodus/CMakeLists.txt index a09a575289..35d0ccddc8 100644 --- a/plugins/exodus/CMakeLists.txt +++ b/plugins/exodus/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/occt/CMakeLists.txt b/plugins/occt/CMakeLists.txt index 25153fbed2..10354d33b5 100644 --- a/plugins/occt/CMakeLists.txt +++ b/plugins/occt/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/plugins/vdb/CMakeLists.txt b/plugins/vdb/CMakeLists.txt index 638dc9cdf6..6e3fc18d2c 100644 --- a/plugins/vdb/CMakeLists.txt +++ b/plugins/vdb/CMakeLists.txt @@ -6,9 +6,6 @@ include(GNUInstallDirs) # Check if the plugin is built externally if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS pluginsdk) else() include(f3dPlugin) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 66ab162d73..96e31a07c7 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -13,9 +13,6 @@ pybind11_add_module(pyf3d MODULE F3DPythonBindings.cxx) # In case pyf3d is built separately, we need to retrieve the existing libf3d if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) find_package(f3d REQUIRED COMPONENTS library) set(F3D_VERSION "${f3d_VERSION}") target_link_libraries(pyf3d PRIVATE f3d::libf3d) diff --git a/vtkext/private/CMakeLists.txt b/vtkext/private/CMakeLists.txt index a6e67e0ecb..bc0f5981f5 100644 --- a/vtkext/private/CMakeLists.txt +++ b/vtkext/private/CMakeLists.txt @@ -23,6 +23,7 @@ foreach (module IN LISTS modules) if (NOT "${f3d_link_options_public}" STREQUAL "") vtk_module_link_options(${module} PUBLIC ${f3d_link_options_public}) endif() + vtk_module_set_properties(${module} CXX_STANDARD 17) if(F3D_STRICT_BUILD AND MSVC) # There are warnings in VTK related to deprecated features in C++17 vtk_module_definitions(${module} PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) diff --git a/vtkext/public/CMakeLists.txt b/vtkext/public/CMakeLists.txt index 95a138c72a..0e488e1fb3 100644 --- a/vtkext/public/CMakeLists.txt +++ b/vtkext/public/CMakeLists.txt @@ -53,6 +53,7 @@ foreach (module IN LISTS modules) if (NOT "${f3d_link_options_public}" STREQUAL "") vtk_module_link_options(${module} PUBLIC ${f3d_link_options_public}) endif() + vtk_module_set_properties(${module} CXX_STANDARD 17) if(F3D_STRICT_BUILD AND MSVC) # There are warnings in VTK related to deprecated features in C++17 vtk_module_definitions(${module} PRIVATE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS) diff --git a/winshellext/CMakeLists.txt b/winshellext/CMakeLists.txt index e1d30ac09d..72c57f1601 100644 --- a/winshellext/CMakeLists.txt +++ b/winshellext/CMakeLists.txt @@ -17,6 +17,7 @@ else () endif () target_link_libraries(F3DShellExtension PUBLIC libf3d PRIVATE pathcch shlwapi windowscodecs) +set_target_properties(F3DShellExtension PROPERTIES CXX_STANDARD 17) # Installing install(TARGETS F3DShellExtension From b0f5e6ba1f3807358f82254a837ffb140c972d64 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 15:44:11 +0200 Subject: [PATCH 20/28] reviews --- library/src/options.cxx | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/library/src/options.cxx b/library/src/options.cxx index 9fe8fbdec2..5b4099a2a8 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -66,45 +66,28 @@ options& options::toggle(const std::string& name) //---------------------------------------------------------------------------- bool options::isSame(const options& other, const std::string& name) const { - option_variant_t ownVal; - option_variant_t otherVal; - bool ownUnset = false; - bool otherUnset = false; - - try - { - ownVal = options_tools::get(*this, name); - } - catch (const f3d::options::unset_exception&) - { - ownUnset = true; - } - try { - otherVal = options_tools::get(other, name); + return options_tools::get(*this, name) == options_tools::get(other, name); } catch (const f3d::options::unset_exception&) { - otherUnset = true; + return !this->isSet(name) && !other.isSet(name); } - - return ownUnset == otherUnset && ownVal == otherVal; } //---------------------------------------------------------------------------- bool options::isSet(const std::string& name) const { - bool ret = true; try { options_tools::get(*this, name); + return true; } catch (const f3d::options::unset_exception&) { - ret = false; + return false; } - return ret; } //---------------------------------------------------------------------------- @@ -125,17 +108,10 @@ std::vector options::getSetNames() const { std::vector names = this->getNames(); std::vector setNames; - for (const std::string& name : names) - { - try - { - options_tools::get(*this, name); - setNames.emplace_back(name); - } - catch (const f3d::options::unset_exception&) - { - } - } + std::copy_if(names.begin(), names.end(), std::back_inserter(setNames), + [&](const std::string& name){ + return this->isSet(name); + }); return setNames; } From 73351fdc7f3103f7cebdcf2575d3ee38e61e7e2d Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 15:45:17 +0200 Subject: [PATCH 21/28] clf --- library/src/options.cxx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/src/options.cxx b/library/src/options.cxx index 5b4099a2a8..1c0bd1de16 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -109,9 +109,7 @@ std::vector options::getSetNames() const std::vector names = this->getNames(); std::vector setNames; std::copy_if(names.begin(), names.end(), std::back_inserter(setNames), - [&](const std::string& name){ - return this->isSet(name); - }); + [&](const std::string& name) { return this->isSet(name); }); return setNames; } From 19c01b115c0f8fe7963d8b97fb72f657b800ab22 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 17:07:25 +0200 Subject: [PATCH 22/28] snoyer review --- application/F3DOptionsTools.cxx | 3 +-- library/public/options.h.in | 2 +- library/src/options.cxx | 4 ++-- library/testing/TestSDKOptions.cxx | 5 +++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index ed334b8ce4..9649f0171a 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -391,8 +391,7 @@ std::pair F3DOptionsTools::GetClosestOption(const std::string& // Check libf3d option names if (checkLib) { - f3d::options opt; - for (const std::string& key : opt.getNames()) + for (const std::string& key : f3d::options::getAllNames()) { checkDistance(key, option, ret); } diff --git a/library/public/options.h.in b/library/public/options.h.in index 419422e006..1112a9533d 100644 --- a/library/public/options.h.in +++ b/library/public/options.h.in @@ -102,7 +102,7 @@ public: /** * Get all available option names. */ - std::vector getNames() const; + static std::vector getAllNames(); /** * Get all option names that are currently set. diff --git a/library/src/options.cxx b/library/src/options.cxx index 1c0bd1de16..1994d7d86b 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -98,7 +98,7 @@ options& options::copy(const options& from, const std::string& name) } //---------------------------------------------------------------------------- -std::vector options::getNames() const +std::vector options::getAllNames() { return options_tools::getNames(); } @@ -106,7 +106,7 @@ std::vector options::getNames() const //---------------------------------------------------------------------------- std::vector options::getSetNames() const { - std::vector names = this->getNames(); + std::vector names = options::getAllNames(); std::vector setNames; std::copy_if(names.begin(), names.end(), std::back_inserter(setNames), [&](const std::string& name) { return this->isSet(name); }); diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index 26be05a340..ba5d3081c3 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -3,6 +3,7 @@ #include "PseudoUnitTest.h" +#include #include int TestSDKOptions(int argc, char* argv[]) @@ -135,8 +136,8 @@ int TestSDKOptions(int argc, char* argv[]) test("move operator", opt5.render.line_width == 2.13); // Test getNames - std::vector names = opt.getNames(); - test("getNames count", names.size() != 0 && names == opt2.getNames()); + std::vector names = f3d::options::getAllNames(); + test("getNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); std::vector setNames = opt.getSetNames(); test("getSetNames count", setNames.size() != 0 && setNames == opt2.getSetNames()); From ce11641f88d545e27d7e02cdb470ba123173de02 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 17:09:05 +0200 Subject: [PATCH 23/28] fixup testing --- vtkext/private/module/Testing/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/vtkext/private/module/Testing/CMakeLists.txt b/vtkext/private/module/Testing/CMakeLists.txt index 7fe4139b33..bd1b4fcbaa 100644 --- a/vtkext/private/module/Testing/CMakeLists.txt +++ b/vtkext/private/module/Testing/CMakeLists.txt @@ -25,6 +25,7 @@ vtk_add_test_cxx(vtkextPrivateTests tests ${test_sources} ${F3D_SOURCE_DIR}/testing/ ${CMAKE_BINARY_DIR}/Testing/Temporary/) vtk_test_cxx_executable(vtkextPrivateTests tests) +set_target_properties(vtkextPrivateTests PROPERTIES CXX_STANDARD 17) if(UNIX) # On windows, the default window output message does not redirect to cout From ec4d183e73a2dc51d1396ab557168a3acc5687bd Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Sun, 15 Sep 2024 19:08:07 +0200 Subject: [PATCH 24/28] clf --- library/testing/TestSDKOptions.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index ba5d3081c3..f081d4a75d 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -137,7 +137,8 @@ int TestSDKOptions(int argc, char* argv[]) // Test getNames std::vector names = f3d::options::getAllNames(); - test("getNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); + test( + "getNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); std::vector setNames = opt.getSetNames(); test("getSetNames count", setNames.size() != 0 && setNames == opt2.getSetNames()); From 3d53d8526ae4d2c5ef2568dad4eaca74ebe88d4b Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Tue, 17 Sep 2024 22:17:50 +0200 Subject: [PATCH 25/28] review --- application/F3DOptionsTools.cxx | 4 ++-- application/F3DStarter.cxx | 4 ++-- doc/user/USAGE.md | 6 ++++++ library/public/options.h.in | 10 +++++----- library/src/options.cxx | 12 ++++++------ library/src/window_impl.cxx | 12 ++++-------- library/testing/TestSDKOptions.cxx | 12 ++++++------ python/F3DPythonBindings.cxx | 6 +++--- 8 files changed, 34 insertions(+), 32 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 9649f0171a..84ebb5be30 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -391,7 +391,7 @@ std::pair F3DOptionsTools::GetClosestOption(const std::string& // Check libf3d option names if (checkLib) { - for (const std::string& key : f3d::options::getAllNames()) + for (const std::string& key : f3d::options::getNames()) { checkDistance(key, option, ret); } @@ -452,7 +452,7 @@ F3DOptionsTools::OptionsDict F3DOptionsTools::ParseCLIOptions( f3d::options opt; std::string name = std::string(libIter->second); // let default value empty for unset options - defaultValue = opt.isSet(name) ? opt.getAsString(name) : ""; + defaultValue = opt.hasValue(name) ? opt.getAsString(name) : ""; } } diff --git a/application/F3DStarter.cxx b/application/F3DStarter.cxx index 524f7522b0..aacfff2737 100644 --- a/application/F3DStarter.cxx +++ b/application/F3DStarter.cxx @@ -957,14 +957,14 @@ void F3DStarter::LoadFile(int index, bool relativeIndex) // Detect interactively changed options and store them into the dynamic options dict // options names are shared between options instance F3DOptionsTools::OptionsDict dynamicOptionsDict; - std::vector optionNames = dynamicOptions.getSetNames(); + std::vector optionNames = dynamicOptions.getValuedNames(); for (const auto& name : optionNames) { if (!dynamicOptions.isSame(this->Internals->LibOptions, name)) { // XXX Currently an assert is enough but it should be a proper try/catch once // we add a mechanism to unset an option - assert(dynamicOptions.isSet(name)); + assert(dynamicOptions.hasValue(name)); dynamicOptionsDict[name] = dynamicOptions.getAsString(name); } } diff --git a/doc/user/USAGE.md b/doc/user/USAGE.md index d12ac95d0a..65dd88a731 100644 --- a/doc/user/USAGE.md +++ b/doc/user/USAGE.md @@ -47,6 +47,12 @@ but also some scene information like *lights*, *cameras*, *actors* in the scene, By default, all this information will be loaded from the file and displayed. Use the `--geometry-only` [options](OPTIONS.md) to modify this behavior. For file formats that do not support it, **a default scene** is created. +For **default scene** formats, certain defaults values are set automatically: + - line_width: 1.0 + - point_size: 10.0 + +They will be overriden if set using [options](OPTIONS.md). + ## Animations F3D can play animations for a number of file formats (.ex2/.e/.exo/.g, .gltf/.glb, .fbx, .dae, .x, .usd) if the file contains an animation. diff --git a/library/public/options.h.in b/library/public/options.h.in index 1112a9533d..bc23e6fa43 100644 --- a/library/public/options.h.in +++ b/library/public/options.h.in @@ -87,11 +87,11 @@ public: bool isSame(const options& other, const std::string& name) const; /** - * Return true if an option is set, false otherwise + * Return true if an option has a value, false otherwise * Always returns true for non-optional options. * Throw an options::inexistent_exception if option does not exist. */ - bool isSet(const std::string& name) const; + bool hasValue(const std::string& name) const; /** * Copy the value of an option from this to the provided other. @@ -102,12 +102,12 @@ public: /** * Get all available option names. */ - static std::vector getAllNames(); + static std::vector getNames(); /** - * Get all option names that are currently set. + * Get all option names that currently have values. */ - std::vector getSetNames() const; + std::vector getValuedNames() const; /** * Get the closest option name and its Levenshtein distance. diff --git a/library/src/options.cxx b/library/src/options.cxx index 1994d7d86b..a134045907 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -72,12 +72,12 @@ bool options::isSame(const options& other, const std::string& name) const } catch (const f3d::options::unset_exception&) { - return !this->isSet(name) && !other.isSet(name); + return !this->hasValue(name) && !other.hasValue(name); } } //---------------------------------------------------------------------------- -bool options::isSet(const std::string& name) const +bool options::hasValue(const std::string& name) const { try { @@ -98,18 +98,18 @@ options& options::copy(const options& from, const std::string& name) } //---------------------------------------------------------------------------- -std::vector options::getAllNames() +std::vector options::getNames() { return options_tools::getNames(); } //---------------------------------------------------------------------------- -std::vector options::getSetNames() const +std::vector options::getValuedNames() const { - std::vector names = options::getAllNames(); + const std::vector names = options::getNames(); std::vector setNames; std::copy_if(names.begin(), names.end(), std::back_inserter(setNames), - [&](const std::string& name) { return this->isSet(name); }); + [&](const std::string& name) { return this->hasValue(name); }); return setNames; } diff --git a/library/src/window_impl.cxx b/library/src/window_impl.cxx index 2e7da41476..f70cf72c62 100644 --- a/library/src/window_impl.cxx +++ b/library/src/window_impl.cxx @@ -347,14 +347,10 @@ void window_impl::UpdateDynamicOptions() // XXX: model.point_sprites.type only has an effect on geometry scene // but we set it here for practical reasons - std::string splatTypeStr = opt.model.point_sprites.type; - int pointSpritesSize = opt.model.point_sprites.size; - vtkF3DRendererWithColoring::SplatType splatType = vtkF3DRendererWithColoring::SplatType::SPHERE; - if (splatTypeStr == "gaussian") - { - splatType = vtkF3DRendererWithColoring::SplatType::GAUSSIAN; - } - + const int pointSpritesSize = opt.model.point_sprites.size; + const vtkF3DRendererWithColoring::SplatType splatType = opt.model.point_sprites.type == "gaussian" + ? vtkF3DRendererWithColoring::SplatType::GAUSSIAN + : vtkF3DRendererWithColoring::SplatType::SPHERE; renderer->SetPointSpritesProperties(splatType, pointSpritesSize); renderer->SetLineWidth(opt.render.line_width); diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index f081d4a75d..84fe6067b9 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -136,19 +136,19 @@ int TestSDKOptions(int argc, char* argv[]) test("move operator", opt5.render.line_width == 2.13); // Test getNames - std::vector names = f3d::options::getAllNames(); + std::vector names = f3d::options::getNames(); test( "getNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); - std::vector setNames = opt.getSetNames(); - test("getSetNames count", setNames.size() != 0 && setNames == opt2.getSetNames()); + std::vector setNames = opt.getValuedNames(); + test("getValuedNames count", setNames.size() != 0 && setNames == opt2.getValuedNames()); - // Test isSame/copy/isSet + // Test isSame/copy/hasValue test("isSame", opt.isSame(opt2, "render.line_width")); test("isSame unset", opt.isSame(opt2, "scene.animation.time")); - test("isSet", opt.isSet("render.line_width")); - test("isSet", !opt.isSet("scene.animation.time")); + test("hasValue", opt.hasValue("render.line_width")); + test("hasValue", !opt.hasValue("scene.animation.time")); opt2.render.line_width = 3.12; test("not isSame", !opt.isSame(opt2, "render.line_width")); diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx index bb979f0ed8..7c8d9a6419 100644 --- a/python/F3DPythonBindings.cxx +++ b/python/F3DPythonBindings.cxx @@ -184,16 +184,16 @@ PYBIND11_MODULE(pyf3d, module) throw py::key_error(key); } }) - .def("__len__", [](f3d::options& opts) { return opts.getSetNames().size(); }) + .def("__len__", [](f3d::options& opts) { return opts.getValuedNames().size(); }) .def( "__iter__", [](f3d::options& opts) { - const auto names = py::cast(opts.getSetNames()); // won't work without cast + const auto names = py::cast(opts.getValuedNames()); // won't work without cast return make_iterator(names); }, py::keep_alive<0, 1>()) - .def("keys", &f3d::options::getSetNames) // to do `dict(options)` + .def("keys", &f3d::options::getValuedNames) // to do `dict(options)` .def("toggle", &f3d::options::toggle) .def("is_same", &f3d::options::isSame) .def("get_closest_option", &f3d::options::getClosestOption) From 4b7e3f94b67cfab3d7008531826e94034ad34392 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Tue, 17 Sep 2024 22:20:38 +0200 Subject: [PATCH 26/28] fixup style --- doc/user/USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/USAGE.md b/doc/user/USAGE.md index 65dd88a731..c34d385899 100644 --- a/doc/user/USAGE.md +++ b/doc/user/USAGE.md @@ -51,7 +51,7 @@ For **default scene** formats, certain defaults values are set automatically: - line_width: 1.0 - point_size: 10.0 -They will be overriden if set using [options](OPTIONS.md). +They will be overridden when using corresponding [options](OPTIONS.md). ## Animations From d6524b97bcea361ad3b91c9b83abdc1a8e4766eb Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Wed, 18 Sep 2024 13:09:10 +0200 Subject: [PATCH 27/28] review --- application/F3DOptionsTools.cxx | 2 +- application/F3DStarter.cxx | 2 +- doc/libf3d/OPTIONS.md | 2 +- doc/user/USAGE.md | 2 +- library/private/options_tools.h.in | 4 ++-- library/public/options.h.in | 14 +++++++------- library/src/options.cxx | 12 ++++++------ library/testing/TestSDKOptions.cxx | 16 ++++++++-------- python/F3DPythonBindings.cxx | 6 +++--- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 84ebb5be30..3330fb44c2 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -391,7 +391,7 @@ std::pair F3DOptionsTools::GetClosestOption(const std::string& // Check libf3d option names if (checkLib) { - for (const std::string& key : f3d::options::getNames()) + for (const std::string& key : f3d::options::getAllNames()) { checkDistance(key, option, ret); } diff --git a/application/F3DStarter.cxx b/application/F3DStarter.cxx index aacfff2737..0380626810 100644 --- a/application/F3DStarter.cxx +++ b/application/F3DStarter.cxx @@ -957,7 +957,7 @@ void F3DStarter::LoadFile(int index, bool relativeIndex) // Detect interactively changed options and store them into the dynamic options dict // options names are shared between options instance F3DOptionsTools::OptionsDict dynamicOptionsDict; - std::vector optionNames = dynamicOptions.getValuedNames(); + std::vector optionNames = dynamicOptions.getNames(); for (const auto& name : optionNames) { if (!dynamicOptions.isSame(this->Internals->LibOptions, name)) diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index f151ff6944..10aba01ae4 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -169,7 +169,7 @@ When using this API make sure to catch exceptions has needed, eg: { std::cout << userProvidedName << " does not exist." << std::endl; } - catch (const f3d::options::unset_exception&) + catch (const f3d::options::no_value_exception&) { std::cout << userProvidedName << " is not set." << std::endl; } diff --git a/doc/user/USAGE.md b/doc/user/USAGE.md index c34d385899..5bffe6aebf 100644 --- a/doc/user/USAGE.md +++ b/doc/user/USAGE.md @@ -47,7 +47,7 @@ but also some scene information like *lights*, *cameras*, *actors* in the scene, By default, all this information will be loaded from the file and displayed. Use the `--geometry-only` [options](OPTIONS.md) to modify this behavior. For file formats that do not support it, **a default scene** is created. -For **default scene** formats, certain defaults values are set automatically: +For **default scene** formats, certain default values are set automatically: - line_width: 1.0 - point_size: 10.0 diff --git a/library/private/options_tools.h.in b/library/private/options_tools.h.in index 0196515d6b..c82444b887 100644 --- a/library/private/options_tools.h.in +++ b/library/private/options_tools.h.in @@ -304,7 +304,7 @@ option_variant_t get(const options& opt, const std::string& name) } catch (const std::bad_optional_access&) { - throw options::unset_exception("Trying to get " + name + " before it was set"); + throw options::no_value_exception("Trying to get " + name + " before it was set"); } } @@ -345,7 +345,7 @@ std::string getAsString(const options& opt, const std::string& name) } catch (const std::bad_optional_access&) { - throw options::unset_exception("Trying to get " + name + " before it was set"); + throw options::no_value_exception("Trying to get " + name + " before it was set"); } } } // option_tools diff --git a/library/public/options.h.in b/library/public/options.h.in index bc23e6fa43..13dad70f5a 100644 --- a/library/public/options.h.in +++ b/library/public/options.h.in @@ -51,7 +51,7 @@ public: /** * Get an option as a variant based on its name * Throw an options::inexistent_exception if option does not exist. - * Throw an options::unset_exception if option has not been set. + * Throw an options::no_value_exception if option has not been set. */ option_variant_t get(const std::string& name) const; @@ -67,7 +67,7 @@ public: /** * Get an option as a string based on its name * Throw an options::inexistent_exception if option does not exist. - * Throw an options::unset_exception if option has not been set. + * Throw an options::no_value_exception if option has not been set. */ std::string getAsString(const std::string& name) const; @@ -75,7 +75,7 @@ public: * A boolean option specific method to toggle it. * Throw an options::inexistent_exception if option does not exist. * Throw an options::incompatible_exception if option is not boolean. - * Throw an options::unset_exception if option has not been set. + * Throw an options::no_value_exception if option has not been set. */ options& toggle(const std::string& name); @@ -102,12 +102,12 @@ public: /** * Get all available option names. */ - static std::vector getNames(); + static std::vector getAllNames(); /** * Get all option names that currently have values. */ - std::vector getValuedNames() const; + std::vector getNames() const; /** * Get the closest option name and its Levenshtein distance. @@ -165,9 +165,9 @@ public: * An exception that can be thrown by the options * when a provided option is accessed before being set. */ - struct unset_exception : public exception + struct no_value_exception : public exception { - explicit unset_exception(const std::string& what = ""); + explicit no_value_exception(const std::string& what = ""); }; /** diff --git a/library/src/options.cxx b/library/src/options.cxx index a134045907..d39e14b7ff 100644 --- a/library/src/options.cxx +++ b/library/src/options.cxx @@ -70,7 +70,7 @@ bool options::isSame(const options& other, const std::string& name) const { return options_tools::get(*this, name) == options_tools::get(other, name); } - catch (const f3d::options::unset_exception&) + catch (const f3d::options::no_value_exception&) { return !this->hasValue(name) && !other.hasValue(name); } @@ -84,7 +84,7 @@ bool options::hasValue(const std::string& name) const options_tools::get(*this, name); return true; } - catch (const f3d::options::unset_exception&) + catch (const f3d::options::no_value_exception&) { return false; } @@ -98,15 +98,15 @@ options& options::copy(const options& from, const std::string& name) } //---------------------------------------------------------------------------- -std::vector options::getNames() +std::vector options::getAllNames() { return options_tools::getNames(); } //---------------------------------------------------------------------------- -std::vector options::getValuedNames() const +std::vector options::getNames() const { - const std::vector names = options::getNames(); + const std::vector names = options::getAllNames(); std::vector setNames; std::copy_if(names.begin(), names.end(), std::back_inserter(setNames), [&](const std::string& name) { return this->hasValue(name); }); @@ -174,7 +174,7 @@ options::inexistent_exception::inexistent_exception(const std::string& what) } //---------------------------------------------------------------------------- -options::unset_exception::unset_exception(const std::string& what) +options::no_value_exception::no_value_exception(const std::string& what) : exception(what) { } diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index 84fe6067b9..c0939b329c 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -136,12 +136,12 @@ int TestSDKOptions(int argc, char* argv[]) test("move operator", opt5.render.line_width == 2.13); // Test getNames - std::vector names = f3d::options::getNames(); + std::vector names = f3d::options::getAllNames(); test( - "getNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); + "getAllNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); - std::vector setNames = opt.getValuedNames(); - test("getValuedNames count", setNames.size() != 0 && setNames == opt2.getValuedNames()); + std::vector setNames = opt.getNames(); + test("getNames count", setNames.size() != 0 && setNames == opt2.getNames()); // Test isSame/copy/hasValue test("isSame", opt.isSame(opt2, "render.line_width")); @@ -182,8 +182,8 @@ int TestSDKOptions(int argc, char* argv[]) test.expect( "inexistent_exception exception on get", [&]() { opt.get("dummy"); }); - test.expect( - "unset_exception exception on get", [&]() { opt.get("scene.animation.time"); }); + test.expect( + "no_value_exception exception on get", [&]() { opt.get("scene.animation.time"); }); // Test setAsString/getAsString error paths test.expect( @@ -192,8 +192,8 @@ int TestSDKOptions(int argc, char* argv[]) test.expect( "inexistent_exception exception on getAsString", [&]() { opt.getAsString("dummy"); }); - test.expect( - "unset_exception exception on getAsString", [&]() { opt.getAsString("scene.animation.time"); }); + test.expect( + "no_value_exception exception on getAsString", [&]() { opt.getAsString("scene.animation.time"); }); return EXIT_SUCCESS; } diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx index 7c8d9a6419..6b80048c24 100644 --- a/python/F3DPythonBindings.cxx +++ b/python/F3DPythonBindings.cxx @@ -184,16 +184,16 @@ PYBIND11_MODULE(pyf3d, module) throw py::key_error(key); } }) - .def("__len__", [](f3d::options& opts) { return opts.getValuedNames().size(); }) + .def("__len__", [](f3d::options& opts) { return opts.getNames().size(); }) .def( "__iter__", [](f3d::options& opts) { - const auto names = py::cast(opts.getValuedNames()); // won't work without cast + const auto names = py::cast(opts.getNames()); // won't work without cast return make_iterator(names); }, py::keep_alive<0, 1>()) - .def("keys", &f3d::options::getValuedNames) // to do `dict(options)` + .def("keys", &f3d::options::getNames) // to do `dict(options)` .def("toggle", &f3d::options::toggle) .def("is_same", &f3d::options::isSame) .def("get_closest_option", &f3d::options::getClosestOption) From a56efafc9118e02eccd96b728bf75c98ebfe1f19 Mon Sep 17 00:00:00 2001 From: Mathieu Westphal Date: Wed, 18 Sep 2024 13:10:36 +0200 Subject: [PATCH 28/28] xlf --- library/testing/TestSDKOptions.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/testing/TestSDKOptions.cxx b/library/testing/TestSDKOptions.cxx index c0939b329c..6d2213aed4 100644 --- a/library/testing/TestSDKOptions.cxx +++ b/library/testing/TestSDKOptions.cxx @@ -137,8 +137,8 @@ int TestSDKOptions(int argc, char* argv[]) // Test getNames std::vector names = f3d::options::getAllNames(); - test( - "getAllNames find", std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); + test("getAllNames find", + std::find(names.begin(), names.end(), "scene.animation.time") != names.end()); std::vector setNames = opt.getNames(); test("getNames count", setNames.size() != 0 && setNames == opt2.getNames()); @@ -192,8 +192,8 @@ int TestSDKOptions(int argc, char* argv[]) test.expect( "inexistent_exception exception on getAsString", [&]() { opt.getAsString("dummy"); }); - test.expect( - "no_value_exception exception on getAsString", [&]() { opt.getAsString("scene.animation.time"); }); + test.expect("no_value_exception exception on getAsString", + [&]() { opt.getAsString("scene.animation.time"); }); return EXIT_SUCCESS; }