Imaginate node fixes (#1084)
This commit is contained in:
parent
fe233504ca
commit
9c10d18308
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue