mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 23:58:12 +08:00
Implement bounds input to constrain the output frame of the brush node
Test Plan: Hook up a constraint to the brush node in the editor and verify the result looks correct Reviewers: Pull Request: https://github.com/GraphiteEditor/Graphite/pull/1195
This commit is contained in:
committed by
Keavon Chambers
parent
3adcc3031a
commit
36f24b7730
+1
@@ -470,6 +470,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
|||||||
inputs: vec![
|
inputs: vec![
|
||||||
DocumentInputType::value("None", TaggedValue::None, false),
|
DocumentInputType::value("None", TaggedValue::None, false),
|
||||||
DocumentInputType::value("Background", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
DocumentInputType::value("Background", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
|
DocumentInputType::value("Bounds", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
DocumentInputType::value("Trace", TaggedValue::VecDVec2((0..2).map(|x| DVec2::new(x as f64 * 10., 0.)).collect()), true),
|
DocumentInputType::value("Trace", TaggedValue::VecDVec2((0..2).map(|x| DVec2::new(x as f64 * 10., 0.)).collect()), true),
|
||||||
DocumentInputType::value("Diameter", TaggedValue::F64(40.), false),
|
DocumentInputType::value("Diameter", TaggedValue::F64(40.), false),
|
||||||
DocumentInputType::value("Hardness", TaggedValue::F64(50.), false),
|
DocumentInputType::value("Hardness", TaggedValue::F64(50.), false),
|
||||||
|
|||||||
+4
-4
@@ -588,11 +588,11 @@ pub fn blur_image_properties(document_node: &DocumentNode, node_id: NodeId, _con
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn brush_node_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
pub fn brush_node_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||||
let color = color_widget(document_node, node_id, 6, "Color", ColorInput::default(), true);
|
let color = color_widget(document_node, node_id, 7, "Color", ColorInput::default(), true);
|
||||||
|
|
||||||
let size = number_widget(document_node, node_id, 3, "Diameter", NumberInput::default().min(1.).max(100.).unit(" px"), true);
|
let size = number_widget(document_node, node_id, 4, "Diameter", NumberInput::default().min(1.).max(100.).unit(" px"), true);
|
||||||
let hardness = number_widget(document_node, node_id, 4, "Hardness", NumberInput::default().min(0.).max(100.).unit("%"), true);
|
let hardness = number_widget(document_node, node_id, 5, "Hardness", NumberInput::default().min(0.).max(100.).unit("%"), true);
|
||||||
let flow = number_widget(document_node, node_id, 5, "Flow", NumberInput::default().min(1.).max(100.).unit("%"), true);
|
let flow = number_widget(document_node, node_id, 6, "Flow", NumberInput::default().min(1.).max(100.).unit("%"), true);
|
||||||
|
|
||||||
vec![color, LayoutGroup::Row { widgets: size }, LayoutGroup::Row { widgets: hardness }, LayoutGroup::Row { widgets: flow }]
|
vec![color, LayoutGroup::Row { widgets: size }, LayoutGroup::Row { widgets: hardness }, LayoutGroup::Row { widgets: flow }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ impl BrushToolData {
|
|||||||
responses.add(NodeGraphMessage::SetQualifiedInputValue {
|
responses.add(NodeGraphMessage::SetQualifiedInputValue {
|
||||||
layer_path,
|
layer_path,
|
||||||
node_path: vec![0],
|
node_path: vec![0],
|
||||||
input_index: 2,
|
input_index: 3,
|
||||||
value: TaggedValue::VecDVec2(points),
|
value: TaggedValue::VecDVec2(points),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -334,6 +334,7 @@ fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, response
|
|||||||
inputs: vec![
|
inputs: vec![
|
||||||
NodeInput::value(TaggedValue::None, false),
|
NodeInput::value(TaggedValue::None, false),
|
||||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
|
NodeInput::value(TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||||
NodeInput::value(TaggedValue::VecDVec2(data.points.last().cloned().unwrap_or_default()), false),
|
NodeInput::value(TaggedValue::VecDVec2(data.points.last().cloned().unwrap_or_default()), false),
|
||||||
// Diameter
|
// Diameter
|
||||||
NodeInput::value(TaggedValue::F64(data.diameter), false),
|
NodeInput::value(TaggedValue::F64(data.diameter), false),
|
||||||
@@ -374,11 +375,12 @@ fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerI
|
|||||||
tagged_value: TaggedValue::ImageFrame(image_frame),
|
tagged_value: TaggedValue::ImageFrame(image_frame),
|
||||||
..
|
..
|
||||||
} = image_input else { return None };
|
} = image_input else { return None };
|
||||||
let points_input = brush_node.inputs.get(2)?;
|
let points_input = brush_node.inputs.get(3)?;
|
||||||
let NodeInput::Value {
|
let NodeInput::Value {
|
||||||
tagged_value: TaggedValue::VecDVec2(points),
|
tagged_value: TaggedValue::VecDVec2(points),
|
||||||
..
|
..
|
||||||
} = points_input else { return None };
|
} = points_input else {
|
||||||
|
return None };
|
||||||
|
|
||||||
Some((layer_path, points.clone(), image_frame.clone()))
|
Some((layer_path, points.clone(), image_frame.clone()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,11 +180,12 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||||||
use graphene_std::brush::*;
|
use graphene_std::brush::*;
|
||||||
|
|
||||||
let image: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0]);
|
let image: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0]);
|
||||||
let trace: DowncastBothNode<(), Vec<DVec2>> = DowncastBothNode::new(args[1]);
|
let bounds: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[1]);
|
||||||
let diameter: DowncastBothNode<(), f64> = DowncastBothNode::new(args[2]);
|
let trace: DowncastBothNode<(), Vec<DVec2>> = DowncastBothNode::new(args[2]);
|
||||||
let hardness: DowncastBothNode<(), f64> = DowncastBothNode::new(args[3]);
|
let diameter: DowncastBothNode<(), f64> = DowncastBothNode::new(args[3]);
|
||||||
let flow: DowncastBothNode<(), f64> = DowncastBothNode::new(args[4]);
|
let hardness: DowncastBothNode<(), f64> = DowncastBothNode::new(args[4]);
|
||||||
let color: DowncastBothNode<(), Color> = DowncastBothNode::new(args[5]);
|
let flow: DowncastBothNode<(), f64> = DowncastBothNode::new(args[5]);
|
||||||
|
let color: DowncastBothNode<(), Color> = DowncastBothNode::new(args[6]);
|
||||||
|
|
||||||
let stamp = BrushStampGeneratorNode::new(color, CopiedNode::new(hardness.eval(())), CopiedNode::new(flow.eval(())));
|
let stamp = BrushStampGeneratorNode::new(color, CopiedNode::new(hardness.eval(())), CopiedNode::new(flow.eval(())));
|
||||||
let stamp = stamp.eval(diameter.eval(()));
|
let stamp = stamp.eval(diameter.eval(()));
|
||||||
@@ -196,7 +197,13 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||||||
let background_bounds = ReduceNode::new(ClonedNode::new(None), ValueNode::new(MergeBoundingBoxNode::new()));
|
let background_bounds = ReduceNode::new(ClonedNode::new(None), ValueNode::new(MergeBoundingBoxNode::new()));
|
||||||
let background_bounds = background_bounds.eval(frames.clone().into_iter());
|
let background_bounds = background_bounds.eval(frames.clone().into_iter());
|
||||||
let background_bounds = MergeBoundingBoxNode::new().eval((background_bounds, image.eval(())));
|
let background_bounds = MergeBoundingBoxNode::new().eval((background_bounds, image.eval(())));
|
||||||
let background_bounds = ClonedNode::new(background_bounds.unwrap().to_transform());
|
let mut background_bounds = CopiedNode::new(background_bounds.unwrap().to_transform());
|
||||||
|
|
||||||
|
let bounds_transform = bounds.eval(()).transform;
|
||||||
|
if bounds_transform != DAffine2::ZERO {
|
||||||
|
background_bounds = CopiedNode::new(bounds_transform);
|
||||||
|
log::debug!("setting transform to {:?}", bounds_transform);
|
||||||
|
}
|
||||||
|
|
||||||
let background_image = background_bounds.then(EmptyImageNode::new(CopiedNode::new(Color::TRANSPARENT)));
|
let background_image = background_bounds.then(EmptyImageNode::new(CopiedNode::new(Color::TRANSPARENT)));
|
||||||
let blend_node = graphene_core::raster::BlendNode::new(CopiedNode::new(BlendMode::Normal), CopiedNode::new(100.));
|
let blend_node = graphene_core::raster::BlendNode::new(CopiedNode::new(BlendMode::Normal), CopiedNode::new(100.));
|
||||||
@@ -213,7 +220,15 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||||||
NodeIOTypes::new(
|
NodeIOTypes::new(
|
||||||
concrete!(()),
|
concrete!(()),
|
||||||
concrete!(ImageFrame<Color>),
|
concrete!(ImageFrame<Color>),
|
||||||
vec![value_fn!(ImageFrame<Color>), value_fn!(Vec<DVec2>), value_fn!(f64), value_fn!(f64), value_fn!(f64), value_fn!(Color)],
|
vec![
|
||||||
|
value_fn!(ImageFrame<Color>),
|
||||||
|
value_fn!(ImageFrame<Color>),
|
||||||
|
value_fn!(Vec<DVec2>),
|
||||||
|
value_fn!(f64),
|
||||||
|
value_fn!(f64),
|
||||||
|
value_fn!(f64),
|
||||||
|
value_fn!(Color),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
)],
|
)],
|
||||||
vec![(
|
vec![(
|
||||||
|
|||||||
Reference in New Issue
Block a user