From 9eb8672ba9f78c7646ba299d27152ca5b938715c Mon Sep 17 00:00:00 2001 From: Andrea Maggiordomo Date: Tue, 10 Dec 2019 10:14:10 +0100 Subject: [PATCH] added RasterizedOutline2Packer::PackBestEffort() sample --- .../space_rasterized_packer.cpp | 146 ++++++++++++++++++ .../space_rasterized_packer.pro | 6 + 2 files changed, 152 insertions(+) create mode 100644 apps/sample/space_rasterized_packer/space_rasterized_packer.cpp create mode 100644 apps/sample/space_rasterized_packer/space_rasterized_packer.pro diff --git a/apps/sample/space_rasterized_packer/space_rasterized_packer.cpp b/apps/sample/space_rasterized_packer/space_rasterized_packer.cpp new file mode 100644 index 00000000..7f9a173d --- /dev/null +++ b/apps/sample/space_rasterized_packer/space_rasterized_packer.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004-2019 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 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 General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// This sample shows how to pack a sequence of outlines at the given scale into +// a number of containers not known in advance using the PackBestEffort() +// function + +typedef std::vector Outline2f; +typedef vcg::RasterizedOutline2Packer RasterizedPacker; +typedef RasterizedPacker::Parameters PackingParams; + + +void FillOutlineVec(std::vector& outlines) +{ + vcg::tri::OutlineUtil::BuildRandomOutlineVec(30, outlines); + for (auto& outline : outlines) + for (auto& p : outline) + p *= 200.0; +} + +int main(int argc, char **argv) +{ + // the vector of outlines to pack + std::vector outlines; + FillOutlineVec(outlines); + + // containerIndices maps each outline index to the container in which is packed + std::vector containerIndices(outlines.size(), -1); // -1 means not packed to any container + + // packingTransforms maps each outline index to its transform */ + std::vector packingTransforms(outlines.size(), vcg::Similarity2f{}); + + /* size of the packing area */ + const vcg::Point2i grid_size(400, 600); + + PackingParams params; + params.costFunction = PackingParams::LowestHorizon; + params.doubleHorizon = true; + params.innerHorizon = true; /* use inner horizons to pack charts in between gaps */ + params.permutations = false; /* do not use permutations (they are ignored by PackBestEffort() */ + params.rotationNum = 16; /* 16 rotations per chart */ + params.gutterWidth = 2; /* 2 pixels gutter */ + params.minmax = false; /* do not combine costs of the two horizons when evaluating placements */ + + int totPacked = 0; + int nc = 0; /* current container index */ + while (true) { + + std::cout << "Packing into container " << nc << std::endl; + + // build a vector with the outlines not yet packed, and a corresponding vector + // of indices into the 'outlines' vector + std::vector outlineIndex_iter; + std::vector outlines_iter; + for (unsigned i = 0; i < containerIndices.size(); ++i) { + if (containerIndices[i] == -1) { + outlineIndex_iter.push_back(i); + outlines_iter.push_back(outlines[i]); + } + } + + std::vector transforms; + std::vector polyToContainer; + int numPacked = RasterizedPacker::PackBestEffort(outlines_iter, {grid_size}, transforms, polyToContainer, params); + + totPacked += numPacked; + + if (numPacked == 0) { + std::cerr << "Failed to pack any outline at the current iteration. Stopping." << std::endl; + std::exit(-1); + } else { + for (unsigned i = 0; i < outlines_iter.size(); ++i) { + if (polyToContainer[i] != -1) { + assert(polyToContainer[i] == 0); // We only use a single container in this example + int outline_i = outlineIndex_iter[i]; + assert(containerIndices[outline_i] == -1); + containerIndices[outline_i] = nc; + packingTransforms[outline_i] = transforms[i]; + } + } + } + + if (totPacked == outlines.size()) + break; + else + nc++; + + if (nc > 10) + std::cerr << "Warning: packing into more than 10 containers! (nc = " << nc << ")" << std::endl; + } + + /* for each container, generate an image */ + for (int i = 0; i < nc + 1; ++i) { + std::vector outlines_iter; + std::vector transforms_iter; + for (unsigned k = 0; k < containerIndices.size(); ++k) { + assert(containerIndices[k] != -1 && "Some outlines were not packed"); + if (containerIndices[k] == i) { + outlines_iter.push_back(outlines[k]); + transforms_iter.push_back(packingTransforms[k]); + } + } + std::string filename = std::string("container_") + std::to_string(i) + std::string(".png"); + Outline2Dumper::Param pp; + pp.width = grid_size.X(); + pp.height = grid_size.Y(); + pp.fill = true; + pp.randomColor = true; + + Outline2Dumper::dumpOutline2VecPNG(filename.c_str(), outlines_iter, transforms_iter, pp); + } +} + + diff --git a/apps/sample/space_rasterized_packer/space_rasterized_packer.pro b/apps/sample/space_rasterized_packer/space_rasterized_packer.pro new file mode 100644 index 00000000..b9da699f --- /dev/null +++ b/apps/sample/space_rasterized_packer/space_rasterized_packer.pro @@ -0,0 +1,6 @@ +include(../common.pri) +QT += opengl svg +TARGET = space_rasterized_packer +SOURCES += space_rasterized_packer.cpp \ +../../../../vcglib/wrap/qt/Outline2ToQImage.cpp \ +../../../../vcglib/wrap/qt/outline2_rasterizer.cpp