Voronoi 3D Manual

About

A Voronoi pattern segments the space into separate cells defined by a list of points. The maxon::Voronoi3DInterface allows to segment 3D space into such Voronoi cells.

Voronoi3DInterface

The maxon::Voronoi3DInterface allows to collect points and to create 3D Voronoi cells around these points.

The points stored in the Voronoi object are handled with:

The calculation of Voronoi cells is divided into two steps:

The created cells are accessed with:

Further functions are:

CellData

A maxon::CellData object represents a single Voronoi cell:

A given cell can be handled with:

Two cells can be merged with:

Further functions are:

An edge within a cell is defined as a maxon::CellEdge:

Example

// This example creates 3D Voronoi cells around the given points.
// The resulting geometry is copied to PolygonObjects.
// calculate size of the workspace which covers all points
MinMax mm;
for (maxon::Int i = 0; i != points.GetCount(); ++i)
{
mm.AddPoint(points[i]);
}
const maxon::Vector buffer(100.0, 100.0, 100.0);
workspace._minValue = mm.GetMin() - buffer;
workspace._maxValue = mm.GetMax() + buffer;
// create and init Voronoi3DRef
const maxon::Voronoi3DRef voronoi = maxon::Voronoi3DRef::Create() iferr_return;
voronoi.Init(workspace) iferr_return;
// add points
voronoi.AddPoints(points) iferr_return;
// calculate result
voronoi.CalcTetrahedralization() iferr_return;
voronoi.CalcCells() iferr_return;
// check success
const maxon::Bool voronoiNotReady = !voronoi.IsReady();
if (MAXON_UNLIKELY(voronoiNotReady))
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// get cell data
maxon::BaseArray<maxon::CellData>& curCellData = voronoi.GetCellDataStructure() iferr_return;
// random generator for object color
maxon::LinearCongruentialRandom<maxon::Float32> randomGen;
// for each cell create a PolygonObject
for (auto& cell : curCellData)
{
// check if the cell does not have "infinite" vertices in case of border cells
auto CheckCell = [workspace](const maxon::CellData& cellArg) -> maxon::Bool
{
const auto& vertices = cellArg.GetVertices();
for (const maxon::Vector& pos : vertices)
{
if (!workspace.Contains(pos))
return false;
}
return true;
};
// create PolygonObject for the given cells
if (CheckCell(cell))
{
const maxon::BaseArray<maxon::Vector>& vertices = cell.GetVertices();
const Int32 vertexCount = (Int32)vertices.GetCount();
// allocate PolygonObject
PolygonObject* const polygonObject = PolygonObject::Alloc(vertexCount, 0);
if (polygonObject != nullptr)
{
// prepare Modeling object to create ngons
if (modeling == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
modeling->InitObject(polygonObject);
// set points
for (maxon::Int32 i = 0; i < vertexCount; ++i)
{
modeling->SetPoint(polygonObject, i, vertices[i]);
}
// set ngons
const maxon::BaseArray<Int>& faces = cell.GetFaces();
const maxon::BaseArray<maxon::CellEdge>& edges = cell.GetEdges();
const maxon::Int faceCount = faces.GetCount();
// for each face create a ngon
for (maxon::Int i = 0; i < faceCount; ++i)
{
// set start edge
maxon::Int currentEdgeIndex = faces[i];
const maxon::Int startEdgeIndex = currentEdgeIndex;
// array to store the ngon's vertex indices
// loop over all edges of the ngon
do
{
// append first vertex index
const maxon::CellEdge& edge = edges[currentEdgeIndex];
ngonIndices.Append((Int32)edge._start) iferr_return;
// get next edge
currentEdgeIndex = edge._nextEdgeOfFace;
} while (startEdgeIndex != currentEdgeIndex);
// create ngon
const Int32 ngonIndexCount = (Int32)ngonIndices.GetCount();
if (ngonIndexCount > 0)
{
modeling->CreateNgon(polygonObject, ngonIndices.GetFirst(), ngonIndexCount, MODELING_SETNGON_FLAG_TRIANGULATE);
}
}
// finalize polygon object
modeling->Commit(polygonObject, MODELING_COMMIT_TRINGONS);
// create random color
auto GetRandomColor = [&randomGen]() -> maxon::Vector
{
color.x = (randomGen.Get01() * 0.5) + 0.5;
color.y = (randomGen.Get01() * 0.5) + 0.5;
color.z = (randomGen.Get01() * 0.5) + 0.5;
return color;
};
// set object color
polygonObject->SetParameter(ID_BASEOBJECT_COLOR, GetRandomColor(), DESCFLAGS_SET::NONE);
// insert object into the scene
doc->InsertObject(polygonObject, nullptr, nullptr);
}
}
}

Further Reading

LMinMax::GetMin
const Vector64 & GetMin(void) const
Definition: c4d_tools.h:569
Modeling::SetPoint
Bool SetPoint(C4DAtom *op, Int32 index, const Vector &p, Int32 flags=0)
Modeling::CreateNgon
Int32 CreateNgon(C4DAtom *op, Int32 *padr, Int32 cnt, Int32 flags=0)
maxon::CellEdge::_nextEdgeOfFace
Int _nextEdgeOfFace
Definition: celldata.h:33
maxon
The maxon namespace contains all declarations of the MAXON API.
Definition: c4d_basedocument.h:27
maxon::Range::Contains
Bool Contains(const T &value) const
Definition: range.h:234
maxon::CellEdge::_start
Int _start
Definition: celldata.h:31
MODELING_SETNGON_FLAG_TRIANGULATE
#define MODELING_SETNGON_FLAG_TRIANGULATE
Force the N-gon to be created as its polygons (similar to the MODELING_COMMIT_TRINGONS but for a sing...
Definition: lib_modeling.h:379
Float32
maxon::Float32 Float32
Definition: ge_sys_math.h:53
LMinMax::AddPoint
void AddPoint(const Vector64 &p)
Definition: c4d_tools.h:501
maxon::Bool
bool Bool
boolean type, possible values are only false/true, 8 bit
Definition: apibase.h:177
maxon::BaseArray::GetFirst
const MAXON_ATTRIBUTE_FORCE_INLINE T * GetFirst() const
Definition: basearray.h:1034
iferr_return
#define iferr_return
Definition: resultbase.h:1434
LMinMax
A class to construct a bounding box around points.
Definition: c4d_tools.h:468
MAXON_SOURCE_LOCATION
#define MAXON_SOURCE_LOCATION
Definition: memoryallocationbase.h:66
maxon::BaseArray
Definition: basearray.h:366
DESCFLAGS_SET::NONE
@ NONE
None.
maxon::CellEdge
Definition: celldata.h:15
maxon::Vec3::z
T z
Definition: vec.h:34
MAXON_UNLIKELY
#define MAXON_UNLIKELY(X)
Definition: compilerdetection.h:480
MODELING_COMMIT_TRINGONS
#define MODELING_COMMIT_TRINGONS
For example, an easy way to triangulate would be to just fetch the polygon selection into the kernel ...
Definition: lib_modeling.h:354
C4DAtom::SetParameter
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
maxon::BaseArray::GetCount
MAXON_ATTRIBUTE_FORCE_INLINE Int GetCount() const
Definition: basearray.h:527
maxon::BaseArray::Append
MAXON_ATTRIBUTE_FORCE_INLINE ResultRef< T > Append()
Definition: basearray.h:569
maxon::Vec3< Float, 1 >
maxon::CellData
CellData struct is a datacontainer that represents a single Voronoi Cell.
Definition: celldata.h:43
maxon::Int32
int32_t Int32
32 bit signed integer datatype.
Definition: apibase.h:172
maxon::Vec3::x
T x
Definition: vec.h:32
maxon::Int
Int64 Int
signed 32/64 bit int, size depends on the platform
Definition: apibase.h:184
PolygonObject::Alloc
static PolygonObject * Alloc(Int32 pcnt, Int32 vcnt)
ID_BASEOBJECT_USECOLOR
@ ID_BASEOBJECT_USECOLOR
Definition: obase.h:16
maxon::Vec3::y
T y
Definition: vec.h:33
LMinMax::GetMax
const Vector64 & GetMax(void) const
Definition: c4d_tools.h:582
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:45
Modeling::InitObject
Bool InitObject(C4DAtom *op, Int32 flags=0)
Modeling::Commit
Bool Commit(C4DAtom *op=nullptr, Int32 flags=0, BaseObject *cobj=nullptr)
maxon::Range::_minValue
T _minValue
The inclusive minimum boundary of this range.
Definition: range.h:256
PolygonObject
Definition: c4d_baseobject.h:1581
AutoAlloc
Definition: ge_autoptr.h:32
maxon::Range
Definition: range.h:25
maxon::Range::_maxValue
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
Bool
maxon::Bool Bool
Definition: ge_sys_math.h:40
ID_BASEOBJECT_COLOR
@ ID_BASEOBJECT_COLOR
Definition: obase.h:21
ID_BASEOBJECT_USECOLOR_ALWAYS
@ ID_BASEOBJECT_USECOLOR_ALWAYS
Definition: obase.h:19