Skip to content

Commit

Permalink
Add Delaunay filter (issue #1855) (#1916)
Browse files Browse the repository at this point in the history
* Fix documentation of greedyprojection and gridprojection to use PLY writer

* Basic scaffolding for new filter

* Correct use of PointView

* Added Geogram PSM, currently crashes when run

* 2D Delaunay working

* Add docs for Delaunay filter

* Add license text

* Add NULL check on mesh

* Remove debugging output

* Add Delaunay filter in stage doc overview

* Fix indentation
  • Loading branch information
plimkilde authored and hobu committed Apr 10, 2018
1 parent e9353e6 commit 49baa20
Show file tree
Hide file tree
Showing 9 changed files with 31,479 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmake/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ option(BUILD_PLUGIN_CPD
add_feature_info("CPD plugin" BUILD_PLUGIN_CPD
"Coherent Point Drift (CPD) computes rigid or nonrigid transformations between point sets")

option(BUILD_PLUGIN_DELAUNAY
"Choose if the Delaunay triangulation filter should be built" FALSE)
add_feature_info("Delaunay plugin" BUILD_PLUGIN_DELAUNAY
"perform Delaunay triangulation of point cloud")

option(BUILD_PLUGIN_GEOWAVE
"Choose if GeoWave support should be built" FALSE)
add_feature_info("GeoWave plugin" BUILD_PLUGIN_GEOWAVE
Expand Down
36 changes: 36 additions & 0 deletions doc/stages/filters.delaunay.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.. _filters.delaunay:

filters.delaunay
================

The Delaunay filter creates a triangulated mesh fulfilling the Delaunay
condition from a collection of points.

The filter is implemented using the `Geogram`_ library by Bruno Lévy,
specifically its Delaunay PSM (pluggable software module, a library standalone
autogenerated from the Geogram source tree).

The filter currently only supports 2D Delaunay triangulation, using the x and y
dimensions of the point cloud.

.. _Geogram: http://alice.loria.fr/software/geogram/doc/html/index.html

.. embed::

Example
-------

.. code-block:: json
{
"pipeline": [
"input.las",
{
"type": "filters.delaunay"
},
{
"type": "writers.ply",
"filename": "output.ply",
"faces": true
}
}
4 changes: 4 additions & 0 deletions doc/stages/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,15 @@ existing KD-tree.
:glob:
:hidden:

filters.delaunay
filters.greedyprojection
filters.gridprojection
filters.movingleastsquares
filters.poisson

:ref:`filters.delaunay`
Create mesh using Delaunay triangulation.

:ref:`filters.greedyprojection`
Create mesh using the Greedy Projection Triangulation approach.

Expand Down
4 changes: 4 additions & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ if(BUILD_PLUGIN_CPD)
add_subdirectory(cpd)
endif(BUILD_PLUGIN_CPD)

if(BUILD_PLUGIN_DELAUNAY)
add_subdirectory(delaunay)
endif(BUILD_PLUGIN_DELAUNAY)

if(BUILD_PLUGIN_GEOWAVE)
add_subdirectory(geowave)
endif(BUILD_PLUGIN_GEOWAVE)
Expand Down
11 changes: 11 additions & 0 deletions plugins/delaunay/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#
# Delaunay plugin CMake configuration
#

#include(${PDAL_CMAKE_DIR}/geogram.cmake)

PDAL_ADD_PLUGIN(filter_libname filter delaunay
FILES
filters/DelaunayFilter.cpp
filters/Delaunay_psm.cpp
)
102 changes: 102 additions & 0 deletions plugins/delaunay/filters/DelaunayFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/******************************************************************************
* Copyright (c) 2018, Danish Agency for Data Supply and Efficiency,
* sdfe@sdfe.dk
*
* 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 SDFE 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 OWNER 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 <cstddef> // NULL
#include "DelaunayFilter.hpp"
#include "Delaunay_psm.h"

namespace pdal
{

static PluginInfo const s_info
{
"filters.delaunay",
"Perform Delaunay triangulation of a pointcloud",
"http://pdal.io/stages/filters.delaunay.html"
};

CREATE_SHARED_STAGE(DelaunayFilter, s_info)

std::string DelaunayFilter::getName() const
{
return s_info.name;
}

PointViewSet DelaunayFilter::run(PointViewPtr pointView)
{
// Returns NULL if the mesh already exists
TriangularMesh *mesh = pointView->createMesh("delaunay2d");

if (mesh != NULL)
{
std::vector<double> delaunayPoints;
for (PointId i = 0; i < pointView->size(); i++)
{
PointRef point(*pointView, i);
double x(point.getFieldAs<double>(Dimension::Id::X));
double y(point.getFieldAs<double>(Dimension::Id::Y));

delaunayPoints.push_back(x);
delaunayPoints.push_back(y);
}

GEO::initialize();

GEO::index_t numDimensions = 2;

// Pick the 2D Delaunay algorithm
GEO::Delaunay_var triangulation = GEO::Delaunay::create(GEO::coord_index_t(numDimensions), "BDEL2d");
GEO::index_t numPoints = delaunayPoints.size() / numDimensions;

// Actually perform the triangulation
triangulation->set_vertices(numPoints, delaunayPoints.data());


for (GEO::index_t i = 0; i < triangulation->nb_cells(); i++)
{
GEO::index_t v_0 = triangulation->cell_vertex(i, 0);
GEO::index_t v_1 = triangulation->cell_vertex(i, 1);
GEO::index_t v_2 = triangulation->cell_vertex(i, 2);

mesh->add((int)v_0, (int)v_1, (int)v_2);
}
}

PointViewSet viewSet;
viewSet.insert(pointView);

return viewSet;
}

} // namespace pdal
56 changes: 56 additions & 0 deletions plugins/delaunay/filters/DelaunayFilter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/******************************************************************************
* Copyright (c) 2018, Danish Agency for Data Supply and Efficiency,
* sdfe@sdfe.dk
*
* 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 SDFE 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 OWNER 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.
****************************************************************************/

#pragma once

#include <pdal/Filter.hpp>

namespace pdal
{

class PDAL_DLL DelaunayFilter : public Filter
{
public:
DelaunayFilter() : Filter()
{}
std::string getName() const;

private:
virtual PointViewSet run(PointViewPtr view);

DelaunayFilter& operator=(const DelaunayFilter&); // not implemented
DelaunayFilter(const DelaunayFilter&); // not implemented
};

} // namespace pdal
Loading

0 comments on commit 49baa20

Please sign in to comment.