From 3f35536566cf39160fb5098033015cca9fa46a4f Mon Sep 17 00:00:00 2001 From: azukizuki Date: Sat, 1 Nov 2025 15:15:26 +0900 Subject: [PATCH 1/2] =?UTF-8?q?combine=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=A7=E3=82=82group=E5=8D=98=E4=BD=8D=E3=81=A7=E5=88=86?= =?UTF-8?q?=E5=89=B2=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polygon_mesh/area_mesh_factory.cpp | 80 ++++++++++++++++---------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 276ec5ba..950ff57e 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -184,46 +184,68 @@ namespace plateau::polygonMesh { city_objects.begin(), city_objects.end()); } - auto merged_meshes = GridMergeResult(); - - // メッシュ生成 - MeshFactory mesh_factory(nullptr, options, extents, geo_reference); - - // グループ内の各主要地物のループ + // LODレベルでグループ分けします。 + // グループIDとグリッドIDのペアをキーとし、グリッドIDは常に0(グリッド分割なし) + auto group_id_to_primary_objects_map = GroupGridIDToObjectsMap(); const auto& all_primary_city_objects_in_model = *all_primary_city_objects; - for (const auto& primary_object : all_primary_city_objects_in_model) { - if (options.highest_lod_only) { - // highest_lod_only オプションが有効な場合、最大LODのみを対象とします。 - unsigned max_lod_in_obj = PolygonMeshUtils::max_lod_in_specification_; - for (unsigned target_lod = lod + 1; target_lod <= PolygonMeshUtils::max_lod_in_specification_; ++target_lod) { - bool target_lod_exists = - PolygonMeshUtils::findFirstPolygon(primary_object, target_lod) != nullptr; - if (!target_lod_exists) { - max_lod_in_obj = target_lod - 1; - break; - } + for (const auto& primary_object : all_primary_city_objects_in_model) { + // この CityObject について、最大でどのLODまで存在するか確認します。 + unsigned max_lod_in_obj = PolygonMeshUtils::max_lod_in_specification_; + for (unsigned target_lod = lod + 1; target_lod <= PolygonMeshUtils::max_lod_in_specification_; ++target_lod) { + bool target_lod_exists = + PolygonMeshUtils::findFirstPolygon(primary_object, target_lod) != nullptr; + if (!target_lod_exists) { + max_lod_in_obj = target_lod - 1; + break; } + } + + if (options.highest_lod_only) { + // highest_lod_only オプションが有効な場合、最大LODのみを対象とします。 if (lod != max_lod_in_obj) { // 最大LOD以外はスキップします。 continue; } - } - - if (MeshExtractor::isTypeToSkip(primary_object->getType())) continue; - if (MeshExtractor::shouldContainPrimaryMesh(lod, *primary_object)) { - mesh_factory.addPolygonsInPrimaryCityObject(*primary_object, lod, gmlPath); } - if (lod >= 2) { - // 主要地物の子である各最小地物をメッシュに加えます。 - auto atomic_objects = PolygonMeshUtils::getChildCityObjectsRecursive(*primary_object); - mesh_factory.addPolygonsInAtomicCityObjects(*primary_object, atomic_objects, lod, gmlPath); + // グループに追加します。 + // grid_idは常に0(グリッド分割なし) + unsigned grid_id = 0; + unsigned group_id = max_lod_in_obj; + const auto group_grid_id = std::make_pair(group_id, grid_id); + + if (group_id_to_primary_objects_map.find(group_grid_id) == group_id_to_primary_objects_map.end()) + group_id_to_primary_objects_map[group_grid_id] = std::list(); + + group_id_to_primary_objects_map.at(group_grid_id).push_back(primary_object); + } + + // グループごとにメッシュを結合します。 + auto merged_meshes = GridMergeResult(); + + // グループごとのループ + for (const auto& [id, primary_objects] : group_id_to_primary_objects_map) { + // 1グループのメッシュ生成 + MeshFactory mesh_factory(nullptr, options, extents, geo_reference); + + // グループ内の各主要地物のループ + for (const auto& primary_object : primary_objects) { + if(MeshExtractor::isTypeToSkip(primary_object->getType())) continue; + if (MeshExtractor::shouldContainPrimaryMesh(lod, *primary_object)) { + mesh_factory.addPolygonsInPrimaryCityObject(*primary_object, lod, gmlPath); + } + + if (lod >= 2) { + // 主要地物の子である各最小地物をメッシュに加えます。 + auto atomic_objects = PolygonMeshUtils::getChildCityObjectsRecursive(*primary_object); + mesh_factory.addPolygonsInAtomicCityObjects(*primary_object, atomic_objects, lod, gmlPath); + } + mesh_factory.incrementPrimaryIndex(); } - mesh_factory.incrementPrimaryIndex(); + mesh_factory.optimizeMesh(); + merged_meshes.emplace(id, mesh_factory.releaseMesh()); } - mesh_factory.optimizeMesh(); - merged_meshes.emplace(std::make_pair(0,0), mesh_factory.releaseMesh()); return merged_meshes; } From 1614f736c2474801d4cb59a09e6e6146c927481b Mon Sep 17 00:00:00 2001 From: azukizuki Date: Sun, 9 Nov 2025 04:45:44 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/polygon_mesh/area_mesh_factory.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/polygon_mesh/area_mesh_factory.cpp b/src/polygon_mesh/area_mesh_factory.cpp index 950ff57e..bee3f3d4 100644 --- a/src/polygon_mesh/area_mesh_factory.cpp +++ b/src/polygon_mesh/area_mesh_factory.cpp @@ -15,6 +15,7 @@ namespace { */ using GridIDToObjectsMap = std::map>; using GroupGridIDToObjectsMap = std::map, std::list>; + using GroupGridIDToObjectsWithPathMap = std::map, std::list>>; bool shouldSkipCityObj(const citygml::CityObject& city_obj, const MeshExtractOptions& options, const std::vector& extents) { if (!options.exclude_city_object_outside_extent) @@ -169,27 +170,30 @@ namespace plateau::polygonMesh { AreaMeshFactory::combine(const CityModelVector& city_models, const MeshExtractOptions& options, unsigned lod, const plateau::geometry::GeoReference& geo_reference, const std::vector& extents) { - const auto& gmlPath = city_models->empty() || city_models->front().expired() ? "" : city_models->front().lock()->getGmlPath(); - std::shared_ptr > all_primary_city_objects = std::make_shared>(); + // 各CityObjectとそのソースのgmlPathをペアで保持 + std::shared_ptr>> all_primary_city_objects = + std::make_shared>>(); const auto& _city_models = *city_models; for (const auto& city_model : _city_models) { if (city_model.expired()) continue; // 参照が切れている場合はスキップ + const auto& gmlPath = city_model.lock()->getGmlPath(); auto city_objects = city_model.lock()->getAllCityObjectsOfType(PrimaryCityObjectTypes::getPrimaryTypeMask()); - all_primary_city_objects->insert(all_primary_city_objects->end(), - city_objects.begin(), city_objects.end()); + for (const auto& city_obj : city_objects) { + all_primary_city_objects->emplace_back(city_obj, gmlPath); + } } // LODレベルでグループ分けします。 // グループIDとグリッドIDのペアをキーとし、グリッドIDは常に0(グリッド分割なし) - auto group_id_to_primary_objects_map = GroupGridIDToObjectsMap(); + auto group_id_to_primary_objects_map = GroupGridIDToObjectsWithPathMap(); const auto& all_primary_city_objects_in_model = *all_primary_city_objects; - for (const auto& primary_object : all_primary_city_objects_in_model) { + for (const auto& [primary_object, gmlPath] : all_primary_city_objects_in_model) { // この CityObject について、最大でどのLODまで存在するか確認します。 unsigned max_lod_in_obj = PolygonMeshUtils::max_lod_in_specification_; for (unsigned target_lod = lod + 1; target_lod <= PolygonMeshUtils::max_lod_in_specification_; ++target_lod) { @@ -216,9 +220,9 @@ namespace plateau::polygonMesh { const auto group_grid_id = std::make_pair(group_id, grid_id); if (group_id_to_primary_objects_map.find(group_grid_id) == group_id_to_primary_objects_map.end()) - group_id_to_primary_objects_map[group_grid_id] = std::list(); + group_id_to_primary_objects_map[group_grid_id] = std::list>(); - group_id_to_primary_objects_map.at(group_grid_id).push_back(primary_object); + group_id_to_primary_objects_map.at(group_grid_id).emplace_back(primary_object, gmlPath); } // グループごとにメッシュを結合します。 @@ -230,7 +234,7 @@ namespace plateau::polygonMesh { MeshFactory mesh_factory(nullptr, options, extents, geo_reference); // グループ内の各主要地物のループ - for (const auto& primary_object : primary_objects) { + for (const auto& [primary_object, gmlPath] : primary_objects) { if(MeshExtractor::isTypeToSkip(primary_object->getType())) continue; if (MeshExtractor::shouldContainPrimaryMesh(lod, *primary_object)) { mesh_factory.addPolygonsInPrimaryCityObject(*primary_object, lod, gmlPath);