From 73088aba011022c542fd810969557520032ba0b9 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Tue, 7 Jul 2020 11:29:25 -0400 Subject: [PATCH] Upgraded PDAL to 2.1, removed odm_filterpoints module Former-commit-id: 653d276b205d8fceda069fc59b5cc35af0067231 --- SuperBuild/cmake/External-PDAL.cmake | 7 +- modules/CMakeLists.txt | 1 - modules/odm_filterpoints/CMakeLists.txt | 21 - modules/odm_filterpoints/src/CmdLineParser.h | 106 ---- .../odm_filterpoints/src/CmdLineParser.inl | 300 ------------ .../odm_filterpoints/src/FloatPlyReader.cpp | 454 ------------------ .../odm_filterpoints/src/FloatPlyReader.hpp | 156 ------ modules/odm_filterpoints/src/Logger.h | 33 -- .../src/ModifiedPlyWriter.cpp | 276 ----------- .../src/ModifiedPlyWriter.hpp | 116 ----- modules/odm_filterpoints/src/main.cpp | 126 ----- opendm/point_cloud.py | 80 ++- stages/odm_filterpoints.py | 1 - 13 files changed, 59 insertions(+), 1618 deletions(-) delete mode 100644 modules/odm_filterpoints/CMakeLists.txt delete mode 100644 modules/odm_filterpoints/src/CmdLineParser.h delete mode 100644 modules/odm_filterpoints/src/CmdLineParser.inl delete mode 100644 modules/odm_filterpoints/src/FloatPlyReader.cpp delete mode 100644 modules/odm_filterpoints/src/FloatPlyReader.hpp delete mode 100644 modules/odm_filterpoints/src/Logger.h delete mode 100644 modules/odm_filterpoints/src/ModifiedPlyWriter.cpp delete mode 100644 modules/odm_filterpoints/src/ModifiedPlyWriter.hpp delete mode 100644 modules/odm_filterpoints/src/main.cpp diff --git a/SuperBuild/cmake/External-PDAL.cmake b/SuperBuild/cmake/External-PDAL.cmake index 2a98144d..869721af 100644 --- a/SuperBuild/cmake/External-PDAL.cmake +++ b/SuperBuild/cmake/External-PDAL.cmake @@ -8,15 +8,14 @@ ExternalProject_Add(${_proj_name} STAMP_DIR ${_SB_BINARY_DIR}/stamp #--Download step-------------- DOWNLOAD_DIR ${SB_DOWNLOAD_DIR} - URL https://github.com/PDAL/PDAL/archive/1.9.1.zip + URL https://github.com/PDAL/PDAL/archive/2.1.0.zip #--Update/Patch step---------- UPDATE_COMMAND "" #--Configure step------------- SOURCE_DIR ${SB_SOURCE_DIR}/${_proj_name} CMAKE_ARGS - -BUILD_PGPOINTCLOUD_TESTS=OFF - -BUILD_PLUGIN_PCL=ON - -BUILD_PLUGIN_PGPOINTCLOUD=ON + -DBUILD_PGPOINTCLOUD_TESTS=OFF + -DBUILD_PLUGIN_PGPOINTCLOUD=OFF -DBUILD_PLUGIN_CPD=OFF -DBUILD_PLUGIN_GREYHOUND=OFF -DBUILD_PLUGIN_HEXBIN=ON diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1f79c085..72858904 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -7,7 +7,6 @@ endif() add_subdirectory(odm_georef) add_subdirectory(odm_orthophoto) add_subdirectory(odm_cleanmesh) -add_subdirectory(odm_filterpoints) if (ODM_BUILD_SLAM) add_subdirectory(odm_slam) diff --git a/modules/odm_filterpoints/CMakeLists.txt b/modules/odm_filterpoints/CMakeLists.txt deleted file mode 100644 index 97ed317b..00000000 --- a/modules/odm_filterpoints/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -project(odm_filterpoints) -cmake_minimum_required(VERSION 2.8) - -# Add compiler options. -add_definitions(-Wall -Wextra -Wconversion -pedantic -std=c++11) - -# PDAL and jsoncpp -find_package(PDAL REQUIRED CONFIG) -include_directories(${PDAL_INCLUDE_DIRS}) -include_directories("${PROJECT_SOURCE_DIR}/../../SuperBuild/src/pdal/vendor/jsoncpp/dist") -link_directories(${PDAL_LIBRARY_DIRS}) -add_definitions(${PDAL_DEFINITIONS}) - -# Add source directory -aux_source_directory("./src" SRC_LIST) - -# Add exectuteable -add_executable(${PROJECT_NAME} ${SRC_LIST}) - -# Link -target_link_libraries(${PROJECT_NAME} jsoncpp ${PDAL_LIBRARIES}) diff --git a/modules/odm_filterpoints/src/CmdLineParser.h b/modules/odm_filterpoints/src/CmdLineParser.h deleted file mode 100644 index a1fbd0e3..00000000 --- a/modules/odm_filterpoints/src/CmdLineParser.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -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 Johns Hopkins University 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. -*/ - -#ifndef CMD_LINE_PARSER_INCLUDED -#define CMD_LINE_PARSER_INCLUDED - -#include -#include -#include -#include -#include - -#ifdef WIN32 -int strcasecmp( const char* c1 , const char* c2 ); -#endif // WIN32 - -class cmdLineReadable -{ -public: - bool set; - char *name; - cmdLineReadable( const char *name ); - virtual ~cmdLineReadable( void ); - virtual int read( char** argv , int argc ); - virtual void writeValue( char* str ) const; -}; - -template< class Type > void cmdLineWriteValue( Type t , char* str ); -template< class Type > void cmdLineCleanUp( Type* t ); -template< class Type > Type cmdLineInitialize( void ); -template< class Type > Type cmdLineCopy( Type t ); -template< class Type > Type cmdLineStringToType( const char* str ); - -template< class Type > -class cmdLineParameter : public cmdLineReadable -{ -public: - Type value; - cmdLineParameter( const char *name ); - cmdLineParameter( const char *name , Type v ); - ~cmdLineParameter( void ); - int read( char** argv , int argc ); - void writeValue( char* str ) const; - bool expectsArg( void ) const { return true; } -}; - -template< class Type , int Dim > -class cmdLineParameterArray : public cmdLineReadable -{ -public: - Type values[Dim]; - cmdLineParameterArray( const char *name, const Type* v=NULL ); - ~cmdLineParameterArray( void ); - int read( char** argv , int argc ); - void writeValue( char* str ) const; - bool expectsArg( void ) const { return true; } -}; - -template< class Type > -class cmdLineParameters : public cmdLineReadable -{ -public: - int count; - Type *values; - cmdLineParameters( const char* name ); - ~cmdLineParameters( void ); - int read( char** argv , int argc ); - void writeValue( char* str ) const; - bool expectsArg( void ) const { return true; } -}; - -void cmdLineParse( int argc , char **argv, cmdLineReadable** params ); -char* FileExtension( char* fileName ); -char* LocalFileName( char* fileName ); -char* DirectoryName( char* fileName ); -char* GetFileExtension( const char* fileName ); -char* GetLocalFileName( const char* fileName ); -char** ReadWords( const char* fileName , int& cnt ); - -#include "CmdLineParser.inl" -#endif // CMD_LINE_PARSER_INCLUDED diff --git a/modules/odm_filterpoints/src/CmdLineParser.inl b/modules/odm_filterpoints/src/CmdLineParser.inl deleted file mode 100644 index 84574a57..00000000 --- a/modules/odm_filterpoints/src/CmdLineParser.inl +++ /dev/null @@ -1,300 +0,0 @@ -/* -*- C++ -*- -Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho -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 Johns Hopkins University 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 -#include - -#if defined( WIN32 ) || defined( _WIN64 ) -inline int strcasecmp( const char* c1 , const char* c2 ){ return _stricmp( c1 , c2 ); } -#endif // WIN32 || _WIN64 - -template< > void cmdLineCleanUp< int >( int* t ){ *t = 0; } -template< > void cmdLineCleanUp< float >( float* t ){ *t = 0; } -template< > void cmdLineCleanUp< double >( double* t ){ *t = 0; } -template< > void cmdLineCleanUp< char* >( char** t ){ if( *t ) free( *t ) ; *t = NULL; } -template< > int cmdLineInitialize< int >( void ){ return 0; } -template< > float cmdLineInitialize< float >( void ){ return 0.f; } -template< > double cmdLineInitialize< double >( void ){ return 0.; } -template< > char* cmdLineInitialize< char* >( void ){ return NULL; } -template< > void cmdLineWriteValue< int >( int t , char* str ){ sprintf( str , "%d" , t ); } -template< > void cmdLineWriteValue< float >( float t , char* str ){ sprintf( str , "%f" , t ); } -template< > void cmdLineWriteValue< double >( double t , char* str ){ sprintf( str , "%f" , t ); } -template< > void cmdLineWriteValue< char* >( char* t , char* str ){ if( t ) sprintf( str , "%s" , t ) ; else str[0]=0; } -template< > int cmdLineCopy( int t ){ return t; } -template< > float cmdLineCopy( float t ){ return t; } -template< > double cmdLineCopy( double t ){ return t; } -#if defined( WIN32 ) || defined( _WIN64 ) -template< > char* cmdLineCopy( char* t ){ return _strdup( t ); } -#else // !WIN32 && !_WIN64 -template< > char* cmdLineCopy( char* t ){ return strdup( t ); } -#endif // WIN32 || _WIN64 -template< > int cmdLineStringToType( const char* str ){ return atoi( str ); } -template< > float cmdLineStringToType( const char* str ){ return float( atof( str ) ); } -template< > double cmdLineStringToType( const char* str ){ return double( atof( str ) ); } -#if defined( WIN32 ) || defined( _WIN64 ) -template< > char* cmdLineStringToType( const char* str ){ return _strdup( str ); } -#else // !WIN32 && !_WIN64 -template< > char* cmdLineStringToType( const char* str ){ return strdup( str ); } -#endif // WIN32 || _WIN64 - - -///////////////////// -// cmdLineReadable // -///////////////////// -#if defined( WIN32 ) || defined( _WIN64 ) -inline cmdLineReadable::cmdLineReadable( const char *name ) : set(false) { this->name = _strdup( name ); } -#else // !WIN32 && !_WIN64 -inline cmdLineReadable::cmdLineReadable( const char *name ) : set(false) { this->name = strdup( name ); } -#endif // WIN32 || _WIN64 - -inline cmdLineReadable::~cmdLineReadable( void ){ if( name ) free( name ) ; name = NULL; } -inline int cmdLineReadable::read( char** , int ){ set = true ; return 0; } -inline void cmdLineReadable::writeValue( char* str ) const { str[0] = 0; } - -////////////////////// -// cmdLineParameter // -////////////////////// -template< class Type > cmdLineParameter< Type >::~cmdLineParameter( void ) { cmdLineCleanUp( &value ); } -template< class Type > cmdLineParameter< Type >::cmdLineParameter( const char *name ) : cmdLineReadable( name ){ value = cmdLineInitialize< Type >(); } -template< class Type > cmdLineParameter< Type >::cmdLineParameter( const char *name , Type v ) : cmdLineReadable( name ){ value = cmdLineCopy< Type >( v ); } -template< class Type > -int cmdLineParameter< Type >::read( char** argv , int argc ) -{ - if( argc>0 ) - { - cmdLineCleanUp< Type >( &value ) , value = cmdLineStringToType< Type >( argv[0] ); - set = true; - return 1; - } - else return 0; -} -template< class Type > -void cmdLineParameter< Type >::writeValue( char* str ) const { cmdLineWriteValue< Type >( value , str ); } - - -/////////////////////////// -// cmdLineParameterArray // -/////////////////////////// -template< class Type , int Dim > -cmdLineParameterArray< Type , Dim >::cmdLineParameterArray( const char *name , const Type* v ) : cmdLineReadable( name ) -{ - if( v ) for( int i=0 ; i( v[i] ); - else for( int i=0 ; i(); -} -template< class Type , int Dim > -cmdLineParameterArray< Type , Dim >::~cmdLineParameterArray( void ){ for( int i=0 ; i( values+i ); } -template< class Type , int Dim > -int cmdLineParameterArray< Type , Dim >::read( char** argv , int argc ) -{ - if( argc>=Dim ) - { - for( int i=0 ; i( values+i ) , values[i] = cmdLineStringToType< Type >( argv[i] ); - set = true; - return Dim; - } - else return 0; -} -template< class Type , int Dim > -void cmdLineParameterArray< Type , Dim >::writeValue( char* str ) const -{ - char* temp=str; - for( int i=0 ; i( values[i] , temp ); - temp = str+strlen( str ); - } -} -/////////////////////// -// cmdLineParameters // -/////////////////////// -template< class Type > -cmdLineParameters< Type >::cmdLineParameters( const char* name ) : cmdLineReadable( name ) , values(NULL) , count(0) { } -template< class Type > -cmdLineParameters< Type >::~cmdLineParameters( void ) -{ - if( values ) delete[] values; - values = NULL; - count = 0; -} -template< class Type > -int cmdLineParameters< Type >::read( char** argv , int argc ) -{ - if( values ) delete[] values; - values = NULL; - - if( argc>0 ) - { - count = atoi(argv[0]); - if( count <= 0 || argc <= count ) return 1; - values = new Type[count]; - if( !values ) return 0; - for( int i=0 ; i( argv[i+1] ); - set = true; - return count+1; - } - else return 0; -} -template< class Type > -void cmdLineParameters< Type >::writeValue( char* str ) const -{ - char* temp=str; - for( int i=0 ; i( values[i] , temp ); - temp = str+strlen( str ); - } -} - - -inline char* FileExtension( char* fileName ) -{ - char* temp = fileName; - for( unsigned int i=0 ; i=0 ; i-- ) - if( fileName[i] =='\\' ) - { - fileName[i] = 0; - return fileName; - } - fileName[0] = 0; - return fileName; -} - -inline void cmdLineParse( int argc , char **argv , cmdLineReadable** params ) -{ - while( argc>0 ) - { - if( argv[0][0]=='-' ) - { - cmdLineReadable* readable=NULL; - for( int i=0 ; params[i]!=NULL && readable==NULL ; i++ ) if( !strcasecmp( params[i]->name , argv[0]+1 ) ) readable = params[i]; - if( readable ) - { - int j = readable->read( argv+1 , argc-1 ); - argv += j , argc -= j; - } - else - { - fprintf( stderr , "[WARNING] Invalid option: %s\n" , argv[0] ); - for( int i=0 ; params[i]!=NULL ; i++ ) printf( "\t-%s\n" , params[i]->name ); - } - } - else fprintf( stderr , "[WARNING] Parameter name should be of the form -: %s\n" , argv[0] ); - ++argv , --argc; - } -} - -inline char** ReadWords(const char* fileName,int& cnt) -{ - char** names; - char temp[500]; - FILE* fp; - - fp=fopen(fileName,"r"); - if(!fp){return NULL;} - cnt=0; - while(fscanf(fp," %s ",temp)==1){cnt++;} - fclose(fp); - - names=new char*[cnt]; - if(!names){return NULL;} - - fp=fopen(fileName,"r"); - if(!fp){ - delete[] names; - cnt=0; - return NULL; - } - cnt=0; - while(fscanf(fp," %s ",temp)==1){ - names[cnt]=new char[strlen(temp)+1]; - if(!names){ - for(int j=0;j -* -* 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 Hobu, Inc. or Flaxen Geo Consulting 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. -****************************************************************************/ - -// Modified to not cast to double and to use certain type identifier ("float" vs "float32") - -#include "FloatPlyReader.hpp" - -#include - -#include -#include -#include - -namespace pdal -{ - - -FloatPlyReader::FloatPlyReader() : m_vertexElt(nullptr) -{} - - -std::string FloatPlyReader::readLine() -{ - m_line.clear(); - if (m_lines.size()) - { - m_line = m_lines.top(); - m_lines.pop(); - } - else - { - do - { - std::getline(*m_stream, m_line); - } while (m_line.empty() && m_stream->good()); - } - Utils::trimTrailing(m_line); - m_linePos = Utils::extract(m_line, 0, - [](char c){ return !std::isspace(c); }); - return std::string(m_line, 0, m_linePos); -} - - -void FloatPlyReader::pushLine() -{ - m_lines.push(m_line); -} - - -std::string FloatPlyReader::nextWord() -{ - std::string s; - std::string::size_type cnt = Utils::extractSpaces(m_line, m_linePos); - m_linePos += cnt; - if (m_linePos == m_line.size()) - return s; - - cnt = Utils::extract(m_line, m_linePos, - [](char c){ return !std::isspace(c); }); - s = std::string(m_line, m_linePos, cnt); - m_linePos += cnt; - return s; -} - - -void FloatPlyReader::extractMagic() -{ - std::string first = readLine(); - if (first != "ply") - throwError("File isn't a PLY file. 'ply' not found."); - if (m_linePos != m_line.size()) - throwError("Text found following 'ply' keyword."); -} - - -void FloatPlyReader::extractEnd() -{ - std::string first = readLine(); - if (first != "end_header") - throwError("'end_header' expected but found line beginning with '" + - first + "' instead."); - if (m_linePos != m_line.size()) - throwError("Text found following 'end_header' keyword."); -} - - -void FloatPlyReader::extractFormat() -{ - std::string word = readLine(); - if (word != "format") - throwError("Expected format line not found in PLY file."); - - word = nextWord(); - if (word == "ascii") - m_format = Format::Ascii; - else if (word == "binary_big_endian") - m_format = Format::BinaryBe; - else if (word == "binary_little_endian") - m_format = Format::BinaryLe; - else - throwError("Unrecognized PLY format: '" + word + "'."); - - word = nextWord(); - if (word != "1.0") - throwError("Unsupported PLY version: '" + word + "'."); -} - - -Dimension::Type FloatPlyReader::getType(const std::string& name) -{ - static std::map types = - { - { "int8", Dimension::Type::Signed8 }, - { "uint8", Dimension::Type::Unsigned8 }, - { "int16", Dimension::Type::Signed16 }, - { "uint16", Dimension::Type::Unsigned16 }, - { "int32", Dimension::Type::Signed32 }, - { "uint32", Dimension::Type::Unsigned32 }, - { "float32", Dimension::Type::Float }, - { "float64", Dimension::Type::Double }, - - { "char", Dimension::Type::Signed8 }, - { "uchar", Dimension::Type::Unsigned8 }, - { "short", Dimension::Type::Signed16 }, - { "ushort", Dimension::Type::Unsigned16 }, - { "int", Dimension::Type::Signed32 }, - { "uint", Dimension::Type::Unsigned32 }, - { "float", Dimension::Type::Float }, - { "double", Dimension::Type::Double } - }; - - try - { - return types.at(name); - } - catch (std::out_of_range&) - {} - return Dimension::Type::None; -} - - -void FloatPlyReader::extractProperty(Element& element) -{ - std::string word = nextWord(); - Dimension::Type type = getType(word); - - if (type != Dimension::Type::None) - { - std::string name = nextWord(); - if (name.empty()) - throwError("No name for property of element '" + - element.m_name + "'."); - element.m_properties.push_back( - std::unique_ptr(new SimpleProperty(name, type))); - } - else if (word == "list") - { - if (element.m_name == "vertex") - throwError("List properties are not supported for the 'vertex' " - "element."); - - word = nextWord(); - Dimension::Type countType = getType(word); - if (countType == Dimension::Type::None) - throwError("No valid count type for list property of element '" + - element.m_name + "'."); - word = nextWord(); - Dimension::Type listType = getType(word); - if (listType == Dimension::Type::None) - throwError("No valid list type for list property of element '" + - element.m_name + "'."); - std::string name = nextWord(); - if (name.empty()) - throwError("No name for property of element '" + - element.m_name + "'."); - element.m_properties.push_back( - std::unique_ptr(new ListProperty(name, countType, - listType))); - } - else - throwError("Invalid property type '" + word + "'."); -} - - -void FloatPlyReader::extractProperties(Element& element) -{ - while (true) - { - std::string word = readLine(); - if (word == "comment" || word == "obj_info") - continue; - else if (word == "property") - extractProperty(element); - else - { - pushLine(); - break; - } - } -} - - -bool FloatPlyReader::extractElement() -{ - std::string word = readLine(); - if (word == "comment" || word == "obj_info") - return true; - else if (word == "end_header") - { - pushLine(); - return false; - } - else if (word == "element") - { - std::string name = nextWord(); - if (name.empty()) - throwError("Missing element name."); - long count = std::stol(nextWord()); - if (count < 0) - throwError("Invalid count for element '" + name + "'."); - m_elements.emplace_back(name, count); - extractProperties(m_elements.back()); - return true; - } - throwError("Invalid keyword '" + word + "' when expecting an element."); - return false; // quiet compiler -} - - -void FloatPlyReader::extractHeader() -{ - m_elements.clear(); - extractMagic(); - extractFormat(); - while (extractElement()) - ; - extractEnd(); - m_dataPos = m_stream->tellg(); - - for (Element& elt : m_elements) - if (elt.m_name == "vertex") - m_vertexElt = &elt; - if (!m_vertexElt) - throwError("Can't read PLY file without a 'vertex' element."); -} - - -std::string FloatPlyReader::getName() const -{ - return "FloatPlyReader"; -} - - -void FloatPlyReader::initialize() -{ - m_stream = Utils::openFile(m_filename, true); - if (!m_stream) - throwError("Couldn't open '" + m_filename + "'."); - extractHeader(); - Utils::closeFile(m_stream); - m_stream = nullptr; -} - - -void FloatPlyReader::addDimensions(PointLayoutPtr layout) -{ - // Override XYZ -// layout->registerDim(Dimension::Id::X); -// layout->registerDim(Dimension::Id::Y); -// layout->registerDim(Dimension::Id::Z); - - for (auto& elt : m_elements) - { - if (elt.m_name == "vertex") - { - for (auto& prop : elt.m_properties) - { - auto vprop = static_cast(prop.get()); - layout->registerOrAssignDim(vprop->m_name, vprop->m_type); - vprop->setDim( - layout->registerOrAssignDim(vprop->m_name, vprop->m_type)); - } - return; - } - } - throwError("No 'vertex' element in header."); -} - - -bool FloatPlyReader::readProperty(Property *prop, PointRef& point) -{ - if (!m_stream->good()) - return false; - prop->read(m_stream, m_format, point); - return true; -} - - -void FloatPlyReader::SimpleProperty::read(std::istream *stream, - FloatPlyReader::Format format, PointRef& point) -{ - if (format == Format::Ascii) - { - double d; - *stream >> d; - point.setField(m_dim, d); - } - else if (format == Format::BinaryLe) - { - ILeStream in(stream); - Everything e = Utils::extractDim(in, m_type); - point.setField(m_dim, m_type, &e); - } - else if (format == Format::BinaryBe) - { - IBeStream in(stream); - Everything e = Utils::extractDim(in, m_type); - point.setField(m_dim, m_type, &e); - } -} - - -// Right now we don't support list properties for point data. We just -// read the data and throw it away. -void FloatPlyReader::ListProperty::read(std::istream *stream, - FloatPlyReader::Format format, PointRef& point) -{ - if (format == Format::Ascii) - { - size_t cnt; - *stream >> cnt; - - double d; - while (cnt--) - *stream >> d; - } - else if (format == Format::BinaryLe) - { - ILeStream istream(stream); - Everything e = Utils::extractDim(istream, m_countType); - size_t cnt = (size_t)Utils::toDouble(e, m_countType); - cnt *= Dimension::size(m_listType); - istream.seek(cnt, std::ios_base::cur); - } - else if (format == Format::BinaryBe) - { - IBeStream istream(stream); - Everything e = Utils::extractDim(istream, m_countType); - size_t cnt = (size_t)Utils::toDouble(e, m_countType); - cnt *= Dimension::size(m_listType); - istream.seek(cnt, std::ios_base::cur); - } -} - - -void FloatPlyReader::readElement(Element& elt, PointRef& point) -{ - for (auto& prop : elt.m_properties) - if (!readProperty(prop.get(), point)) - throwError("Error reading data for point/element " + - std::to_string(point.pointId()) + "."); -} - - -void FloatPlyReader::ready(PointTableRef table) -{ - m_stream = Utils::openFile(m_filename, true); - if (m_stream) - m_stream->seekg(m_dataPos); - for (Element& elt : m_elements) - { - if (&elt == m_vertexElt) - break; - - // We read an element into point 0. Since the element's properties - // weren't registered as dimensions, we'll try to write the data - // to a NULL dimension, which is a noop. - // This essentially just gets us to the vertex element. - // In binary mode, this is all silliness, since we should be able - // to seek right where we want to go, but in text mode, you've got - // to go through the data. - PointRef point(table, 0); - for (PointId idx = 0; idx < elt.m_count; ++idx) - readElement(elt, point); - } - m_index = 0; -} - - -bool FloatPlyReader::processOne(PointRef& point) -{ - if (m_index < m_vertexElt->m_count) - { - readElement(*m_vertexElt, point); - m_index++; - return true; - } - return false; -} - - -// We're just reading the vertex element here. -point_count_t FloatPlyReader::read(PointViewPtr view, point_count_t num) -{ - point_count_t cnt(0); - - PointRef point(view->point(0)); - for (PointId idx = 0; idx < m_vertexElt->m_count && idx < num; ++idx) - { - point.setPointId(idx); - processOne(point); - cnt++; - } - return cnt; -} - - -void FloatPlyReader::done(PointTableRef table) -{ - Utils::closeFile(m_stream); -} - -} // namespace pdal diff --git a/modules/odm_filterpoints/src/FloatPlyReader.hpp b/modules/odm_filterpoints/src/FloatPlyReader.hpp deleted file mode 100644 index 1f206ed1..00000000 --- a/modules/odm_filterpoints/src/FloatPlyReader.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2015, Peter J. Gadomski -* -* 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 Hobu, Inc. or Flaxen Geo Consulting 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 -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace pdal -{ - -class PDAL_DLL FloatPlyReader : public Reader -{ -public: - std::string getName() const; - - typedef std::map DimensionMap; - - FloatPlyReader(); - -private: - enum class Format - { - Ascii, - BinaryLe, - BinaryBe - }; - - struct Property - { - Property(const std::string& name) : m_name(name) - {} - virtual ~Property() - {} - - std::string m_name; - - virtual void setDim(Dimension::Id id) - {} - virtual void read(std::istream *stream, FloatPlyReader::Format format, - PointRef& point) = 0; - }; - - struct SimpleProperty : public Property - { - SimpleProperty(const std::string& name, Dimension::Type type) : - Property(name), m_type(type), m_dim(Dimension::Id::Unknown) - {} - - Dimension::Type m_type; - Dimension::Id m_dim; - - virtual void read(std::istream *stream, FloatPlyReader::Format format, - PointRef& point) override; - virtual void setDim(Dimension::Id id) override - { m_dim = id; } - }; - - struct ListProperty : public Property - { - ListProperty(const std::string& name, Dimension::Type countType, - Dimension::Type listType) : Property(name), m_countType(countType), - m_listType(listType) - {} - - Dimension::Type m_countType; - Dimension::Type m_listType; - - virtual void read(std::istream *stream, FloatPlyReader::Format format, - PointRef& point) override; - }; - - struct Element - { - Element(const std::string name, size_t count) : - m_name(name), m_count(count) - {} - - std::string m_name; - size_t m_count; - std::vector> m_properties; - }; - - Format m_format; - std::string m_line; - std::string::size_type m_linePos; - std::stack m_lines; - std::istream *m_stream; - std::istream::streampos m_dataPos; - std::vector m_elements; - PointId m_index; - Element *m_vertexElt; - - virtual void initialize(); - virtual void addDimensions(PointLayoutPtr layout); - virtual void ready(PointTableRef table); - virtual point_count_t read(PointViewPtr view, point_count_t num); - virtual void done(PointTableRef table); - virtual bool processOne(PointRef& point); - - std::string readLine(); - void pushLine(); - std::string nextWord(); - void extractMagic(); - void extractEnd(); - void extractFormat(); - Dimension::Type getType(const std::string& name); - void extractProperty(Element& element); - void extractProperties(Element& element); - bool extractElement(); - void extractHeader(); - void readElement(Element& elt, PointRef& point); - bool readProperty(Property *prop, PointRef& point); -}; - -} // namespace pdal - diff --git a/modules/odm_filterpoints/src/Logger.h b/modules/odm_filterpoints/src/Logger.h deleted file mode 100644 index 723b8762..00000000 --- a/modules/odm_filterpoints/src/Logger.h +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include "CmdLineParser.h" - -struct Logger{ - bool verbose; - const char* outputFile; - - Logger(){ - this->verbose = false; - this->outputFile = NULL; - } - - void operator() ( const char* format , ... ) - { - if( outputFile ) - { - FILE* fp = fopen( outputFile , "a" ); - va_list args; - va_start( args , format ); - vfprintf( fp , format , args ); - fclose( fp ); - va_end( args ); - } - if( verbose ) - { - va_list args; - va_start( args , format ); - vprintf( format , args ); - va_end( args ); - } - } -}; diff --git a/modules/odm_filterpoints/src/ModifiedPlyWriter.cpp b/modules/odm_filterpoints/src/ModifiedPlyWriter.cpp deleted file mode 100644 index 7a1fca16..00000000 --- a/modules/odm_filterpoints/src/ModifiedPlyWriter.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2015, Peter J. Gadomski -* -* 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 Hobu, Inc. or Flaxen Geo Consulting 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. -****************************************************************************/ - -// Modified to output certain property names in normalized format ("nx", "ny", ... instead of "normalx", "normaly", etc.) - -#include "ModifiedPlyWriter.hpp" - -#include -#include - -#include -#include - -namespace pdal -{ - -std::string ModifiedPlyWriter::getName() const { return "ModifiedPlyWriter"; } - - -ModifiedPlyWriter::ModifiedPlyWriter() -{} - - -void ModifiedPlyWriter::addArgs(ProgramArgs& args) -{ - args.add("filename", "Output filename", m_filename).setPositional(); - args.add("storage_mode", "PLY Storage Mode", m_format, Format::Ascii); - args.add("dims", "Dimension names", m_dimNames); - args.add("faces", "Write faces", m_faces); - m_precisionArg = &args.add("precision", "Output precision", m_precision, 3); -} - - -void ModifiedPlyWriter::prepared(PointTableRef table) -{ - if (m_precisionArg->set() && m_format != Format::Ascii) - throwError("Option 'precision' can only be set of the 'storage_mode' " - "is ascii."); - if (m_dimNames.size()) - { - for (auto& name : m_dimNames) - { - auto id = table.layout()->findDim(name); - if (id == Dimension::Id::Unknown) - throwError("Unknown dimension '" + name + "' in provided " - "dimension list."); - m_dims.push_back(id); - } - } - else - { - m_dims = table.layout()->dims(); - for (auto dim : m_dims) - m_dimNames.push_back(Utils::tolower(table.layout()->dimName(dim))); - } -} - - -std::string ModifiedPlyWriter::getType(Dimension::Type type) const -{ - static std::map types = - { - { Dimension::Type::Signed8, "char" }, - { Dimension::Type::Unsigned8, "uchar" }, - { Dimension::Type::Signed16, "short" }, - { Dimension::Type::Unsigned16, "ushort" }, - { Dimension::Type::Signed32, "int" }, - { Dimension::Type::Unsigned32, "uint" }, - { Dimension::Type::Float, "float" }, - { Dimension::Type::Double, "double" } - }; - - try - { - return types.at(type); - } - catch (std::out_of_range&) - { - throwError("Can't write dimension of type '" + - Dimension::interpretationName(type) + "'."); - } - return ""; -} - - -void ModifiedPlyWriter::writeHeader(PointLayoutPtr layout) const -{ - *m_stream << "ply" << std::endl; - *m_stream << "format " << m_format << " 1.0" << std::endl; - *m_stream << "comment Generated by odm_filterpoints" << std::endl; - *m_stream << "element vertex " << pointCount() << std::endl; - - auto ni = m_dimNames.begin(); - for (auto dim : m_dims) - { - std::string name = *ni++; - std::string typeString = getType(layout->dimType(dim)); - - // Normalize certain property names - if (name == "normalx" || name == "normal_x") name = "nx"; - if (name == "normaly" || name == "normal_y") name = "ny"; - if (name == "normalz" || name == "normal_z") name = "nz"; - - if (name == "diffuse_red") name = "red"; - if (name == "diffuse_green") name = "green"; - if (name == "diffuse_blue") name = "blue"; - - *m_stream << "property " << typeString << " " << name << std::endl; - } - if (m_faces) - { - *m_stream << "element face " << faceCount() << std::endl; - *m_stream << "property list uchar uint vertex_indices" << std::endl; - } - *m_stream << "end_header" << std::endl; -} - - -void ModifiedPlyWriter::ready(PointTableRef table) -{ - if (pointCount() > (std::numeric_limits::max)()) - throwError("Can't write PLY file. Only " + - std::to_string((std::numeric_limits::max)()) + - " points supported."); - - m_stream = Utils::createFile(m_filename, true); - if (m_format == Format::Ascii && m_precisionArg->set()) - { - *m_stream << std::fixed; - m_stream->precision(m_precision); - } - writeHeader(table.layout()); -} - - -void ModifiedPlyWriter::write(const PointViewPtr data) -{ - m_views.push_back(data); -} - - -void ModifiedPlyWriter::writeValue(PointRef& point, Dimension::Id dim, - Dimension::Type type) -{ - if (m_format == Format::Ascii) - { - double d = point.getFieldAs(dim); - *m_stream << d; - } - else if (m_format == Format::BinaryLe) - { - OLeStream out(m_stream); - Everything e; - point.getField((char *)&e, dim, type); - Utils::insertDim(out, type, e); - } - else if (m_format == Format::BinaryBe) - { - OBeStream out(m_stream); - Everything e; - point.getField((char *)&e, dim, type); - Utils::insertDim(out, type, e); - } -} - - -void ModifiedPlyWriter::writePoint(PointRef& point, PointLayoutPtr layout) -{ - for (auto it = m_dims.begin(); it != m_dims.end();) - { - Dimension::Id dim = *it; - writeValue(point, dim, layout->dimType(dim)); - ++it; - if (m_format == Format::Ascii && it != m_dims.end()) - *m_stream << " "; - } - if (m_format == Format::Ascii) - *m_stream << std::endl; -} - - -void ModifiedPlyWriter::writeTriangle(const Triangle& t, size_t offset) -{ - if (m_format == Format::Ascii) - { - *m_stream << "3 " << (t.m_a + offset) << " " << - (t.m_b + offset) << " " << (t.m_c + offset) << std::endl; - } - else if (m_format == Format::BinaryLe) - { - OLeStream out(m_stream); - unsigned char count = 3; - uint32_t a = (uint32_t)(t.m_a + offset); - uint32_t b = (uint32_t)(t.m_b + offset); - uint32_t c = (uint32_t)(t.m_c + offset); - out << count << a << b << c; - } - else if (m_format == Format::BinaryBe) - { - OBeStream out(m_stream); - unsigned char count = 3; - uint32_t a = (uint32_t)(t.m_a + offset); - uint32_t b = (uint32_t)(t.m_b + offset); - uint32_t c = (uint32_t)(t.m_c + offset); - out << count << a << b << c; - } -} - - -// Deferring write until this time allows both points and faces from multiple -// point views to be written. -void ModifiedPlyWriter::done(PointTableRef table) -{ - for (auto& v : m_views) - { - PointRef point(*v, 0); - for (PointId idx = 0; idx < v->size(); ++idx) - { - point.setPointId(idx); - writePoint(point, table.layout()); - } - } - if (m_faces) - { - PointId offset = 0; - for (auto& v : m_views) - { - TriangularMesh *mesh = v->mesh(); - if (mesh) - { - for (size_t id = 0; id < mesh->size(); ++id) - { - const Triangle& t = (*mesh)[id]; - writeTriangle(t, offset); - } - } - offset += v->size(); - } - } - Utils::closeFile(m_stream); - m_stream = nullptr; - getMetadata().addList("filename", m_filename); -} - -} // namespace pdal diff --git a/modules/odm_filterpoints/src/ModifiedPlyWriter.hpp b/modules/odm_filterpoints/src/ModifiedPlyWriter.hpp deleted file mode 100644 index b69c66a9..00000000 --- a/modules/odm_filterpoints/src/ModifiedPlyWriter.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2015, Peter J. Gadomski -* -* 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 Hobu, Inc. or Flaxen Geo Consulting 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 -#include - -namespace pdal -{ - -class Triangle; - -class PDAL_DLL ModifiedPlyWriter : public Writer -{ -public: - enum class Format - { - Ascii, - BinaryLe, - BinaryBe - }; - - std::string getName() const; - - ModifiedPlyWriter(); - -private: - virtual void addArgs(ProgramArgs& args); - virtual void prepared(PointTableRef table); - virtual void ready(PointTableRef table); - virtual void write(const PointViewPtr data); - virtual void done(PointTableRef table); - - std::string getType(Dimension::Type type) const; - void writeHeader(PointLayoutPtr layout) const; - void writeValue(PointRef& point, Dimension::Id dim, Dimension::Type type); - void writePoint(PointRef& point, PointLayoutPtr layout); - void writeTriangle(const Triangle& t, size_t offset); - - std::ostream *m_stream; - std::string m_filename; - Format m_format; - bool m_faces; - StringList m_dimNames; - Dimension::IdList m_dims; - int m_precision; - Arg *m_precisionArg; - std::vector m_views; -}; - -inline std::istream& operator>>(std::istream& in, ModifiedPlyWriter::Format& f) -{ - std::string s; - std::getline(in, s); - Utils::trim(s); - Utils::tolower(s); - if (s == "ascii" || s == "default") - f = ModifiedPlyWriter::Format::Ascii; - else if (s == "little endian" || s == "binary_little_endian") - f = ModifiedPlyWriter::Format::BinaryLe; - else if (s == "big endian" || s == "binary_big_endian") - f = ModifiedPlyWriter::Format::BinaryBe; - else - in.setstate(std::ios_base::failbit); - return in; -} - - -inline std::ostream& operator<<(std::ostream& out, const ModifiedPlyWriter::Format& f) -{ - switch (f) - { - case ModifiedPlyWriter::Format::Ascii: - out << "ascii"; - break; - case ModifiedPlyWriter::Format::BinaryLe: - out << "binary_little_endian"; - break; - case ModifiedPlyWriter::Format::BinaryBe: - out << "binary_big_endian"; - break; - } - return out; -} - -} diff --git a/modules/odm_filterpoints/src/main.cpp b/modules/odm_filterpoints/src/main.cpp deleted file mode 100644 index a4497c1e..00000000 --- a/modules/odm_filterpoints/src/main.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include -#include -#include -#include "CmdLineParser.h" -#include "Logger.h" -#include "FloatPlyReader.hpp" -#include "ModifiedPlyWriter.hpp" - -Logger logWriter; - -cmdLineParameter< char* > - InputFile( "inputFile" ) , - OutputFile( "outputFile" ); -cmdLineParameter< float > - StandardDeviation( "sd" ) , - MeanK ( "meank" ) , - Confidence ( "confidence" ) , - Sample ( "sample" ); -cmdLineReadable - Verbose( "verbose" ); - -cmdLineReadable* params[] = { - &InputFile , &OutputFile , &StandardDeviation, &MeanK, &Confidence, &Sample, &Verbose , - NULL -}; - -void help(char *ex){ - std::cout << "Usage: " << ex << std::endl - << "\t -" << InputFile.name << " " << std::endl - << "\t -" << OutputFile.name << " " << std::endl - << "\t [-" << StandardDeviation.name << " ]" << std::endl - << "\t [-" << MeanK.name << " ]" << std::endl - << "\t [-" << Confidence.name << " ]" << std::endl - - << "\t [-" << Verbose.name << "]" << std::endl; - exit(EXIT_FAILURE); -} - - -void logArgs(cmdLineReadable* params[], Logger& logWriter){ - logWriter("Running with parameters:\n"); - char str[1024]; - for( int i=0 ; params[i] ; i++ ){ - if( params[i]->set ){ - params[i]->writeValue( str ); - if( strlen( str ) ) logWriter( "\t--%s %s\n" , params[i]->name , str ); - else logWriter( "\t--%s\n" , params[i]->name ); - } - } -} - - -int main(int argc, char **argv) { - cmdLineParse( argc-1 , &argv[1] , params ); - if( !InputFile.set || !OutputFile.set ) help(argv[0]); - if( !StandardDeviation.set ) StandardDeviation.value = 2.0; - if( !MeanK.set ) MeanK.value = 8; - - logWriter.verbose = Verbose.set; - logArgs(params, logWriter); - - logWriter("Filtering point cloud...\n"); - - pdal::Options inPlyOpts; - inPlyOpts.add("filename", InputFile.value); - - pdal::PointTable table; - pdal::FloatPlyReader plyReader; - pdal::Stage *currentStage = &plyReader; - plyReader.setOptions(inPlyOpts); - - pdal::RangeFilter confidenceFilter; - if (Confidence.set){ - logWriter("Filtering confidence\n"); - - pdal::Options confidenceFilterOpts; - float confidenceValue = std::min(1.0f, std::max(Confidence.value, 0.0f)); - std::ostringstream confidenceLimit; - confidenceLimit << "confidence[" << confidenceValue << ":1]"; - confidenceFilterOpts.add("limits", confidenceLimit.str()); - - confidenceFilter.setInput(*currentStage); - currentStage = &confidenceFilter; - confidenceFilter.setOptions(confidenceFilterOpts); - } - - pdal::SampleFilter sampleFilter; - if (Sample.set && Sample.value > 0.0f){ - logWriter("Radius sampling\n"); - pdal::Options sampleFilterOpts; - sampleFilterOpts.add("radius", Sample.value); - sampleFilter.setOptions(sampleFilterOpts); - sampleFilter.setInput(*currentStage); - currentStage = &sampleFilter; - } - - pdal::Options outlierOpts; - outlierOpts.add("method", "statistical"); - outlierOpts.add("mean_k", MeanK.value); - outlierOpts.add("multiplier", StandardDeviation.value); - - pdal::OutlierFilter outlierFilter; - outlierFilter.setInput(*currentStage); - outlierFilter.setOptions(outlierOpts); - - pdal::Options rangeOpts; - rangeOpts.add("limits", "Classification![7:7]"); // Remove outliers - - pdal::RangeFilter rangeFilter; - rangeFilter.setInput(outlierFilter); - rangeFilter.setOptions(rangeOpts); - - pdal::Options outPlyOpts; - outPlyOpts.add("storage_mode", "little endian"); - outPlyOpts.add("filename", OutputFile.value); - - pdal::ModifiedPlyWriter plyWriter; - plyWriter.setOptions(outPlyOpts); - plyWriter.setInput(rangeFilter); - plyWriter.prepare(table); - plyWriter.execute(table); - - logWriter("Done!\n"); -} diff --git a/opendm/point_cloud.py b/opendm/point_cloud.py index 57a7569f..2fb4f996 100644 --- a/opendm/point_cloud.py +++ b/opendm/point_cloud.py @@ -7,7 +7,26 @@ from opendm import entwine from opendm import io from pipes import quote -def filter(input_point_cloud, output_point_cloud, standard_deviation=2.5, meank=16, confidence=None, sample_radius=0, verbose=False): +def ply_has_normals(input_ply): + if not os.path.exists(input_ply): + return False + + # Read PLY header, check if point cloud has normals + has_normals = False + with open(input_ply, 'r') as f: + line = f.readline().strip().lower() + i = 0 + while line != "end_header" and i < 100: + line = f.readline().strip().lower() + props = line.split(" ") + if len(props) == 3 and props[0] == "property" and props[2] in ["nx", "normalx", "normal_x"]: + has_normals = True + break + i += 1 + + return has_normals + +def filter(input_point_cloud, output_point_cloud, standard_deviation=2.5, meank=16, sample_radius=0, verbose=False): """ Filters a point cloud """ @@ -21,40 +40,53 @@ def filter(input_point_cloud, output_point_cloud, standard_deviation=2.5, meank= shutil.copy(input_point_cloud, output_point_cloud) return - if standard_deviation > 0 and meank > 0: - log.ODM_INFO("Filtering point cloud (statistical, meanK {}, standard deviation {})".format(meank, standard_deviation)) - - if confidence: - log.ODM_INFO("Keeping only points with > %s confidence" % confidence) + filters = [] if sample_radius > 0: log.ODM_INFO("Sampling points around a %sm radius" % sample_radius) + filters.append('sample') - filter_program = os.path.join(context.odm_modules_path, 'odm_filterpoints') - if not os.path.exists(filter_program): - log.ODM_WARNING("{} program not found. Will skip filtering, but this installation should be fixed.") - shutil.copy(input_point_cloud, output_point_cloud) - return + if standard_deviation > 0 and meank > 0: + log.ODM_INFO("Filtering point cloud (statistical, meanK {}, standard deviation {})".format(meank, standard_deviation)) + filters.append('outlier') + + if len(filters) > 0: + filters.append('range') + + dims = "x=float,y=float,z=float," + if ply_has_normals(input_point_cloud): + dims += "nx=float,ny=float,nz=float," + dims += "red=uchar,blue=uchar,green=uchar" filterArgs = { - 'bin': filter_program, 'inputFile': input_point_cloud, 'outputFile': output_point_cloud, - 'sd': standard_deviation, - 'meank': meank, - 'verbose': '-verbose' if verbose else '', - 'confidence': '-confidence %s' % confidence if confidence else '', - 'sample': max(0, sample_radius) + 'stages': " ".join(filters), + 'dims': dims } - system.run('{bin} -inputFile {inputFile} ' - '-outputFile {outputFile} ' - '-sd {sd} ' - '-meank {meank} ' - '-sample {sample} ' - '{confidence} {verbose} '.format(**filterArgs)) + cmd = ("pdal translate -i \"{inputFile}\" " + "-o \"{outputFile}\" " + "{stages} " + "--writers.ply.sized_types=false " + "--writers.ply.storage_mode='little endian' " + "--writers.ply.dims=\"{dims}\" " + "").format(**filterArgs) + + if 'sample' in filters: + cmd += "--filters.sample.radius={} ".format(sample_radius) + + if 'outlier' in filters: + cmd += ("--filters.outlier.method='statistical' " + "--filters.outlier.mean_k={} " + "--filters.outlier.multiplier={} ").format(meank, standard_deviation) + + if 'range' in filters: + # Remove outliers + cmd += "--filters.range.limits='Classification![7:7]' " + + system.run(cmd) - # Remove input file, swap temp file if not os.path.exists(output_point_cloud): log.ODM_WARNING("{} not found, filtering has failed.".format(output_point_cloud)) diff --git a/stages/odm_filterpoints.py b/stages/odm_filterpoints.py index 182fa867..962c1644 100644 --- a/stages/odm_filterpoints.py +++ b/stages/odm_filterpoints.py @@ -25,7 +25,6 @@ class ODMFilterPoints(types.ODM_Stage): point_cloud.filter(inputPointCloud, tree.filtered_point_cloud, standard_deviation=args.pc_filter, - confidence=None, sample_radius=args.pc_sample, verbose=args.verbose)