C++ Distribution Example Plugin
Introduction
This page describes what is present in example_plugin directory of the Windows and WebAssembly distribution archive and how to use it.
- Note
- Please have a look at MeshLib С++ setup guide first.
Content
This example contains several files:
- example_plugin.sln - Visual Studio solution file
- example_plugin.vcxproj - Visual Studio project file
- MyPlugin.items.json - tools configuration file
- MyPlugin.ui.json - tools visualization in MeshLib/MeshInspector viewer
- resource - directory with icons in four different sizes for menu in viewer
- MyPlugin.cpp - source code with actual (demo) tools
- CMakeLists.txt - CMake project file
- ViewerApp.cpp - sample viewer app that has enough functionality to load and test the tools
- wasm/index.html - (WebAssembly only) sample HTML page for loading the sample viewer app
Lets have a closer look at each of these points:
Visual Studio Solution File
example_plugin.sln - This can be used to build an example with Visual Studio, it only includes example_plugin.vcxproj in it.
Visual Studio Project File
example_plugin.vcxproj - This file is configured so project can work with MeshLib distribuiton
- Debug only:
- Debug Configuration: C/C++ → Preprocessor → Preprocessor Definitions:
Add: _ITERATOR_DEBUG_LEVEL=0
- For all configurations:
- General Properties -> C++ Language Standard:
Set: /std:c++20 or later
- C/C++ → General → Additional Include Directories:
Add: C:\meshlib-built\install\include
- C/C++ → All Options → Additional Options:
Add: /bigobj /utf8
- Linker → Input → Additional Dependencies:
Add: C:\meshlib-built\install\lib\$(Configuration)\*.lib
Define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
- Copy other files to target directory:
<ItemGroup>
<CopyFileToFolders Include="MyPlugin.items.json">
<FileType>Document</FileType>
</CopyFileToFolders>
<CopyFileToFolders Include="MyPlugin.ui.json">
<FileType>Document</FileType>
</CopyFileToFolders>
<Content Include="resource\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Tools Configuration File
MyPlugin.items.json - this file contains information about each tool that is present in the plugin:
- "Name" - name of the tool, should be same as in the code
- "Tooltip" - tooltip that is shown when user hover tool in UI
- "Icon" - unicode symbol from Fontawesome, it is shown in UI for the tool if there is no actual icon present in resource folder
- "Caption" - optional: label that is displayed instead of name in UI, if not present "Name" is used intead
- "HelpLink" - optional: link to web page that will be opened if "Help" button is pressed in UI
- "DropList" - optional: array with other tools that will be available in this tool drop list (see "List" in next section)
{
"Items": [
{
"Name": "My Tool",
"Tooltip": "Simple button that shows Hello World message",
"Icon": "\uE05D"
},
{
"Name": "My State Tool",
"Tooltip": "Simple dialog that shows Hello World message",
"Icon": "\uE05D"
}
]
}
Tools Visualization Order File
MyPlugin.ui.json - this file has information about order of the plugin loading, and UI schema for present tools:
- "Order" - order of loading dll produced by this plugin, it can be used to determine constuction of tools in diferent plugins
- "LibName" - name of the dll that contains provided tools (in this case it is same dll)
- "Tabs" - tabs where tools are located in UI, could be new tabs or existing ones (specified plugins with less "Order" number)
- "Name" - name of the tab
- "Priority" - optional: tabs are ordered by this number
- "Groups" - specify groups of tools in single tab, could be new groups or existing ones (specified plugins with less "Order" number)
- "Name" - name of the group (it is not used now)
- "List" - list of the tools in this group
- "Name" - name of the tool, should be same as in the code and in the items.json file
{
"Order": 999,
"LibName": "example_plugin",
"Tabs": [
{
"Name": "MyPlugin",
"Priority": 20,
"Groups": [
{
"Name": "Primal",
"List": [
{
"Name": "My Tool"
},
{
"Name": "My State Tool"
}
]
}
]
}
]
}
Resoure Directory
resource - directory with icons that is used in UI, it should have same structure as in example:
- resource
- icons
- X0_5 (16x16 px)
- X0_75 (24x24 px)
- X1 (32x32 px)
- X3 (96x96 px)
- Note
- Icons should have same name as tool in the code, in items.json file and in ui.json file
Source Code File
MyPlugin.cpp - this file contains two simple tools:
- MyTool() : RibbonMenuItem( "My Tool" ) - shows "Hello World" modal window
- MyStateTool() : StatePlugin( "My State Tool" ) - shows "Hello World" dialog window
For more information have a look at State Plugin Page
Sample Viewer App
ViewerApp.cpp - source file for running the viewer instance. You can set your own viewer launch parameters and alterate viewer setup process.
Usage
Windows
- Open solution file with Visual Studio
- Compile it
- Copy content of just appeared x64\Release\ folder to MeshLib or MeshInspector app folder
- MeshLib: install\app\Release
- MeshInspector: C:\Program Files\MeshInspector\MeshInspector, please note that you should use same version of MeshLib that is used in MeshInspector to avoid unexpected errors
- Note
- take x64\Debug\ if you want to test it in MeshLib debug app folder: install\app\Debug
Linux
- Install MeshLib (apt install meshlib) or unpack the SDK archive next to your plugin source.
- Build:
cmake -S example_plugin -B example_plugin_build -D CMAKE_BUILD_TYPE=Release \
-D MeshLib_DIR=/usr/lib/cmake/meshlib # adjust to your install
cmake --build example_plugin_build -j
- Deploy:
sudo cp example_plugin_build/libMyPlugin.so /usr/lib/MeshInspector/
sudo cp example_plugin/MyPlugin.items.json /usr/share/MeshInspector/
sudo cp example_plugin/MyPlugin.ui.json /usr/share/MeshInspector/
sudo cp -R example_plugin/resource /usr/share/MeshInspector/
macOS (arm64 / Intel)
The MeshLib SDK ships as a framework at /Library/Frameworks/MeshLib.framework.
- Install MeshLib SDK.
- Build:
cmake -S example_plugin -B example_plugin_build -D CMAKE_BUILD_TYPE=Release
cmake --build example_plugin_build -j
- Deploy. Recommended (safer): install into a writable clone of the host app — does not touch the system bundle and does not break its code signature.
mkdir -p ~/Apps
cp -R /Applications/MeshInspector.app ~/Apps/MI-MyPlugin # NB: drop the .app suffix
cp example_plugin_build/libMyPlugin.dylib ~/Apps/MI-MyPlugin/Contents/libs/
cp example_plugin/MyPlugin.items.json ~/Apps/MI-MyPlugin/Contents/Resources/
cp example_plugin/MyPlugin.ui.json ~/Apps/MI-MyPlugin/Contents/Resources/
cp -R example_plugin/resource ~/Apps/MI-MyPlugin/Contents/Resources/
The system-wide alternative (writes into the notarized MeshInspector.app bundle) is documented under How to Add Plugin → macOS option B, including the signature trade-off.
WebAssembly
- Install and activate Emscripten SDK
- Download and unpack MeshLib SDK
- Configure and build the project using CMake and emcmake:
emcmake cmake -S example_plugin -B example_plugin_build -D CMAKE_FIND_ROOT_PATH=/path/to/meshlib/sdk/
cmake --build example_plugin_build --config Release
- Copy the result files from the example_plugin_build/html directory to your web server location.
- Note
- Make sure your web server enables cross-origin isolation for these files.
After install — quick sanity check
Restart the host app and look at the log:
- Windows: TEMP%\MeshInspector\Logs\MRLog_*.txt
- Linux: /tmp/MeshInspector/Logs/MRLog_*.txt
- macOS: $TMPDIR/MeshInspector/Logs/MRLog_*.txt
You should see two lines per plugin:
[info] Loading library MyPlugin with priority 999
[info] Load library MyPlugin was successful
If instead you get:
[error] dlopen(...): Library not loaded: ...
[warning] Ribbon item "My Tool" is not registered
the plugin's transitive dependencies didn't resolve from the host bundle (so the dylib never loaded, and therefore no items got registered). See How to Add Plugin → "Verifying the install" for fix paths.