UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
OccupancyGrid3.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "DenseGrid3.h"
6#include "FastWinding.h"
7#include "MeshAABBTree3.h"
9#include "Algo/Count.h"
10
11namespace UE::Geometry
12{
13
20{
22 enum class EDomain : int32
23 {
24 Exterior,
25 Boundary,
27 };
28
29 template<typename MeshType>
31 const MeshType& InMesh,
33 )
34 {
35 // Compute a voxel grid
37 TFastWindingTree FastWinding(&Spatial);
38 const FAxisAlignedBox3d Bounds = Spatial.GetBoundingBox();
39 CellSize = float(Bounds.MaxDim() / InVoxelResolution);
40 CellMidPoint = {CellSize / 2.0f, CellSize / 2.0f, CellSize / 2.0f};
41
42 TMeshWindingNumberGrid WindingGrid(&InMesh, &FastWinding, CellSize);
43
44 WindingGrid.Compute();
45
46 // Our occupancy grid is computed on the winding number grid's cell centers.
47 const FVector3i WindingDims = WindingGrid.Dimensions();
48 Occupancy = {WindingDims.X - 1, WindingDims.Y - 1, WindingDims.Z - 1, EDomain::Exterior};
49
50 GridOrigin = WindingGrid.GridOrigin + CellMidPoint;
51
52 static constexpr FVector3i CornerOffsets[] = {
53 FVector3i(0, 0, 0),
54 FVector3i(0, 0, 1),
55 FVector3i(0, 1, 0),
56 FVector3i(0, 1, 1),
57 FVector3i(1, 0, 0),
58 FVector3i(1, 0, 1),
59 FVector3i(1, 1, 0),
60 FVector3i(1, 1, 1),
61 };
62
63 ParallelFor(Occupancy.Size(), [&](const int32 OccupancyId)
64 {
65 const FVector3i OccupancyIndex(Occupancy.ToIndex(OccupancyId));
66 const int32 Count = Algo::CountIf(CornerOffsets, [&WindingGrid, OccupancyIndex](FVector3i CornerOffset)
67 {
68 const FVector3i CornerIndex(OccupancyIndex + CornerOffset);
69 return WindingGrid.GetValue(CornerIndex) >= WindingGrid.WindingIsoValue;
70 });
71
72 if (Count == 8)
73 {
75 }
76 else if (Count > 0)
77 {
79 }
80 });
81
82 // Make sure we include all the vertices of the mesh as a part of the boundary, if
83 // the vertex areas are marked as being exterior.
84 for (int32 VertexIdx = 0; VertexIdx < InMesh.VertexCount(); VertexIdx++)
85 {
86 const FVector3d& Pos = InMesh.GetVertex(VertexIdx);
88
89 if (ensure(Occupancy.IsValidIndex(OccupancyIndex)))
90 {
91 if (Occupancy[OccupancyIndex] == EDomain::Exterior)
92 {
94 }
95 }
96 }
97 }
98
103 {
105 PP -= GridOrigin;
106
107 return { FMath::FloorToInt(PP.X / CellSize),
108 FMath::FloorToInt(PP.Y / CellSize),
109 FMath::FloorToInt(PP.Z / CellSize) };
110 }
111
115 {
116 return {float(Index.X) * CellSize + GridOrigin.X + CellMidPoint.X,
117 float(Index.Y) * CellSize + GridOrigin.Y + CellMidPoint.Y,
118 float(Index.Z) * CellSize + GridOrigin.Z + CellMidPoint.Z};
119 }
120
124 {
125 const FVector3f P = GetCellCenterFromIndex(Index);
126 return {P - CellMidPoint, P + CellMidPoint};
127 }
128
131 {
132 return Occupancy;
133 }
134
135 // Returns the size of the cell. The cell size is uniform on each axis.
136 float GetCellSize() const
137 {
138 return CellSize;
139 }
140
141private:
142 // The dense grid that contains the occupancy state of the mesh within each voxel.
143 TDenseGrid3<EDomain> Occupancy;
144
145 // The size of each cell, applies to all dimensions.
146 float CellSize;
147
148 // The origin of the occupancy grid. Since the occupancy of a cell is defined at the winding number grid's cell
149 // centers, this is offset by half the cell size, compared to the winding number grid's origin (same as the
150 // mesh's origin, which defined by the lowest coordinate value).
151 FVector3f GridOrigin;
152
153 // This value is the offset from the lowest coordinate of a winding number grid's cell's box, to its mid-point.
154 FVector3f CellMidPoint;
155};
156
157
158
159}
#define ensure( InExpression)
Definition AssertionMacros.h:464
void ParallelFor(int32 Num, TFunctionRef< void(int32)> Body, bool bForceSingleThread, bool bPumpRenderingThread=false)
Definition ParallelFor.h:481
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define FVector
Definition IOSSystemIncludes.h:8
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
Definition DenseGrid3.h:23
bool IsValidIndex(const FVector3i &Index) const
Definition DenseGrid3.h:50
int Size() const
Definition DenseGrid3.h:45
Definition FastWinding.h:316
Definition MeshAABBTree3.h:61
Definition MeshWindingNumberGrid.h:35
FVector3i Dimensions() const
Definition MeshWindingNumberGrid.h:117
FVector3f GridOrigin
Definition MeshWindingNumberGrid.h:67
void Compute()
Definition MeshWindingNumberGrid.h:80
Definition ParametricSurfaceData.h:18
U16 Index
Definition radfft.cpp:71
Definition OccupancyGrid3.h:20
FBox3f GetCellBoxFromIndex(const FVector3i &Index) const
Definition OccupancyGrid3.h:123
EDomain
An enum representing a voxel's classification.
Definition OccupancyGrid3.h:23
@ Boundary
The point in the occupancy grid is completely on the exterior of the given mesh.
@ Interior
The point in the occupancy grid includes a mesh boundary.
const TDenseGrid3< EDomain > & GetOccupancyStateGrid() const
Returns a reference to the occupancy grid.
Definition OccupancyGrid3.h:130
FOccupancyGrid3(const MeshType &InMesh, const int32 InVoxelResolution)
Definition OccupancyGrid3.h:30
float GetCellSize() const
Definition OccupancyGrid3.h:136
FVector3i GetCellIndexFromPoint(const FVector &InPoint) const
Definition OccupancyGrid3.h:102
FVector3f GetCellCenterFromIndex(const FVector3i &Index) const
Definition OccupancyGrid3.h:114
Definition IntVectorTypes.h:252
RealType MaxDim() const
Definition BoxTypes.h:598