Commit 81bde409 authored by Yiting Shao's avatar Yiting Shao Committed by David Flynn
Browse files

slice/m44910: add longest-edge slice partitioning scheme

This partitioning method (--partitionMethod=2) finds the longest edge of
the point cloud and divides it into --partitionNumUniformGeom=n slices
along the longest edge.

If n = 0, the ratio of longest edge to shortest edge determines
the number of slices.
parent 693f8517
...@@ -124,9 +124,15 @@ attribute coding, as if they had never been configured. ...@@ -124,9 +124,15 @@ attribute coding, as if they had never been configured.
### `--partitionMethod=0` ### `--partitionMethod=0`
Selects the partitioning method to map points to tiles and slices: Selects the partitioning method to map points to tiles and slices:
| Value | Description | | Value | Description |
|:-----:| --------------------| |:-----:| ----------------------------------------|
| 0 | none (single slice) | | 0 | none (single slice) |
| 2 | uniform partitioning along longest edge |
### `--partitionNumUniformGeom=INT-VALUE`
Sets the number of slices to generate using `partitionMethod=2`.
If equal to zero, the number of slices is the integer ratio of the
longest to shortest edges of the point cloud bounding box.
Geometry coding Geometry coding
......
...@@ -118,6 +118,7 @@ file(GLOB PROJECT_CPP_FILES ...@@ -118,6 +118,7 @@ file(GLOB PROJECT_CPP_FILES
"io_hls.cpp" "io_hls.cpp"
"io_tlv.cpp" "io_tlv.cpp"
"osspecific.cpp" "osspecific.cpp"
"partitioning.cpp"
"pcc_chrono.cpp" "pcc_chrono.cpp"
"tables.cpp" "tables.cpp"
"../dependencies/arithmetic-coding/src/*.cpp" "../dependencies/arithmetic-coding/src/*.cpp"
......
...@@ -53,6 +53,9 @@ enum class PartitionMethod ...@@ -53,6 +53,9 @@ enum class PartitionMethod
{ {
// Don't partition input // Don't partition input
kNone = 0, kNone = 0,
// Partition according to uniform geometry
kUniformGeom = 2,
}; };
//============================================================================ //============================================================================
...@@ -73,6 +76,9 @@ struct EncoderParams { ...@@ -73,6 +76,9 @@ struct EncoderParams {
// Method for partitioning the input cloud // Method for partitioning the input cloud
PartitionMethod partitionMethod; PartitionMethod partitionMethod;
// Number of slices used by PartitionMethod::kUniformGeom
int partitionNumUniformGeom;
}; };
//============================================================================ //============================================================================
......
...@@ -168,6 +168,8 @@ operator<<(std::ostream& out, const PartitionMethod& val) ...@@ -168,6 +168,8 @@ operator<<(std::ostream& out, const PartitionMethod& val)
{ {
switch (val) { switch (val) {
case PartitionMethod::kNone: out << "0 (None)"; break; case PartitionMethod::kNone: out << "0 (None)"; break;
case PartitionMethod::kUniformGeom: out << "0 (UniformGeom)"; break;
default: out << int(val) << " (Unknown)"; break;
} }
return out; return out;
} }
...@@ -319,7 +321,15 @@ ParseParameters(int argc, char* argv[], Parameters& params) ...@@ -319,7 +321,15 @@ ParseParameters(int argc, char* argv[], Parameters& params)
("partitionMethod", ("partitionMethod",
params.encoder.partitionMethod, PartitionMethod::kNone, params.encoder.partitionMethod, PartitionMethod::kNone,
"Method used to partition input point cloud into slices/tiles:\n" "Method used to partition input point cloud into slices/tiles:\n"
" 0: none") " 0: none\n"
" 1: none (deprecated)\n"
" 2: n Uniform-Geometry partition bins along the longest edge")
("partitionNumUniformGeom",
params.encoder.partitionNumUniformGeom, 0,
"Number of bins for partitionMethod=2:\n"
" 0: slice partition with adaptive-defined bins\n"
" >=1: slice partition with user-defined bins\n")
("disableAttributeCoding", ("disableAttributeCoding",
params.disableAttributeCoding, false, params.disableAttributeCoding, false,
......
...@@ -122,6 +122,11 @@ PCCTMC3Encoder3::compress( ...@@ -122,6 +122,11 @@ PCCTMC3Encoder3::compress(
switch (params->partitionMethod) { switch (params->partitionMethod) {
// NB: this method is handled earlier // NB: this method is handled earlier
case PartitionMethod::kNone: return 1; case PartitionMethod::kNone: return 1;
case PartitionMethod::kUniformGeom:
partitions = partitionByUniformGeom(
quantizedInputCloud, params->partitionNumUniformGeom);
break;
} }
} while (0); } while (0);
......
/* The copyright in this software is being made available under the BSD
* Licence, included below. This software may be subject to other third
* party and contributor rights, including patent rights, and no such
* rights are granted under this licence.
*
* Copyright (c) 2017-2018, ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the ISO/IEC nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "partitioning.h"
#include <algorithm>
#include <cstdlib>
namespace pcc {
//============================================================================
template<typename T>
static int
longestAxis(const PCCBox3<T>& curBox)
{
int edgeAxis = 0;
for (int i = 1; i < 3; i++) {
T axisLength = curBox.max[i] - curBox.min[i];
T longestLength = curBox.max[edgeAxis] - curBox.min[edgeAxis];
if (axisLength > longestLength)
edgeAxis = i;
}
return edgeAxis;
}
//----------------------------------------------------------------------------
template<typename T>
static int
shortestAxis(const PCCBox3<T>& curBox)
{
int edgeAxis = 0;
for (int i = 1; i < 3; i++) {
T axisLength = curBox.max[i] - curBox.min[i];
T shortestLength = curBox.max[edgeAxis] - curBox.min[edgeAxis];
if (axisLength < shortestLength)
edgeAxis = i;
}
return edgeAxis;
}
//----------------------------------------------------------------------------
// Split point cloud into slices along the longest axis.
// numPartitions describes the number of slices to produce (if zero, the
// ratio of longest:shortest axis is used).
// No tile metadata is generated.
PartitionSet
partitionByUniformGeom(const PCCPointSet3& cloud, int numPartitions)
{
PartitionSet partitions;
PCCBox3D bbox = cloud.computeBoundingBox();
int maxEdgeAxis = longestAxis(bbox);
int maxEdge = bbox.max[maxEdgeAxis] - bbox.min[maxEdgeAxis];
int minEdgeAxis = shortestAxis(bbox);
int minEdge = bbox.max[minEdgeAxis] - bbox.min[minEdgeAxis];
int sliceNum;
int sliceSize;
if (!numPartitions) {
sliceNum = maxEdge / minEdge;
sliceSize = minEdge;
} else {
sliceNum = numPartitions;
sliceSize = maxEdge / sliceNum;
}
partitions.slices.resize(sliceNum);
for (int i = 0; i < sliceNum; i++) {
auto& slice = partitions.slices[i];
slice.sliceId = i;
slice.tileId = -1;
slice.origin = PCCVector3<int>{0};
}
for (int n = 0; n < cloud.getPointCount(); n++) {
for (int p = sliceNum - 1; p >= 0; p--) {
if (
cloud[n][maxEdgeAxis] >= int(p * sliceSize + bbox.min[maxEdgeAxis])) {
auto& slice = partitions.slices[p];
slice.pointIndexes.push_back(n);
break;
}
}
}
// Delete the slice that with no points
partitions.slices.erase(
std::remove_if(
partitions.slices.begin(), partitions.slices.end(),
[](const Partition& p) { return p.pointIndexes.empty(); }),
partitions.slices.end());
return partitions;
}
//============================================================================
} // namespace pcc
...@@ -72,4 +72,9 @@ struct PartitionSet { ...@@ -72,4 +72,9 @@ struct PartitionSet {
//============================================================================ //============================================================================
PartitionSet
partitionByUniformGeom(const PCCPointSet3& cloud, int numPartitions);
//============================================================================
} // namespace pcc } // namespace pcc
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