From db14aa57944f4a6e6fe6a93578556042d7310eb3 Mon Sep 17 00:00:00 2001 From: TadaTeruki Date: Thu, 29 Aug 2024 11:16:47 +0900 Subject: [PATCH 1/5] =?UTF-8?q?max-texture-pixels-per-meter=E7=94=A8?= =?UTF-8?q?=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nusamai/src/parameters/mod.rs | 42 +++++++++++++++++++++++++++++ nusamai/src/sink/cesiumtiles/mod.rs | 30 +++++++++++++++++---- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/nusamai/src/parameters/mod.rs b/nusamai/src/parameters/mod.rs index 9ce20f8a2..55aa28b93 100644 --- a/nusamai/src/parameters/mod.rs +++ b/nusamai/src/parameters/mod.rs @@ -118,6 +118,7 @@ impl ParameterEntry { ParameterType::String(p) => p.validate(self.required), ParameterType::Boolean(p) => p.validate(self.required), ParameterType::Integer(p) => p.validate(self.required), + ParameterType::Float64(p) => p.validate(self.required), } } @@ -128,6 +129,7 @@ impl ParameterEntry { ParameterType::String(p) => p.update_value_with_str(s), ParameterType::Boolean(p) => p.update_value_with_str(s), ParameterType::Integer(p) => p.update_value_with_str(s), + ParameterType::Float64(p) => p.update_value_with_str(s), } } @@ -138,6 +140,7 @@ impl ParameterEntry { ParameterType::String(p) => p.update_value_with_json(v), ParameterType::Boolean(p) => p.update_value_with_json(v), ParameterType::Integer(p) => p.update_value_with_json(v), + ParameterType::Float64(p) => p.update_value_with_json(v), } } } @@ -148,6 +151,7 @@ pub enum ParameterType { String(StringParameter), Boolean(BooleanParameter), Integer(IntegerParameter), + Float64(Float64Parameter), // and so on ... } @@ -253,6 +257,44 @@ impl BooleanParameter { } } +#[derive(Debug, Serialize, Deserialize)] +pub struct Float64Parameter { + pub value: Option, +} + +impl Float64Parameter { + pub fn validate(&self, required: bool) -> Result<(), Error> { + if required { + match &self.value { + Some(_) => Ok(()), + _ => Err(Error::RequiredValueNotProvided), + } + } else { + Ok(()) + } + } + + pub fn update_value_with_str(&mut self, s: &str) -> Result<(), Error> { + let Ok(v) = s.parse::() else { + return Err(Error::InvalidValue("Value must be a boolean.".into())); + }; + self.value = Some(v); + Ok(()) + } + + pub fn update_value_with_json(&mut self, v: &serde_json::Value) -> Result<(), Error> { + if let serde_json::Value::Number(n) = v { + if let Some(v) = n.as_f64() { + self.value = Some(v); + return Ok(()); + } + } + Err(Error::InvalidValue( + "Value must be a floating-point number.".into(), + )) + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct IntegerParameter { pub value: Option, diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index 322225091..444e499fe 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,8 +46,6 @@ use crate::{ }; use utils::calculate_normal; -const MAX_PIXEL_PER_DISTANCE: f64 = 30.0; - // WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { uv_coords @@ -98,6 +96,16 @@ impl DataSinkProvider for CesiumTilesSinkProvider { }, ); + params.define( + "max-texture-pixels-per-meter".into(), + ParameterEntry { + description: "limiting texture resolution".into(), + required: false, + parameter: ParameterType::Float64(Float64Parameter { value: Some(30.0) }), + label: Some("距離(メートル)あたりのテクスチャの最大解像度".into()), + }, + ); + params } @@ -116,11 +124,14 @@ impl DataSinkProvider for CesiumTilesSinkProvider { fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); + let max_texture_pixels_per_meter = + *get_parameter_value!(params, "max-texture-pixels-per-meter", Float64); let transformer_registry = self.available_transformer(); Box::::new(CesiumTilesSink { output_path: output_path.as_ref().unwrap().into(), transformer_registry, + max_texture_pixels_per_meter, }) } } @@ -128,6 +139,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { struct CesiumTilesSink { output_path: PathBuf, transformer_registry: TransformerRegistry, + max_texture_pixels_per_meter: Option, } impl DataSink for CesiumTilesSink { @@ -157,6 +169,8 @@ impl DataSink for CesiumTilesSink { let min_zoom = 12; let max_zoom = 18; + let max_texture_pixels_per_meter = self.max_texture_pixels_per_meter; + // TODO: refactoring std::thread::scope(|s| { @@ -203,6 +217,7 @@ impl DataSink for CesiumTilesSink { receiver_sorted, tile_id_conv, schema, + max_texture_pixels_per_meter, ) { feedback.fatal_error(error); } @@ -324,6 +339,7 @@ fn tile_writing_stage( receiver_sorted: mpsc::Receiver<(u64, String, Vec>)>, tile_id_conv: TileIdMethod, schema: &Schema, + max_texture_pixels_per_meter: Option, ) -> Result<()> { let ellipsoid = nusamai_projection::ellipsoid::wgs84(); let contents: Arc>> = Default::default(); @@ -560,9 +576,13 @@ fn tile_writing_stage( .min_by(|a, b| a.total_cmp(b)) .unwrap_or(1.0); - let max_pixel_per_distance = MAX_PIXEL_PER_DISTANCE; - let downsample_scale = - (1.0_f64).min(max_pixel_per_distance / pixel_per_distance); + let downsample_scale = if let Some(max_texture_pixels_per_meter) = + max_texture_pixels_per_meter + { + 1.0_f64.min(max_texture_pixels_per_meter / pixel_per_distance) + } else { + 1.0 + }; let factor = apply_downsample_factor(tile_zoom, downsample_scale as f32); let downsample_factor = DownsampleFactor::new(&factor); From 175e8b62fbe5fb1c00695ea0565d653480fd939b Mon Sep 17 00:00:00 2001 From: Tada Teruki Date: Thu, 29 Aug 2024 17:31:42 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=E3=83=86=E3=82=AF=E3=82=B9=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=81=AE=E3=82=B9=E3=82=B1=E3=83=BC=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E3=81=AE=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=AE=E4=BB=95=E6=A7=98=E5=A4=89=E6=9B=B4=20(Float64=20->?= =?UTF-8?q?=20Boolean)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nusamai/src/parameters/mod.rs | 42 ----------------------------- nusamai/src/sink/cesiumtiles/mod.rs | 28 +++++++++---------- 2 files changed, 14 insertions(+), 56 deletions(-) diff --git a/nusamai/src/parameters/mod.rs b/nusamai/src/parameters/mod.rs index 55aa28b93..9ce20f8a2 100644 --- a/nusamai/src/parameters/mod.rs +++ b/nusamai/src/parameters/mod.rs @@ -118,7 +118,6 @@ impl ParameterEntry { ParameterType::String(p) => p.validate(self.required), ParameterType::Boolean(p) => p.validate(self.required), ParameterType::Integer(p) => p.validate(self.required), - ParameterType::Float64(p) => p.validate(self.required), } } @@ -129,7 +128,6 @@ impl ParameterEntry { ParameterType::String(p) => p.update_value_with_str(s), ParameterType::Boolean(p) => p.update_value_with_str(s), ParameterType::Integer(p) => p.update_value_with_str(s), - ParameterType::Float64(p) => p.update_value_with_str(s), } } @@ -140,7 +138,6 @@ impl ParameterEntry { ParameterType::String(p) => p.update_value_with_json(v), ParameterType::Boolean(p) => p.update_value_with_json(v), ParameterType::Integer(p) => p.update_value_with_json(v), - ParameterType::Float64(p) => p.update_value_with_json(v), } } } @@ -151,7 +148,6 @@ pub enum ParameterType { String(StringParameter), Boolean(BooleanParameter), Integer(IntegerParameter), - Float64(Float64Parameter), // and so on ... } @@ -257,44 +253,6 @@ impl BooleanParameter { } } -#[derive(Debug, Serialize, Deserialize)] -pub struct Float64Parameter { - pub value: Option, -} - -impl Float64Parameter { - pub fn validate(&self, required: bool) -> Result<(), Error> { - if required { - match &self.value { - Some(_) => Ok(()), - _ => Err(Error::RequiredValueNotProvided), - } - } else { - Ok(()) - } - } - - pub fn update_value_with_str(&mut self, s: &str) -> Result<(), Error> { - let Ok(v) = s.parse::() else { - return Err(Error::InvalidValue("Value must be a boolean.".into())); - }; - self.value = Some(v); - Ok(()) - } - - pub fn update_value_with_json(&mut self, v: &serde_json::Value) -> Result<(), Error> { - if let serde_json::Value::Number(n) = v { - if let Some(v) = n.as_f64() { - self.value = Some(v); - return Ok(()); - } - } - Err(Error::InvalidValue( - "Value must be a floating-point number.".into(), - )) - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct IntegerParameter { pub value: Option, diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index 444e499fe..bf5a103c6 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,6 +46,8 @@ use crate::{ }; use utils::calculate_normal; +const MAX_TEXTURE_PIXELS_PER_METER: f64 = 3.0; + // WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { uv_coords @@ -97,12 +99,12 @@ impl DataSinkProvider for CesiumTilesSinkProvider { ); params.define( - "max-texture-pixels-per-meter".into(), + "limit-texture-pixels-per-meter".into(), ParameterEntry { description: "limiting texture resolution".into(), required: false, - parameter: ParameterType::Float64(Float64Parameter { value: Some(30.0) }), - label: Some("距離(メートル)あたりのテクスチャの最大解像度".into()), + parameter: ParameterType::Boolean(BooleanParameter { value: None }), + label: Some("距離(メートル)あたりのテクスチャの解像度を制限する".into()), }, ); @@ -124,14 +126,14 @@ impl DataSinkProvider for CesiumTilesSinkProvider { fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); - let max_texture_pixels_per_meter = - *get_parameter_value!(params, "max-texture-pixels-per-meter", Float64); + let limit_texture_pixels_per_meter = + *get_parameter_value!(params, "limit-texture-pixels-per-meter", Boolean); let transformer_registry = self.available_transformer(); Box::::new(CesiumTilesSink { output_path: output_path.as_ref().unwrap().into(), transformer_registry, - max_texture_pixels_per_meter, + limit_texture_pixels_per_meter, }) } } @@ -139,7 +141,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { struct CesiumTilesSink { output_path: PathBuf, transformer_registry: TransformerRegistry, - max_texture_pixels_per_meter: Option, + limit_texture_pixels_per_meter: Option, } impl DataSink for CesiumTilesSink { @@ -169,7 +171,7 @@ impl DataSink for CesiumTilesSink { let min_zoom = 12; let max_zoom = 18; - let max_texture_pixels_per_meter = self.max_texture_pixels_per_meter; + let limit_texture_pixels_per_meter = self.limit_texture_pixels_per_meter; // TODO: refactoring @@ -217,7 +219,7 @@ impl DataSink for CesiumTilesSink { receiver_sorted, tile_id_conv, schema, - max_texture_pixels_per_meter, + limit_texture_pixels_per_meter, ) { feedback.fatal_error(error); } @@ -339,7 +341,7 @@ fn tile_writing_stage( receiver_sorted: mpsc::Receiver<(u64, String, Vec>)>, tile_id_conv: TileIdMethod, schema: &Schema, - max_texture_pixels_per_meter: Option, + limit_texture_pixels_per_meter: Option, ) -> Result<()> { let ellipsoid = nusamai_projection::ellipsoid::wgs84(); let contents: Arc>> = Default::default(); @@ -576,10 +578,8 @@ fn tile_writing_stage( .min_by(|a, b| a.total_cmp(b)) .unwrap_or(1.0); - let downsample_scale = if let Some(max_texture_pixels_per_meter) = - max_texture_pixels_per_meter - { - 1.0_f64.min(max_texture_pixels_per_meter / pixel_per_distance) + let downsample_scale = if limit_texture_pixels_per_meter.unwrap_or(false) { + 1.0_f64.min(MAX_TEXTURE_PIXELS_PER_METER / pixel_per_distance) } else { 1.0 }; From a983433b380c4173bf39b1297b818ad032b0fcf7 Mon Sep 17 00:00:00 2001 From: Tada Teruki Date: Fri, 30 Aug 2024 15:29:17 +0900 Subject: [PATCH 3/5] =?UTF-8?q?=E3=83=86=E3=82=AF=E3=82=B9=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=81=AE=E3=82=B9=E3=82=B1=E3=83=BC=E3=83=AA=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E3=81=AE=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E5=90=8D=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nusamai/src/sink/cesiumtiles/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index bf5a103c6..f93c345b4 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,7 +46,7 @@ use crate::{ }; use utils::calculate_normal; -const MAX_TEXTURE_PIXELS_PER_METER: f64 = 3.0; +const MAX_TEXTURE_PIXELS_PER_METER: f64 = 30.0; // WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { @@ -99,7 +99,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { ); params.define( - "limit-texture-pixels-per-meter".into(), + "limit_texture_resolution".into(), ParameterEntry { description: "limiting texture resolution".into(), required: false, @@ -126,14 +126,14 @@ impl DataSinkProvider for CesiumTilesSinkProvider { fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); - let limit_texture_pixels_per_meter = - *get_parameter_value!(params, "limit-texture-pixels-per-meter", Boolean); + let limit_texture_resolution = + *get_parameter_value!(params, "limit_texture_resolution", Boolean); let transformer_registry = self.available_transformer(); Box::::new(CesiumTilesSink { output_path: output_path.as_ref().unwrap().into(), transformer_registry, - limit_texture_pixels_per_meter, + limit_texture_resolution, }) } } @@ -141,7 +141,7 @@ impl DataSinkProvider for CesiumTilesSinkProvider { struct CesiumTilesSink { output_path: PathBuf, transformer_registry: TransformerRegistry, - limit_texture_pixels_per_meter: Option, + limit_texture_resolution: Option, } impl DataSink for CesiumTilesSink { @@ -171,7 +171,7 @@ impl DataSink for CesiumTilesSink { let min_zoom = 12; let max_zoom = 18; - let limit_texture_pixels_per_meter = self.limit_texture_pixels_per_meter; + let limit_texture_resolution = self.limit_texture_resolution; // TODO: refactoring @@ -219,7 +219,7 @@ impl DataSink for CesiumTilesSink { receiver_sorted, tile_id_conv, schema, - limit_texture_pixels_per_meter, + limit_texture_resolution, ) { feedback.fatal_error(error); } @@ -341,7 +341,7 @@ fn tile_writing_stage( receiver_sorted: mpsc::Receiver<(u64, String, Vec>)>, tile_id_conv: TileIdMethod, schema: &Schema, - limit_texture_pixels_per_meter: Option, + limit_texture_resolution: Option, ) -> Result<()> { let ellipsoid = nusamai_projection::ellipsoid::wgs84(); let contents: Arc>> = Default::default(); @@ -578,7 +578,7 @@ fn tile_writing_stage( .min_by(|a, b| a.total_cmp(b)) .unwrap_or(1.0); - let downsample_scale = if limit_texture_pixels_per_meter.unwrap_or(false) { + let downsample_scale = if limit_texture_resolution.unwrap_or(false) { 1.0_f64.min(MAX_TEXTURE_PIXELS_PER_METER / pixel_per_distance) } else { 1.0 From 331c466383d6d4f71bdbb05a22f1c31facba8496 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Aug 2024 12:14:22 +0900 Subject: [PATCH 4/5] Bump svelte from 4.2.11 to 4.2.19 in /app in the npm_and_yarn group across 1 directory (#632) Bumps the npm_and_yarn group with 1 update in the /app directory: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte). Updates `svelte` from 4.2.11 to 4.2.19
Release notes

Sourced from svelte's releases.

svelte@4.2.19

Patch Changes

  • fix: ensure typings for <svelte:options> are picked up (#12902)

  • fix: escape < in attribute strings (#12989)

svelte@4.2.18

Patch Changes

  • chore: speed up regex (#11922)
Changelog

Sourced from svelte's changelog.

4.2.19

Patch Changes

  • fix: ensure typings for <svelte:options> are picked up (#12902)

  • fix: escape < in attribute strings (#12989)

4.2.18

Patch Changes

  • chore: speed up regex (#11922)

4.2.17

Patch Changes

  • fix: correctly handle falsy values of style directives in SSR mode (#11584)

4.2.16

Patch Changes

  • fix: check if svelte component exists on custom element destroy (#11489)

4.2.15

Patch Changes

  • support attribute selector inside :global() (#11135)

4.2.14

Patch Changes

  • fix parsing camelcase container query name (#11131)

4.2.13

Patch Changes

  • fix: applying :global for +,~ sibling combinator when slots are present (#9282)

4.2.12

Patch Changes

  • fix: properly update svelte:component props when there are spread props (#10604)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=svelte&package-manager=npm_and_yarn&previous-version=4.2.11&new-version=4.2.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/MIERUNE/plateau-gis-converter/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- app/package-lock.json | 8 ++++---- app/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index ea4b5a737..0f9da3653 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -25,7 +25,7 @@ "postcss": "^8.4.35", "prettier": "^3.2.5", "prettier-plugin-svelte": "^3.1.2", - "svelte": "^4.2.10", + "svelte": "^4.2.19", "svelte-check": "^3.6.4", "svelte-virtual-scroll-list": "^1.3.0", "tailwindcss": "^3.4.1", @@ -4372,9 +4372,9 @@ } }, "node_modules/svelte": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.11.tgz", - "integrity": "sha512-YIQk3J4X89wOLhjsqIW8tqY3JHPuBdtdOIkASP2PZeAMcSW9RsIjQzMesCrxOF3gdWYC0mKknlKF7OqmLM+Zqg==", + "version": "4.2.19", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", + "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", diff --git a/app/package.json b/app/package.json index 005414ec3..cd7e99076 100644 --- a/app/package.json +++ b/app/package.json @@ -27,7 +27,7 @@ "postcss": "^8.4.35", "prettier": "^3.2.5", "prettier-plugin-svelte": "^3.1.2", - "svelte": "^4.2.10", + "svelte": "^4.2.19", "svelte-check": "^3.6.4", "svelte-virtual-scroll-list": "^1.3.0", "tailwindcss": "^3.4.1", From 7e77d883cdfb15fe9ddcf47d96be4f59276a26b6 Mon Sep 17 00:00:00 2001 From: Teruki TADA Date: Mon, 2 Sep 2024 08:44:14 +0900 Subject: [PATCH 5/5] =?UTF-8?q?=E3=83=86=E3=82=AF=E3=82=B9=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=82=B9=E3=82=B1=E3=83=BC=E3=83=AA=E3=83=B3=E3=82=B0?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92glTF=E3=81=8A=E3=82=88=E3=81=B3OBJ?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=81=AB=E3=82=82=E5=B0=8E=E5=85=A5=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(#631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close #626 ### What I did(変更内容) - objやglTFにおけるテクスチャのスケーリング対応・オプションの追加 ### Notes(連絡事項) --- nusamai/src/sink/cesiumtiles/mod.rs | 59 +++----------------------- nusamai/src/sink/gltf/mod.rs | 25 ++++++++++- nusamai/src/sink/mod.rs | 1 + nusamai/src/sink/obj/mod.rs | 27 +++++++++++- nusamai/src/sink/texture_resolution.rs | 53 +++++++++++++++++++++++ 5 files changed, 110 insertions(+), 55 deletions(-) create mode 100644 nusamai/src/sink/texture_resolution.rs diff --git a/nusamai/src/sink/cesiumtiles/mod.rs b/nusamai/src/sink/cesiumtiles/mod.rs index f93c345b4..c19355369 100644 --- a/nusamai/src/sink/cesiumtiles/mod.rs +++ b/nusamai/src/sink/cesiumtiles/mod.rs @@ -46,20 +46,7 @@ use crate::{ }; use utils::calculate_normal; -const MAX_TEXTURE_PIXELS_PER_METER: f64 = 30.0; - -// WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. -fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { - uv_coords - .iter() - .map(|(u, v)| { - ( - (u.clamp(0.0, 1.0) * width as f64).min(width as f64 - 1.0) as u32, - ((1.0 - v.clamp(0.0, 1.0)) * height as f64).min(height as f64 - 1.0) as u32, - ) - }) - .collect() -} +use super::texture_resolution::get_texture_downsample_scale_of_polygon; pub struct CesiumTilesSinkProvider {} @@ -544,45 +531,11 @@ fn tile_writing_stage( let texture_uri = base_texture.uri.to_file_path().unwrap(); let texture_size = texture_size_cache.get_or_insert(&texture_uri); - let pixel_coords = - uv_to_pixel_coords(&uv_coords, texture_size.0, texture_size.1); - - let pixel_per_distance = (0..original_vertices.len()) - .map(|i| { - let j = (i + 1) % original_vertices.len(); - let (euc0, txl0) = ( - ( - original_vertices[i].0, - original_vertices[i].1, - original_vertices[i].2, - ), - pixel_coords[i], - ); - let (euc1, txl1) = ( - ( - original_vertices[j].0, - original_vertices[j].1, - original_vertices[j].2, - ), - pixel_coords[j], - ); - let euc_dist = ((euc0.0 - euc1.0).powi(2) - + (euc0.1 - euc1.1).powi(2) - + (euc0.2 - euc1.2).powi(2)) - .sqrt(); - let txl_dist = ((txl0.0 as f64 - txl1.0 as f64).powi(2) - + (txl0.1 as f64 - txl1.1 as f64).powi(2)) - .sqrt(); - txl_dist / euc_dist - }) - .min_by(|a, b| a.total_cmp(b)) - .unwrap_or(1.0); - - let downsample_scale = if limit_texture_resolution.unwrap_or(false) { - 1.0_f64.min(MAX_TEXTURE_PIXELS_PER_METER / pixel_per_distance) - } else { - 1.0 - }; + let downsample_scale = get_texture_downsample_scale_of_polygon( + &original_vertices, + texture_size, + limit_texture_resolution, + ); let factor = apply_downsample_factor(tile_zoom, downsample_scale as f32); let downsample_factor = DownsampleFactor::new(&factor); diff --git a/nusamai/src/sink/gltf/mod.rs b/nusamai/src/sink/gltf/mod.rs index a7931714d..cd13c5368 100644 --- a/nusamai/src/sink/gltf/mod.rs +++ b/nusamai/src/sink/gltf/mod.rs @@ -36,6 +36,8 @@ use crate::{ transformer::{TransformerConfig, TransformerOption, TransformerRegistry}, }; +use super::texture_resolution::get_texture_downsample_scale_of_polygon; + pub struct GltfSinkProvider {} impl DataSinkProvider for GltfSinkProvider { @@ -71,6 +73,16 @@ impl DataSinkProvider for GltfSinkProvider { }, ); + params.define( + "limit_texture_resolution".into(), + ParameterEntry { + description: "limiting texture resolution".into(), + required: false, + parameter: ParameterType::Boolean(BooleanParameter { value: None }), + label: Some("距離(メートル)あたりのテクスチャの解像度を制限する".into()), + }, + ); + params } @@ -89,11 +101,14 @@ impl DataSinkProvider for GltfSinkProvider { fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); + let limit_texture_resolution = + *get_parameter_value!(params, "limit_texture_resolution", Boolean); let transform_settings = self.available_transformer(); Box::::new(GltfSink { output_path: output_path.as_ref().unwrap().into(), transform_settings, + limit_texture_resolution, }) } } @@ -101,6 +116,7 @@ impl DataSinkProvider for GltfSinkProvider { pub struct GltfSink { output_path: PathBuf, transform_settings: TransformerRegistry, + limit_texture_resolution: Option, } pub struct BoundingVolume { @@ -449,7 +465,14 @@ impl DataSink for GltfSink { let texture_uri = base_texture.uri.to_file_path().unwrap(); let texture_size = texture_size_cache.get_or_insert(&texture_uri); - let downsample_factor = DownsampleFactor::new(&1.0); + + let downsample_scale = get_texture_downsample_scale_of_polygon( + &original_vertices, + texture_size, + self.limit_texture_resolution, + ) as f32; + + let downsample_factor = DownsampleFactor::new(&downsample_scale); let cropped_texture = CroppedTexture::new( &texture_uri, texture_size, diff --git a/nusamai/src/sink/mod.rs b/nusamai/src/sink/mod.rs index 4b1400ef2..c71f56035 100644 --- a/nusamai/src/sink/mod.rs +++ b/nusamai/src/sink/mod.rs @@ -13,6 +13,7 @@ pub mod obj; pub mod ply; pub mod serde; pub mod shapefile; +mod texture_resolution; use nusamai_citygml::schema::Schema; use nusamai_projection::crs; diff --git a/nusamai/src/sink/obj/mod.rs b/nusamai/src/sink/obj/mod.rs index 6e8f5b530..e395f171b 100644 --- a/nusamai/src/sink/obj/mod.rs +++ b/nusamai/src/sink/obj/mod.rs @@ -43,6 +43,8 @@ use crate::{ transformer::{TransformerConfig, TransformerOption, TransformerRegistry}, }; +use super::texture_resolution::get_texture_downsample_scale_of_polygon; + pub struct ObjSinkProvider {} impl DataSinkProvider for ObjSinkProvider { @@ -88,6 +90,16 @@ impl DataSinkProvider for ObjSinkProvider { }, ); + params.define( + "limit_texture_resolution".into(), + ParameterEntry { + description: "limiting texture resolution".into(), + required: false, + parameter: ParameterType::Boolean(BooleanParameter { value: None }), + label: Some("距離(メートル)あたりのテクスチャの解像度を制限する".into()), + }, + ); + params } @@ -106,6 +118,8 @@ impl DataSinkProvider for ObjSinkProvider { fn create(&self, params: &Parameters) -> Box { let output_path = get_parameter_value!(params, "@output", FileSystemPath); + let limit_texture_resolution = + *get_parameter_value!(params, "limit_texture_resolution", Boolean); let transform_options = self.available_transformer(); let is_split = get_parameter_value!(params, "split", Boolean).unwrap(); @@ -113,6 +127,7 @@ impl DataSinkProvider for ObjSinkProvider { output_path: output_path.as_ref().unwrap().into(), transform_settings: transform_options, obj_options: ObjParams { is_split }, + limit_texture_resolution, }) } } @@ -121,6 +136,7 @@ pub struct ObjSink { output_path: PathBuf, transform_settings: TransformerRegistry, obj_options: ObjParams, + limit_texture_resolution: Option, } struct ObjParams { @@ -482,10 +498,19 @@ impl DataSink for ObjSink { .iter() .map(|(_, _, _, u, v)| (*u, *v)) .collect::>(); - let downsample_factor = DownsampleFactor::new(&1.0); let texture_size = texture_size_cache.get_or_insert(&texture_uri); + let downsample_scale = get_texture_downsample_scale_of_polygon( + &original_vertices, + texture_size, + self.limit_texture_resolution, + ) + as f32; + + let downsample_factor = + DownsampleFactor::new(&downsample_scale); + let texture = CroppedTexture::new( &texture_uri, texture_size, diff --git a/nusamai/src/sink/texture_resolution.rs b/nusamai/src/sink/texture_resolution.rs new file mode 100644 index 000000000..1e988b141 --- /dev/null +++ b/nusamai/src/sink/texture_resolution.rs @@ -0,0 +1,53 @@ +/// Limits the texture resolution based on the distance (meters) between the vertices of a polygon. +const MAX_TEXTURE_PIXELS_PER_METER: f64 = 30.0; + +// WARN: This function has an equivalent in `atlas-packer/src/texture.rs`. +fn uv_to_pixel_coords(uv_coords: &[(f64, f64)], width: u32, height: u32) -> Vec<(u32, u32)> { + uv_coords + .iter() + .map(|(u, v)| { + ( + (u.clamp(0.0, 1.0) * width as f64).min(width as f64 - 1.0) as u32, + ((1.0 - v.clamp(0.0, 1.0)) * height as f64).min(height as f64 - 1.0) as u32, + ) + }) + .collect() +} + +pub fn get_texture_downsample_scale_of_polygon( + vertices: &[(f64, f64, f64, f64, f64)], // (x, y, z, u, v) + texture_size: (u32, u32), + limit_texture_resolution: Option, +) -> f64 { + let uv_coords = vertices.iter().map(|v| (v.3, v.4)).collect::>(); + + let pixel_coords = uv_to_pixel_coords(&uv_coords, texture_size.0, texture_size.1); + + let pixel_per_distance = (0..vertices.len()) + .map(|i| { + let j = (i + 1) % vertices.len(); + let (euc0, txl0) = ( + (vertices[i].0, vertices[i].1, vertices[i].2), + pixel_coords[i], + ); + let (euc1, txl1) = ( + (vertices[j].0, vertices[j].1, vertices[j].2), + pixel_coords[j], + ); + let euc_dist = + ((euc0.0 - euc1.0).powi(2) + (euc0.1 - euc1.1).powi(2) + (euc0.2 - euc1.2).powi(2)) + .sqrt(); + let txl_dist = ((txl0.0 as f64 - txl1.0 as f64).powi(2) + + (txl0.1 as f64 - txl1.1 as f64).powi(2)) + .sqrt(); + txl_dist / euc_dist + }) + .min_by(|a, b| a.total_cmp(b)) + .unwrap_or(1.0); + + if limit_texture_resolution.unwrap_or(false) { + 1.0_f64.min(MAX_TEXTURE_PIXELS_PER_METER / pixel_per_distance) + } else { + 1.0 + } +}