Imaginate node fixes (#1084)

This commit is contained in:
0HyperCube 2023-03-18 20:34:42 +00:00 committed by Keavon Chambers
parent fe233504ca
commit 9c10d18308
6 changed files with 101 additions and 44 deletions

View File

@ -98,11 +98,20 @@ pub enum DocumentMessage {
delta: (f64, f64),
mirror_distance: bool,
},
NodeGraphFrameGenerate,
NodeGraphFrameClear {
layer_path: Vec<LayerId>,
node_id: NodeId,
cached_index: usize,
},
NodeGraphFrameGenerate {
layer_path: Vec<LayerId>,
},
NodeGraphFrameImaginate {
layer_path: Vec<LayerId>,
imaginate_node: Vec<NodeId>,
},
NodeGraphFrameImaginateRandom {
layer_path: Vec<LayerId>,
imaginate_node: Vec<NodeId>,
then_generate: bool,
},

View File

@ -512,23 +512,36 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
responses.push_back(DocumentOperation::MoveSelectedManipulatorPoints { layer_path, delta, mirror_distance }.into());
}
}
NodeGraphFrameGenerate => {
if let Some(message) = self.call_node_graph_frame(document_id, preferences, persistent_data, None) {
NodeGraphFrameClear {
layer_path,
node_id,
cached_index: input_index,
} => {
let value = graph_craft::document::value::TaggedValue::RcImage(None);
responses.push_back(NodeGraphMessage::SetInputValue { node_id, input_index, value }.into());
responses.push_back(NodeGraphFrameGenerate { layer_path }.into());
}
NodeGraphFrameGenerate { layer_path } => {
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, None) {
responses.push_back(message);
}
}
NodeGraphFrameImaginate { imaginate_node } => {
if let Some(message) = self.call_node_graph_frame(document_id, preferences, persistent_data, Some(imaginate_node)) {
NodeGraphFrameImaginate { layer_path, imaginate_node } => {
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, Some(imaginate_node)) {
responses.push_back(message);
}
}
NodeGraphFrameImaginateRandom { imaginate_node, then_generate } => {
NodeGraphFrameImaginateRandom {
layer_path,
imaginate_node,
then_generate,
} => {
// Set a random seed input
responses.push_back(
NodeGraphMessage::SetInputValue {
node_id: *imaginate_node.last().unwrap(),
// Needs to match the index of the seed parameter in `pub const IMAGINATE_NODE: DocumentNodeType` in `document_node_type.rs`
input_index: 2,
input_index: 1,
value: graph_craft::document::value::TaggedValue::F64((generate_uuid() >> 1) as f64),
}
.into(),
@ -536,7 +549,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
// Generate the image
if then_generate {
responses.push_back(DocumentMessage::NodeGraphFrameImaginate { imaginate_node }.into());
responses.push_back(DocumentMessage::NodeGraphFrameImaginate { layer_path, imaginate_node }.into());
}
}
NodeGraphFrameImaginateTerminate { layer_path, node_path } => {
@ -651,13 +664,13 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
responses.push_back(
DocumentOperation::SetLayerTransform {
path,
path: path.clone(),
transform: transform.to_cols_array(),
}
.into(),
);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path: path }.into());
// Force chosen tool to be Select Tool after importing image.
responses.push_back(ToolMessage::ActivateTool { tool_type: ToolType::Select }.into());
@ -1015,18 +1028,14 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
}
impl DocumentMessageHandler {
pub fn call_node_graph_frame(&mut self, document_id: u64, _preferences: &PreferencesMessageHandler, persistent_data: &PersistentData, imaginate_node: Option<Vec<NodeId>>) -> Option<Message> {
let layer_path = {
let mut selected_nodegraph_layers = self.selected_layers_with_type(LayerDataTypeDiscriminant::NodeGraphFrame);
// Get what is hopefully the only selected nodegraph layer
match selected_nodegraph_layers.next() {
// Continue only if there are no additional nodegraph layers also selected
Some(layer_path) if selected_nodegraph_layers.next().is_none() => layer_path.to_owned(),
_ => return None,
}
};
pub fn call_node_graph_frame(
&mut self,
document_id: u64,
layer_path: Vec<LayerId>,
_preferences: &PreferencesMessageHandler,
persistent_data: &PersistentData,
imaginate_node: Option<Vec<NodeId>>,
) -> Option<Message> {
// Prepare the node graph input image
let Some(node_network) = self.document_legacy.layer(&layer_path).ok().and_then(|layer|layer.as_node_graph().ok()) else {
@ -1034,7 +1043,7 @@ impl DocumentMessageHandler {
};
// Skip processing under node graph frame input if not connected
if !node_network.connected_to_output(node_network.inputs[0]) {
if !node_network.connected_to_output(node_network.inputs[0], false) {
return Some(
PortfolioMessage::ProcessNodeGraphFrame {
document_id,

View File

@ -455,7 +455,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
let input = NodeInput::node(output_node, output_node_connector_index);
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
let should_rerender = network.connected_to_output(node_id);
let should_rerender = network.connected_to_output(node_id, true);
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
}
NodeGraphMessage::Copy => {
@ -513,8 +513,10 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
if let Some(network) = self.get_active_network(document) {
// Only generate node graph if one of the selected nodes is connected to the output
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id)) {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
if let Some(layer_path) = self.layer_path.clone() {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
}
@ -537,7 +539,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
let input = node_type.inputs[input_index].default.clone();
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
let should_rerender = network.connected_to_output(node_id);
let should_rerender = network.connected_to_output(node_id, true);
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
}
NodeGraphMessage::DoubleClickNode { node } => {
@ -613,7 +615,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
}
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
let should_rerender = network.connected_to_output(node_id);
let should_rerender = network.connected_to_output(node_id, true);
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
}
@ -708,7 +710,9 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
if let Some(network) = self.get_active_network(document) {
Self::send_graph(network, responses);
if should_rerender {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if let Some(layer_path) = self.layer_path.clone() {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
}
@ -739,8 +743,10 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
let input = NodeInput::Value { tagged_value: value, exposed: false };
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id) {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id, true) {
if let Some(layer_path) = self.layer_path.clone() {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
}
@ -776,8 +782,8 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
node.inputs.extend(((node.inputs.len() - 1)..input_index).map(|_| NodeInput::Network(generic!(T))));
}
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
if network.connected_to_output(*node_id) {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if network.connected_to_output(*node_id, true) {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
@ -849,8 +855,10 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
Self::send_graph(network, responses);
// Only generate node graph if one of the selected nodes is connected to the output
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id)) {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
if let Some(layer_path) = self.layer_path.clone() {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
self.update_selection_action_buttons(document, responses);
@ -873,7 +881,9 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
Self::send_graph(network, responses);
}
self.update_selection_action_buttons(document, responses);
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
if let Some(layer_path) = self.layer_path.clone() {
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
}
}
}
}

View File

@ -414,11 +414,12 @@ fn color_widget(document_node: &DocumentNode, node_id: u64, index: usize, name:
LayoutGroup::Row { widgets }
}
/// Properties for the input node, with information describing how frames work and a refresh button
pub fn input_properties(_document_node: &DocumentNode, _node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
pub fn input_properties(_document_node: &DocumentNode, _node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let information = WidgetHolder::text_widget("The graph's input is the artwork under the frame layer");
let layer_path = context.layer_path.to_vec();
let refresh_button = TextButton::new("Refresh Input")
.tooltip("Refresh the artwork under the frame")
.on_update(|_| DocumentMessage::NodeGraphFrameGenerate.into())
.on_update(move |_| DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() }.into())
.widget_holder();
vec![LayoutGroup::Row { widgets: vec![information] }, LayoutGroup::Row { widgets: vec![refresh_button] }]
}
@ -804,8 +805,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Generate with a new random seed")
.on_update({
let imaginate_node = imaginate_node.clone();
let layer_path = context.layer_path.to_vec();
move |_| {
DocumentMessage::NodeGraphFrameImaginateRandom {
layer_path: layer_path.clone(),
imaginate_node: imaginate_node.clone(),
then_generate: true,
}
@ -818,8 +821,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Fill layer frame by generating a new image")
.on_update({
let imaginate_node = imaginate_node.clone();
let layer_path = context.layer_path.to_vec();
move |_| {
DocumentMessage::NodeGraphFrameImaginate {
layer_path: layer_path.clone(),
imaginate_node: imaginate_node.clone(),
}
.into()
@ -830,7 +835,17 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
TextButton::new("Clear")
.tooltip("Remove generated image from the layer frame")
.disabled(cached_data.is_none())
.on_update(update_value(|_| TaggedValue::RcImage(None), node_id, cached_index))
.on_update({
let layer_path = context.layer_path.to_vec();
move |_| {
DocumentMessage::NodeGraphFrameClear {
node_id,
layer_path: layer_path.clone(),
cached_index,
}
.into()
}
})
.widget_holder(),
]),
}
@ -852,8 +867,10 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
.tooltip("Set a new random seed")
.on_update({
let imaginate_node = imaginate_node.clone();
let layer_path = context.layer_path.to_vec();
move |_| {
DocumentMessage::NodeGraphFrameImaginateRandom {
layer_path: layer_path.clone(),
imaginate_node: imaginate_node.clone(),
then_generate: false,
}
@ -881,7 +898,8 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
transform,
});
// Compute the transform input to the node graph frame
let transform: glam::DAffine2 = context.executor.compute_input(context.network, &imaginate_node, 1, image_frame).unwrap_or_default();
let image_frame: graphene_core::raster::ImageFrame = context.executor.compute_input(context.network, &imaginate_node, 0, image_frame).unwrap_or_default();
let transform = image_frame.transform;
let resolution = {
use document_legacy::document::pick_safe_imaginate_resolution;

View File

@ -149,8 +149,14 @@ impl NodeGraphExecutor {
};
let use_base_image = self.compute_input::<bool>(&network, &imaginate_node, get("Adapt Input Image"), Cow::Borrowed(&image_frame))?;
let base_image = if use_base_image {
let image: Image = self.compute_input(&network, &imaginate_node, get("Input Image"), Cow::Borrowed(&image_frame))?;
let input_image_frame: Option<ImageFrame> = if use_base_image {
Some(self.compute_input::<ImageFrame>(&network, &imaginate_node, get("Input Image"), Cow::Borrowed(&image_frame))?)
} else {
None
};
let image_transform = input_image_frame.as_ref().map(|image_frame| image_frame.transform);
let base_image = if let Some(ImageFrame { image, .. }) = input_image_frame {
// Only use if has size
if image.width > 0 && image.height > 0 {
let (image_data, size) = Self::encode_img(image, Some(resolution), image::ImageOutputFormat::Png)?;
@ -164,7 +170,7 @@ impl NodeGraphExecutor {
None
};
let mask_image = if base_image.is_some() {
let mask_image = if let Some(transform) = image_transform {
let mask_path: Option<Vec<LayerId>> = self.compute_input(&network, &imaginate_node, get("Masking Layer"), Cow::Borrowed(&image_frame))?;
// Calculate the size of the node graph frame

View File

@ -533,7 +533,7 @@ impl NodeNetwork {
}
/// Check if the specified node id is connected to the output
pub fn connected_to_output(&self, target_node_id: NodeId) -> bool {
pub fn connected_to_output(&self, target_node_id: NodeId, ignore_imaginate: bool) -> bool {
// If the node is the output then return true
if self.outputs.iter().any(|&NodeOutput { node_id, .. }| node_id == target_node_id) {
return true;
@ -546,6 +546,11 @@ impl NodeNetwork {
already_visited.extend(self.outputs.iter().map(|output| output.node_id));
while let Some(node) = stack.pop() {
// Skip the imaginate node inputs
if ignore_imaginate && node.name == "Imaginate" {
continue;
}
for input in &node.inputs {
if let &NodeInput::Node { node_id: ref_id, .. } = input {
// Skip if already viewed