Download node-graph/gcore/src/transform.rs from openfree/graphite2: direct link, hf CLI and curl.
- Browser
- Download file 4.16 kB
-
https://huggingface.co/spaces/openfree/graphite2/resolve/main/node-graph/gcore/src/transform.rs
- Command line
-
hf download hf://spaces/openfree/graphite2/node-graph/gcore/src/transform.rs
-
curl -L -o transform.rs https://huggingface.co/spaces/openfree/graphite2/resolve/main/node-graph/gcore/src/transform.rs
4.16 kB
| use crate::Artboard; | |
| use crate::math::bbox::AxisAlignedBbox; | |
| pub use crate::vector::ReferencePoint; | |
| use core::f64; | |
| use glam::{DAffine2, DMat2, DVec2}; | |
| pub trait Transform { | |
| fn transform(&self) -> DAffine2; | |
| fn local_pivot(&self, pivot: DVec2) -> DVec2 { | |
| pivot | |
| } | |
| fn decompose_scale(&self) -> DVec2 { | |
| DVec2::new( | |
| self.transform().transform_vector2((1., 0.).into()).length(), | |
| self.transform().transform_vector2((0., 1.).into()).length(), | |
| ) | |
| } | |
| } | |
| pub trait TransformMut: Transform { | |
| fn transform_mut(&mut self) -> &mut DAffine2; | |
| fn translate(&mut self, offset: DVec2) { | |
| *self.transform_mut() = DAffine2::from_translation(offset) * self.transform(); | |
| } | |
| } | |
| // Implementation for references to anything that implements Transform | |
| impl<T: Transform> Transform for &T { | |
| fn transform(&self) -> DAffine2 { | |
| (*self).transform() | |
| } | |
| } | |
| // Implementations for Artboard | |
| impl Transform for Artboard { | |
| fn transform(&self) -> DAffine2 { | |
| DAffine2::from_translation(self.location.as_dvec2()) | |
| } | |
| fn local_pivot(&self, pivot: DVec2) -> DVec2 { | |
| self.location.as_dvec2() + self.dimensions.as_dvec2() * pivot | |
| } | |
| } | |
| // Implementations for DAffine2 | |
| impl Transform for DAffine2 { | |
| fn transform(&self) -> DAffine2 { | |
| *self | |
| } | |
| } | |
| impl TransformMut for DAffine2 { | |
| fn transform_mut(&mut self) -> &mut DAffine2 { | |
| self | |
| } | |
| } | |
| // Implementations for Footprint | |
| impl Transform for Footprint { | |
| fn transform(&self) -> DAffine2 { | |
| self.transform | |
| } | |
| } | |
| impl TransformMut for Footprint { | |
| fn transform_mut(&mut self) -> &mut DAffine2 { | |
| &mut self.transform | |
| } | |
| } | |
| pub enum RenderQuality { | |
| /// Low quality, fast rendering | |
| Preview, | |
| /// Ensure that the render is available with at least the specified quality | |
| /// A value of 0.5 means that the render is available with at least 50% of the final image resolution | |
| Scale(f32), | |
| /// Flip a coin to decide if the render should be available with the current quality or done at full quality | |
| /// This should be used to gradually update the render quality of a cached node | |
| Probability(f32), | |
| /// Render at full quality | |
| Full, | |
| } | |
| pub struct Footprint { | |
| /// Inverse of the transform which will be applied to the node output during the rendering process | |
| pub transform: DAffine2, | |
| /// Resolution of the target output area in pixels | |
| pub resolution: glam::UVec2, | |
| /// Quality of the render, this may be used by caching nodes to decide if the cached render is sufficient | |
| pub quality: RenderQuality, | |
| } | |
| impl Default for Footprint { | |
| fn default() -> Self { | |
| Self::DEFAULT | |
| } | |
| } | |
| impl Footprint { | |
| pub const DEFAULT: Self = Self { | |
| transform: DAffine2::IDENTITY, | |
| resolution: glam::UVec2::new(1920, 1080), | |
| quality: RenderQuality::Full, | |
| }; | |
| pub const BOUNDLESS: Self = Self { | |
| transform: DAffine2 { | |
| matrix2: DMat2::from_diagonal(DVec2::splat(f64::INFINITY)), | |
| translation: DVec2::ZERO, | |
| }, | |
| resolution: glam::UVec2::new(0, 0), | |
| quality: RenderQuality::Full, | |
| }; | |
| pub fn viewport_bounds_in_local_space(&self) -> AxisAlignedBbox { | |
| let inverse = self.transform.inverse(); | |
| let start = inverse.transform_point2((0., 0.).into()); | |
| let end = inverse.transform_point2(self.resolution.as_dvec2()); | |
| AxisAlignedBbox { start, end } | |
| } | |
| pub fn scale(&self) -> DVec2 { | |
| self.transform.decompose_scale() | |
| } | |
| pub fn offset(&self) -> DVec2 { | |
| self.transform.transform_point2(DVec2::ZERO) | |
| } | |
| } | |
| impl From<()> for Footprint { | |
| fn from(_: ()) -> Self { | |
| Footprint::default() | |
| } | |
| } | |
| impl std::hash::Hash for Footprint { | |
| fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | |
| self.transform.to_cols_array().iter().for_each(|x| x.to_le_bytes().hash(state)); | |
| self.resolution.hash(state) | |
| } | |
| } | |
| pub trait ApplyTransform { | |
| fn apply_transform(&mut self, modification: &DAffine2); | |
| } | |
| impl<T: TransformMut> ApplyTransform for T { | |
| fn apply_transform(&mut self, &modification: &DAffine2) { | |
| *self.transform_mut() = self.transform() * modification | |
| } | |
| } | |
| impl ApplyTransform for () { | |
| fn apply_transform(&mut self, &_modification: &DAffine2) {} | |
| } | |