diff --git a/plugins/mmstd_datatools/src/FSOctree.cpp b/plugins/mmstd_datatools/src/FSOctree.cpp new file mode 100644 index 0000000000..1f0702d696 --- /dev/null +++ b/plugins/mmstd_datatools/src/FSOctree.cpp @@ -0,0 +1,137 @@ +#include "stdafx.h" +#include "FSOctree.h" + +#include "mmcore/moldyn/MultiParticleDataCall.h" +#include "mmcore/param/StringParam.h" +#include "mmcore/param/IntParam.h" +#include "vislib/StringConverter.h" +#include "vislib/StringTokeniser.h" +#include "mmpld.h" + +#include +#include +#include + +megamol::stdplugin::datatools::FSOctreeMMPLD::FSOctreeMMPLD() + : outBoxesSlot("outBoxes", "Output") + , pathSlot("path", "where the files are located") + , filenamePrefixSlot("filenamePrefix", "set the filename prefix") + , extensionSlot("fileExtension", "set the filename extension") + , maxSearchDepthSlot("maxDepth", "set how far to recurse to find the root node") { + outBoxesSlot.SetCallback(megamol::geocalls::LinesDataCall::ClassName(), + megamol::geocalls::LinesDataCall::FunctionName(0), &FSOctreeMMPLD::getDataCallback); + outBoxesSlot.SetCallback(megamol::geocalls::LinesDataCall::ClassName(), + megamol::geocalls::LinesDataCall::FunctionName(1), &FSOctreeMMPLD::getExtentCallback); + MakeSlotAvailable(&outBoxesSlot); + + pathSlot << new core::param::StringParam(""); + MakeSlotAvailable(&pathSlot); + + filenamePrefixSlot << new core::param::StringParam(""); + MakeSlotAvailable(&filenamePrefixSlot); + + extensionSlot << new core::param::StringParam(""); + MakeSlotAvailable(&extensionSlot); + + maxSearchDepthSlot << new core::param::IntParam(10, 1, 50); + MakeSlotAvailable(&maxSearchDepthSlot); +} + + +megamol::stdplugin::datatools::FSOctreeMMPLD::~FSOctreeMMPLD() { this->Release(); } + + +bool megamol::stdplugin::datatools::FSOctreeMMPLD::create() { return true; } + + +void megamol::stdplugin::datatools::FSOctreeMMPLD::release() {} + + +std::vector octants_from_filename(const std::filesystem::path& file, const std::string& ext, const std::string& prefix) { + std::vector ret; + auto n = file.stem(); + auto e = file.extension(); + if (e == ext) { + auto pos = n.string().find_first_of(prefix); + if (pos != std::string::npos) { + auto nstr = n.string(); + auto treeStuff = nstr.substr(prefix.length(), nstr.length() - prefix.length()); + int d = std::count(treeStuff.begin(), treeStuff.end(), '_'); + ret.reserve(d); + pos = treeStuff.find('_'); + while (pos != std::string::npos) { + auto bits = treeStuff.substr(pos + 1, 3); + int i = std::stoi(bits); + int val = (i / 100) * 4 + (i % 100) / 10 * 2 + (i % 10); + ret.push_back(val); + pos = treeStuff.find('_', pos + 1); + } + } + } + return ret; +} + +bool megamol::stdplugin::datatools::FSOctreeMMPLD::assertData(megamol::geocalls::LinesDataCall& outCall) { + if (filenamePrefixSlot.IsDirty() || extensionSlot.IsDirty()) { + + std::string path = pathSlot.Param()->Value().PeekBuffer(); + std::string prefix = filenamePrefixSlot.Param()->Value().PeekBuffer(); + std::string ext = extensionSlot.Param()->Value().PeekBuffer(); + int maxDepth = maxSearchDepthSlot.Param()->Value(); + + struct stat statbuf; + + //int minDepth = + for (auto& file: std::filesystem::directory_iterator(path)) { + auto oct = octants_from_filename(file.path(), ext, prefix); + if (oct.size() > 0) { + octree_node::insert_node(this->tree, oct, file.path().stem().string()); + } + } + + + //bool anythingFound = false; + //int minDepth = 0; + //std::string currPrefix = prefix; + //int currdepth = -1; + //while(true) { + // for (int x = 0; x < 8; x++) { + // std::string filename = prefix + "_"; + // filename += ((x & 4) > 0) ? "1" : "0"; + // filename += ((x & 2) > 0) ? "1" : "0"; + // filename += ((x & 1) > 0) ? "1" : "0"; + // filename += ext; + + // vislib::sys::Log::DefaultLog.WriteInfo("constructed filename: %s", filename.c_str()); + // if (stat(filename.c_str(), &statbuf) == 0) { + // minDepth = currdepth; + // break; + // } + // } + // if (minDepth != -1 || ++currdepth > maxDepth) break; + // prefix += "_000"; + //} + //vislib::sys::Log::DefaultLog.WriteInfo("octree root: %s", rootName.c_str()); + + filenamePrefixSlot.ResetDirty(); + extensionSlot.ResetDirty(); + } + + return true; +} + + +bool megamol::stdplugin::datatools::FSOctreeMMPLD::getDataCallback(core::Call& c) { + auto outCall = dynamic_cast(&c); + if (outCall == nullptr) return false; + + return assertData(*outCall); +} + + +bool megamol::stdplugin::datatools::FSOctreeMMPLD::getExtentCallback(core::Call& c) { + auto outCall = dynamic_cast(&c); + if (outCall == nullptr) return false; + + return assertData(*outCall); +} diff --git a/plugins/mmstd_datatools/src/FSOctree.h b/plugins/mmstd_datatools/src/FSOctree.h new file mode 100644 index 0000000000..11ed65c561 --- /dev/null +++ b/plugins/mmstd_datatools/src/FSOctree.h @@ -0,0 +1,96 @@ +#pragma once + +#include "mmcore/CalleeSlot.h" +#include "mmcore/Module.h" +#include "mmcore/param/ParamSlot.h" +#include "mmcore/moldyn/MultiParticleDataCall.h" +#include "geometry_calls/LinesDataCall.h" + +#include "mmpld.h" +#include "vislib/math/mathtypes.h" +#include "vislib/math/Cuboid.h" + +namespace megamol { +namespace stdplugin { +namespace datatools { + +// TODO extract template? +class FSOctreeMMPLD: public core::Module { +public: + /** + * Answer the name of this module. + * + * @return The name of this module. + */ + static const char* ClassName(void) { return "FSOctreeMMPLD"; } + + /** + * Answer a human readable description of this module. + * + * @return A human readable description of this module. + */ + static const char* Description(void) { return "generates octree file names for a chunked MMPLD and outputs bounding boxes"; } + + /** + * Answers whether this module is available on the current system. + * + * @return 'true' if the module is available, 'false' otherwise. + */ + static bool IsAvailable(void) { return true; } + + /** Ctor. */ + FSOctreeMMPLD(void); + + /** Dtor. */ + virtual ~FSOctreeMMPLD(void); + +protected: + bool create() override; + + void release() override; + + core::param::ParamSlot pathSlot; + core::param::ParamSlot filenamePrefixSlot; + core::param::ParamSlot extensionSlot; + core::param::ParamSlot maxSearchDepthSlot; + +private: + + class octree_node { + public: + std::string filename; + std::array, 8> children; + + static void insert_node(std::shared_ptr root, const std::vector& address, const std::string& filename) { + auto curr_node = root; + for (auto a: address) { + if (curr_node->children[a] == nullptr) { + curr_node->children[a] = std::make_shared(); + } + curr_node = curr_node->children[a]; + } + curr_node->filename = filename; + } + }; + + std::shared_ptr tree = std::make_shared(); + + + bool assertData(megamol::geocalls::LinesDataCall& outCall); + + bool getDataCallback(core::Call& c); + + bool getExtentCallback(core::Call& c); + + core::CalleeSlot outBoxesSlot; + + //std::vector output_frames; + + //vislib::math::Cuboid gbbox; + + uint32_t version = 0; +}; // end class FSOctreeMMPLD + +} // end namespace datatools +} // end namespace stdplugin +} // end namespace megamol \ No newline at end of file diff --git a/plugins/mmstd_datatools/src/mmstd_datatools.cpp b/plugins/mmstd_datatools/src/mmstd_datatools.cpp index c022219f96..cf2cab3b28 100644 --- a/plugins/mmstd_datatools/src/mmstd_datatools.cpp +++ b/plugins/mmstd_datatools/src/mmstd_datatools.cpp @@ -76,6 +76,7 @@ #include "mmstd_datatools/MultiIndexListDataCall.h" #include "mmstd_datatools/ParticleFilterMapDataCall.h" #include "mmstd_datatools/table/TableDataCall.h" +#include "FSOctree.h" #include "table/CSVDataSource.h" #include "table/MMFTDataSource.h" #include "table/MMFTDataWriter.h" @@ -237,6 +238,7 @@ class plugin_instance : public megamol::core::utility::plugins::Plugin200Instanc this->module_descriptions.RegisterAutoDescription(); this->module_descriptions.RegisterAutoDescription(); this->module_descriptions.RegisterAutoDescription(); + this->module_descriptions.RegisterAutoDescription(); // register calls here: this->call_descriptions.RegisterAutoDescription();