From a7c81643a43e7a6c8cd93aa1a55a3316e4331374 Mon Sep 17 00:00:00 2001 From: Bradley J Chambers Date: Mon, 13 May 2013 17:18:45 -0400 Subject: [PATCH] this is still a bit messy, but we can actually also create a PDF --- CMakeLists.txt | 7 +- README | 22 ++++ include/prc/Writer.hpp | 6 +- src/Writer.cpp | 271 +++++++++++++++++++++++++++++------------ test/pipeline_prc.xml | 13 +- 5 files changed, 239 insertions(+), 80 deletions(-) create mode 100644 README diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cf102f..56b9bd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,10 @@ mark_as_advanced(CLEAR PDAL_INCLUDE_DIR) mark_as_advanced(CLEAR PDAL_LIBRARIES) include_directories(${PDAL_INCLUDE_DIR}) +find_library(HPDF_LIBRARY hpdf) +find_path(HPDF_INCLUDE_DIR hpdf_u3d.h) +include_directories(${HPDF_INCLUDE_DIR}) + #------------------------------------------------------------------------------ # subdirectory controls #------------------------------------------------------------------------------ @@ -180,7 +184,8 @@ set(PRC_SOURCES add_library(${PRC_WRITER_NAME} SHARED ${PRC_SOURCES}) target_link_libraries(${PRC_WRITER_NAME} ${PDAL_LIBRARY} - ${ZLIB_LIBRARY}) + ${ZLIB_LIBRARY} + ${HPDF_LIBRARY}) set_target_properties(${PRC_WRITER_NAME} PROPERTIES SOVERSION "0.1.0" ) diff --git a/README b/README new file mode 100644 index 0000000..ecf3ff7 --- /dev/null +++ b/README @@ -0,0 +1,22 @@ +This PRC code is based off the PRC writer developed by Orest Shardt and Michaeil Vidiassov. It has been used by both MathGL and Asymptote. It is released under the LGPL v3. + +We may also use HARU to write the PDF directly. HARU is licensed under ZLIB/LIBPNG. MathGL has a good example of how to use both the PRC writer and HARU. MathGL is GPL licensed. + +This file is part of a tool for producing 3D content in the PRC format. +Copyright (C) 2008 Orest Shardt +with enhancements contributed by Michail Vidiassov. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . + + diff --git a/include/prc/Writer.hpp b/include/prc/Writer.hpp index 28797d3..061c01a 100644 --- a/include/prc/Writer.hpp +++ b/include/prc/Writer.hpp @@ -89,7 +89,11 @@ class PDAL_DLL Writer : public pdal::Writer virtual void writeEnd(boost::uint64_t actualNumPointsWritten); oPRCFile m_prcFile; - PRCoptions grpopt; + //PRCoptions grpopt; + + //std::string m_prcFilename; + //std::string m_pdfFilename; + int m_outputFormat; private: diff --git a/src/Writer.cpp b/src/Writer.cpp index db5465b..ba32308 100644 --- a/src/Writer.cpp +++ b/src/Writer.cpp @@ -32,25 +32,37 @@ * OF SUCH DAMAGE. ****************************************************************************/ -#include #include -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include #include #include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include MAKE_WRITER_CREATOR(prcWriter, pdal::drivers::prc::Writer) CREATE_WRITER_PLUGIN(prc, pdal::drivers::prc::Writer) +enum OUTPUT_FORMAT { + OUTPUT_FORMAT_PDF, + OUTPUT_FORMAT_PRC +}; + namespace pdal { @@ -59,111 +71,220 @@ namespace drivers namespace prc { - Writer::Writer(Stage& prevStage, const Options& options) - : pdal::Writer(prevStage, options) - , m_prcFile(options.getOption("filename").getValue()) + : pdal::Writer(prevStage, options) + //, m_prcFile(getOptions().getValueOrThrow("prc_filename")) + , m_prcFile(options.getOption("prc_filename").getValue()) + //, m_prcFilename() + //, m_pdfFilename() + , m_outputFormat(OUTPUT_FORMAT_PDF) { - - return; + std::cout << "writer\n"; + std::cout << options.getOption("prc_filename").getValue() << std::endl; + + return; } Writer::~Writer() { - return; + return; } void Writer::initialize() { - pdal::Writer::initialize(); + std::cout << "init\n"; + + pdal::Writer::initialize(); + + std::cout << "succes\n"; + + //m_prcFilename = getOptions().getValueOrThrow("prc_filename"); + //m_pdfFilename = getOptions().getValueOrThrow("pdf_filename"); + + //std::cout << m_prcFilename << "\n" << m_pdfFilename << std::endl; + + std::string output_format = getOptions().getValueOrDefault("output_format", "pdf"); - grpopt.no_break = true; - grpopt.do_break = false; - grpopt.tess = true; + if(boost::iequals(output_format, "pdf")) + m_outputFormat = OUTPUT_FORMAT_PDF; + else if (boost::iequals(output_format, "prc")) + m_outputFormat = OUTPUT_FORMAT_PRC; + else + { + std::ostringstream oss; + oss << "Unrecognized output format " << output_format; + throw prc_driver_error("Unrecognized output format"); + } - return; + //m_prcFile(m_filename); + + return; } Options Writer::getDefaultOptions() { - Options options; + Options options; - Option filename("filename", "", "Filename to write PRC file to"); + Option prc_filename("prc_filename", "", "Filename to write PRC file to"); + Option pdf_filename("pdf_filename", "", "Filename to write PDF file to"); + Option output_format("output_format", "", "PRC or PDF"); - options.add(filename); + options.add(prc_filename); + options.add(pdf_filename); + options.add(output_format); - return options; + return options; } void Writer::writeBegin(boost::uint64_t /*targetNumPointsToWrite*/) -{ - m_prcFile.begingroup("points",&grpopt); - - return; +{ + PRCoptions grpopt; + grpopt.no_break = true; + grpopt.do_break = false; + grpopt.tess = true; + + m_prcFile.begingroup("points",&grpopt); + + std::cout << "begin\n"; + + return; } void Writer::writeEnd(boost::uint64_t /*actualNumPointsWritten*/) { - m_prcFile.endgroup(); - m_prcFile.finish(); + std::cout << "end\n"; + + m_prcFile.endgroup(); + m_prcFile.finish(); + + std::cout << "format is " << m_outputFormat << std::endl; + + if(m_outputFormat == OUTPUT_FORMAT_PDF) + { + std::cout << "detected PDF\n"; + // std::string prc_name (m_filename); +// std::string pdf_name ("/Users/bchambers/dev/test.pdf"); - return; + //std::cout << m_prcFilename << std::endl; + //std::cout << m_pdfFilename << std::endl; + + const double width = 256.0f; + const double height = 256.0f; + const double depth = std::sqrt(width*height); + + std::cout << width << " " << height << " " << depth << std::endl; + + const HPDF_Rect rect = { 0, 0, width, height }; + HPDF_Doc pdf; + HPDF_Page page; + HPDF_Annotation annot; + HPDF_U3D u3d; + HPDF_Dict view; + + pdf = HPDF_New( NULL, NULL ); + pdf->pdf_version = HPDF_VER_17; + + std::cout << "pdf version " << pdf->pdf_version << std::endl; + + page = HPDF_AddPage( pdf ); + HPDF_Page_SetWidth( page, width ); + HPDF_Page_SetHeight( page, height ); + + std::string prcFilename = getOptions().getValueOrThrow("prc_filename"); + std::cout << prcFilename; + u3d = HPDF_LoadU3DFromFile( pdf, prcFilename.c_str() ); + std::cout << " loaded\n"; + + view = HPDF_Create3DView( u3d->mmgr, "DefaultView" ); + + std::cout << "default view\n"; + + HPDF_3DView_SetCamera( view, 0, 0, 0, 0, 0, 1, /*depth*/ 10, 0 ); + //HPDF_3DView_SetOrthogonalProjection( view, 1 ); + HPDF_3DView_SetPerspectiveProjection( view, 30.0 ); + HPDF_3DView_SetBackgroundColor( view, 0, 0, 0 ); + HPDF_3DView_SetLighting( view, "Headlamp" ); + + std::cout << "view created\n"; + + HPDF_U3D_Add3DView( u3d, view ); + HPDF_U3D_SetDefault3DView( u3d, "DefaultView" ); + + annot = HPDF_Page_Create3DAnnot( page, rect, u3d ); + + HPDF_Dict action = (HPDF_Dict) HPDF_Dict_GetItem( annot, "3DA", HPDF_OCLASS_DICT ); + HPDF_Dict_AddBoolean( action, "TB", HPDF_TRUE ); + + std::cout << "annotated\n"; + + std::string pdfFilename = getOptions().getValueOrThrow("pdf_filename"); + std::cout << pdfFilename; + HPDF_SaveToFile( pdf, pdfFilename.c_str() ); + std::cout << " saved\n"; + + HPDF_Free( pdf ); + } + + return; } boost::uint32_t Writer::writeBuffer(const PointBuffer& data) { - boost::uint32_t numPoints = 0; - - pdal::Schema const& schema = data.getSchema(); - - pdal::Dimension const& dimX = schema.getDimension("X"); - pdal::Dimension const& dimY = schema.getDimension("Y"); - pdal::Dimension const& dimZ = schema.getDimension("Z"); - - double **points; - points = (double**) malloc(data.getNumPoints()*sizeof(double*)); - for (boost::uint32_t i = 0; i < data.getNumPoints(); ++i) - { - points[i] = (double*) malloc(3*sizeof(double)); - } - - double xd(0.0); - double yd(0.0); - double zd(0.0); - - for(boost::uint32_t i = 0; i < data.getNumPoints(); ++i) - { - boost::int32_t x = data.getField(dimX, i); - boost::int32_t y = data.getField(dimY, i); - boost::int32_t z = data.getField(dimZ, i); - -/* - xd = dimX.applyScaling(x); - yd = dimY.applyScaling(y); - zd = dimZ.applyScaling(z); -*/ - points[i][0] = x; - points[i][1] = y; - points[i][2] = z; - - numPoints++; - } - - m_prcFile.addPoints(numPoints, const_cast(points), RGBAColour(1.0,1.0,0.0,1.0),1.0); - - for (boost::uint32_t i = 0; i < data.getNumPoints(); ++i) - { - free(points[i]); - } - free(points); - - return numPoints; + std::cout << "write\n"; + + boost::uint32_t numPoints = 0; + + pdal::Schema const& schema = data.getSchema(); + + pdal::Dimension const& dimX = schema.getDimension("X"); + pdal::Dimension const& dimY = schema.getDimension("Y"); + pdal::Dimension const& dimZ = schema.getDimension("Z"); + + double **points; + points = (double**) malloc(data.getNumPoints()*sizeof(double*)); + for (boost::uint32_t i = 0; i < data.getNumPoints(); ++i) + { + points[i] = (double*) malloc(3*sizeof(double)); + } + + double xd(0.0); + double yd(0.0); + double zd(0.0); + + for(boost::uint32_t i = 0; i < data.getNumPoints(); ++i) + { + boost::int32_t x = data.getField(dimX, i); + boost::int32_t y = data.getField(dimY, i); + boost::int32_t z = data.getField(dimZ, i); + + xd = dimX.applyScaling(x) - 1210000; + yd = dimY.applyScaling(y) - 320000; + zd = dimZ.applyScaling(z) - 4000; + + if(i % 10000) printf("%f %f %f\n", xd, yd, zd); + + points[i][0] = xd; + points[i][1] = yd; + points[i][2] = zd; + + numPoints++; + } + + m_prcFile.addPoints(numPoints, const_cast(points), RGBAColour(1.0,1.0,0.0,1.0),1.0); + + for (boost::uint32_t i = 0; i < data.getNumPoints(); ++i) + { + free(points[i]); + } + free(points); + + return numPoints; } diff --git a/test/pipeline_prc.xml b/test/pipeline_prc.xml index e8e62f4..a5a28e1 100644 --- a/test/pipeline_prc.xml +++ b/test/pipeline_prc.xml @@ -1,12 +1,19 @@ - + +