@@ -184,46 +184,68 @@ namespace plateau::polygonMesh {
184184 city_objects.begin (), city_objects.end ());
185185 }
186186
187- auto merged_meshes = GridMergeResult ();
188-
189- // メッシュ生成
190- MeshFactory mesh_factory (nullptr , options, extents, geo_reference);
191-
192- // グループ内の各主要地物のループ
187+ // LODレベルでグループ分けします。
188+ // グループIDとグリッドIDのペアをキーとし、グリッドIDは常に0(グリッド分割なし)
189+ auto group_id_to_primary_objects_map = GroupGridIDToObjectsMap ();
193190 const auto & all_primary_city_objects_in_model = *all_primary_city_objects;
194- for (const auto & primary_object : all_primary_city_objects_in_model) {
195191
196- if (options.highest_lod_only ) {
197- // highest_lod_only オプションが有効な場合、最大LODのみを対象とします。
198- unsigned max_lod_in_obj = PolygonMeshUtils::max_lod_in_specification_;
199- for (unsigned target_lod = lod + 1 ; target_lod <= PolygonMeshUtils::max_lod_in_specification_; ++target_lod) {
200- bool target_lod_exists =
201- PolygonMeshUtils::findFirstPolygon (primary_object, target_lod) != nullptr ;
202- if (!target_lod_exists) {
203- max_lod_in_obj = target_lod - 1 ;
204- break ;
205- }
192+ for (const auto & primary_object : all_primary_city_objects_in_model) {
193+ // この CityObject について、最大でどのLODまで存在するか確認します。
194+ unsigned max_lod_in_obj = PolygonMeshUtils::max_lod_in_specification_;
195+ for (unsigned target_lod = lod + 1 ; target_lod <= PolygonMeshUtils::max_lod_in_specification_; ++target_lod) {
196+ bool target_lod_exists =
197+ PolygonMeshUtils::findFirstPolygon (primary_object, target_lod) != nullptr ;
198+ if (!target_lod_exists) {
199+ max_lod_in_obj = target_lod - 1 ;
200+ break ;
206201 }
202+ }
203+
204+ if (options.highest_lod_only ) {
205+ // highest_lod_only オプションが有効な場合、最大LODのみを対象とします。
207206 if (lod != max_lod_in_obj) {
208207 // 最大LOD以外はスキップします。
209208 continue ;
210209 }
211- }
212-
213- if (MeshExtractor::isTypeToSkip (primary_object->getType ())) continue ;
214- if (MeshExtractor::shouldContainPrimaryMesh (lod, *primary_object)) {
215- mesh_factory.addPolygonsInPrimaryCityObject (*primary_object, lod, gmlPath);
216210 }
217211
218- if (lod >= 2 ) {
219- // 主要地物の子である各最小地物をメッシュに加えます。
220- auto atomic_objects = PolygonMeshUtils::getChildCityObjectsRecursive (*primary_object);
221- mesh_factory.addPolygonsInAtomicCityObjects (*primary_object, atomic_objects, lod, gmlPath);
212+ // グループに追加します。
213+ // grid_idは常に0(グリッド分割なし)
214+ unsigned grid_id = 0 ;
215+ unsigned group_id = max_lod_in_obj;
216+ const auto group_grid_id = std::make_pair (group_id, grid_id);
217+
218+ if (group_id_to_primary_objects_map.find (group_grid_id) == group_id_to_primary_objects_map.end ())
219+ group_id_to_primary_objects_map[group_grid_id] = std::list<const CityObject*>();
220+
221+ group_id_to_primary_objects_map.at (group_grid_id).push_back (primary_object);
222+ }
223+
224+ // グループごとにメッシュを結合します。
225+ auto merged_meshes = GridMergeResult ();
226+
227+ // グループごとのループ
228+ for (const auto & [id, primary_objects] : group_id_to_primary_objects_map) {
229+ // 1グループのメッシュ生成
230+ MeshFactory mesh_factory (nullptr , options, extents, geo_reference);
231+
232+ // グループ内の各主要地物のループ
233+ for (const auto & primary_object : primary_objects) {
234+ if (MeshExtractor::isTypeToSkip (primary_object->getType ())) continue ;
235+ if (MeshExtractor::shouldContainPrimaryMesh (lod, *primary_object)) {
236+ mesh_factory.addPolygonsInPrimaryCityObject (*primary_object, lod, gmlPath);
237+ }
238+
239+ if (lod >= 2 ) {
240+ // 主要地物の子である各最小地物をメッシュに加えます。
241+ auto atomic_objects = PolygonMeshUtils::getChildCityObjectsRecursive (*primary_object);
242+ mesh_factory.addPolygonsInAtomicCityObjects (*primary_object, atomic_objects, lod, gmlPath);
243+ }
244+ mesh_factory.incrementPrimaryIndex ();
222245 }
223- mesh_factory.incrementPrimaryIndex ();
246+ mesh_factory.optimizeMesh ();
247+ merged_meshes.emplace (id, mesh_factory.releaseMesh ());
224248 }
225- mesh_factory.optimizeMesh ();
226- merged_meshes.emplace (std::make_pair (0 ,0 ), mesh_factory.releaseMesh ());
227249
228250 return merged_meshes;
229251 }
0 commit comments