Volume Tools Manual

Table of Contents

About

Volumes can be created and edited with specific commands and maxon::VolumeToolsInterface.

Commands

maxon::InvokeCommand() can be used with these commands (see Commands Manual):

The maxon::VolumeCommandData structure has these members:

// This example performs multiple commands to turn the
// given polygon objects into volumes, to perform a
// boolean operation on these volumes and to create
// a polygon hull for the result volume.
VolumeObject* volumeObjectA = nullptr;
VolumeObject* volumeObjectB = nullptr;
VolumeObject* resultVolume = nullptr;
{
// make volume objects
maxon::LegacyCommandDataRef context = maxon::LegacyCommandDataClasses::VOLUMEDATA().Create() iferr_return;
sourceObjects.Append(polyObjectA) iferr_return;
sourceObjects.Append(polyObjectB) iferr_return;
data.op = &sourceObjects;
context.SetLegacyData<maxon::VolumeCommandData>(data) iferr_return;
const auto command = maxon::CommandClasses::MESHTOVOLUME();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
const maxon::VolumeCommandData& result = context.GetLegacyData<maxon::VolumeCommandData>() iferr_return;
if (result.result.GetCount() == 2)
{
volumeObjectA = static_cast<VolumeObject*>(result.result[0]);
volumeObjectB = static_cast<VolumeObject*>(result.result[1]);
}
}
{
// perform bool operation
maxon::LegacyCommandDataRef context = maxon::LegacyCommandDataClasses::VOLUMEDATA().Create() iferr_return;
sourceObjects.Append(volumeObjectA) iferr_return;
sourceObjects.Append(volumeObjectB) iferr_return;
data.op = &sourceObjects;
// 1 equals BOOLTYPE::DIFF
context.SetLegacyData<maxon::VolumeCommandData>(data) iferr_return;
const auto command = maxon::CommandClasses::BOOLE();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
const maxon::VolumeCommandData& result = context.GetLegacyData<maxon::VolumeCommandData>() iferr_return;
if (result.result.GetCount() == 1)
{
resultVolume = static_cast<VolumeObject*>(result.result[0]);
}
}
{
// create mesh
maxon::LegacyCommandDataRef context = maxon::LegacyCommandDataClasses::VOLUMEDATA().Create() iferr_return;
sourceObjects.Append(resultVolume) iferr_return;
data.op = &sourceObjects;
context.SetLegacyData<maxon::VolumeCommandData>(data) iferr_return;
const auto command = maxon::CommandClasses::VOLUMETOMESH();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
const maxon::VolumeCommandData& result = context.GetLegacyData<maxon::VolumeCommandData>() iferr_return;
if (result.result.GetCount() == 1)
{
BaseObject* const object = result.result[0];
doc->InsertObject(object, nullptr, nullptr);
}
}
// free data
VolumeObject::Free(resultVolume);
VolumeObject::Free(volumeObjectA);
VolumeObject::Free(volumeObjectB);

Tools

The maxon::VolumeToolsInterface provides multiple functions to handle volumes.

Load volumes from files:

Volume operations:

Volume creation:

Volume conversion:

// This example uses multiple tools to turn the
// given polygon objects into volumes, to perform a
// boolean operation on these volumes and to create
// a polygon hull for the result volume.
// lambda funtion to convert the given PolygonObject to a VolumeRef
auto PolyToVolume = [](PolygonObject* const poly) -> maxon::Result<maxon::VolumeRef>
{
// check polygon object data
const Vector* const points = poly->GetPointR();
const CPolygon* const polys = poly->GetPolygonR();
const maxon::Bool noPoints = points == nullptr;
const maxon::Bool noPolys = polys == nullptr;
if (noPoints || noPolys)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// get polygon object data
const Int32 pointCount = poly->GetPointCount();
const Int32 polyCount = poly->GetPolygonCount();
const Matrix objectMatrix = poly->GetMg();
// point array
volPoints.Resize(pointCount, flags) iferr_return;
// copy point data
for (Int32 pointIndex = 0; pointIndex < pointCount; ++pointIndex)
volPoints[pointIndex] = objectMatrix * points[pointIndex];
// polygon array
volPolys.Resize(polyCount, flags) iferr_return;
// copy polygon data
for (Int32 polyIndex = 0; polyIndex < polyCount; polyIndex++)
{
volPolys[polyIndex] = *reinterpret_cast<const maxon::VolumeConversionPolygon*>(&polys[polyIndex]);
if (polys[polyIndex].IsTriangle())
volPolys[polyIndex].SetTriangle();
}
const maxon::ThreadInterface* const thread = maxon::ThreadRef::GetCurrentThread().GetPointer();
if (thread == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
const maxon::ThreadRef threadRef = const_cast<maxon::ThreadInterface*>(thread);
return maxon::VolumeToolsInterface::MeshToVolume(volPoints, volPolys, objectMatrix, 10.0, 10, 10, threadRef);
};
maxon::VolumeRef volumeA;
maxon::VolumeRef volumeB;
maxon::VolumeRef resultVolume;
// convert polygon objects to volumes
volumeA = PolyToVolume(polyObjectA) iferr_return;
volumeB = PolyToVolume(polyObjectB) iferr_return;
// perform bool
// result to mesh
PolygonObject* const mesh = maxon::VolumeToolsInterface::VolumeToMesh(resultVolume, 10.0, 10.0) iferr_return;
if (mesh == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
doc->InsertObject(mesh, nullptr, nullptr);

Further Reading