These documents describe how to build 3D Forest and develop new plugins using APIs in 3D Forest and other libraries.
git clone https://github.com/VUKOZ-OEL/3d-forest.git cd 3d-forest
git checkout your-branch
# Push your current changes in your branch if you have any (git status) git add --all git commit -m "Update" git push # Checking latest changes in 'main' git checkout main git fetch git pull # Merging 'main' into your branch git checkout your-branch git merge --no-ff -m "Merge branch 'main' into your-branch" main # Resolve conflicts and push git push # Merging your branch into 'main' (contribution, pull requests later) git checkout main git merge --no-ff -m "Merge branch 'your-branch' into main" your-branch git push # Return to your branch git checkout your-branch
git checkout <branch> git fetch git pull
git branch git status git add <path> git add --all git commit -m "Add feature x" git push
The code uses C++17, CMake, Qt5/Qt6 and OpenGL which will be installed in the following steps. Qt and OpenGL are required only for GUI desktop application.
$ sudo apt update $ sudo apt upgrade
$ sudo apt install open-vm-tools-desktop
$ sudo apt install build-essential
$ sudo apt install mesa-common-dev libgl1-mesa-dev $ sudo apt install libxkbcommon-dev libxkbfile-dev
$ sudo apt install cmake $ sudo apt install git
$ sudo apt install libxcb-cursor0 libxcb-cursor-dev $ sudo apt-get install libxcb-xinerama0
$ cd /home/user/ $ git clone https://github.com/VUKOZ-OEL/3d-forest.git
$ cd /home/user/3d-forest $ mkdir build $ cd /home/user/3d-forest/build $ PATH=$PATH:/home/user/Qt/6.8.0/gcc_64/bin $ cmake -G "Unix Makefiles" .. -DCMAKE_INSTALL_PREFIX=.. -DOpenGL_GL_PREFERENCE=GLVND -DCMAKE_INSTALL_RPATH="/home/user/3d-forest/bin;/home/user/Qt/6.8.0/gcc_64/lib" -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE $ make $ make install
$ cd /home/user/3d-forest/bin $ ./3DForest
The code uses C++17, CMake, Qt5/Qt6 and OpenGL which will be installed in the following steps. Qt and OpenGL are required only for GUI desktop application.
cd Documents/devel/ git clone https://github.com/VUKOZ-OEL/3d-forest.git cd 3d-forest
> cd /Users/user/Documents/devel/3d-forest > mkdir build > cd build > /Applications/CMake.app/Contents/bin/cmake -G "Unix Makefiles" .. -DCMAKE_INSTALL_PREFIX=.. -DCMAKE_PREFIX_PATH=/Users/user/Qt/5.15.2/clang_64 -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXAMPLES=ON > make > make install
> cd /Users/user/Documents/devel/3d-forest/bin > DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Users/user/Documents/devel/3d-forest/bin ./3DForestExampleFile
> install_name_tool -change @rpath/lib3DForestGui.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestGui.dylib 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/lib3DForestEditor.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestEditor.dylib 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/lib3DForestCore.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestCore.dylib 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/QtOpenGL.framework/Versions/5/QtOpenGL /Users/user/Qt/5.15.2/clang_64/lib/QtOpenGL.framework/Versions/5/QtOpenGL 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/QtWidgets.framework/Versions/5/QtWidgets /Users/user/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/QtGui.framework/Versions/5/QtGui /Users/user/Qt/5.15.2/clang_64/lib/QtGui.framework/Versions/5/QtGui 3DForest.app/Contents/MacOS/3DForest > install_name_tool -change @rpath/QtCore.framework/Versions/5/QtCore /Users/user/Qt/5.15.2/clang_64/lib/QtCore.framework/Versions/5/QtCore 3DForest.app/Contents/MacOS/3DForest > 3DForest.app/Contents/MacOS/3DForest @verbatim - Or to run generated executable 3DForest (by changing rpath to abs path): @verbatim > cd /Users/user/Documents/devel/3d-forest/bin > install_name_tool -change @rpath/lib3DForestGui.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestGui.dylib 3DForest > install_name_tool -change @rpath/lib3DForestEditor.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestEditor.dylib 3DForest > install_name_tool -change @rpath/lib3DForestCore.dylib /Users/user/Documents/devel/3d-forest/bin/lib3DForestCore.dylib 3DForest > install_name_tool -change @rpath/QtOpenGL.framework/Versions/5/QtOpenGL /Users/user/Qt/5.15.2/clang_64/lib/QtOpenGL.framework/Versions/5/QtOpenGL 3DForest > install_name_tool -change @rpath/QtWidgets.framework/Versions/5/QtWidgets /Users/user/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets 3DForest > install_name_tool -change @rpath/QtGui.framework/Versions/5/QtGui /Users/user/Qt/5.15.2/clang_64/lib/QtGui.framework/Versions/5/QtGui 3DForest > install_name_tool -change @rpath/QtCore.framework/Versions/5/QtCore /Users/user/Qt/5.15.2/clang_64/lib/QtCore.framework/Versions/5/QtCore 3DForest > ./3DForest
The code uses C++17, CMake, Qt5/Qt6 and OpenGL which will be installed in the following steps. Qt and OpenGL are required only for GUI desktop application.
[diff "astextplain"] textconv = astextplain [filter "lfs"] clean = git-lfs clean -- %f smudge = git-lfs smudge -- %f process = git-lfs filter-process required = true [http] sslBackend = openssl sslCAInfo = C:/Users/user/AppData/Local/Programs/Git/mingw64/ssl/certs/ca-bundle.crt [core] autocrlf = false fscache = true symlinks = false editor = notepad [pull] rebase = false [credential] helper = manager [credential "https://dev.azure.com"] useHttpPath = true [init] defaultBranch = main
$ git config --global user.name "Vaclav Bubnik" $ git config --global user.email "vaclav@email.com"
[user] email = vaclav@email.com name = Vaclav Bubnik
$ pacman -Syu
$ pacman -Syuor
$ pacman -Su
$ pacman -S mingw-w64-x86_64-clang $ pacman -S mingw-w64-x86_64-cmake $ pacman -S mingw-w64-x86_64-make
$ pacman -S mingw-w64-x86_64-doxygen $ pacman -S mingw-w64-x86_64-graphviz
$ pacman -S mingw-w64-x86_64-python $ pacman -S mingw-w64-x86_64-python-pip
cd Documents\3d-forestor first clone the repository to "Documents" as follows:
cd Documents git clone https://github.com/VUKOZ-OEL/3d-forest.git cd 3d-forest
> mkdir build > cd build > cmake -G "MinGW Makefiles" .. -DCMAKE_INSTALL_PREFIX=.. > mingw32-make > mingw32-make install
The code uses C++17, CMake, Qt5/Qt6 and OpenGL which will be installed in the following steps. Qt and OpenGL are required only for GUI desktop application.
[diff "astextplain"] textconv = astextplain [filter "lfs"] clean = git-lfs clean -- %f smudge = git-lfs smudge -- %f process = git-lfs filter-process required = true [http] sslBackend = openssl sslCAInfo = C:/Users/user/AppData/Local/Programs/Git/mingw64/ssl/certs/ca-bundle.crt [core] autocrlf = false fscache = true symlinks = false editor = notepad [pull] rebase = false [credential] helper = manager-core [credential "https://dev.azure.com"] useHttpPath = true [init] defaultBranch = main
$ git config --global user.name "Vaclav Bubnik" $ git config --global user.email "vaclav@email.com"
[user] email = vaclav@email.com name = Vaclav Bubnik
There are several ways to add new functionality. The most easy way is to add new external plugin. External plugins are self contained. It is not necessary to touch any file outside of your plugin directory with exception of one cmake file.
add_subdirectory(myplugin)
It is possible to add new command line tool to "src/apps/tools/mytool".
The third way is to add new internal plugin.
file(GLOB_RECURSE SOURCES_MYACTION "../plugins/myplugin/*.cpp") add_library ${SOURCES_MYACTION} ../plugins/myplugin/resources/resources.qrc target_include_directories ../plugins/myplugin
class MyPlugin; MyPlugin *myPlugin_;
myPlugin_ = new MyPlugin(); myPlugin_->initialize(this);
The last and most difficult way is to modify core functionality in the following directories. This functionality is available in all plugins.
The following command performs automatic code formatting. It is good to run this command before 'git add <file>' and git commit to GitHub:
mingw32-make format
The code is using C++ std on Backend and Qt on Frontend.
Function names follow mixed Qt style and std:
get: bool hasFocus() const; bool isHidden() const; int height() const; size_t size() const; // Can be better than Qt like 'count'. std uses 'size'. get/set: bool isSizeGripEnabled() const; // get void setSizeGripEnabled(bool); // set int result() const; // get void setResult(int i); // set const T &at(int i) const; // get (inconsistent, easy to read) void append(const QList<T> &value); // set (inconsistent, easy to read) signals: void accepted(); void finished(int result); void rejected(); void toolsRequested(const QString &source); void findTextFinished(const QString &text); void loadProgress(int progress);
directory "3rd Party" is "3rdparty" lowercase, no separators source "MainWindow.hpp" C++ header, CamelCase for classes "MainWindow.cpp" C++ source, CamelCase for classes "examplecolorpalette.cpp" lowercase for executables "las.cpp" lowercase for executables files anything "README.md" "CMakeLists.txt" "layout_grid_24px.png" ".clang-format" ".gitignore"
Example log for file DescriptorPca.cpp
#define LOG_MODULE_NAME "DescriptorPca" #define LOG_MODULE_DEBUG_ENABLED 1 /* Define to enable all debug log messages from this file. */ #include <Log.hpp> LOG_DEBUG(<< "Found <" << nPoints << "> points.");
Example command to generate documentation:
mingw32-make doc
Your favorite syntax of documentation comments.
Suggestions:
/** First paragraph is automatically brief <detail description> @todo Documentation is not complete. */ int value; /**< field description, after */ /** Link to function foo() */ /** Link to parameter @e value */ void foo(value); [in], [out], [in,out] for parameters: /** @param [in] milliseconds sleep until milliseconds have elapsed. */ void Time::msleep(long milliseconds); Group 'Point Data' creates hierarchy in generated output: /** @name Point Data */ /**@{*/ /** Point coordinates. */ std::vector<double> xyz; /** Pulse return magnitude. */ std::vector<float> intensity; /**@}*/ Examples: /** JSON. @example Json obj; obj["name"] = "John"; std::cout << obj << "\n"; // Output: {"name":"John"} @endexample */ /** @section @subsection */ /** @file Window.hpp */ /** @class Window.cpp::Window Documenting another file. */
We would like to be able to give users access to documentation from within the user interface of our application. This section demonstrates how to edit, generate and distribute such documentation with 3D Forest.
These are the locations where it is possible to write the documentation:
The following steps will generate the documentation and prepare it for distribution:
mingw32-make doxygenProduced output: html\index.qhp, html\index.qch
qhelpgenerator ..\doc\index.qhcp -o html\index.qhcProduced output: html\index.qhc, html\index.qch
mkdir ..\bin\documentation copy html\index.qhc ..\bin\documentation\ copy html\index.qch ..\bin\documentation\
To show the documentation in the application:
Third party libraries used by 3D Forest are copied to '3rdparty' directory and therefore distributed together with 3D Forest. 3rd party code is build as a part of 3D Forest build process. This removes inconvenient step which would require to search, download and install dependencies.
GPLv3 compatibility matrix: https://www.gnu.org/licenses/gpl-faq.en.html#AllCompatibility
GPL-Compatible Free Software Licenses: https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses
GPL-Incompatible Free Software Licenses: https://www.gnu.org/licenses/license-list.html#GPLIncompatibleLicenses
Example Windows build script executed from directory build:
cmake -G "MinGW Makefiles" .. -DCMAKE_INSTALL_PREFIX=.. -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXAMPLES=ON mingw32-make format mingw32-make mingw32-make install mingw32-make doc qhelpgenerator ..\doc\index.qhcp -o html\index.qhc mkdir ..\bin\documentation copy html\index.qhc ..\bin\documentation\ copy html\index.qch ..\bin\documentation\
Conversion of '.ui' files to '.hpp' files by using 'uic' command line tool:
which uic uic -o ui_window.h window.ui
Rename filenames:
powershell -C "gci | % {rni $_.Name ($_.Name -replace '24px', '24')}"
{ "files.eol": "\n", "C_Cpp.default.includePath":[ "C:/Qt/6.3.0/mingw_64/include/**", "${workspaceRoot}/3rdparty/delaunator", "${workspaceRoot}/3rdparty/eigen", "${workspaceRoot}/3rdparty/libigl/include", "${workspaceRoot}/3rdparty/stb", "${workspaceRoot}/3rdparty/unibnoctree", "${workspaceRoot}/3rdparty/warnings", "${workspaceRoot}/3rdparty/widgets/ctk", "${workspaceRoot}/3rdparty/widgets/flowlayout", "${workspaceRoot}/src/apps/3dforest", "${workspaceRoot}/src/apps/tests", "${workspaceRoot}/src/apps/tools/sandbox", "${workspaceRoot}/src/core", "${workspaceRoot}/src/editor", "${workspaceRoot}/src/gui", "${workspaceRoot}/src/plugins/ComputeClassification", "${workspaceRoot}/src/plugins/ComputeDescriptor", "${workspaceRoot}/src/plugins/ComputeElevation", "${workspaceRoot}/src/plugins/ComputeHeightMap", "${workspaceRoot}/src/plugins/ComputeSegmentationNN", "${workspaceRoot}/src/plugins/ComputeTreeAttributes", "${workspaceRoot}/src/plugins/Edit", "${workspaceRoot}/src/plugins/ExportFile", "${workspaceRoot}/src/plugins/FilterArea", "${workspaceRoot}/src/plugins/FilterClassification", "${workspaceRoot}/src/plugins/FilterDescriptor", "${workspaceRoot}/src/plugins/FilterElevation", "${workspaceRoot}/src/plugins/FilterFiles", "${workspaceRoot}/src/plugins/FilterIntensity", "${workspaceRoot}/src/plugins/FilterTrees", "${workspaceRoot}/src/plugins/Help", "${workspaceRoot}/src/plugins/ImportFile", "${workspaceRoot}/src/plugins/MessageLog", "${workspaceRoot}/src/plugins/ProjectFile", "${workspaceRoot}/src/plugins/SettingsUnits", "${workspaceRoot}/src/plugins/SettingsView", "${workspaceRoot}/src/plugins/TreeTable", "${workspaceRoot}/src/plugins/Viewer" ] }
{ "cmake.configureOnOpen": false, "cmake.mingwSearchDirs": [ "C:\\msys64\\mingw-w64\\bin" ], "cmake.generator": "MinGW Makefiles", }
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/3dforest.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }
{ "version": "2.0.0", "command": "sh", "args": ["-c"], "presentation": { "echo": true, "reveal": "always", "focus": true, "panel": "new" }, "tasks": [ { "label": "cmake", "type": "shell", "options": { "cwd": "${workspaceRoot}/build" }, "args": ["cmake -G 'MinGW Makefiles' .. -DCMAKE_INSTALL_PREFIX=.."] }, { "label": "make", "type": "shell", "args": ["mingw32-make"], "options": {"cwd": "${workspaceRoot}/build"}, "dependsOn": ["cmake"], "group": {"kind": "build","isDefault": true} } ] }