Volume Tools Manual

Table of Contents

About

Volumes can be created and edited with specific commands and functions provided in the maxon::VolumeToolsInterface.

Commands

These commands can be used to handle volume data (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;
const maxon::Int dataIndex = 0;
context.SetLegacyData<maxon::VolumeCommandData>(data, dataIndex) iferr_return;
const auto command = maxon::CommandClasses::MESHTOVOLUME();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
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;
const maxon::Int dataIndex = 0;
// 1 equals BOOLTYPE::DIFF
context.SetLegacyData<maxon::VolumeCommandData>(data, dataIndex) iferr_return;
const auto command = maxon::CommandClasses::BOOLE();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
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;
const maxon::Int dataIndex = 0;
context.SetLegacyData<maxon::VolumeCommandData>(data, dataIndex) iferr_return;
const auto command = maxon::CommandClasses::VOLUMETOMESH();
const maxon::COMMANDRESULT res = context.Invoke(command, false) iferr_return;
return maxon::OK;
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);
Definition: c4d_baseobject.h:225
Definition: lib_volumeobject.h:41
static void Free(VolumeObject *&p)
Definition: lib_volumeobject.h:66
MAXON_ATTRIBUTE_FORCE_INLINE ResultRef< T > Append(ARG &&x)
Definition: basearray.h:677
PyObject PyObject * result
Definition: abstract.h:43
Py_UCS4 * res
Definition: unicodeobject.h:1113
Int64 Int
signed 32/64 bit int, size depends on the platform
Definition: apibase.h:188
#define MAXON_SCOPE
Definition: apibase.h:2841
return OK
Definition: apibase.h:2690
@ GRIDSIZE
Float Grid voxel cube size.
@ BOOLETYPE
Int32 The Boole type (union, difference, intersection).
COMMANDRESULT
Defines the result of the command after execution.
Definition: commandbase.h:35
@ OK
The command was executed properly.
void * context
Definition: pycapsule.h:49
const char * doc
Definition: pyerrors.h:226
#define iferr_return
Definition: resultbase.h:1519
Definition: volumecommands.h:20
BaseArray<::BaseObject * > * op
Definition: volumecommands.h:36

Tools

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

Load volumes from files:

See also maxon::VolumeInterface::CreateFromFile() (VolumeInterface Manual).

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::Volume>
{
// 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);
};
// convert polygon objects to volumes
const maxon::Volume volumeA = PolyToVolume(polyObjectA) iferr_return;
const maxon::Volume volumeB = PolyToVolume(polyObjectB) iferr_return;
// perform bool
const maxon::Volume resultVolume = maxon::VolumeToolsInterface::BoolVolumes(volumeA, volumeB, BOOLTYPE::DIFF) iferr_return;
// 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);
PyCompilerFlags * flags
Definition: ast.h:14
Definition: c4d_baseobject.h:1631
ResultMem Resize(Int newCnt, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::DEFAULT)
Definition: basearray.h:1369
Definition: resultbase.h:766
Definition: thread.h:46
static StrongRef< const ThreadInterface > GetCurrentThread()
Definition: thread.h:356
static MAXON_METHOD Result< PolygonObject * > VolumeToMesh(const Volume &volume, Float iso, Float adaptiveValue)
static MAXON_METHOD Result< Volume > MeshToVolume(const Block< Vector > &vertices, const Block< VolumeConversionPolygon > &polygons, Matrix polygonObjectMatrix, Float gridSize, Int32 bandWidthInterior, Int32 bandWidthExterior, const ThreadRef &checkForCancellation, POLYGONCONVERSIONFLAGS conversionSettings=POLYGONCONVERSIONFLAGS::NONE, const Matrix *creationTransform=nullptr)
static MAXON_METHOD Result< Volume > BoolVolumes(const Volume &volumeOne, const Volume &volumeTwo, BOOLTYPE type)
maxon::Int32 Int32
Definition: ge_sys_math.h:60
bool Bool
boolean type, possible values are only false/true, 8 bit
Definition: apibase.h:181
COLLECTION_RESIZE_FLAGS
Flags for Resize(). Depending on the type of collection the flags might be ignored (except for ON_GRO...
Definition: collection.h:126
@ ON_GROW_UNINITIALIZED
Do not initialize added elements (usually PODs) when resizing the array (is supported by all collecti...
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:67
The maxon namespace contains all declarations of the MAXON API.
Definition: autoweight.h:14
#define iferr_scope
Definition: resultbase.h:1384
Represents a polygon that can be either a triangle or a quadrangle.
Definition: c4d_baseobject.h:44
Definition: volumetools.h:154
// This example creates a vector volume from the given field object.
// prepare conversion
sampleData.doc = doc;
sampleData.fieldList = nullptr;
sampleData.fieldOwner = fieldObject;
sampleData.extraTransform = fieldObject->GetMg();
sampleBox.minValue = maxon::Vector { -100.0 };
sampleBox.maxValue = maxon::Vector { 100.0 };
const maxon::Float gridSize = 10.0;
// convert
const maxon::Volume volume = maxon::VolumeToolsInterface::ConvertFieldsToVectorVolume(sampleData, gridSize, sampleBox, thread, nullptr, nullptr) iferr_return;
// make volume object
VolumeObject* const volumeObject = VolumeObject::Alloc();
if (volumeObject == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
doc->InsertObject(volumeObject, nullptr, nullptr);
// store volume data
volumeObject->SetVolume(volume);
Definition: range.h:26
T maxValue
The inclusive maximum boundary of this range. If the minimum boundary is not less than or equal to th...
Definition: range.h:257
T minValue
The inclusive minimum boundary of this range.
Definition: range.h:256
static MAXON_METHOD Result< Volume > ConvertFieldsToVectorVolume(FieldSampleData &fieldData, Float gridSize, const Range< Vector > &sampleBox, const ThreadRef &checkForCancellation, const Volume *volumeReference=nullptr, const Matrix *creationTransform=nullptr)
Float64 Float
Definition: apibase.h:197
@ NONE
Default state.
Definition: volumetools.h:139
::BaseList2D * fieldOwner
Definition: volumetools.h:144
FIELDLAYER_FLAG flags
Definition: volumetools.h:142
::BaseDocument * doc
Definition: volumetools.h:145
Matrix extraTransform
Definition: volumetools.h:141
::FieldList * fieldList
Definition: volumetools.h:143

Further Reading