From cc94eba5514e14312555cfd0ba484387f5c65109 Mon Sep 17 00:00:00 2001 From: yamahigashi Date: Tue, 4 Jun 2024 14:43:03 +0900 Subject: [PATCH] Added SVG as supported format --- python/uv_snapshot_edge_drawer/ui.py | 46 ++++- rust/edge_drawer/Cargo.lock | 286 ++++++++++++++++++++++++++- rust/edge_drawer/Cargo.toml | 2 + rust/edge_drawer/src/main.rs | 61 +++++- 4 files changed, 380 insertions(+), 15 deletions(-) diff --git a/python/uv_snapshot_edge_drawer/ui.py b/python/uv_snapshot_edge_drawer/ui.py index a7c2d0e..adee426 100644 --- a/python/uv_snapshot_edge_drawer/ui.py +++ b/python/uv_snapshot_edge_drawer/ui.py @@ -68,9 +68,11 @@ def show_ui(): okCaption='Select', dialogStyle=2, startingDirectory=sd, - fileFilter='*.png' + fileFilter='Image Files PNG or SVG(*.png *.svg)' ) if res: + if not res[0].endswith(".png") and not res[0].endswith(".svg"): + res[0] += ".png" cmds.optionVar(sv=('uvSnapshotFileName', res[0])) cmds.textFieldButtonGrp("filenameField", edit=True, text=res[0]) """) @@ -199,11 +201,51 @@ def show_ui(): ) cmds.button(label="Close", command='cmds.deleteUI("settingsWindow", window=True)') + # Attach the update_controls function to the checkboxes + cmds.checkBoxGrp("exportSoftEdge", edit=True, changeCommand=update_controls) + cmds.checkBoxGrp("exportHardEdge", edit=True, changeCommand=update_controls) + cmds.checkBoxGrp("exportBorderEdge", edit=True, changeCommand=update_controls) + cmds.checkBoxGrp("exportBoundaryEdge", edit=True, changeCommand=update_controls) + cmds.checkBoxGrp("exportCreaseEdge", edit=True, changeCommand=update_controls) + cmds.checkBoxGrp("exportFoldEdge", edit=True, changeCommand=update_controls) + + # Call update_controls initially to set the correct states + update_controls() + # Show the window uv_snapchot_ctrl_changed() cmds.showWindow(settingsWindow) +def update_controls(*args): + # Get the states of the checkboxes + soft_edge_state = cmds.checkBoxGrp("exportSoftEdge", query=True, value1=True) + hard_edge_state = cmds.checkBoxGrp("exportHardEdge", query=True, value1=True) + border_edge_state = cmds.checkBoxGrp("exportBorderEdge", query=True, value1=True) + boundary_edge_state = cmds.checkBoxGrp("exportBoundaryEdge", query=True, value1=True) + crease_edge_state = cmds.checkBoxGrp("exportCreaseEdge", query=True, value1=True) + fold_edge_state = cmds.checkBoxGrp("exportFoldEdge", query=True, value1=True) + + # Enable or disable the color and width controls based on the checkbox states + cmds.colorSliderGrp("softEdgeColor", edit=True, visible=soft_edge_state) + cmds.intSliderGrp("softEdgeWidth", edit=True, visible=soft_edge_state) + + cmds.colorSliderGrp("hardEdgeColor", edit=True, visible=hard_edge_state) + cmds.intSliderGrp("hardEdgeWidth", edit=True, visible=hard_edge_state) + + cmds.colorSliderGrp("borderEdgeColor", edit=True, visible=border_edge_state) + cmds.intSliderGrp("borderEdgeWidth", edit=True, visible=border_edge_state) + + cmds.colorSliderGrp("boundaryEdgeColor", edit=True, visible=boundary_edge_state) + cmds.intSliderGrp("boundaryEdgeWidth", edit=True, visible=boundary_edge_state) + + cmds.colorSliderGrp("creaseEdgeColor", edit=True, visible=crease_edge_state) + cmds.intSliderGrp("creaseEdgeWidth", edit=True, visible=crease_edge_state) + + cmds.colorSliderGrp("foldEdgeColor", edit=True, visible=fold_edge_state) + cmds.intSliderGrp("foldEdgeWidth", edit=True, visible=fold_edge_state) + + def get_uv_min_max(): # type: () -> Tuple[float, float, float, float] @@ -237,8 +279,6 @@ def uv_snapchot_ctrl_changed(*args): def snapshot(): file_path = cmds.textFieldButtonGrp("filenameField", query=True, text=True) - if not file_path.endswith(".png"): - file_path += ".png" x_resolution = cmds.intSliderGrp("resoX", query=True, value=True) y_resolution = cmds.intSliderGrp("resoY", query=True, value=True) diff --git a/rust/edge_drawer/Cargo.lock b/rust/edge_drawer/Cargo.lock index 222aabf..21a0d7d 100644 --- a/rust/edge_drawer/Cargo.lock +++ b/rust/edge_drawer/Cargo.lock @@ -23,6 +23,18 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "atty" version = "0.2.14" @@ -40,6 +52,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bit_field" version = "0.10.2" @@ -52,6 +70,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "bumpalo" version = "3.13.0" @@ -83,7 +107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_lex", "indexmap", "strsim", @@ -169,6 +193,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + [[package]] name = "edge_drawer" version = "0.1.0" @@ -178,6 +208,8 @@ dependencies = [ "imageproc", "serde", "serde_json", + "svg", + "usvg", ] [[package]] @@ -221,6 +253,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + [[package]] name = "flume" version = "0.10.14" @@ -234,6 +272,29 @@ dependencies = [ "spin", ] +[[package]] +name = "fontconfig-parser" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +dependencies = [ + "roxmltree 0.19.0", +] + +[[package]] +name = "fontdb" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.21.1", +] + [[package]] name = "futures-core" version = "0.3.29" @@ -341,6 +402,12 @@ dependencies = [ "rusttype", ] +[[package]] +name = "imagesize" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" + [[package]] name = "indexmap" version = "1.9.3" @@ -384,6 +451,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kurbo" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c" +dependencies = [ + "arrayvec", + "smallvec", +] + [[package]] name = "lebe" version = "0.5.2" @@ -392,9 +469,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "lock_api" @@ -422,6 +499,15 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -559,7 +645,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" dependencies = [ - "ttf-parser", + "ttf-parser 0.15.2", ] [[package]] @@ -568,6 +654,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.3" @@ -594,7 +686,7 @@ version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -710,6 +802,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "roxmltree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + [[package]] name = "rusttype" version = "0.9.3" @@ -720,6 +824,22 @@ dependencies = [ "owned_ttf_parser", ] +[[package]] +name = "rustybuzz" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7730060ad401b0d1807c904ea56735288af101430aa0d2ab8358b789f5f37002" +dependencies = [ + "bitflags 2.5.0", + "bytemuck", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + [[package]] name = "ryu" version = "1.0.15" @@ -791,6 +911,30 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.11.0" @@ -806,12 +950,37 @@ dependencies = [ "lock_api", ] +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "svg" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "700efb40f3f559c23c18b446e8ed62b08b56b2bb3197b36d57e0470b4102779e" + +[[package]] +name = "svgtypes" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" +dependencies = [ + "kurbo", + "siphasher", +] + [[package]] name = "syn" version = "2.0.39" @@ -849,24 +1018,125 @@ dependencies = [ "weezl", ] +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "ttf-parser" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-script" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "usvg" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84ea542ae85c715f07b082438a4231c3760539d902e11d093847a0b22963032" +dependencies = [ + "base64", + "data-url", + "flate2", + "fontdb", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree 0.20.0", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -980,6 +1250,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + [[package]] name = "zune-inflate" version = "0.2.54" diff --git a/rust/edge_drawer/Cargo.toml b/rust/edge_drawer/Cargo.toml index 48a945c..2b4f398 100644 --- a/rust/edge_drawer/Cargo.toml +++ b/rust/edge_drawer/Cargo.toml @@ -10,3 +10,5 @@ imageproc = "0.23" clap = "3.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +usvg = "0.42.0" +svg = "0.17.0" diff --git a/rust/edge_drawer/src/main.rs b/rust/edge_drawer/src/main.rs index 5a40f5d..4974357 100644 --- a/rust/edge_drawer/src/main.rs +++ b/rust/edge_drawer/src/main.rs @@ -6,14 +6,16 @@ use image::{Rgba, RgbaImage}; use imageproc::drawing::draw_polygon_mut; use imageproc::point::Point; use imageproc::{ - drawing::draw_antialiased_line_segment_mut, + // drawing::draw_antialiased_line_segment_mut, pixelops::interpolate }; -use std::path::Path; use clap::{App, Arg}; -// use serde_json::Value; use serde::Deserialize; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +// use usvg::{Tree, Options}; +use svg::node::element::path::{Data}; +use svg::node::element::{Path as SvgPath, Line}; +use svg::Document; struct Config { image_path: PathBuf, @@ -103,6 +105,41 @@ fn parse_arguments() -> Config { } +fn draw_edges_svg(edges: &[Edges], width: u32, height: u32) -> Document { + let mut document = Document::new() + .set("viewBox", (0, 0, width, height)); + + for edge in edges { + for line in edge.lines.iter() { + let u1 = line.uv1[0] * width as f32; + let v1 = (1.0 - line.uv1[1]) * height as f32; + let u2 = line.uv2[0] * width as f32; + let v2 = (1.0 - line.uv2[1]) * height as f32; + + let data = Data::new() + .move_to((u1 as f64, v1 as f64)) + .line_to((u2 as f64, v2 as f64)); + + let color = format!("rgb({}, {}, {})", + edge.line_color[0], + edge.line_color[1], + edge.line_color[2]); + + let path = SvgPath::new() + .set("fill", "none") + .set("stroke", color) + .set("stroke-width", edge.line_width) + .set("stroke-linecap", "round") + .set("d", data); + + document = document.add(path); + } + } + + document +} + + fn draw_edges(img: &mut RgbaImage, edges: &[Edges]) { for edge in edges { @@ -162,11 +199,21 @@ fn save_image(img: &RgbaImage, image_path: &PathBuf) { } +fn save_svg(document: &Document, image_path: &PathBuf) { + svg::save(image_path, document).expect("Failed to save SVG"); +} + + fn main() { let config = parse_arguments(); - let mut img = RgbaImage::new(config.width, config.height); - draw_edges(&mut img, &config.edges); - save_image(&img, &config.image_path); + if config.image_path.extension().and_then(|s| s.to_str()) == Some("svg") { + let document = draw_edges_svg(&config.edges, config.width, config.height); + save_svg(&document, &config.image_path); + } else { + let mut img = RgbaImage::new(config.width, config.height); + draw_edges(&mut img, &config.edges); + save_image(&img, &config.image_path); + } }