Skip to content

Commit

Permalink
add pipeline_impl
Browse files Browse the repository at this point in the history
  • Loading branch information
chambbj committed Oct 14, 2014
1 parent 385e5a3 commit d4d1522
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 89 deletions.
2 changes: 1 addition & 1 deletion include/pdal/filters/PCLBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class PDAL_DLL PCLBlock : public Filter
{}

private:
std::string m_filename;
std::string m_json;
bool m_isFilename;

virtual void processOptions(const Options& options);
virtual void ready(PointContext ctx) {};
Expand Down
25 changes: 25 additions & 0 deletions include/pdal/pclsupport/pipeline_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <memory>
#include <pdal/Log.hpp>
#include <pdal/PointBuffer.hpp>

namespace pdal
{
namespace pclsupport
{

class Pipeline
{
public:
Pipeline(pdal::PointBuffer& input, std::string const json, bool isFilename, pdal::LogPtr log);
~Pipeline();
void filter(pdal::PointBuffer& output);

private:
class PipelineImpl;
std::unique_ptr<PipelineImpl> m_pipeline_pimpl;
};

} //namespace pclsupport
} //namespace pdal
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -762,11 +762,13 @@ set(PDAL_PCLSUPPORT_HPP
${PDAL_PCLSUPPORT_HEADERS}/PCLPipeline.h
${PDAL_PCLSUPPORT_HEADERS}/impl/PCLPipeline.hpp
${PDAL_PCLSUPPORT_HEADERS}/voxel_grid.h
${PDAL_PCLSUPPORT_HEADERS}/pipeline_impl.h
)

set(PDAL_PCLSUPPORT_CPP
${PDAL_PCLSUPPORT_SRC}/PCLPipeline.cpp
${PDAL_PCLSUPPORT_SRC}/voxel_grid.cpp
${PDAL_PCLSUPPORT_SRC}/pipeline_impl.cpp
)

list(APPEND PDAL_HPP ${PDAL_PCLSUPPORT_HPP})
Expand Down
93 changes: 7 additions & 86 deletions src/filters/PCLBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,9 @@
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/pclsupport/PCLConversions.hpp>
#include <pdal/PointBuffer.hpp>
#include <pdal/filters/PCLBlock.hpp>

#ifdef PDAL_HAVE_PCL
#include <pdal/pclsupport/impl/PCLPipeline.hpp>
#include <pcl/console/print.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#endif
#include <pdal/pclsupport/pipeline_impl.h>

namespace pdal
{
Expand All @@ -51,93 +45,20 @@ namespace filters

void PCLBlock::processOptions(const Options& options)
{
m_filename = options.getValueOrDefault<std::string>("filename", "");
m_json = options.getValueOrDefault<std::string>("json", "");
m_isFilename = options.getValueOrDefault<bool>("isFilename", true);
}


PointBufferSet PCLBlock::run(PointBufferPtr input)
{
PointBufferPtr output = input->makeNew();
PointBufferSet pbSet;
pbSet.insert(output);

#ifdef PDAL_HAVE_PCL
bool logOutput = log()->getLevel() > LogLevel::Debug1;
if (logOutput)
log()->floatPrecision(8);

log()->get(LogLevel::Debug2) << input->getFieldAs<double>(Dimension::Id::X, 0) << ", " <<
input->getFieldAs<double>(Dimension::Id::Y, 0) << ", " <<
input->getFieldAs<double>(Dimension::Id::Z, 0) << std::endl;
log()->get(LogLevel::Debug2) << "Process PCLBlock..." << std::endl;

BOX3D const& buffer_bounds = input->calculateBounds();

// convert PointBuffer to PointNormal
typedef pcl::PointCloud<pcl::PointNormal> Cloud;
Cloud::Ptr cloud(new Cloud);
pclsupport::PDALtoPCD(*input, *cloud, buffer_bounds);

log()->get(LogLevel::Debug2) << cloud->points[0].x << ", " <<
cloud->points[0].y << ", " << cloud->points[0].z << std::endl;

int level = log()->getLevel();
switch (level)
{
case 0:
pcl::console::setVerbosityLevel(pcl::console::L_ALWAYS);
break;
case 1:
pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
break;
case 2:
pcl::console::setVerbosityLevel(pcl::console::L_WARN);
break;
case 3:
pcl::console::setVerbosityLevel(pcl::console::L_INFO);
break;
case 4:
pcl::console::setVerbosityLevel(pcl::console::L_DEBUG);
break;
default:
pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE);
break;
}

pcl::Pipeline<pcl::PointNormal> pipeline;
pipeline.setInputCloud(cloud);
if (!m_filename.empty())
pipeline.setFilename(m_filename);
else if (!m_json.empty())
pipeline.setJSON(m_json);
else
throw pdal_error("No PCL pipeline specified!");
// PDALtoPCD subtracts min values in each XYZ dimension to prevent rounding
// errors in conversion to float. These offsets need to be conveyed to the
// pipeline to offset any bounds entered as part of a PassThrough filter.
pipeline.setOffsets(buffer_bounds.minx, buffer_bounds.miny, buffer_bounds.minz);

// create PointCloud for results
Cloud::Ptr cloud_f(new Cloud);
pipeline.filter(*cloud_f);

if (cloud_f->points.empty())
{
log()->get(LogLevel::Debug2) << "Filtered cloud has no points!" << std::endl;
return pbSet;
}

pclsupport::PCDtoPDAL(*cloud_f, *output, buffer_bounds);
PointBufferPtr output = input->makeNew();

log()->get(LogLevel::Debug2) << cloud->points.size() << " before, " <<
cloud_f->points.size() << " after" << std::endl;
log()->get(LogLevel::Debug2) << output->size() << std::endl;
log()->get(LogLevel::Debug2) << output->getFieldAs<double>(Dimension::Id::X, 0) << ", " <<
output->getFieldAs<double>(Dimension::Id::Y, 0) << ", " <<
output->getFieldAs<double>(Dimension::Id::Z, 0) << std::endl;
#endif
pclsupport::Pipeline pipeline(*input, m_json, m_isFilename, log());
pipeline.filter(*output);

pbSet.insert(output);
return pbSet;
}

Expand Down
1 change: 1 addition & 0 deletions src/kernel/Ground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ int Ground::execute()
ss << "}";
std::string json = ss.str();
groundOptions.add<std::string>("json", json);
groundOptions.add<bool>("isFilename", false);
groundOptions.add<bool>("debug", isDebug());
groundOptions.add<boost::uint32_t>("verbose", getVerboseLevel());

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/PCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ int PCL::execute()
bufferReader.addBuffer(input_buffer);

Options pclOptions;
pclOptions.add<std::string>("filename", m_pclFile);
pclOptions.add<std::string>("json", m_pclFile);
pclOptions.add<bool>("debug", isDebug());
pclOptions.add<boost::uint32_t>("verbose", getVerboseLevel());

Expand Down
151 changes: 151 additions & 0 deletions src/pclsupport/pipeline_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <pdal/pclsupport/pipeline_impl.h>

#include <pdal/Bounds.hpp>
#include <pdal/Log.hpp>
#include <pdal/PointBuffer.hpp>

#ifdef PDAL_HAVE_PCL
#ifdef PDAL_COMPILER_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wfloat-equal"
#endif
#include <pdal/pclsupport/PCLConversions.hpp>
#include <pdal/pclsupport/impl/PCLPipeline.hpp>
#include <pcl/console/print.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#ifdef PDAL_COMPILER_CLANG
# pragma clang diagnostic pop
#endif
#endif

namespace pdal
{
namespace pclsupport
{

class Pipeline::PipelineImpl
{
public:
PipelineImpl(pdal::PointBuffer& input, std::string const json, bool isFilename, pdal::LogPtr log) : m_input(input), m_json(json), m_isFilename(isFilename), m_log(log) {}

void filter(pdal::PointBuffer& output)
{
#ifdef PDAL_HAVE_PCL
bool logOutput = m_log->getLevel() > LogLevel::Debug1;
if (logOutput)
m_log->floatPrecision(8);

//m_log->get(LogLevel::Debug2) << m_input.getFieldAs<double>(Dimension::Id::X, 0) << ", " <<
// m_input.getFieldAs<double>(Dimension::Id::Y, 0) << ", " <<
// m_input.getFieldAs<double>(Dimension::Id::Z, 0) << std::endl;
m_log->get(LogLevel::Debug2) << "Process PCLBlock..." << std::endl;

BOX3D const& buffer_bounds = m_input.calculateBounds();

// convert PointBuffer to PointNormal
typedef pcl::PointCloud<pcl::PointNormal> Cloud;
Cloud::Ptr cloud(new Cloud);
pclsupport::PDALtoPCD(m_input, *cloud, buffer_bounds);

//m_log->get(LogLevel::Debug2) << cloud->points[0].x << ", " <<
// cloud->points[0].y << ", " << cloud->points[0].z << std::endl;

int level = m_log->getLevel();
switch (level)
{
case 0:
pcl::console::setVerbosityLevel(pcl::console::L_ALWAYS);
break;
case 1:
pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
break;
case 2:
pcl::console::setVerbosityLevel(pcl::console::L_WARN);
break;
case 3:
pcl::console::setVerbosityLevel(pcl::console::L_INFO);
break;
case 4:
pcl::console::setVerbosityLevel(pcl::console::L_DEBUG);
break;
default:
pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE);
break;
}

pcl::Pipeline<pcl::PointNormal> pipeline;
pipeline.setInputCloud(cloud);
if (m_isFilename)
pipeline.setFilename(m_json);
else
pipeline.setJSON(m_json);
// PDALtoPCD subtracts min values in each XYZ dimension to prevent rounding
// errors in conversion to float. These offsets need to be conveyed to the
// pipeline to offset any bounds entered as part of a PassThrough filter.
pipeline.setOffsets(buffer_bounds.minx, buffer_bounds.miny, buffer_bounds.minz);

// create PointCloud for results
Cloud::Ptr cloud_f(new Cloud);
pipeline.filter(*cloud_f);

if (cloud_f->points.empty())
{
m_log->get(LogLevel::Debug2) << "Filtered cloud has no points!" << std::endl;
return;
}

pclsupport::PCDtoPDAL(*cloud_f, output, buffer_bounds);

m_log->get(LogLevel::Debug2) << cloud->points.size() << " before, " <<
cloud_f->points.size() << " after" << std::endl;
//m_log->get(LogLevel::Debug2) << output.size() << std::endl;
//m_log->get(LogLevel::Debug2) << output.getFieldAs<double>(Dimension::Id::X, 0) << ", " <<
// output.getFieldAs<double>(Dimension::Id::Y, 0) << ", " <<
// output.getFieldAs<double>(Dimension::Id::Z, 0) << std::endl;
#endif

/*
#ifdef PDAL_HAVE_PCL
pdal::BOX3D const& buffer_bounds = m_input.calculateBounds();
// create PCL cloud objects
typedef pcl::PointCloud<pcl::PointNormal> Cloud;
Cloud::Ptr cloud(new Cloud);
Cloud::Ptr cloud_f(new Cloud);
// convert PointBuffer to PointCloud
pdal::pclsupport::PDALtoPCD(m_input, *cloud, buffer_bounds);
// apply the voxel grid
pcl::Pipeline<pcl::PointNormal> vg;
vg.setInputCloud(cloud);
vg.setLeafSize(m_leaf_size,m_leaf_size,m_leaf_size);
vg.filter(*cloud_f);
// and convert PointCloud back to PointBuffer
pdal::pclsupport::PCDtoPDAL(*cloud_f, output, buffer_bounds);
#else
throw pdal_error("Pipeline requested without PCL support");
#endif
*/
}

private:
pdal::PointBuffer& m_input;
std::string m_json;
bool m_isFilename;
pdal::LogPtr m_log;
};

Pipeline::Pipeline(pdal::PointBuffer& input, std::string const json, bool isFilename, pdal::LogPtr log) : m_pipeline_pimpl(new PipelineImpl(input, json, isFilename, log)) {}

Pipeline::~Pipeline() {}

void Pipeline::filter(pdal::PointBuffer& output)
{
m_pipeline_pimpl->filter(output);
}

} //namespace pclsupport
} //namespace pdal
2 changes: 1 addition & 1 deletion test/unit/filters/PCLBlockFilterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void test_filter(const std::string& jsonFile,
drivers::las::Reader reader;
reader.setOptions(options);

Option fname("filename", Support::datapath(jsonFile));
Option fname("json", Support::datapath(jsonFile));
Options filter_options;
filter_options.add(fname);

Expand Down

0 comments on commit d4d1522

Please sign in to comment.