mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 01:38:11 +08:00
Add Outer Path, Fix mscv package.json bug
This commit is contained in:
Generated
+18
-16
@@ -7,7 +7,7 @@
|
|||||||
"name": "graphite-web-frontend",
|
"name": "graphite-web-frontend",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.2.0",
|
"@rollup/rollup-win32-x64-msvc": "^4.40.1",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
"reflect-metadata": "^0.2.2"
|
"reflect-metadata": "^0.2.2"
|
||||||
@@ -989,15 +989,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.34.9",
|
"version": "4.40.1",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz",
|
||||||
"integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
|
"integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
@@ -1050,16 +1048,6 @@
|
|||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/api": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-R8epOeZl1eJEl603aUMIGb4RXlhPjpgxbGVEaqY+0G5JG9vzV/clNlzTeqc+NLYXVqXcn8mb4c5b9pJIUDEyAg==",
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/tauri"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node10": {
|
"node_modules/@tsconfig/node10": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
@@ -4668,6 +4656,20 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
|
"version": "4.34.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
|
||||||
|
"integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"reflect-metadata": "^0.2.2"
|
"reflect-metadata": "^0.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@rollup/rollup-win32-x64-msvc": "^4.40.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
||||||
"@types/node": "^22.6.1",
|
"@types/node": "^22.6.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.7.0",
|
"@typescript-eslint/eslint-plugin": "^8.7.0",
|
||||||
@@ -46,17 +47,17 @@
|
|||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"eslint-plugin-svelte": "^2.44.0",
|
"eslint-plugin-svelte": "^2.44.0",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"prettier": "^3.3.3",
|
|
||||||
"prettier-plugin-svelte": "^3.2.6",
|
"prettier-plugin-svelte": "^3.2.6",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"rollup-plugin-license": "^3.5.3",
|
"rollup-plugin-license": "^3.5.3",
|
||||||
"sass": "1.78.0",
|
"sass": "1.78.0",
|
||||||
"svelte": "^4.2.19",
|
|
||||||
"svelte-preprocess": "^6.0.2",
|
"svelte-preprocess": "^6.0.2",
|
||||||
|
"svelte": "^4.2.19",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "^5.6.2",
|
||||||
"vite": "^5.4.14",
|
"vite-multiple-assets": "1.3.1",
|
||||||
"vite-multiple-assets": "1.3.1"
|
"vite": "^5.4.14"
|
||||||
},
|
},
|
||||||
"//": "The dev dependency for `sass` can be removed once <https://github.com/sveltejs/svelte-preprocess/issues/656> is fixed, but meanwhile we have to",
|
"//": "The dev dependency for `sass` can be removed once <https://github.com/sveltejs/svelte-preprocess/issues/656> is fixed, but meanwhile we have to",
|
||||||
"///": "list it here and pin it to 1.78.0 so `vite` and `svelte-preprocess` use it instead of 1.79+ which spams the console with deprecation warnings.",
|
"///": "list it here and pin it to 1.78.0 so `vite` and `svelte-preprocess` use it instead of 1.79+ which spams the console with deprecation warnings.",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::algorithms::offset_subpath::offset_subpath;
|
use super::algorithms::offset_subpath::offset_subpath;
|
||||||
use super::misc::CentroidType;
|
use super::misc::CentroidType;
|
||||||
use super::style::{Fill, Gradient, GradientStops, Stroke};
|
use super::style::{Fill, Gradient, GradientStops, Stroke};
|
||||||
use super::{PointId, RegionId, SegmentDomain, SegmentId, StrokeId, VectorData, VectorDataTable};
|
use super::{PointId, SegmentDomain, SegmentId, StrokeId, VectorData, VectorDataTable};
|
||||||
use crate::instances::{InstanceMut, Instances};
|
use crate::instances::{InstanceMut, Instances};
|
||||||
use crate::registry::types::{Angle, Fraction, IntegerCount, Length, Multiplier, Percentage, PixelLength, SeedValue};
|
use crate::registry::types::{Angle, Fraction, IntegerCount, Length, Multiplier, Percentage, PixelLength, SeedValue};
|
||||||
use crate::renderer::GraphicElementRendered;
|
use crate::renderer::GraphicElementRendered;
|
||||||
@@ -1480,6 +1480,94 @@ async fn offset_path(_: impl Ctx, vector_data: VectorDataTable, distance: f64, l
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
|
||||||
|
async fn outer_path(_: impl Ctx, vector_data: VectorDataTable) -> VectorDataTable {
|
||||||
|
let vector_data_transform = vector_data.transform();
|
||||||
|
let vector_data = vector_data.one_instance().instance;
|
||||||
|
|
||||||
|
// Create a new VectorData to store our result
|
||||||
|
let mut result = VectorData::empty();
|
||||||
|
result.style = vector_data.style.clone();
|
||||||
|
|
||||||
|
// Collect all closed subpaths with their indices
|
||||||
|
let subpaths: Vec<_> = vector_data
|
||||||
|
.stroke_bezier_paths()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, subpath)| subpath.closed())
|
||||||
|
.map(|(i, mut subpath)| {
|
||||||
|
// Apply transform to work in world space
|
||||||
|
subpath.apply_transform(vector_data_transform);
|
||||||
|
(i, subpath)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if subpaths.is_empty() {
|
||||||
|
// No closed paths found, return empty result
|
||||||
|
let mut result_table = VectorDataTable::new(result);
|
||||||
|
*result_table.transform_mut() = vector_data_transform;
|
||||||
|
return result_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the outermost path:
|
||||||
|
// 1. Start by assuming all subpaths could be the outermost
|
||||||
|
let mut potential_outer_paths: Vec<_> = subpaths.iter().map(|(i, _)| *i).collect();
|
||||||
|
|
||||||
|
// 2. For each subpath, test against all others
|
||||||
|
for (i, subpath_i) in &subpaths {
|
||||||
|
// Skip if already eliminated
|
||||||
|
if !potential_outer_paths.contains(i) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j, subpath_j) in &subpaths {
|
||||||
|
// Skip comparing to self
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sample points from subpath_i
|
||||||
|
let total_points = 20;
|
||||||
|
let mut contained_points = 0;
|
||||||
|
|
||||||
|
// Check several points along subpath_i to see if they're contained in subpath_j
|
||||||
|
for k in 0..total_points {
|
||||||
|
let t = k as f64 / total_points as f64;
|
||||||
|
let point = subpath_i.evaluate(bezier_rs::SubpathTValue::GlobalParametric(t));
|
||||||
|
|
||||||
|
if subpath_j.contains_point(point) {
|
||||||
|
contained_points += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If most points from subpath_i are inside subpath_j,
|
||||||
|
// then subpath_i is not an outer path
|
||||||
|
if contained_points > total_points / 2 {
|
||||||
|
potential_outer_paths.retain(|&x| x != *i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Among remaining potential outer paths, choose the one with the largest area
|
||||||
|
if let Some(&outer_index) = potential_outer_paths.iter().max_by(|&&a, &&b| {
|
||||||
|
let area_a = subpaths.iter().find(|(i, _)| *i == a).map(|(_, s)| s.area(None, None).abs()).unwrap_or(0.0);
|
||||||
|
let area_b = subpaths.iter().find(|(i, _)| *i == b).map(|(_, s)| s.area(None, None).abs()).unwrap_or(0.0);
|
||||||
|
area_a.partial_cmp(&area_b).unwrap_or(std::cmp::Ordering::Equal)
|
||||||
|
}) {
|
||||||
|
// Find the outer path and add it to the result
|
||||||
|
if let Some((_, outer_path)) = subpaths.iter().find(|(i, _)| *i == outer_index) {
|
||||||
|
let mut path_copy = outer_path.clone();
|
||||||
|
path_copy.apply_transform(vector_data_transform.inverse());
|
||||||
|
result.append_subpath(path_copy, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the resulting VectorDataTable
|
||||||
|
let mut result_table = VectorDataTable::new(result);
|
||||||
|
*result_table.transform_mut() = vector_data_transform;
|
||||||
|
result_table
|
||||||
|
}
|
||||||
|
|
||||||
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
|
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
|
||||||
async fn solidify_stroke(_: impl Ctx, vector_data: VectorDataTable) -> VectorDataTable {
|
async fn solidify_stroke(_: impl Ctx, vector_data: VectorDataTable) -> VectorDataTable {
|
||||||
let vector_data_transform = vector_data.transform();
|
let vector_data_transform = vector_data.transform();
|
||||||
|
|||||||
Reference in New Issue
Block a user