Commit 9f898950 authored by David Flynn's avatar David Flynn
Browse files

ply: perform inverse scaling during ply writing

This commit moves the non-normative inverse position scaling process
from the codec's reconstruction process into the ply writer.  This
is to support changing the internal point cloud position representation
to integer.
parent ee064ec9
......@@ -90,11 +90,6 @@ private:
//==========================================================================
public:
void inverseQuantization(PCCPointSet3& pointCloud);
//==========================================================================
private:
// Decoder specific parameters
DecoderParams _params;
......
......@@ -1126,7 +1126,10 @@ SequenceEncoder::compressOneFrame(Stopwatch* clock)
std::string recName{expandNum(params->reconstructedDataPath, frameNum)};
ply::write(
*reconPointCloud, _plyAttrNames, recName, !params->outputBinaryPly);
*reconPointCloud, _plyAttrNames,
1.0 / params->encoder.sps.seq_source_geom_scale_factor,
params->encoder.sps.seq_bounding_box_xyz0, recName,
!params->outputBinaryPly);
}
return 0;
......@@ -1153,13 +1156,21 @@ SequenceEncoder::onPostRecolour(const PCCPointSet3& cloud)
// todo(df): stop the clock
if (!params->convertColourspace) {
ply::write(cloud, _plyAttrNames, plyName, !params->outputBinaryPly);
ply::write(
cloud, _plyAttrNames,
1.0 / params->encoder.sps.seq_source_geom_scale_factor,
params->encoder.sps.seq_bounding_box_xyz0, plyName,
!params->outputBinaryPly);
return;
}
PCCPointSet3 tmpCloud(cloud);
convertToGbr(params->encoder.sps, tmpCloud);
ply::write(tmpCloud, _plyAttrNames, plyName, !params->outputBinaryPly);
ply::write(
tmpCloud, _plyAttrNames,
1.0 / params->encoder.sps.seq_source_geom_scale_factor,
params->encoder.sps.seq_bounding_box_xyz0, plyName,
!params->outputBinaryPly);
}
//============================================================================
......@@ -1239,16 +1250,18 @@ SequenceDecoder::onOutputCloud(
if (!params->preInvScalePath.empty()) {
std::string filename{expandNum(params->preInvScalePath, frameNum)};
ply::write(
pointCloud, attrNames, params->preInvScalePath,
pointCloud, attrNames,
1.0 / params->encoder.sps.seq_source_geom_scale_factor,
params->encoder.sps.seq_bounding_box_xyz0, params->preInvScalePath,
!params->outputBinaryPly);
}
decoder.inverseQuantization(pointCloud);
clock->stop();
std::string decName{expandNum(params->reconstructedDataPath, frameNum)};
if (!ply::write(pointCloud, attrNames, decName, !params->outputBinaryPly)) {
if (!ply::write(
pointCloud, attrNames, 1.0 / sps.seq_source_geom_scale_factor,
sps.seq_bounding_box_xyz0, decName, !params->outputBinaryPly)) {
cout << "Error: can't open output file!" << endl;
}
......
......@@ -308,22 +308,6 @@ PCCTMC3Decoder3::decodeAttributeBrick(const PayloadBuffer& buf)
std::cout << std::endl;
}
//==========================================================================
void
PCCTMC3Decoder3::inverseQuantization(PCCPointSet3& pointCloud)
{
const size_t pointCount = pointCloud.getPointCount();
const double invScale = 1.0 / _sps->seq_source_geom_scale_factor;
for (size_t i = 0; i < pointCount; ++i) {
auto& point = pointCloud[i];
for (size_t k = 0; k < 3; ++k) {
point[k] = point[k] * invScale + _sps->seq_bounding_box_xyz0[k];
}
}
}
//============================================================================
} // namespace pcc
......@@ -513,18 +513,9 @@ PCCTMC3Encoder3::appendReconstructedPoints(PCCPointSet3* reconstructedCloud)
pointCloud.hasColors(), pointCloud.hasReflectances());
reconstructedCloud->resize(outIdx + pointCount);
const double minPositionQuantizationScale = 0.0000000001;
const double invScale =
fabs(_sps->seq_source_geom_scale_factor) > minPositionQuantizationScale
? 1.0 / _sps->seq_source_geom_scale_factor
: 1.0;
for (size_t i = 0; i < pointCount; ++i, ++outIdx) {
const auto quantizedPoint = pointCloud[i];
auto& point = (*reconstructedCloud)[outIdx];
for (size_t k = 0; k < 3; ++k) {
point[k] = (quantizedPoint[k] + _sliceOrigin[k]) * invScale
+ _sps->seq_bounding_box_xyz0[k];
}
(*reconstructedCloud)[outIdx] = pointCloud[i] + _sliceOrigin;
if (pointCloud.hasColors()) {
reconstructedCloud->setColor(outIdx, pointCloud.getColor(i));
}
......
......@@ -89,6 +89,8 @@ bool
ply::write(
const PCCPointSet3& cloud,
const PropertyNameMap& attributeNames,
double positionScale,
Vec3<int32_t> positionOffset,
const std::string& fileName,
bool asAscii)
{
......@@ -139,7 +141,7 @@ ply::write(
// fout << std::setprecision(std::numeric_limits<double>::max_digits10);
fout << std::fixed << std::setprecision(5);
for (size_t i = 0; i < pointCount; ++i) {
const Vec3<double>& position = cloud[i];
Vec3<double> position = cloud[i] * positionScale + positionOffset;
fout << position.x() << " " << position.y() << " " << position.z();
if (cloud.hasColors()) {
const Vec3<attr_t>& color = cloud.getColor(i);
......@@ -160,7 +162,7 @@ ply::write(
fout.close();
fout.open(fileName, std::ofstream::binary | std::ofstream::app);
for (size_t i = 0; i < pointCount; ++i) {
const Vec3<double>& position = cloud[i];
Vec3<double> position = cloud[i] * positionScale + positionOffset;
fout.write(
reinterpret_cast<const char* const>(&position), sizeof(double) * 3);
if (cloud.hasColors()) {
......
......@@ -55,11 +55,25 @@ namespace ply {
//============================================================================
///
// Write @a pointCloud to a PLY file called @a fileName.
// Each point position, pt, is converted prior to writing by:
// pt' = pt * positionScale + offset
//
// @param pointCloud points to be written.
// @param propertyNames Describes ply property names of pointcloud attributes.
// @param positionScale scale factor for positions.
// @param positionOffset offset for positions (after scaling).
// @param fileName output filename.
// @param asAscii PLY writing format (true => ascii, false => binary).
bool write(
const PCCPointSet3& cloud,
const PCCPointSet3& pointCloud,
const PropertyNameMap& propertyNames,
double positionScale,
Vec3<int32_t> positionOffset,
const std::string& fileName,
bool asAscii);
bool read(
const std::string& fileName,
const PropertyNameMap& propertyNames,
......
......@@ -273,7 +273,7 @@ runMerge(const Options& opts)
}
string outName{expandNum(opts.outPath, outFrameNum)};
if (!ply::write(outCloud, propNames, outName, !opts.outputBinaryPly))
if (!ply::write(outCloud, propNames, 1, 0, outName, !opts.outputBinaryPly))
throw runtime_error("failed to write output file: " + outName);
cout << outName << endl;
}
......@@ -341,7 +341,8 @@ runSplit(const Options& opts)
string outName{expandNum(opts.outPath, outFrameNum)};
if (outCloud.getPointCount() > 0)
if (!ply::write(outCloud, propNames, outName, !opts.outputBinaryPly))
if (!ply::write(
outCloud, propNames, 1, 0, outName, !opts.outputBinaryPly))
throw runtime_error("failed to write output file: " + outName);
cout << outName << endl;
......
Supports Markdown
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