Skip to content

Commit

Permalink
テクスチャ付き最大LODを出力するオプションを追加 (#647)
Browse files Browse the repository at this point in the history
<!-- Close or Related Issues -->
#643 (最適化が必要なのでクローズしません)
Close #644
Close #645

※不要なコミットが多いため `Squash and merge`を推奨


### What I did(変更内容)
<!-- Please describe the motivation behind this PR and the changes it
introduces. -->
<!-- どのような変更をしますか? 目的は? -->



- テクスチャ付き最大LODを出力するオプションを追加(`-t use_lod=textured_max_lod`)
- 単体のテクスチャありなしオプションを削除(`-t use_texture=true`)
- すべてのLODを抽出するオプションを追加(通常は機能しないため、開発時にコメントアウトを解除する)
- UI画面の初期ウィンドウサイズと各UIの間隔を修正(変換ボタンが見える様に)


![image](https://github.com/user-attachments/assets/3861ca1b-bdba-4c57-b5b5-16f579dea224)



### Notes(連絡事項)
<!-- If manual testing is required, please describe the procedure. -->
<!-- 手動での動作確認が必要なら手順を簡単に伝えてください。そのほか連絡事項など。 -->

動作確認
```sh

# テクスチャ付き最大LODを出力
cargo run -- <input_path> --sink gltf -t use_lod=textured_max_lod  -o --output <output_path>
```


```sh
# 全てのLODを出力 `nusamai/src/transformer/setting.rs`の`get_lod_selection_options()`内のコメントアウトを解除して実行
cargo run -- <input_path> --sink gltf -t use_lod=all_lod  -o --output <output_path>
```
  • Loading branch information
satoshi7190 authored Sep 25, 2024
1 parent 58eb3e2 commit 734ad3d
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 38 deletions.
2 changes: 1 addition & 1 deletion app/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"title": "PLATEAU GIS Converter",
"fullscreen": false,
"resizable": true,
"height": 800,
"height": 900,
"width": 640,
"minHeight": 600,
"minWidth": 500
Expand Down
2 changes: 1 addition & 1 deletion app/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
{/if}

<div class="py-5 grid place-items-center h-screen">
<div class="max-w-2xl flex flex-col gap-12 pb-8">
<div class="max-w-2xl flex flex-col gap-8 pb-4">
<div class="flex items-center gap-1.5">
<h1 class="font-bold text-2xl">PLATEAU GIS Converter</h1>
<a href="/about" class="hover:text-accent1">
Expand Down
2 changes: 1 addition & 1 deletion nusamai-plateau/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use nusamai_citygml::{geometry::GeometryStore, object::Value};
use crate::appearance::AppearanceStore;

/// City objects, features, objects or data
#[derive(Debug, serde::Deserialize, serde::Serialize)]
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct Entity {
/// Attribute tree
pub root: Value,
Expand Down
16 changes: 9 additions & 7 deletions nusamai/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ pub fn use_lod_config(default_value: &str) -> TransformerConfig {
TransformerConfig {
key: "use_lod".to_string(),
label: "出力LODの選択".to_string(),
parameter: transformer::ParameterType::Selection(LodSelection::create_lod_selection(
default_value,
)),
parameter: transformer::ParameterType::Selection(
LodSelection::lod_selection_without_texture(default_value),
),
}
}

pub fn use_texture_config(default_value: bool) -> TransformerConfig {
pub fn use_textured_lod_config(default_value: &str) -> TransformerConfig {
TransformerConfig {
key: "use_texture".to_string(),
label: "テクスチャの使用".to_string(),
parameter: transformer::ParameterType::Boolean(default_value),
key: "use_lod".to_string(),
label: "出力LODの選択".to_string(),
parameter: transformer::ParameterType::Selection(LodSelection::lod_selection_with_texture(
default_value,
)),
}
}
5 changes: 2 additions & 3 deletions nusamai/src/sink/cesiumtiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use url::Url;

use crate::{
get_parameter_value,
option::{use_lod_config, use_texture_config},
option::use_textured_lod_config,
parameters::*,
pipeline::{Feedback, PipelineError, Receiver, Result},
sink::{DataRequirements, DataSink, DataSinkProvider, SinkInfo},
Expand Down Expand Up @@ -69,8 +69,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider {

fn transformer_options(&self) -> TransformerRegistry {
let mut settings: TransformerRegistry = TransformerRegistry::new();
settings.insert(use_lod_config("max_lod"));
settings.insert(use_texture_config(false));
settings.insert(use_textured_lod_config("max_lod"));

settings
}
Expand Down
6 changes: 2 additions & 4 deletions nusamai/src/sink/gltf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use url::Url;

use crate::{
get_parameter_value,
option::{use_lod_config, use_texture_config},
option::use_textured_lod_config,
parameters::*,
pipeline::{Feedback, PipelineError, Receiver, Result},
sink::{cesiumtiles::metadata, DataRequirements, DataSink, DataSinkProvider, SinkInfo},
Expand Down Expand Up @@ -58,12 +58,10 @@ impl DataSinkProvider for GltfSinkProvider {

fn transformer_options(&self) -> TransformerRegistry {
let mut settings: TransformerRegistry = TransformerRegistry::new();
settings.insert(use_lod_config("max_lod"));
settings.insert(use_texture_config(false));
settings.insert(use_textured_lod_config("max_lod"));

settings
}

fn create(&self, params: &Parameters) -> Box<dyn DataSink> {
let output_path = get_parameter_value!(params, "@output", FileSystemPath);
let limit_texture_resolution =
Expand Down
5 changes: 2 additions & 3 deletions nusamai/src/sink/obj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use nusamai_projection::cartesian::geodetic_to_geocentric;

use crate::{
get_parameter_value,
option::{use_lod_config, use_texture_config},
option::use_textured_lod_config,
parameters::*,
pipeline::{Feedback, PipelineError, Receiver, Result},
sink::{DataRequirements, DataSink, DataSinkProvider, SinkInfo},
Expand Down Expand Up @@ -75,8 +75,7 @@ impl DataSinkProvider for ObjSinkProvider {

fn transformer_options(&self) -> TransformerRegistry {
let mut settings: TransformerRegistry = TransformerRegistry::new();
settings.insert(use_lod_config("max_lod"));
settings.insert(use_texture_config(false));
settings.insert(use_textured_lod_config("max_lod"));

settings
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/obj/obj_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ fn write_obj(

mesh_data.push((feature_id, mesh, vertex_offset, uv_offset));
}

let mut obj_writer = BufWriter::new(File::create(obj_path)?);

writeln!(obj_writer, "mtllib {}.mtl", file_name)?;
Expand Down
40 changes: 33 additions & 7 deletions nusamai/src/transformer/setting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,26 @@ pub struct LodSelection;

impl LodSelection {
pub fn get_lod_selection_options() -> Vec<(&'static str, &'static str)> {
vec![("最大LOD", "max_lod"), ("最小LOD", "min_lod")]
vec![
("最大LOD", "max_lod"),
("最小LOD", "min_lod"),
("テクスチャ付き最大LOD", "textured_max_lod"),
// This option will be used in 3dtiles sink
// ("すべてのLOD", "all_lod"),
]
}

pub fn create_lod_selection(default_value: &str) -> Selection {
pub fn lod_selection_with_texture(default_value: &str) -> Selection {
Selection::new(Self::get_lod_selection_options(), default_value)
}

pub fn lod_selection_without_texture(default_value: &str) -> Selection {
let options = Self::get_lod_selection_options()
.into_iter()
.filter(|&(_, value)| value != "textured_max_lod")
.collect::<Vec<_>>();
Selection::new(options, default_value)
}
}

#[derive(Debug, Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -135,10 +149,8 @@ impl TransformerRegistry {
ParameterType::String(_value) => {
// TODO: Processing for String types.
}
ParameterType::Boolean(value) => {
if config.key == "use_texture" {
data_requirements.set_appearance(*value);
}
ParameterType::Boolean(_value) => {
// TODO: Processing for Boolean types.
}
ParameterType::Integer(_value) => {
// TODO: Processing for Integer types.
Expand All @@ -150,14 +162,28 @@ impl TransformerRegistry {
data_requirements.set_lod_filter(transformer::LodFilterSpec {
mode: transformer::LodFilterMode::Highest,
..Default::default()
})
});
}
"min_lod" => {
data_requirements.set_lod_filter(transformer::LodFilterSpec {
mode: transformer::LodFilterMode::Lowest,
..Default::default()
})
}
"textured_max_lod" => {
data_requirements.set_lod_filter(transformer::LodFilterSpec {
mode: transformer::LodFilterMode::TexturedHighest,
..Default::default()
});
data_requirements.set_appearance(true);
}
"all_lod" => {
data_requirements.set_lod_filter(transformer::LodFilterSpec {
mode: transformer::LodFilterMode::All,
..Default::default()
});
data_requirements.set_appearance(true);
}
_ => {}
}
}
Expand Down
76 changes: 65 additions & 11 deletions nusamai/src/transformer/transform/lods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::{pipeline::Feedback, transformer::Transform};
pub enum LodFilterMode {
Highest,
Lowest,
TexturedHighest,
All,
}

#[derive()]
Expand All @@ -29,16 +31,68 @@ impl FilterLodTransform {
/// Transform to filter and split the LODs
impl Transform for FilterLodTransform {
fn transform(&mut self, _feedback: &Feedback, mut entity: Entity, out: &mut Vec<Entity>) {
let lods = find_lods(&entity.root) & self.mask;

let target_lod = match self.mode {
LodFilterMode::Highest => lods.highest_lod(),
LodFilterMode::Lowest => lods.lowest_lod(),
};

if let Some(target_lod) = target_lod {
edit_tree(&mut entity.root, target_lod);
out.push(entity);
match self.mode {
LodFilterMode::TexturedHighest => {
// TODO: Processing needs to be optimised
let original_lods = find_lods(&entity.root) & self.mask;
let mut current_lods = original_lods;
let mut highest_lod_entity = None;

while current_lods.0 != 0 {
let target_lod = current_lods.highest_lod();

if let Some(lod) = target_lod {
// Create a copy of the entity
let mut entity_copy = entity.clone();
edit_tree(&mut entity_copy.root, lod);

let has_textures = {
let appearance = entity_copy.appearance_store.read().unwrap();
!appearance.textures.is_empty()
};

if has_textures {
out.push(entity_copy);
return;
} else {
// Save the highest LOD entity
if highest_lod_entity.is_none() {
highest_lod_entity = Some(entity_copy);
}
// Exclude the current LOD and try the next LOD
current_lods.0 &= !(1 << lod);
}
} else {
break;
}
}

// If no texture is found, push entity with highest LOD
if let Some(highest_entity) = highest_lod_entity {
out.push(highest_entity);
}
}
LodFilterMode::Highest => {
let lods = find_lods(&entity.root) & self.mask;
let target_lod = lods.highest_lod();

if let Some(target_lod) = target_lod {
edit_tree(&mut entity.root, target_lod);
out.push(entity);
}
}
LodFilterMode::Lowest => {
let lods = find_lods(&entity.root) & self.mask;
let target_lod = lods.lowest_lod();

if let Some(target_lod) = target_lod {
edit_tree(&mut entity.root, target_lod);
out.push(entity);
}
}
LodFilterMode::All => {
out.push(entity);
}
}
}

Expand Down Expand Up @@ -92,7 +146,7 @@ fn find_lods(value: &Value) -> LodMask {
mask
}

#[derive(Default, Clone, Copy)]
#[derive(Default, Clone, Copy, Debug)]
pub struct LodMask(
u8, // lods bit mask
);
Expand Down

0 comments on commit 734ad3d

Please sign in to comment.