f3d
f3d copied to clipboard
Brainstorm libf3d API
libf3d was introduced in !259 (closed), let's brainstorm a stable API for it.
Tasklist:
libf3d
- [x] Introduce f3d::options: #191
- [x] Refactor F3DLoader and F3D to use f3d::options cleanly
- [x] Introduce f3d::loader and use it
- [x] Introduce f3d::window and use it
- [x] modularize VTK code
- [x] Add unit test for VTK modules : https://github.com/f3d-app/f3d/issues/265
- [x] sanity check call order with window and interactor
- [x] transform F3DLog into f3d::log
- [x] fix #32 by using categories for options
- [x] improve f3d_options by providing initialization methods
- [x] store init value in f3d::options for easier reset ?
- [x] support std::initializer_list to be able to call options.set("color", { 1., 1., 1. });
- [x] add a way to inform user when an options does not exist
- [x] introduce a factory and use it to create classes to hide the private API
- [x] Add SDK test infrastructure
- [ ] Adress as many TODOs as possible
- [x] Rework engine for bit flag and init early
- [x] Add SDK tests
- [x] (optional) expand f3d_interactor to support user set behavior for many more context
- [x] add more window types
- [x] improve all classes from f3d namespaces to ensure all santiy checks are done correctly
- [x] unit testing of the API and general coverage improvements
- [x] Add a vtkNoRenderWindow
- [x] modernization of API
- [x] constness of API
- [ ] Public Review of the API to anyone willing to help
F3D
- [x] Rework F3DOptions and F3DOptionsParser to interface with f3d::options
- [x] (Optional) introduce f3d::config in libf3d ?
- [x] rewrite F3DStarter from scratch to not depends on VTK
Doc
- [x] In header doc
- [ ] example doc
- [ ] website doc
Ignoring completelly how libf3d and f3d are currently implemented, let's consider the fonctionnality we want to provide as a lib.
Features:
- Set a list of options
- Read a file
- Display resuting scene using file and options in a OpenGL context, potentially provided by user
Restrictions:
- User must not need to find_package VTK to use libf3d or use any vtk* class
- User does not need to know much about rendering to use libf3d
inputs @Meakk ?
I agree, VTK should be a private dependency of libf3d.
Ideally, f3d executable should only provide the command-line parsing, and config file management.
So trying to link it with current implementation, we could have the following rough public API
F3DOptions
SetFoo
SetBar
F3DFileLoader(F3DOptions)
AddFile
F3DViewer(F3DOptions, F3DFileLoader)
Show
Here are my inputs.
libf3d usage should allow the user to call something like that:
f3d::window w = f3d::createWindow(f3d::context ctx); // create window (external, native, android ...)
w.addFile("/path/file.vtp"); // add a file
w.addFolder("/path"); // add all the files in folder
w.setActiveFile(int index); // set the active file
w.setOption("key", "value"); // configure all options using this function (parse the value string inside the function)
w.clear(); // remove all files
w.render(); // render the scene
w.saveTofile("/path/image.png"); // save the rendered image
w.setKeyCallBack([](int keyCode, int modifier) {
// do something
});
w.setMouseCallBack([](float dx, float dy, int button) {
// do something
});
w.setMotionCallBack([](float whatever) {
// do something on Android
});
It also means that the interactor should be moved to the executable, but it makes sense to me.
The API is clear, simple, and it's easy to remove/add options without breaking the compilation on the user side. Maybe providing an equivalent API in C would be useful too.
The list I provided is most likely incomplete.
I think it would be better to separate loading data and rendering data. here is a proposition:
f3d::options opt;
opt.setOption("key", "value"); // configure all options using this function (parse the value string inside the function)
f3d::loader load;
load.setOptions(opt);
load.addFile("/path/file.vtp"); // add a file
load.addFolder("/path"); // add all the files in folder
load.setActiveFile(int index); // set the active file
f3d::interactor interact
interact.setKeyCallBack([](int keyCode, int modifier) {
// do something
});
interact.setMouseCallBack([](float dx, float dy, int button) {
// do something
});
interact.setMotionCallBack([](float whatever) {
// do something on Android
});
f3d::window win (f3d::context ctx); // create window (external, native, android ...)
win.setOptions(opt)
win.setLoader(load);
win.setInteractor(interact);
win.render(); // render the scene
win.saveTofile("/path/image.png"); // save the rendered image
I dont really care about C bindings, python bindings would be much more important imo.
@mwestphal I like it! Regarding bindings, we will need Java bindings too for Android. I will take care of it, don't worry 😛
Great ! Lets focus on this one when we find the time. We may want to merge into a dedicated branch until it stabilize.
I still think providing C functions can be useful, for C programmers of course, but it will make other bindings easier, like Rust for instance: https://stackoverflow.com/questions/52923460/how-to-call-a-c-dynamic-library-from-rust
Interesting.
Hi, I'm also interested by C functions 😃 Given I write my SketchUp plugins in Ruby, I could use Fiddle to call libf3d from Ruby.
To ease language interoperability and type mapping, I suggest to use JSON as string when value passed or returned is structured.
Haha, nice screenshot :+1:
Discussed API moving forward
f3d::options opt;
opt.setOption("key", "value"); // configure all options using this function (parse the value string inside the function)
f3d::window win (f3d::context ctx); // create window (external, native, android ...)
f3d::loader load;
load.setOptions(opt);
load.setWindow(win);
load.addFile("/path/file.vtp"); // add a file
load.addFolder("/path"); // add all the files in folder
load.setActiveFile(int index); // set the active file
f3d::interactor interact
interact.setMouseCallBack([](float dx, float dy, int button) {
// do something
});
interact.setMotionCallBack([](float whatever) {
// do something on Android
});
win.setInteractor(interact);
win.render(); // render the scene
win.saveTofile("/path/image.png"); // save the rendered image
interact.loop();
@mwestphal Once model is loaded and rendered, could we access renderer then change things in real time? For instance:
win.render(); // render the scene
ren = win.getRenderer();
cam = ren.getActiveCamera();
cam.setPosition(float x, float y, float z);
Yes, any options will be changeable dynamically when all is implemented.
So a very early version of the API is now in master, I'll try to update the issue to identify the remaining work.
@Meakk updated with your suggestions
Here is how it looks now:
f3d::engine eng(f3d::engine::WindowTypeEnum::WINDOW_STANDARD);
f3d::loader& load = eng.getLoader();
load.addFile(filepath);
load.loadFile(f3d::loader::LoadFileEnum::LOAD_CURRENT);
f3d::window& win = eng.getWindow();
f3d::interactor& inter = eng.getInteractor();
inter.start();
For anyone following this. We are close to completion of the first version of the API. stay tuned.
store init value in f3d::options for easier reset ?
not needed
(Optional) introduce f3d::config in libf3d ?
not needed
(optional) expand f3d_interactor to support user set behavior for many more context
Not needed, for now
Doc item in their own issue: https://github.com/f3d-app/f3d/issues/48
All items have been adressed, closing.