4.2. C++ API Reference¶
4.2.1. Native.h¶
This is the central file with all exported functions that are callable from C#. These are the ‘entry points’.
As this is a library we do not have a main()
, however we have the Initialize()
function as a replacement.
Unity also triggers the functions UnityPluginLoad()
and UnityPluginUnload()
at the start and end.
These are called first and last, notably Initialize()
is called after UnityPluginLoad()
.
The two important functions for the lifecycle of a mesh are InitializeMesh()
and DisposeMesh()
.
These are called whenever a LibiglMesh
is instaniated or destroyed in Unity. This is where the C++ owned
memory is allocated and deleted.
To make these functions callable from C# we must put the declarations inside an extern "C"
scope,
as well as prepending the UNITY_INTERFACE_EXPORT
to the declaration. This is because C# and C++ use different
default calling conventions, see x86 Calling Conventions
specifically __stdcall
. This also is different for every platform, but luckily the IUnityInterface header handles
this for us if we use this macro.
Note that the implementations of the defined functions are split across several cpp files, as indicated in the code. This is done so we have one central place where we have all the exported functions that are callable from C#.
Functions
-
void
Initialize
(StringCallback debugCallback, StringCallback debugWarningCallback, StringCallback debugErrorCallback)¶ Called just before the first function is called from this library. Use this to pass initial data from C#
- See
C# Native.Initialize()
- Parameters
debugCallback
: A C# delegate (function pointer) to print to the Unity Debug.Log
-
MeshState *
InitializeMesh
(const UMeshDataNative data, const char *name)¶ Called when a new mesh is loaded. Initialize global variables, do pre-calculations for a mesh
- Return
A pointer to the C++ state for this mesh
- Parameters
data
: The Unity MeshDataname
: Name of the mesh
-
void
UnityPluginLoad
(IUnityInterfaces *unityInterfaces) Called when the plugin is loaded, this can be after/before Initialize()
Declared in IUnityInterface.h
- Parameters
unityInterfaces
: Unity class for accessing minimal Unity functionality exposed to C++ Plugins
-
void
UnityPluginUnload
() Called when the plugin is unloaded, clean up here Declared in IUnityInterface.h
-
void
ApplyDirty
(MeshState *state, const UMeshDataNative data, const unsigned int visibleSelectionMask)¶ Propagates changes from the libigl mesh (Eigen matrices) to the Unity NativeArrays so we can apply it to the mesh in C#. This functions also recalculated selection sizes, colors based on the selection. This should be called once after apply all wanted changes to the libigl mesh. This function itself does not modify the Unity mesh, see UMeshData.cs
- Parameters
data
: Pointers to the Unity Mesh Data, where to apply changes to.visibleSelectionMask
: Selections which are currently visible, will ignore changes to invisible selections.
-
void
ReadOFF
(const char *path, const bool setCenter, const bool normalizeScale, const float scale, void *&VPtr, int &VSize, void *&NPtr, int &NSize, void *&FPtr, int &FSize, bool calculateNormalsIfEmpty = false)¶ Reads an .off file into row major Eigen matrices, these can then be mapped by a NativeArray in C#. Matrices are allocated with
new
and must be deleted manually (e.g. byNativeArray<T>.Dispose()
or converting withAllocator.Temp
).- Parameters
path
: The asset path, absolute or relative to the project root e.g. AssetImportContext.assetPath or “Assets/model.off”setCenter
: Set the center as the mean vertex, see ApplyScalenormalizeScale
: Whether to normalize the y-scale to 1scale
: Scale the mesh by this factor after normalization[out] VPtr
: Pointer to the first element of the Vertex matrix[out] VSize
: Number of vertices, rows of V[out] NPtr
: Pointer to the first element of the Normals matrix[out] NSize
: Number of normals, usually equal to VSize[out] FPtr
: Pointer to the first element of the Face/Indices matrix, one row is a triangle[out] FSize
: Number of faces, rows of FcalculateNormalsIfEmpty
: Calculate per vertex normals, if no normals are present in the .off file
-
void
TranslateAllVertices
(MeshState *state, Vector3 value)¶ Debug function to simply translate all vertices by the value.
-
void
TranslateSelection
(MeshState *state, Vector3 value, unsigned int maskId = -1)¶ Translate vertices in specific selections.
- Parameters
value
: displacement in local spacemaskId
: Which selections to transform as a bitmask
-
void
TransformSelection
(MeshState *state, Vector3 translation, float scale, Quaternion rotation, Vector3 pivot, unsigned int maskId = -1)¶ Transform the selected vertices in place. Translate + Rotate + Scale in this order. Rotation is currently only around the origin of the mesh
- Parameters
maskId
: Which selections to transform
-
void
Harmonic
(MeshState *state, unsigned int boundaryMask = -1, bool showDeformationField = true)¶ Run the igl::harmonic biharmonic deformation on the mesh with provided fixed boundary conditions.
- Remark
From libigl Tutorial 401, https://libigl.github.io/tutorial/#biharmonic-deformation
- Parameters
boundaryMask
: Which selections to use as the boundaryshowDeformationField
: Whether to show the deformation field, see libigl tutorial
-
void
Arap
(MeshState *state, unsigned int boundaryMask = -1)¶ Run the igl::arap As-Rigid-As-Possible deformation on the mesh with the provided fixed boundary conditions.
- Remark
From libigl Tutorial 405, https://libigl.github.io/tutorial/#as-rigid-as-possible
- Parameters
boundaryMask
: Which selections to use as the boundary
-
void
ResetV
(MeshState *state)¶ Reset the vertices to their initial position V0 (set when loading the mesh).
-
void
SelectSphere
(MeshState *state, Vector3 position, float radius, int selectionId = 0, unsigned int selectionMode = SelectionMode::Add)¶ Modify the selection inside a sphere.
- Parameters
position
: Center of the sphere in local spaceradius
: Radius of the sphere in local spaceselectionId
: Which selection to modifyselectionMode
: How to change the selection, use SelectionMode constants.
-
unsigned int
GetSelectionMaskSphere
(MeshState *state, Vector3 position, float radius)¶ - Return
A mask of all selections partially inside the sphere (based on if a vertex is inside).
- Parameters
position
: Center of the sphere in local spaceradius
: Radius of the sphere in local space
-
Vector3
GetSelectionCenter
(MeshState *state, unsigned int maskId)¶ - Return
The mean vertex of the specified selections
-
void
ClearSelectionMask
(MeshState *state, unsigned int maskId = -1)¶ Resets a particular selections, can clear multiple selections at once.
- Parameters
maskId
: Which selections to clear as a bitmask
-
void
SetColorSingleByMask
(MeshState *state, unsigned int maskId = -1, int colorId = 0)¶ Naive SetColorByMask. Show all selections in the mask in the same color.
- Parameters
maskId
: Which selections to show in the colorcolorId
: Which color to use, see Color::GetColorById
Variables
-
IUnityInterfaces *
s_IUnityInterfaces
Access to the Unity interfaces, currently not used.
4.2.2. InterfaceTypes.h¶
This file includes all the types that are shared between C# and C++.
These are declared once in both languages and if one if modified the other must also be updated.
In C# this corresponds to the classes with the attribute [StructLayout(LayoutKind.Sequential)]
.
The MeshState
is also an interface type but has its own file.
Note
UNITY_INTERFACE_EXPORT
is a macro provided by Unity in external/Unity/IUnityInterface.h
,
which allows the function to be callable from C# (given it is within an extern "C"
clause)
-
struct
Vector3
¶ - #include <InterfaceTypes.h>
The Unity Vector3 with functonality for converting to/from Eigen::Vector3f (float).
-
struct
Quaternion
¶ - #include <InterfaceTypes.h>
The Unity Quaternion with functonality for converting to/from Eigen::Quaternionf (float).
Beware: Unity and Eigen have different conventions for ordering the values.
Public Functions
-
Quaternion
() = default¶
-
Quaternion
(float x, float y, float z, float w)¶
-
Quaternion
(Eigen::Quaternionf &q)¶
-
Eigen::Quaternionf
AsEigen
() const¶ - Warning
Eigen has a different ordering of the values, handled safely by this function. We cannot simply reinterpret the bits.
Public Static Functions
-
Quaternion
Identity
()¶
-
-
struct
DirtyFlag
¶ - #include <InterfaceTypes.h>
Marks which data has changed in
UMeshDataNative
as a bitmaskPublic Static Attributes
-
const unsigned int
None
= 0¶
-
const unsigned int
VDirty
= 1¶
-
const unsigned int
NDirty
= 2¶
-
const unsigned int
CDirty
= 4¶
-
const unsigned int
UVDirty
= 8¶
-
const unsigned int
FDirty
= 16¶
-
const unsigned int
DontComputeNormals
= 32¶ Don’t recaluclate normals when VDirty is set. NDirty overrides this.
-
const unsigned int
DontComputeBounds
= 64¶ Don’t recalculate bounds when VDirty is set. Bounds are used for occlusion culling.
-
const unsigned int
DontComputeColorsBySelection
= 128¶ Don’t recompute colors if a visible selection has changed.
-
const unsigned int
VDirtyExclBoundary
= 256¶ Use this when the vertex positions have changed, but the boundary conditions are unaffected. VDirty overrides this.
-
const unsigned int
All
= (unsigned int)-1 - DontComputeNormals - DontComputeBounds - DontComputeColorsBySelection¶
-
const unsigned int
-
struct
UMeshDataNative
¶ - #include <InterfaceTypes.h>
Stores all pointers to the MeshData arrays.
Usually this should be as a
const
parameter.
-
struct
SelectionMode
¶ - #include <InterfaceTypes.h>
Constants related to how a select operation modifies the current selection.
4.2.3. NativeCallbacks.h¶
Defines
-
STR
(message)¶ Macro to easily concatenate strings using stringstream, use the operator<<
STR("My value: " << 123)
-
LOG
(message)¶ Macro to easily and safely print to the Unity Debug.Log, disabled in release. Uses STR.
LOG("My value: " << 123)
-
LOGWARN
(message)¶ Call Unity Debug.LogWarning safely. Uses STR.
-
LOGERR
(message)¶ Call Unity Debug.LogError safely. Uses STR.
Typedefs
-
typedef void (*
StringCallback
)(const char *message)¶ Function pointer to a C# delegate:
void MyFct(string message)
- Note
C# delegates are
fixed
by default, so we do not have to worry about these pointers becoming invalid due to the Garbage Collector.
Variables
-
StringCallback
DebugLog
¶ Print to the Unity Debug.Log. Check that the function pointer is not null before using
if (DebugLog) DebugLog("Hello");
This is what the LOG macro does, use that instead.
- See
Callbacks like this are set in Initialize and reset to
nullptr
in UnityPluginUnload
-
StringCallback
DebugLogWarning
¶
-
StringCallback
DebugLogError
¶
4.2.4. Deform.h¶
This is where the deformations are as well as other functions which manipulate the vertices. This (the .cpp) is a good place to start for how to implement your own deformation.
Functions
-
bool
UpdateBoundary
(MeshState *state, unsigned int boundaryMask)¶ Recalculates the boundary
state->Native->Boundary
MeshStateNative.Boundary if the relevant selections have changed- Return
True if boundary has changed
- Parameters
boundaryMask
: The current mask of selections part of the boundary
-
bool
UpdateBoundaryConditions
(MeshState *state)¶ Recalculates the boundary conditions
state->Native->BoundaryConditions
MeshStateNative.BoundaryConditions for Harmonic and Arap- Return
True if the boundary conditions have changed
4.2.5. MeshState.h¶
This is the shared state between C++/C# and changes in one must be applied to the other. If the two structs do not match exactly problems arise with reading/writing to the wrong memory.
-
struct
MeshState
¶ - #include <MeshState.h>
Stores all data related to a specific mesh. Members are shared between native(C++) and managed(C#). Some members point to native only or managed only and are depicted as void*
Public Functions
-
MeshState
(UMeshDataNative udata)¶ Initialise the shared state from a Unity mesh
- Parameters
udata
: All data required to create the state
-
~MeshState
()¶ This is where all C++ allocated memory for a mesh is deleted.
Public Members
-
unsigned int
DirtyState
= {DirtyFlag::None}¶ Tells us what has changed with the mesh using the DirtyFlag constants
-
unsigned int
DirtySelections
= {0}¶ Tells us which selections have been modified, as a bitmask. Each bit represents one selection.
-
unsigned int
DirtySelectionsResized
= {0}¶ Less stricter version than DirtySelections, where we only consider a selection dirty if the selected vertices size changes, see SSizes.
-
Eigen::MatrixXf *
V
¶ The vertex matrix in column major with dimensions VSize x 3. Stores position for each vertex, one row represents one vertex.
-
Eigen::MatrixXf *
N
¶ The normals matrix in column major with dimensions VSize x 3. Stores the normal for each vertex.
-
Eigen::MatrixXf *
C
¶ The rgba color matrix in column major with dimensions VSize x 4. Stores the color for each vertex.
-
Eigen::MatrixXf *
UV
¶ The UV0 matrix in column major with dimensions VSize x 2. Stores the 2D uv coordinate for each vertex.
-
Eigen::MatrixXi *
F
¶ The Face/Indices matrix in column major with dimensions FSize x 3. Stores the vertex indices for each face/triangle, one row represents one face.
-
int
VSize
= {0}¶ Number of vertices, columns in V
-
int
FSize
= {0}¶ Number of faces, columns in F
-
Eigen::VectorXi *
S
¶ The selection vector, stores the selection state for each vertex. We store one uint per vertex. The selection is represented as a bitmask, with each bit indicating if the vertex is in that selection or not. So there are max 32 selections (32 bits)
-
unsigned int
SSize
= {1}¶ Amount of selections that are in use
-
unsigned int *
SSizes
¶ uint[32], number of vertices selected per selection. Stored as a pointer so we can easily share this with C#.
-
unsigned int
SSizesAll
= {0}¶ Total vertices selected
-
MeshStateNative *
Native
¶ Native only state, a void* in C#
-
4.2.6. MeshStateNative.h¶
This contains mesh specific data only used in C++, e.g. pre-calculations.
-
struct
MeshStateNative
¶ - #include <MeshStateNative.h>
Contains all variables that are only used in C++ for a specific mesh. We use one MeshStateNative per mesh.
Public Members
-
Eigen::VectorXi
Boundary
= {Eigen::VectorXi::Zero(0)}¶ Vertices part of the boundary. Has a variable length.
- Note
Evaluated in a lazy manner.
-
Eigen::MatrixXf
BoundaryConditions
= {Eigen::VectorXf::Zero(0)}¶ Positions of vertices in the Boundary (rows correspond). Has a variable length, the same as Boundary.
- Note
Evaluated in a lazy manner.
-
unsigned int
BoundaryMask
= {0}¶ The selections currently used for the Boundary.
- Note
Evaluated in a lazy manner.
-
unsigned int
DirtySelectionsForBoundary
= {0}¶ Selections that have changed since the last time the Boundary was calculated. Used for lazy recalculation of Boundary.
-
bool
DirtyBoundaryConditions
= {true}¶ Whether the boundary conditions have changed since the last time they were calculated. Used for lazy recalculation of BoundaryConditions.
-
Eigen::MatrixXf *
V0
¶ Initial V, before deformations. Used for deformations and resetting V
-
bool
harmonicShowDeformationField
= {false}¶ The harmonic deformation field value at the last recalculation
-
igl::ARAPData<float> *
ArapData
= {nullptr}¶ Pre-computations for Arap
-
Eigen::VectorXi
4.2.7. Util.h¶
Contains various helper functions, classes and constants.
Typedefs
-
using
Color_t
= Eigen::RowVector4f¶ RGBA color
Functions
-
template<typename
Matrix
, typenameScalar
>
voidTransposeToMap
(Matrix *from, Scalar *to)¶ Transpose an Eigen::Matrix to an Eigen::Map, given by the pointer to the first element Dimensions are inferred from the Matrix
- Template Parameters
Matrix
: An Eigen MatrixScalar
: Type on one element
- Parameters
to
: Pointer to the first element of a matrix or an array
-
template<typename
Scalar
, typenameMatrix
>
voidTransposeFromMap
(Scalar *from, Matrix *to)¶ Transpose an Eigen::Map to an Eigen::Matrix
- Template Parameters
Scalar
: Type on one elementMatrix
: An Eigen Matrix
- Parameters
from
: Pointer to the first element of a matrix or an array
-
template<typename
V_T
>
voidCenterToMean
(float *VPtr, int VSize)¶ Set the center/origin of the mesh to be the mean vertex
- Template Parameters
V_T
: Type of the vertex matrix to support both Col and RowMajor
-
template<typename
V_T
>
voidApplyScale
(float *VPtr, int VSize, bool centerToMean = true, bool normalize = true, float targetScale = 1.f)¶ Applies the scale of a mesh to the vertices, i.e. cwise multiply. If
targetScale
is set to zero, the model scale is normalized so it has unit height.- Note
y-axis center will be the center of the bounding box for easier positioning
- Parameters
centerToMean
: If true sets the center to the mean vertex.normalize
: If set to true the absolute y-height of the model will betargetScale
otherwise only the targetScale factor is applied.
- Template Parameters
V_T
: Type of the vertex matrix to support both Col and RowMajor
-
struct
Color
¶ - #include <Util.h>
Contains color constants
Public Static Functions