Commit 4f17624e authored by Sebastien Lasserre's avatar Sebastien Lasserre Committed by David Flynn
Browse files

geom/m48905: permit more than one duplicate point in IDCM nodes

This adoption permits IDCM nodes to signal either:
 - two unique points, or
 - a single position with an arbitrary number of duplicates
parent 2c74c097
......@@ -165,6 +165,7 @@ public:
template<class OutputIt>
int decodeDirectPosition(
bool geom_unique_points_flag,
const Vec3<int>& nodeSizeLog2,
const PCCOctree3Node& node,
OutputIt outputPoints);
......@@ -179,9 +180,10 @@ private:
StaticBitModel _ctxEquiProb;
AdaptiveBitModel _ctxSingleChild;
AdaptiveBitModel _ctxSinglePointPerBlock;
AdaptiveBitModel _ctxSingleIdcmDupPoint;
AdaptiveBitModel _ctxPointCountPerBlock;
AdaptiveBitModel _ctxBlockSkipTh;
AdaptiveBitModel _ctxNumIdcmPointsEq1;
AdaptiveBitModel _ctxNumIdcmPointsGt1;
AdaptiveBitModel _ctxQpOffsetIsZero;
AdaptiveBitModel _ctxQpOffsetSign;
AdaptiveBitModel _ctxQpOffsetAbsEgl;
......@@ -850,6 +852,7 @@ GeometryOctreeDecoder::decodeQpOffset()
template<class OutputIt>
int
GeometryOctreeDecoder::decodeDirectPosition(
bool geom_unique_points_flag,
const Vec3<int>& nodeSizeLog2,
const PCCOctree3Node& node,
OutputIt outputPoints)
......@@ -860,14 +863,31 @@ GeometryOctreeDecoder::decodeDirectPosition(
}
int numPoints = 1;
if (_arithmeticDecoder->decode(_ctxNumIdcmPointsEq1))
numPoints++;
bool numPointsGt1 = _arithmeticDecoder->decode(_ctxNumIdcmPointsGt1);
numPoints += numPointsGt1;
int numDuplicatePoints = 0;
if (!geom_unique_points_flag && !numPointsGt1) {
numDuplicatePoints = !_arithmeticDecoder->decode(_ctxSinglePointPerBlock);
if (numDuplicatePoints) {
bool singleDup = _arithmeticDecoder->decode(_ctxSingleIdcmDupPoint);
if (!singleDup)
numDuplicatePoints += 1
+ _arithmeticDecoder->decodeExpGolomb(
0, _ctxEquiProb, _ctxPointCountPerBlock);
}
}
Vec3<uint32_t> pos;
for (int i = 0; i < numPoints; i++)
*(outputPoints++) =
*(outputPoints++) = pos =
decodePointPosition(nodeSizeLog2, node.planarMode, node.planePosBits);
return numPoints;
// todo(df): currently the output buffer holds two points ...
for (int i = 0; i < std::min(1, numDuplicatePoints); i++)
*(outputPoints++) = pos;
return numPoints + numDuplicatePoints;
}
//-------------------------------------------------------------------------
......@@ -1228,10 +1248,10 @@ decodeGeometryOctree(
idcmEnabled, effectiveNodeMaxDimLog2, node0, child)) {
// todo(df): this should go away when output is integer
Vec3<uint32_t> points[2]{};
int numPoints =
decoder.decodeDirectPosition(effectiveChildSizeLog2, child, points);
int numPoints = decoder.decodeDirectPosition(
gps.geom_unique_points_flag, effectiveChildSizeLog2, child, points);
for (int j = 0; j < numPoints; j++) {
for (int j = 0; j < std::min(2, numPoints); j++) {
auto& point = points[j];
for (int k = 0; k < 3; k++) {
int shift = std::max(0, effectiveChildSizeLog2[k]);
......@@ -1243,6 +1263,11 @@ decodeGeometryOctree(
Vec3<double>(point[0], point[1], point[2]);
}
// todo(df): remove this when removing points array
for (int j = 2; j < numPoints; j++)
pointCloud[processedPointCount++] =
Vec3<double>(points[1][0], points[1][1], points[1][2]);
if (numPoints > 0) {
// node fully decoded, do not split: discard child
fifo.pop_back();
......
......@@ -175,6 +175,7 @@ public:
void encodeQpOffset(int dqp);
bool encodeDirectPosition(
bool geom_unique_points_flag,
const Vec3<int>& nodeSizeLog2,
int shiftBits,
const PCCOctree3Node& node,
......@@ -190,9 +191,10 @@ private:
StaticBitModel _ctxEquiProb;
AdaptiveBitModel _ctxSingleChild;
AdaptiveBitModel _ctxSinglePointPerBlock;
AdaptiveBitModel _ctxSingleIdcmDupPoint;
AdaptiveBitModel _ctxPointCountPerBlock;
AdaptiveBitModel _ctxBlockSkipTh;
AdaptiveBitModel _ctxNumIdcmPointsEq1;
AdaptiveBitModel _ctxNumIdcmPointsGt1;
AdaptiveBitModel _ctxSameZ;
AdaptiveBitModel _ctxQpOffsetIsZero;
......@@ -939,21 +941,48 @@ checkDuplicatePoints(
bool
GeometryOctreeEncoder::encodeDirectPosition(
bool geom_unique_points_flag,
const Vec3<int>& nodeSizeLog2,
int shiftBits,
const PCCOctree3Node& node,
const PCCPointSet3& pointCloud)
{
int numPoints = node.end - node.start;
if (numPoints > MAX_NUM_DM_LEAF_POINTS) {
// Check for duplicated points only if there are less than 10.
// NB: this limit is rather arbitrary
if (numPoints > 10) {
_arithmeticEncoder->encode(0, _ctxBlockSkipTh);
return false;
}
_arithmeticEncoder->encode(1, _ctxBlockSkipTh);
_arithmeticEncoder->encode(numPoints > 1, _ctxNumIdcmPointsEq1);
bool allPointsAreEqual = numPoints > 1 && !geom_unique_points_flag;
for (auto idx = node.start + 1; allPointsAreEqual && idx < node.end; idx++) {
allPointsAreEqual &= pointCloud[node.start] == pointCloud[idx];
}
if (!allPointsAreEqual) {
if (numPoints > MAX_NUM_DM_LEAF_POINTS) {
_arithmeticEncoder->encode(0, _ctxBlockSkipTh);
return false;
}
_arithmeticEncoder->encode(1, _ctxBlockSkipTh);
_arithmeticEncoder->encode(numPoints > 1, _ctxNumIdcmPointsGt1);
if (!geom_unique_points_flag && numPoints == 1)
_arithmeticEncoder->encode(numPoints == 1, _ctxSinglePointPerBlock);
} else {
_arithmeticEncoder->encode(1, _ctxBlockSkipTh);
_arithmeticEncoder->encode(0, _ctxNumIdcmPointsGt1);
_arithmeticEncoder->encode(0, _ctxSinglePointPerBlock);
_arithmeticEncoder->encode(numPoints == 2, _ctxSingleIdcmDupPoint);
if (numPoints > 2)
_arithmeticEncoder->encodeExpGolomb(
numPoints - 3, 0, _ctxEquiProb, _ctxPointCountPerBlock);
// only one actual psoition to code
numPoints = 1;
}
for (auto idx = node.start; idx < node.end; idx++) {
for (auto idx = node.start; idx < node.start + numPoints; idx++)
encodePointPosition(
nodeSizeLog2,
Vec3<uint32_t>{uint32_t(pointCloud[idx][0]),
......@@ -961,7 +990,6 @@ GeometryOctreeEncoder::encodeDirectPosition(
uint32_t(pointCloud[idx][2])}
>> shiftBits,
node.planarMode);
}
return true;
}
......@@ -1351,7 +1379,8 @@ encodeGeometryOctree(
if (isDirectModeEligible(
idcmEnabled, effectiveNodeMaxDimLog2, node0, child)) {
bool directModeUsed = encoder.encodeDirectPosition(
effectiveChildSizeLog2, shiftBits, child, pointCloud);
gps.geom_unique_points_flag, effectiveChildSizeLog2, shiftBits,
child, pointCloud);
if (directModeUsed) {
// inverse quantise any quantised positions
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment