diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp index 785f865c97ccc5ea9e5cd2859176ee920d54a5c3..5ffeb8f4a448ba71bd3344f8e672cedf14f4263b 100644 --- a/src/pe/raytracing/Raytracer.cpp +++ b/src/pe/raytracing/Raytracer.cpp @@ -46,7 +46,7 @@ namespace raytracing { */ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, - size_t pixelsHorizontal, size_t pixelsVertical, + uint16_t pixelsHorizontal, uint16_t pixelsVertical, real_t fov_vertical, const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector, const Lighting& lighting, @@ -61,7 +61,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI blockAABBIntersectionPadding_(blockAABBIntersectionPadding), tBufferOutputEnabled_(false), imageOutputEnabled_(false), - localImageOutputEnabled_(false) + localImageOutputEnabled_(false), + outputFilenameTimestepZeroPadding_(4) { setupView_(); } @@ -77,7 +78,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI * for each of cameraPosition, lookAt and the upVector. Optional is blockAABBIntersectionPadding (real) and backgroundColor (Vec3). * To output both process local and global tbuffers after raytracing, set tbuffer_output_directory (string). * For image output after raytracing, set image_output_directory (string); for local image output additionally set - * local_image_output_enabled (bool) to true. + * local_image_output_enabled (bool) to true. outputFilenameTimestepZeroPadding (int) sets zero padding for timesteps of output filenames. * For the lighting a config block named Lighting has to be defined, information about its contents is in Lighting.h. */ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, @@ -86,8 +87,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI : forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage) { WALBERLA_CHECK(config.isValid(), "No valid config passed to raytracer"); - pixelsHorizontal_ = config.getParameter<size_t>("image_x"); - pixelsVertical_ = config.getParameter<size_t>("image_y"); + pixelsHorizontal_ = config.getParameter<uint16_t>("image_x"); + pixelsVertical_ = config.getParameter<uint16_t>("image_y"); fov_vertical_ = config.getParameter<real_t>("fov_vertical"); if (config.isDefined("tbuffer_output_directory")) { @@ -105,6 +106,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI } else if (getLocalImageOutputEnabled()) { WALBERLA_ABORT("Cannot enable local image output without image_output_directory parameter being set."); } + + outputFilenameTimestepZeroPadding_ = config.getParameter<int8_t>("outputFilenameTimestepZeroPadding", int8_t(4)); cameraPosition_ = config.getParameter<Vec3>("cameraPosition"); lookAtPoint_ = config.getParameter<Vec3>("lookAt"); @@ -113,7 +116,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI backgroundColor_ = config.getParameter<Color>("backgroundColor", Vec3(0.1, 0.1, 0.1)); blockAABBIntersectionPadding_ = config.getParameter<real_t>("blockAABBIntersectionPadding", real_t(0.0)); - + setupView_(); } @@ -142,15 +145,15 @@ void Raytracer::setupView_() { * \param isGlobalImage Whether this image is the fully stitched together one. */ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage) const { - WALBERLA_CHECK(timestep < 100000, "Raytracer only supports outputting 99 999 timesteps."); + uint_t maxTimestep = uint_c(pow(10, outputFilenameTimestepZeroPadding_+1)); + WALBERLA_CHECK(timestep < maxTimestep, "Raytracer only supports outputting " << (maxTimestep-1) << " timesteps for the configured output filename zero padding."); mpi::MPIRank rank = mpi::MPIManager::instance()->rank(); - uint8_t padding = (timestep < 10 ? 4 : - (timestep < 100 ? 3 : - (timestep < 1000 ? 2 : - (timestep < 10000 ? 1 : - 0)))); - std::string fileName = "tbuffer_" + std::string(padding, '0') + std::to_string(timestep) + "+" + (isGlobalImage ? "global" : std::to_string(rank)) + ".ppm"; - writeTBufferToFile(tBuffer, fileName); + std::stringstream fileNameStream; + fileNameStream << "tbuffer_"; + fileNameStream << std::setfill('0') << std::setw(int_c(outputFilenameTimestepZeroPadding_)) << timestep; // add timestep + fileNameStream << "+" << (isGlobalImage ? "global" : std::to_string(rank)); // add rank + fileNameStream << ".ppm"; // add extension + writeTBufferToFile(tBuffer, fileNameStream.str()); } /*!\brief Writes the tBuffer to a file in the tBuffer output directory. @@ -209,15 +212,15 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std * \param isGlobalImage Whether this image is the fully stitched together one. */ void Raytracer::writeImageBufferToFile(const std::vector<Color>& imageBuffer, size_t timestep, bool isGlobalImage) const { - WALBERLA_CHECK(timestep < 100000, "Raytracer only supports outputting 99 999 timesteps."); + uint_t maxTimestep = uint_c(pow(10, outputFilenameTimestepZeroPadding_+1)); + WALBERLA_CHECK(timestep < maxTimestep, "Raytracer only supports outputting " << (maxTimestep-1) << " timesteps for the configured output filename zero padding."); mpi::MPIRank rank = mpi::MPIManager::instance()->rank(); - uint8_t padding = (timestep < 10 ? 4 : - (timestep < 100 ? 3 : - (timestep < 1000 ? 2 : - (timestep < 10000 ? 1 : - 0)))); - std::string fileName = "image_" + std::string(padding, '0') + std::to_string(timestep) + "+" + (isGlobalImage ? "global" : std::to_string(rank)) + ".ppm"; - writeImageBufferToFile(imageBuffer, fileName); + std::stringstream fileNameStream; + fileNameStream << "image_"; + fileNameStream << std::setfill('0') << std::setw(int_c(outputFilenameTimestepZeroPadding_)) << timestep; // add timestep + fileNameStream << "+" << (isGlobalImage ? "global" : std::to_string(rank)); // add rank + fileNameStream << ".ppm"; // add extension + writeImageBufferToFile(imageBuffer, fileNameStream.str()); } /*!\brief Writes the image buffer to a file in the image output directory. diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h index 5bb9fa77b4ed1b885aa4a84924efd0a9a6a9c3f4..7701eed0a39ddab1d792495c6268aa56f1e1c0a8 100644 --- a/src/pe/raytracing/Raytracer.h +++ b/src/pe/raytracing/Raytracer.h @@ -55,7 +55,7 @@ public: //@{ explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, - size_t pixelsHorizontal, size_t pixelsVertical, + uint16_t pixelsHorizontal, uint16_t pixelsVertical, real_t fov_vertical, const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector, const Lighting& lighting, @@ -70,19 +70,18 @@ private: /*!\name Member variables */ //@{ const shared_ptr<BlockStorage> forest_; //!< The BlockForest the raytracer operates on. - BlockDataID storageID_; /*!< The storage ID of the block data storage the raytracer operates - on.*/ + BlockDataID storageID_; //!< The storage ID of the block data storage the raytracer operates on. const shared_ptr<BodyStorage> globalBodyStorage_; //!< The global body storage the raytracer operates on. - size_t pixelsHorizontal_; //!< The horizontal amount of pixels of the generated image. - size_t pixelsVertical_; //!< The vertical amount of pixels of the generated image. + uint16_t pixelsHorizontal_; //!< The horizontal amount of pixels of the generated image. + uint16_t pixelsVertical_; //!< The vertical amount of pixels of the generated image. real_t fov_vertical_; //!< The vertical field-of-view of the camera. Vec3 cameraPosition_; //!< The position of the camera in the global world frame. Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame, marks the center of the view plane.*/ Vec3 upVector_; //!< The vector indicating the upwards direction of the camera. Lighting lighting_; //!< The lighting of the scene. - Color backgroundColor_; //!< Background color of the scene. + Color backgroundColor_; //!< Background color of the scene. real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as some objects within a block might protrude from the block's AABB.*/ @@ -92,6 +91,10 @@ private: bool imageOutputEnabled_; //!< Enable / disable writing images to file. bool localImageOutputEnabled_; //!< Enable / disable writing images of the local process to file. std::string imageOutputDirectory_; //!< Path to the image output directory. + + int8_t outputFilenameTimestepZeroPadding_; /*!< Zero padding for timesteps of output filenames. + * Use e.g. 4 for ranges from 1 to 100000: Will result in + * filenames like image_00001.png up to image_99999.png. */ //@} Vec3 n_; //!< The normal vector of the viewing plane. @@ -109,8 +112,8 @@ private: public: /*!\name Get functions */ //@{ - inline size_t getPixelsHorizontal() const; - inline size_t getPixelsVertical() const; + inline uint16_t getPixelsHorizontal() const; + inline uint16_t getPixelsVertical() const; inline real_t getFOVVertical() const; inline const Vec3& getCameraPosition() const; inline const Vec3& getLookAtPoint() const; @@ -121,6 +124,7 @@ public: inline bool getImageOutputEnabled() const; inline bool getLocalImageOutputEnabled() const; inline const std::string& getImageOutputDirectory() const; + inline int8_t getOutputFilenameTimestepZeroPadding() const; //@} /*!\name Set functions */ @@ -131,6 +135,7 @@ public: inline void setImageOutputEnabled(const bool enabled); inline void setLocalImageOutputEnabled(const bool enabled); inline void setImageOutputDirectory(const std::string& path); + inline void setOutputFilenameTimestepZeroPadding(int8_t padding); //@} /*!\name Functions */ @@ -156,7 +161,7 @@ private: * * \return The horizontal amount of pixels of the generated image. */ -inline size_t Raytracer::getPixelsHorizontal() const { +inline uint16_t Raytracer::getPixelsHorizontal() const { return pixelsHorizontal_; } @@ -164,7 +169,7 @@ inline size_t Raytracer::getPixelsHorizontal() const { * * \return The vertical amount of pixels of the generated image. */ -inline size_t Raytracer::getPixelsVertical() const { +inline uint16_t Raytracer::getPixelsVertical() const { return pixelsVertical_; } @@ -257,6 +262,13 @@ inline const std::string& Raytracer::getImageOutputDirectory() const { return imageOutputDirectory_; } +/*!\brief Returns the zero padding for timesteps in output filenames. + * \return Zero padding amount. + */ +inline int8_t Raytracer::getOutputFilenameTimestepZeroPadding() const { + return outputFilenameTimestepZeroPadding_; +} + /*!\brief Set the background color of the scene. * * \param color New background color. @@ -309,6 +321,13 @@ inline void Raytracer::setImageOutputDirectory(const std::string& path) { imageOutputDirectory_ = path; } + +/*!\brief Set zero padding for timesteps of output filenames. + * \param padding Set to true / false to enable / disable image output. + */ +inline void Raytracer::setOutputFilenameTimestepZeroPadding(int8_t padding) { + outputFilenameTimestepZeroPadding_ = padding; +} /*!\brief Checks if a plane should get rendered. * \param plane Plane to check for visibility. diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp index ba13106b2c412b86d1f4e0766322523c91714cda..f45b13af050e260c436bbf2d002d92d0881b6a31 100644 --- a/tests/pe/Raytracing.cpp +++ b/tests/pe/Raytracing.cpp @@ -259,8 +259,9 @@ void RaytracerTest() { //raytracer.setTBufferOutputDirectory("tbuffer"); //raytracer.setTBufferOutputEnabled(true); - //raytracer.setImageOutputDirectory("image"); - //raytracer.setImageOutputEnabled(true); + raytracer.setImageOutputDirectory("image"); + raytracer.setImageOutputEnabled(true); + //raytracer.setLocalImageOutputEnabled(true); raytracer.rayTrace<BodyTuple>(0); }