88#include < plateau/polygon_mesh/polygon_mesh_utils.h>
99#include < plateau/dataset/gml_file.h>
1010#include < plateau/texture/texture_packer.h>
11+ #include < chrono>
12+
13+ #include " plateau_dll_logger.h"
1114
1215namespace {
1316 using namespace plateau ;
@@ -17,6 +20,34 @@ namespace {
1720 using namespace citygml ;
1821 namespace fs = std::filesystem;
1922
23+ class Stopwatch {
24+ public:
25+ Stopwatch (std::shared_ptr<citygml::CityGMLLogger> logger, const std::string& task_name)
26+ : logger_(std::move(logger)), task_name_(task_name) {
27+ total_start_time_ = std::chrono::steady_clock::now ();
28+ stage_start_time_ = total_start_time_;
29+ logger_->log (citygml::CityGMLLogger::LOGLEVEL::LL_INFO, task_name_ + " start." );
30+ }
31+
32+ ~Stopwatch () {
33+ const auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - total_start_time_).count ();
34+ logger_->log (citygml::CityGMLLogger::LOGLEVEL::LL_INFO, task_name_ + " finished. Total: " + std::to_string (total_duration) + " ms" );
35+ }
36+
37+ void log_stage (const std::string& stage_name) {
38+ const auto end_time = std::chrono::steady_clock::now ();
39+ const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - stage_start_time_).count ();
40+ logger_->log (citygml::CityGMLLogger::LOGLEVEL::LL_INFO, " " + stage_name + " : " + std::to_string (duration) + " ms" );
41+ stage_start_time_ = end_time;
42+ }
43+
44+ private:
45+ std::shared_ptr<citygml::CityGMLLogger> logger_;
46+ std::string task_name_;
47+ std::chrono::steady_clock::time_point total_start_time_;
48+ std::chrono::steady_clock::time_point stage_start_time_;
49+ };
50+
2051 bool shouldSkipCityObj (const CityObject& city_obj, const MeshExtractOptions& options, const std::vector<geometry::Extent>& extents) {
2152
2253 // 範囲内であっても、COT_Roomは意図的に省きます。なぜなら、LOD4の建物においてRoomと天井、床等が完全に重複するのをなくしたいからです。
@@ -36,14 +67,25 @@ namespace {
3667 void extractInner (
3768 Model& out_model, const CityModel& city_model,
3869 const MeshExtractOptions& options,
39- const std::vector<geometry::Extent>& extents_before_adjust) {
70+ const std::vector<geometry::Extent>& extents_before_adjust,
71+ std::shared_ptr<citygml::CityGMLLogger> logger) {
4072
41- if (options.max_lod < options.min_lod ) throw std::logic_error (" Invalid LOD range." );
73+ if (logger == nullptr ) {
74+ logger = std::make_shared<PlateauDllLogger>();
75+ }
76+
77+ Stopwatch stopwatch (logger, " MeshExtractor" );
78+
79+ if (options.max_lod < options.min_lod ) {
80+ logger->log (citygml::CityGMLLogger::LOGLEVEL::LL_ERROR, " Invalid LOD range." );
81+ throw std::logic_error (" Invalid LOD range." );
82+ }
4283
4384 const auto geo_reference = geometry::GeoReference (options.coordinate_zone_id , options.reference_point , options.unit_scale , options.mesh_axes );
4485
4586 // 範囲の境界上にある地物を取り逃さないように、範囲を少し広げます。
4687 auto extents = MeshExtractor::extendExtents (extents_before_adjust, 1 .2f );
88+ stopwatch.log_stage (" Initialize" );
4789
4890 // rootNode として LODノード を作ります。
4991 for (unsigned lod = options.min_lod ; lod <= options.max_lod ; lod++) {
@@ -143,23 +185,27 @@ namespace {
143185
144186 out_model.addNode (std::move (lod_node));
145187 }
188+ stopwatch.log_stage (" LOD loop" );
146189 out_model.eraseEmptyNodes ();
147190 out_model.assignNodeHierarchy ();
191+ stopwatch.log_stage (" Node arrange" );
148192
149193 // テクスチャを結合します。
150194 if (options.enable_texture_packing ) {
151195 TexturePacker packer (options.texture_packing_resolution , options.texture_packing_resolution );
152196 packer.process (out_model);
153197 }
198+ stopwatch.log_stage (" Texture packing" );
154199
155200 // 現在の都市モデルが地形であるなら、衛星写真または地図用のUVを付与し、地図タイルをダウンロードします。
156201 auto package = GmlFile (city_model.getGmlPath ()).getPackage ();
157202 if (package == PredefinedCityModelPackage::Relief && options.attach_map_tile ) {
158203 const auto gml_path = fs::u8path (city_model.getGmlPath ());
159204 const auto map_download_dest = gml_path.parent_path () / (gml_path.filename ().u8string () + " _map" );
160205 MapAttacher ().attach (out_model, options.map_tile_url , map_download_dest, options.map_tile_zoom_level ,
161- geo_reference);
206+ geo_reference);
162207 }
208+ stopwatch.log_stage (" Map attach" );
163209 }
164210}
165211
@@ -173,7 +219,11 @@ namespace plateau::polygonMesh {
173219
174220 void MeshExtractor::extract (Model& out_model, const CityModel& city_model,
175221 const MeshExtractOptions& options) {
176- extractInner (out_model, city_model, options, { plateau::geometry::Extent::all () });
222+ extractInner (out_model, city_model, options, { plateau::geometry::Extent::all () }, nullptr );
223+ }
224+
225+ void MeshExtractor::extract (Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::shared_ptr<citygml::CityGMLLogger>& logger) {
226+ extractInner (out_model, city_model, options, { plateau::geometry::Extent::all () }, logger);
177227 }
178228
179229 std::shared_ptr<Model> MeshExtractor::extractInExtents (
@@ -190,7 +240,11 @@ namespace plateau::polygonMesh {
190240 const MeshExtractOptions& options,
191241 const std::vector<plateau::geometry::Extent>& extents) {
192242
193- extractInner (out_model, city_model, options, extents);
243+ extractInner (out_model, city_model, options, extents, nullptr );
244+ }
245+
246+ void MeshExtractor::extractInExtents (Model& out_model, const citygml::CityModel& city_model, const MeshExtractOptions& options, const std::vector<plateau::geometry::Extent>& extents, const std::shared_ptr<citygml::CityGMLLogger>& logger) {
247+ extractInner (out_model, city_model, options, extents, logger);
194248 }
195249
196250
0 commit comments