From 4ddc446ba468aa75921386bdd430280718cc9daa Mon Sep 17 00:00:00 2001 From: Linoal <1321932+linoal@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:52:46 +0900 Subject: [PATCH] =?UTF-8?q?MeshExtractor=E3=82=92=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E5=87=BA=E5=8A=9B=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=95=E3=81=9B?= =?UTF-8?q?=E3=80=81=E5=90=84=E6=AE=B5=E9=9A=8E=E3=81=AE=E5=87=A6=E7=90=86?= =?UTF-8?q?=E6=99=82=E9=96=93=E3=82=92=E3=83=AD=E3=82=B0=E3=81=AB=E5=87=BA?= =?UTF-8?q?=E3=81=99=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit meshExtractorにストップウォッチ機能を追加 同上 --- include/plateau/polygon_mesh/mesh_extractor.h | 3 + src/c_wrapper/mesh_extractor_c.cpp | 20 ++++++ src/polygon_mesh/mesh_extractor.cpp | 64 +++++++++++++++++-- .../PolygonMesh/MeshExtractor.cs | 24 ++++++- 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/include/plateau/polygon_mesh/mesh_extractor.h b/include/plateau/polygon_mesh/mesh_extractor.h index 2c34a65a..d5f3d987 100644 --- a/include/plateau/polygon_mesh/mesh_extractor.h +++ b/include/plateau/polygon_mesh/mesh_extractor.h @@ -6,6 +6,7 @@ #include #include #include "citygml/citymodel.h" +#include "citygml/citygmllogger.h" #include "model.h" namespace plateau::polygonMesh { @@ -33,6 +34,7 @@ namespace plateau::polygonMesh { * 生ポインタのdeleteはDLLの利用者の責任です。 */ static void extract(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options); + static void extract(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::shared_ptr& logger); /** * CityModelから範囲内のModelを取り出します。 @@ -43,6 +45,7 @@ namespace plateau::polygonMesh { * CityModelから範囲内のModelを取り出します。 */ static void extractInExtents(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::vector& extents); + static void extractInExtents(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::vector& extents, const std::shared_ptr& logger); /** * 引数で与えられた LOD の主要地物について、次を判定して bool で返します。 diff --git a/src/c_wrapper/mesh_extractor_c.cpp b/src/c_wrapper/mesh_extractor_c.cpp index e82bd453..31d4b877 100644 --- a/src/c_wrapper/mesh_extractor_c.cpp +++ b/src/c_wrapper/mesh_extractor_c.cpp @@ -2,6 +2,7 @@ #include "city_model_c.h" #include #include +#include using namespace libplateau; using namespace plateau::polygonMesh; @@ -43,4 +44,23 @@ extern "C"{ API_CATCH; return APIResult::ErrorUnknown; } + + LIBPLATEAU_C_EXPORT APIResult LIBPLATEAU_C_API plateau_mesh_extractor_extract_in_extents_with_log( + const CityModelHandle* const city_model_handle, + const MeshExtractOptions options, + const std::vector* extents, + Model* const out_model, + const DllLogLevel logLevel, + LogCallbackFuncPtr logErrorCallback, + LogCallbackFuncPtr logWarnCallback, + LogCallbackFuncPtr logInfoCallback) { + API_TRY{ + auto logger = std::make_shared(logLevel); + logger->setLogCallbacks(logErrorCallback, logWarnCallback, logInfoCallback); + MeshExtractor::extractInExtents(*out_model, city_model_handle->getCityModel(), options, *extents, logger); + return APIResult::Success; + } + API_CATCH; + return APIResult::ErrorUnknown; + } } diff --git a/src/polygon_mesh/mesh_extractor.cpp b/src/polygon_mesh/mesh_extractor.cpp index 912e135a..7bdc1463 100644 --- a/src/polygon_mesh/mesh_extractor.cpp +++ b/src/polygon_mesh/mesh_extractor.cpp @@ -8,6 +8,9 @@ #include #include #include +#include + +#include "plateau_dll_logger.h" namespace { using namespace plateau; @@ -17,6 +20,34 @@ namespace { using namespace citygml; namespace fs = std::filesystem; + class Stopwatch { + public: + Stopwatch(std::shared_ptr logger, const std::string& task_name) + : logger_(std::move(logger)), task_name_(task_name) { + total_start_time_ = std::chrono::steady_clock::now(); + stage_start_time_ = total_start_time_; + logger_->log(citygml::CityGMLLogger::LOGLEVEL::LL_INFO, task_name_ + " start."); + } + + ~Stopwatch() { + const auto total_duration = std::chrono::duration_cast(std::chrono::steady_clock::now() - total_start_time_).count(); + logger_->log(citygml::CityGMLLogger::LOGLEVEL::LL_INFO, task_name_ + " finished. Total: " + std::to_string(total_duration) + "ms"); + } + + void log_stage(const std::string& stage_name) { + const auto end_time = std::chrono::steady_clock::now(); + const auto duration = std::chrono::duration_cast(end_time - stage_start_time_).count(); + logger_->log(citygml::CityGMLLogger::LOGLEVEL::LL_INFO, " " + stage_name + " : " + std::to_string(duration) + "ms"); + stage_start_time_ = end_time; + } + + private: + std::shared_ptr logger_; + std::string task_name_; + std::chrono::steady_clock::time_point total_start_time_; + std::chrono::steady_clock::time_point stage_start_time_; + }; + bool shouldSkipCityObj(const CityObject& city_obj, const MeshExtractOptions& options, const std::vector& extents) { // 範囲内であっても、COT_Roomは意図的に省きます。なぜなら、LOD4の建物においてRoomと天井、床等が完全に重複するのをなくしたいからです。 @@ -36,14 +67,25 @@ namespace { void extractInner( Model& out_model, const CityModel& city_model, const MeshExtractOptions& options, - const std::vector& extents_before_adjust) { + const std::vector& extents_before_adjust, + std::shared_ptr logger) { - if (options.max_lod < options.min_lod) throw std::logic_error("Invalid LOD range."); + if (logger == nullptr) { + logger = std::make_shared(); + } + + Stopwatch stopwatch(logger, "MeshExtractor"); + + if (options.max_lod < options.min_lod) { + logger->log(citygml::CityGMLLogger::LOGLEVEL::LL_ERROR, "Invalid LOD range."); + throw std::logic_error("Invalid LOD range."); + } const auto geo_reference = geometry::GeoReference(options.coordinate_zone_id, options.reference_point, options.unit_scale, options.mesh_axes); // 範囲の境界上にある地物を取り逃さないように、範囲を少し広げます。 auto extents = MeshExtractor::extendExtents(extents_before_adjust, 1.2f); + stopwatch.log_stage("Initialize"); // rootNode として LODノード を作ります。 for (unsigned lod = options.min_lod; lod <= options.max_lod; lod++) { @@ -143,14 +185,17 @@ namespace { out_model.addNode(std::move(lod_node)); } + stopwatch.log_stage("LOD loop"); out_model.eraseEmptyNodes(); out_model.assignNodeHierarchy(); + stopwatch.log_stage("Node arrange"); // テクスチャを結合します。 if (options.enable_texture_packing) { TexturePacker packer(options.texture_packing_resolution, options.texture_packing_resolution); packer.process(out_model); } + stopwatch.log_stage("Texture packing"); // 現在の都市モデルが地形であるなら、衛星写真または地図用のUVを付与し、地図タイルをダウンロードします。 auto package = GmlFile(city_model.getGmlPath()).getPackage(); @@ -158,8 +203,9 @@ namespace { const auto gml_path = fs::u8path(city_model.getGmlPath()); const auto map_download_dest = gml_path.parent_path() / (gml_path.filename().u8string() + "_map"); MapAttacher().attach(out_model, options.map_tile_url, map_download_dest, options.map_tile_zoom_level, - geo_reference); + geo_reference); } + stopwatch.log_stage("Map attach"); } } @@ -173,7 +219,11 @@ namespace plateau::polygonMesh { void MeshExtractor::extract(Model& out_model, const CityModel& city_model, const MeshExtractOptions& options) { - extractInner(out_model, city_model, options, { plateau::geometry::Extent::all() }); + extractInner(out_model, city_model, options, { plateau::geometry::Extent::all() }, nullptr); + } + + void MeshExtractor::extract(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::shared_ptr& logger) { + extractInner(out_model, city_model, options, { plateau::geometry::Extent::all() }, logger); } std::shared_ptr MeshExtractor::extractInExtents( @@ -190,7 +240,11 @@ namespace plateau::polygonMesh { const MeshExtractOptions& options, const std::vector& extents) { - extractInner(out_model, city_model, options, extents); + extractInner(out_model, city_model, options, extents, nullptr); + } + + void MeshExtractor::extractInExtents(Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::vector& extents, const std::shared_ptr& logger) { + extractInner(out_model, city_model, options, extents, logger); } diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractor.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractor.cs index 5dbf9493..890df938 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractor.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/PolygonMesh/MeshExtractor.cs @@ -32,16 +32,22 @@ public static void Extract(ref Model outModel, CityModel cityModel, MeshExtractO /// 結果は に格納されます。 /// 通常、 には new したばかりの Model を渡してください。 /// - public static void ExtractInExtents(ref Model outModel, CityModel cityModel, MeshExtractOptions options, List extents) + public static void ExtractInExtents(ref Model outModel, CityModel cityModel, MeshExtractOptions options, List extents, + LogCallbacks logCallbacks = null, DllLogLevel logLevel = DllLogLevel.Error) { + if (logCallbacks == null) + { + logCallbacks = LogCallbacks.StdOut; + } var nativeExtents = NativeVectorExtent.Create(); foreach (var extent in extents) { nativeExtents.Add(extent); } - var result = NativeMethods.plateau_mesh_extractor_extract_in_extents( - cityModel.Handle, options, nativeExtents.Handle, outModel.Handle + var result = NativeMethods.plateau_mesh_extractor_extract_in_extents_with_log( + cityModel.Handle, options, nativeExtents.Handle, outModel.Handle, logLevel, + logCallbacks.LogErrorFuncPtr, logCallbacks.LogWarnFuncPtr, logCallbacks.LogInfoFuncPtr ); DLLUtil.CheckDllError(result); } @@ -60,6 +66,18 @@ internal static extern APIResult plateau_mesh_extractor_extract_in_extents( MeshExtractOptions options, [In] IntPtr extentsPtr, [In] IntPtr outModelPtr); + + [DllImport(DLLUtil.DllName)] + internal static extern APIResult plateau_mesh_extractor_extract_in_extents_with_log( + [In] IntPtr cityModelPtr, + MeshExtractOptions options, + [In] IntPtr extentsPtr, + [In] IntPtr outModelPtr, + DllLogLevel logLevel, + [In] IntPtr logErrorCallback, + [In] IntPtr logWarnCallback, + [In] IntPtr logInfoCallback + ); } } }