mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 06:38:03 +08:00
Fix transforms, Brush tool, and G/R/S (#1473)
* Transform fixes * Fix the desert artwork * Change artboard icon * Better handling when transforming brush strokes * Code review pass --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -14,11 +14,12 @@ use graph_craft::graphene_compiler::Compiler;
|
||||
use graph_craft::imaginate_input::ImaginatePreferences;
|
||||
use graph_craft::{concrete, Type};
|
||||
use graphene_core::application_io::{ApplicationIo, NodeGraphUpdateMessage, NodeGraphUpdateSender, RenderConfig};
|
||||
use graphene_core::raster::Image;
|
||||
use graphene_core::raster::{Image, ImageFrame};
|
||||
use graphene_core::renderer::{ClickTarget, GraphicElementRendered, SvgSegment, SvgSegmentList};
|
||||
use graphene_core::text::FontCache;
|
||||
use graphene_core::transform::{Footprint, Transform};
|
||||
use graphene_core::vector::style::ViewMode;
|
||||
use graphene_core::vector::VectorData;
|
||||
|
||||
use graphene_core::{Color, SurfaceFrame, SurfaceId};
|
||||
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
|
||||
@@ -71,8 +72,7 @@ pub(crate) struct GenerationRequest {
|
||||
generation_id: u64,
|
||||
graph: NodeNetwork,
|
||||
path: Vec<LayerId>,
|
||||
transform: DAffine2,
|
||||
viewport_resolution: UVec2,
|
||||
render_config: RenderConfig,
|
||||
}
|
||||
|
||||
pub(crate) struct GenerationResponse {
|
||||
@@ -146,12 +146,12 @@ impl NodeRuntime {
|
||||
NodeRuntimeMessage::GenerationRequest(GenerationRequest {
|
||||
generation_id,
|
||||
graph,
|
||||
transform,
|
||||
render_config,
|
||||
path,
|
||||
viewport_resolution,
|
||||
..
|
||||
}) => {
|
||||
let (result, monitor_nodes) = self.execute_network(&path, graph, transform, viewport_resolution).await;
|
||||
let transform = render_config.viewport.transform;
|
||||
let (result, monitor_nodes) = self.execute_network(&path, graph, render_config).await;
|
||||
let mut responses = VecDeque::new();
|
||||
if let Some(ref monitor_nodes) = monitor_nodes {
|
||||
self.update_thumbnails(&path, monitor_nodes, &mut responses);
|
||||
@@ -173,7 +173,7 @@ impl NodeRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
async fn execute_network<'a>(&'a mut self, path: &[LayerId], graph: NodeNetwork, transform: DAffine2, viewport_resolution: UVec2) -> (Result<TaggedValue, String>, Option<MonitorNodes>) {
|
||||
async fn execute_network<'a>(&'a mut self, path: &[LayerId], graph: NodeNetwork, render_config: RenderConfig) -> (Result<TaggedValue, String>, Option<MonitorNodes>) {
|
||||
if self.wasm_io.is_none() {
|
||||
self.wasm_io = Some(WasmApplicationIo::new().await);
|
||||
}
|
||||
@@ -182,17 +182,7 @@ impl NodeRuntime {
|
||||
application_io: self.wasm_io.as_ref().unwrap(),
|
||||
node_graph_message_sender: &self.sender,
|
||||
imaginate_preferences: &self.imaginate_preferences,
|
||||
render_config: RenderConfig {
|
||||
viewport: Footprint {
|
||||
transform,
|
||||
resolution: viewport_resolution,
|
||||
..Default::default()
|
||||
},
|
||||
#[cfg(any(feature = "resvg", feature = "vello"))]
|
||||
export_format: graphene_core::application_io::ExportFormat::Canvas,
|
||||
#[cfg(not(any(feature = "resvg", feature = "vello")))]
|
||||
export_format: graphene_core::application_io::ExportFormat::Svg,
|
||||
},
|
||||
render_config,
|
||||
image_frame: None,
|
||||
};
|
||||
|
||||
@@ -325,11 +315,19 @@ impl NodeRuntime {
|
||||
warn!("Failed to introspect monitor node for upstream transforms");
|
||||
continue;
|
||||
};
|
||||
let Some(graphic_element_data) = value.downcast_ref::<graphene_core::vector::VectorData>() else {
|
||||
warn!("Failed to downcast transform input to vector data");
|
||||
let Some(transform) = value
|
||||
.downcast_ref::<graphene_core::memo::IORecord<Footprint, VectorData>>()
|
||||
.map(|vector_data| vector_data.output.transform())
|
||||
.or_else(|| {
|
||||
value
|
||||
.downcast_ref::<graphene_core::memo::IORecord<Footprint, ImageFrame<Color>>>()
|
||||
.map(|image| image.output.transform())
|
||||
})
|
||||
else {
|
||||
warn!("Failed to downcast transform input");
|
||||
continue;
|
||||
};
|
||||
self.upstream_transforms.insert(node_id, graphic_element_data.transform());
|
||||
self.upstream_transforms.insert(node_id, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,14 +397,13 @@ impl Default for NodeGraphExecutor {
|
||||
|
||||
impl NodeGraphExecutor {
|
||||
/// Execute the network by flattening it and creating a borrow stack.
|
||||
fn queue_execution(&self, network: NodeNetwork, layer_path: Vec<LayerId>, transform: DAffine2, viewport_resolution: UVec2) -> u64 {
|
||||
fn queue_execution(&self, network: NodeNetwork, layer_path: Vec<LayerId>, render_config: RenderConfig) -> u64 {
|
||||
let generation_id = generate_uuid();
|
||||
let request = GenerationRequest {
|
||||
path: layer_path,
|
||||
graph: network,
|
||||
generation_id,
|
||||
transform,
|
||||
viewport_resolution,
|
||||
render_config,
|
||||
};
|
||||
self.sender.send(NodeRuntimeMessage::GenerationRequest(request)).expect("Failed to send generation request");
|
||||
|
||||
@@ -499,11 +496,21 @@ impl NodeGraphExecutor {
|
||||
layer_layer.network.clone()
|
||||
};
|
||||
|
||||
// Construct the input image frame
|
||||
let document_transform = document.document_legacy.metadata.document_to_viewport;
|
||||
let render_config = RenderConfig {
|
||||
viewport: Footprint {
|
||||
transform: document.document_legacy.metadata.document_to_viewport,
|
||||
resolution: viewport_resolution,
|
||||
..Default::default()
|
||||
},
|
||||
#[cfg(any(feature = "resvg", feature = "vello"))]
|
||||
export_format: graphene_core::application_io::ExportFormat::Canvas,
|
||||
#[cfg(not(any(feature = "resvg", feature = "vello")))]
|
||||
export_format: graphene_core::application_io::ExportFormat::Svg,
|
||||
view_mode: document.view_mode,
|
||||
};
|
||||
|
||||
// Execute the node graph
|
||||
let generation_id = self.queue_execution(network, layer_path.clone(), document_transform, viewport_resolution);
|
||||
let generation_id = self.queue_execution(network, layer_path.clone(), render_config);
|
||||
|
||||
self.futures.insert(generation_id, ExecutionContext { layer_path });
|
||||
|
||||
@@ -542,7 +549,9 @@ impl NodeGraphExecutor {
|
||||
.to_string(),
|
||||
tooltip: format!("Layer id: {node_id}"),
|
||||
visible: !document.document_network.disabled.contains(&layer.to_node()),
|
||||
layer_type: if document.metadata.is_folder(layer) {
|
||||
layer_type: if document.metadata.is_artboard(layer) {
|
||||
LayerDataTypeDiscriminant::Artboard
|
||||
} else if document.metadata.is_folder(layer) {
|
||||
LayerDataTypeDiscriminant::Folder
|
||||
} else {
|
||||
LayerDataTypeDiscriminant::Layer
|
||||
|
||||
Reference in New Issue
Block a user