Commit 29ab50ed authored by Vladyslav Zakharchenko's avatar Vladyslav Zakharchenko Committed by David Flynn
Browse files

attr/m44940: add binary tree based level-of-detail generator

This uses a binary-tree to generate the levels-of-details for the
lifting/predicting transforms as an alternative to Euclidean distance
thresholding methods.
parent 81b3c8b8
...@@ -32,6 +32,10 @@ categories: ...@@ -32,6 +32,10 @@ categories:
- levelOfDetailCount: ${seq_lod} - levelOfDetailCount: ${seq_lod}
- positionQuantizationScaleAdjustsDist2: 1 - positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2} - dist2: ${seq_dist2}
- lodBinaryTree: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
## ##
# attribute coding -- reflectance # attribute coding -- reflectance
......
...@@ -41,6 +41,10 @@ categories: ...@@ -41,6 +41,10 @@ categories:
- levelOfDetailCount: ${seq_lod} - levelOfDetailCount: ${seq_lod}
- positionQuantizationScaleAdjustsDist2: 1 - positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2} - dist2: ${seq_dist2}
- lodBinaryTree: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
## ##
# attribute coding -- reflectance # attribute coding -- reflectance
......
...@@ -32,6 +32,10 @@ categories: ...@@ -32,6 +32,10 @@ categories:
- transformType: 2 - transformType: 2
- numberOfNearestNeighborsInPrediction: 3 - numberOfNearestNeighborsInPrediction: 3
- levelOfDetailCount: ${seq_lod} - levelOfDetailCount: ${seq_lod}
- lodBinaryTree: 0
-
- !conditional '"${group}" =~ m{^cat3}'
- lodBinaryTree: 1
- positionQuantizationScaleAdjustsDist2: 1 - positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2} - dist2: ${seq_dist2}
......
...@@ -236,6 +236,14 @@ attribute prediction. ...@@ -236,6 +236,14 @@ attribute prediction.
### `--levelOfDetailCount=INT-VALUE` ### `--levelOfDetailCount=INT-VALUE`
Attribute's number of levels of detail. Attribute's number of levels of detail.
### `--lodBinaryTree=0|1`
Controls the level-of-detail generation method:
| Value | Description |
|:-----:| ------------------------------- |
| 0 | Binary-tree based |
| 1 | Euclidean distance thresholding |
### `--quantizationStepLuma=INT-VALUE` ### `--quantizationStepLuma=INT-VALUE`
Attribute's luma quantization step size. Attribute's luma quantization step size.
......
...@@ -238,16 +238,25 @@ AttributeDecoder::decodeReflectancesPred( ...@@ -238,16 +238,25 @@ AttributeDecoder::decodeReflectancesPred(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
if (aps.num_detail_levels <= 1) {
buildPredictorsFastNoLod( if (!aps.lod_binary_tree_enabled_flag) {
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range, if (aps.num_detail_levels <= 1) {
predictors, indexesLOD); buildPredictorsFastNoLod(
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range,
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
}
} else { } else {
buildPredictorsFast( buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.dist2, aps.num_detail_levels, computePredictors(
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, pointCloud, numberOfPointsPerLOD, indexesLOD,
predictors, numberOfPointsPerLOD, indexesLOD); aps.num_pred_nearest_neighbours, predictors);
} }
const int64_t maxReflectance = (1ll << desc.attr_bitdepth) - 1; const int64_t maxReflectance = (1ll << desc.attr_bitdepth) - 1;
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
...@@ -316,16 +325,25 @@ AttributeDecoder::decodeColorsPred( ...@@ -316,16 +325,25 @@ AttributeDecoder::decodeColorsPred(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
if (aps.num_detail_levels <= 1) {
buildPredictorsFastNoLod( if (!aps.lod_binary_tree_enabled_flag) {
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range, if (aps.num_detail_levels <= 1) {
predictors, indexesLOD); buildPredictorsFastNoLod(
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range,
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
}
} else { } else {
buildPredictorsFast( buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.dist2, aps.num_detail_levels, computePredictors(
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, pointCloud, numberOfPointsPerLOD, indexesLOD,
predictors, numberOfPointsPerLOD, indexesLOD); aps.num_pred_nearest_neighbours, predictors);
} }
uint32_t values[3]; uint32_t values[3];
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
...@@ -510,10 +528,19 @@ AttributeDecoder::decodeColorsLift( ...@@ -510,10 +528,19 @@ AttributeDecoder::decodeColorsLift(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels, if (!aps.lod_binary_tree_enabled_flag) {
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, buildPredictorsFast(
predictors, numberOfPointsPerLOD, indexesLOD); pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
pointCloud, numberOfPointsPerLOD, indexesLOD,
aps.num_pred_nearest_neighbours, predictors);
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
predictors[predictorIndex].computeWeights(); predictors[predictorIndex].computeWeights();
...@@ -573,10 +600,19 @@ AttributeDecoder::decodeReflectancesLift( ...@@ -573,10 +600,19 @@ AttributeDecoder::decodeReflectancesLift(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels, if (!aps.lod_binary_tree_enabled_flag) {
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, buildPredictorsFast(
predictors, numberOfPointsPerLOD, indexesLOD); pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
pointCloud, numberOfPointsPerLOD, indexesLOD,
aps.num_pred_nearest_neighbours, predictors);
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
predictors[predictorIndex].computeWeights(); predictors[predictorIndex].computeWeights();
......
...@@ -429,16 +429,25 @@ AttributeEncoder::encodeReflectancesPred( ...@@ -429,16 +429,25 @@ AttributeEncoder::encodeReflectancesPred(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
if (aps.num_detail_levels <= 1) {
buildPredictorsFastNoLod( if (!aps.lod_binary_tree_enabled_flag) {
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range, if (aps.num_detail_levels <= 1) {
predictors, indexesLOD); buildPredictorsFastNoLod(
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range,
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
}
} else { } else {
buildPredictorsFast( buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.dist2, aps.num_detail_levels, computePredictors(
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, pointCloud, numberOfPointsPerLOD, indexesLOD,
predictors, numberOfPointsPerLOD, indexesLOD); aps.num_pred_nearest_neighbours, predictors);
} }
const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1; const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1;
PCCResidualsEntropyEstimator context; PCCResidualsEntropyEstimator context;
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
...@@ -577,16 +586,25 @@ AttributeEncoder::encodeColorsPred( ...@@ -577,16 +586,25 @@ AttributeEncoder::encodeColorsPred(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
if (aps.num_detail_levels <= 1) {
buildPredictorsFastNoLod( if (!aps.lod_binary_tree_enabled_flag) {
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range, if (aps.num_detail_levels <= 1) {
predictors, indexesLOD); buildPredictorsFastNoLod(
pointCloud, aps.num_pred_nearest_neighbours, aps.search_range,
predictors, indexesLOD);
} else {
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
}
} else { } else {
buildPredictorsFast( buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
pointCloud, aps.dist2, aps.num_detail_levels, computePredictors(
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, pointCloud, numberOfPointsPerLOD, indexesLOD,
predictors, numberOfPointsPerLOD, indexesLOD); aps.num_pred_nearest_neighbours, predictors);
} }
const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1; const int64_t clipMax = (1ll << desc.attr_bitdepth) - 1;
uint32_t values[3]; uint32_t values[3];
PCCResidualsEntropyEstimator context; PCCResidualsEntropyEstimator context;
...@@ -821,10 +839,19 @@ AttributeEncoder::encodeColorsLift( ...@@ -821,10 +839,19 @@ AttributeEncoder::encodeColorsLift(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels, if (!aps.lod_binary_tree_enabled_flag) {
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, buildPredictorsFast(
predictors, numberOfPointsPerLOD, indexesLOD); pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
pointCloud, numberOfPointsPerLOD, indexesLOD,
aps.num_pred_nearest_neighbours, predictors);
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
predictors[predictorIndex].computeWeights(); predictors[predictorIndex].computeWeights();
...@@ -906,10 +933,19 @@ AttributeEncoder::encodeReflectancesLift( ...@@ -906,10 +933,19 @@ AttributeEncoder::encodeReflectancesLift(
std::vector<PCCPredictor> predictors; std::vector<PCCPredictor> predictors;
std::vector<uint32_t> numberOfPointsPerLOD; std::vector<uint32_t> numberOfPointsPerLOD;
std::vector<uint32_t> indexesLOD; std::vector<uint32_t> indexesLOD;
buildPredictorsFast(
pointCloud, aps.dist2, aps.num_detail_levels, if (!aps.lod_binary_tree_enabled_flag) {
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range, buildPredictorsFast(
predictors, numberOfPointsPerLOD, indexesLOD); pointCloud, aps.dist2, aps.num_detail_levels,
aps.num_pred_nearest_neighbours, aps.search_range, aps.search_range,
predictors, numberOfPointsPerLOD, indexesLOD);
} else {
buildLevelOfDetailBinaryTree(pointCloud, numberOfPointsPerLOD, indexesLOD);
computePredictors(
pointCloud, numberOfPointsPerLOD, indexesLOD,
aps.num_pred_nearest_neighbours, predictors);
}
for (size_t predictorIndex = 0; predictorIndex < pointCount; for (size_t predictorIndex = 0; predictorIndex < pointCount;
++predictorIndex) { ++predictorIndex) {
predictors[predictorIndex].computeWeights(); predictors[predictorIndex].computeWeights();
......
...@@ -470,5 +470,244 @@ private: ...@@ -470,5 +470,244 @@ private:
std::vector<PCCIncrementalKdTree3Node> nodes; std::vector<PCCIncrementalKdTree3Node> nodes;
uint32_t root; uint32_t root;
}; };
//---------------------------------------
class PCCKdTree3 {
struct PCCKdTree3Node {
PCCBox3D BB;
PCCPoint3D centd;
uint32_t id;
uint32_t start;
uint32_t end;
PCCAxis3 axis;
uint32_t median;
uint32_t medianIdx;
};
struct PointIDNode {
PCCPoint3D pos;
uint32_t id;
bool isVisisted;
};
public:
PCCKdTree3(const PCCPointSet3& pointCloud, uint8_t depth)
{
init(pointCloud, depth);
}
PCCKdTree3(const PCCKdTree3&) = default;
PCCKdTree3& operator=(const PCCKdTree3&) = default;
~PCCKdTree3(void) = default;
std::vector<PCCKdTree3Node> nodes;
void build()
{
uint32_t nodeCount =
(1 << (kdDepth + 1)) - 1; // std::pow(2, kdDepth + 1) - 1
for (size_t nodeIt = 1; nodeIt < nodeCount; nodeIt++) {
bool isLeftNode = (nodeIt & 1) != 0;
uint32_t parentNodeIdx =
isLeftNode ? (nodeIt - 1) >> 1 : (nodeIt - 2) >> 1;
const uint32_t start = isLeftNode
? static_cast<uint32_t>(nodes[parentNodeIdx].start)
: static_cast<uint32_t>(nodes[parentNodeIdx].medianIdx + 1);
const uint32_t end = isLeftNode
? static_cast<uint32_t>(nodes[parentNodeIdx].medianIdx)
: static_cast<uint32_t>(nodes[parentNodeIdx].end);
PCCBox3D BB = nodes[parentNodeIdx].BB;
isLeftNode
? BB.max[nodes[parentNodeIdx].axis] = nodes[parentNodeIdx].median
: BB.min[nodes[parentNodeIdx].axis] = nodes[parentNodeIdx].median;
PCCPoint3D nodeMean = computePCCMean(start, end);
PCCAxis3 axis = computeSplitAxisVar(start, end, nodeMean);
uint32_t medianIdx = findMedian(start, end, axis);
PCCKdTree3Node& node = nodes[nodeIt];
node.BB = BB;
node.centd = nodeMean;
node.id = nodeIt;
node.start = start;
node.end = end;
node.axis = axis;
node.median = pointCloudTemp[medianIdx].pos[axis];
node.medianIdx = medianIdx;
}
}
void init(const PCCPointSet3& pointCloud, uint8_t depth)
{
kdDepth = depth;
nodes.resize(0);
nodes.resize(std::pow(2, kdDepth + 1) - 1);
uint32_t pointCount = pointCloud.getPointCount();
pointCloudTemp.resize(pointCount);
for (size_t i = 0; i < pointCount; i++) {
pointCloudTemp[i].pos = pointCloud[i];
pointCloudTemp[i].id = i;
pointCloudTemp[i].isVisisted = false;
}
PCCBox3D BB = computeBoundingBox(0, pointCount);
PCCPoint3D nodeMean = computePCCMean(0, pointCount);
PCCAxis3 axis = computeSplitAxisVar(0, pointCount, nodeMean);
uint32_t medianIdx = findMedian(0, pointCount, axis);
PCCKdTree3Node& rootNode = nodes[0];
rootNode.BB = BB;
rootNode.centd = nodeMean;
rootNode.id = 0;
rootNode.start = static_cast<uint32_t>(0);
rootNode.end = static_cast<uint32_t>(pointCount - 1);
;
rootNode.axis = axis;
rootNode.median = pointCloudTemp[medianIdx].pos[axis];
rootNode.medianIdx = medianIdx;
}
uint32_t searchClosestAvailablePoint(PCCPoint3D queryPoint)
{
uint32_t idToClosestPoint = -1;
uint32_t id = 0;
for (int8_t d = 0; d < kdDepth; d++) {
id = (queryPoint[nodes[id].axis] <= nodes[id].median) ? 2 * id + 1
: 2 * id + 2;
}
const uint32_t start = nodes[id].start;
const uint32_t end = nodes[id].end;
const uint32_t closestDistThr = 1;
uint32_t smallestDist = -1;
uint32_t closestID = 0;
for (size_t i = start; i <= end; ++i) {
if (!pointCloudTemp[i].isVisisted) {
PCCPoint3D diff = pointCloudTemp[i].pos - queryPoint;
uint32_t dist =
std::sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]);
if (dist <= closestDistThr) {
return pointCloudTemp[i].id;
}
if (dist < smallestDist) {
smallestDist = dist;
idToClosestPoint = pointCloudTemp[i].id;
closestID = i;
}
}
}
if (smallestDist != -1) {
pointCloudTemp[closestID].isVisisted = true;
}
return idToClosestPoint;
}
private:
PCCBox3D computeBoundingBox(const uint32_t start, const uint32_t end) const
{
PCCPoint3D minBB = pointCloudTemp[start].pos;
PCCPoint3D maxBB = pointCloudTemp[start].pos;
for (size_t i = start + 1; i < end; ++i) {
const PCCPoint3D& pt = pointCloudTemp[i].pos;
for (int32_t k = 0; k < 3; ++k) {
if (minBB[k] > pt[k]) {
minBB[k] = pt[k];
} else if (maxBB[k] < pt[k]) {
maxBB[k] = pt[k];
}
}
}
PCCBox3D BB;
{
BB.min = minBB;
BB.max = maxBB;
}
return BB;
}
PCCAxis3 computeSplitAxis(const uint32_t start, const uint32_t end) const
{
PCCBox3D BB = computeBoundingBox(start, end);
PCCPoint3D d = BB.max - BB.min;
if (d.x() > d.y() && d.x() > d.z()) {
return PCC_AXIS3_X;
} else if (d.y() > d.z()) {
return PCC_AXIS3_Y;
} else {
return PCC_AXIS3_Z;
}
}
PCCAxis3 computeSplitAxisVar(
const uint32_t start, const uint32_t end, PCCPoint3D nodeMean) const
{
double nodeVar[3] = {0, 0, 0};
for (size_t axis = 0; axis < 3; ++axis) {
double acc = 0, diff = 0;
for (size_t i = start; i < end; i++) {
diff = pointCloudTemp[i].pos[axis] - nodeMean[axis];
acc += diff * diff;
}
nodeVar[axis] = acc / (end - start);
}
if (nodeVar[0] > nodeVar[1] && nodeVar[0] > nodeVar[2]) {
return PCC_AXIS3_X;
} else if (nodeVar[1] > nodeVar[2]) {
return PCC_AXIS3_Y;
} else {
return PCC_AXIS3_Z;
}
}
PCCPoint3D computePCCMean(const uint32_t start, const uint32_t end)
{
assert(end >= start);
PCCPoint3D nodeMean;
for (size_t axis = 0; axis < 3; ++axis) {
uint32_t acc = 0;
for (size_t i = start; i < end; i++) {
acc += pointCloudTemp[i].pos[axis];
}
nodeMean[axis] = round(acc / (end - start));
}
return nodeMean;
}
uint32_t findMedian(uint32_t start, uint32_t end, const PCCAxis3 splitAxis)
{
assert(start < end);
if (end == start + 1) {
return start;
}
const uint32_t medianIndex = start + (end - start) / 2;
while (1) {
double pivot = pointCloudTemp[medianIndex].pos[splitAxis];
std::swap(pointCloudTemp[medianIndex], pointCloudTemp[end - 1]);
uint32_t store, p;
for (store = p = start; p < end; p++) {
if (pointCloudTemp[p].pos[splitAxis] < pivot) {
if (p != store) {
std::swap(pointCloudTemp[p], pointCloudTemp[store]);
}
++store;
}
}
std::swap(pointCloudTemp[store], pointCloudTemp[end - 1]);
while (store < medianIndex
&& pointCloudTemp[store].pos[splitAxis]
== pointCloudTemp[store + 1].pos[splitAxis]) {
// optimization in case of duplicated values
++store;
}
if (store == medianIndex) {
return medianIndex;
} else if (store > medianIndex) {
end = store;
} else {
start = store + 1;
}
}
}
private:
std::vector<PointIDNode> pointCloudTemp;
uint8_t kdDepth;
};
//---------------------------------------
} // namespace pcc } // namespace pcc
#endif /* PCCKdTree_h */ #endif /* PCCKdTree_h */
...@@ -584,7 +584,150 @@ updatePredictors( ...@@ -584,7 +584,150 @@ updatePredictors(
} }
//---------------------------------------------------------------------------