1
+ use super :: line_shape:: NodeGraphLayer ;
1
2
use super :: shape_utility:: { ShapeToolModifierKey , update_radius_sign} ;
2
3
use super :: * ;
3
4
use crate :: messages:: portfolio:: document:: graph_operation:: utility_types:: TransformIn ;
4
5
use crate :: messages:: portfolio:: document:: node_graph:: document_node_definitions:: resolve_document_node_type;
6
+ use crate :: messages:: portfolio:: document:: overlays:: utility_types:: OverlayContext ;
5
7
use crate :: messages:: portfolio:: document:: utility_types:: document_metadata:: LayerNodeIdentifier ;
6
8
use crate :: messages:: portfolio:: document:: utility_types:: network_interface:: { InputConnector , NodeTemplate } ;
7
9
use crate :: messages:: tool:: common_functionality:: graph_modification_utils;
8
10
use crate :: messages:: tool:: tool_messages:: tool_prelude:: * ;
9
11
use glam:: DAffine2 ;
10
12
use graph_craft:: document:: NodeInput ;
11
13
use graph_craft:: document:: value:: TaggedValue ;
14
+ use graphene_std:: vector:: PointId ;
12
15
use std:: collections:: VecDeque ;
13
16
14
17
#[ derive( Default ) ]
15
18
pub struct Star ;
16
19
20
+ #[ derive( Clone , Debug , Default ) ]
21
+ pub struct PointRadiusHandle {
22
+ pub center : DVec2 ,
23
+ pub vertex : Option < PointId > ,
24
+ pub index : usize ,
25
+ }
26
+
27
+ #[ derive( Clone , Debug , Default ) ]
28
+ pub struct StarShapeData {
29
+ pub point_radius_handle : PointRadiusHandle ,
30
+ }
31
+
17
32
impl Star {
18
33
pub fn create_node ( vertices : u32 ) -> NodeTemplate {
19
34
let node_type = resolve_document_node_type ( "Star" ) . expect ( " Star node does not exist" ) ;
@@ -25,6 +40,122 @@ impl Star {
25
40
] )
26
41
}
27
42
43
+ pub fn set_point_radius_handle ( document : & DocumentMessageHandler , mouse_pos : DVec2 , shape_tool_data : & mut ShapeToolData ) -> bool {
44
+ if let Some ( ( layer, ( center, _, vertex, index) ) ) = Self :: points_on_inner_circle ( document, mouse_pos) . iter ( ) . next ( ) {
45
+ shape_tool_data. data . layer = Some ( * layer) ;
46
+ shape_tool_data. star_data . point_radius_handle = PointRadiusHandle {
47
+ center : * center,
48
+ vertex : Some ( * vertex) ,
49
+ index : * index,
50
+ } ;
51
+ return true ;
52
+ }
53
+ false
54
+ }
55
+
56
+ pub fn inner_gizmo_overlays ( document : & DocumentMessageHandler , shape_tool_data : & mut ShapeToolData , overlay_context : & mut OverlayContext ) {
57
+ let PointRadiusHandle { center, vertex, .. } = shape_tool_data. star_data . point_radius_handle ;
58
+ let layer = shape_tool_data. data . layer . unwrap ( ) ;
59
+ let vector_data = document. network_interface . compute_modified_vector ( layer) . unwrap ( ) ;
60
+ let viewport = document. metadata ( ) . transform_to_viewport ( layer) ;
61
+ let vertex_pos = vector_data. point_domain . position_from_id ( vertex. unwrap ( ) ) . unwrap ( ) ;
62
+ Self :: draw_point_radius_overlay ( center, vertex_pos, viewport, overlay_context) ;
63
+ }
64
+
65
+ fn draw_point_radius_overlay ( center : DVec2 , vertex_pos : DVec2 , transform : DAffine2 , overlay_context : & mut OverlayContext ) {
66
+ let viewport_center = transform. transform_point2 ( center) ;
67
+ let viewport_vertex = transform. transform_point2 ( vertex_pos) ;
68
+ let extension_length = ( viewport_vertex - viewport_center) . length ( ) * 0.5 ;
69
+ let extension = ( viewport_vertex - viewport_center) . normalize ( ) * extension_length;
70
+
71
+ overlay_context. line ( viewport_center, viewport_vertex + extension, None , None ) ;
72
+ overlay_context. manipulator_handle ( viewport_vertex, true , None ) ;
73
+ }
74
+ // when hovered
75
+ pub fn hover_point_radius_handle ( document : & DocumentMessageHandler , mouse_pos : DVec2 , overlay_context : & mut OverlayContext ) -> bool {
76
+ for ( layer, ( center, vertex_pos, _, _) ) in Self :: points_on_inner_circle ( document, mouse_pos) {
77
+ let transform = document. metadata ( ) . transform_to_viewport ( layer) ;
78
+ Self :: draw_point_radius_overlay ( center, vertex_pos, transform, overlay_context) ;
79
+ return true ;
80
+ }
81
+
82
+ for layer in document
83
+ . network_interface
84
+ . selected_nodes ( )
85
+ . selected_visible_and_unlocked_layers ( & document. network_interface )
86
+ . filter ( |layer| graph_modification_utils:: get_star_id ( * layer, & document. network_interface ) . is_some ( ) )
87
+ {
88
+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
89
+ return false ;
90
+ } ;
91
+
92
+ for ( _, anchor_positions) in vector_data. point_domain . position_ids ( ) {
93
+ let transform = document. metadata ( ) . transform_to_viewport ( layer) ;
94
+ overlay_context. manipulator_handle ( transform. transform_point2 ( * anchor_positions) , false , None ) ;
95
+ }
96
+
97
+ return false ;
98
+ }
99
+ false
100
+ }
101
+
102
+ pub fn points_on_inner_circle ( document : & DocumentMessageHandler , mouse_pos : DVec2 ) -> HashMap < LayerNodeIdentifier , ( DVec2 , DVec2 , PointId , usize ) > {
103
+ let mut result = HashMap :: new ( ) ;
104
+
105
+ for layer in document
106
+ . network_interface
107
+ . selected_nodes ( )
108
+ . selected_visible_and_unlocked_layers ( & document. network_interface )
109
+ . filter ( |layer| graph_modification_utils:: get_star_id ( * layer, & document. network_interface ) . is_some ( ) )
110
+ {
111
+ let Some ( node_inputs) = NodeGraphLayer :: new ( layer, & document. network_interface ) . find_node_inputs ( "Star" ) else {
112
+ return result;
113
+ } ;
114
+
115
+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
116
+ return result;
117
+ } ;
118
+
119
+ let transform = document. network_interface . document_metadata ( ) . transform_to_viewport ( layer) ;
120
+ let center = DVec2 :: ZERO ;
121
+
122
+ let ( Some ( & TaggedValue :: F64 ( outer) ) , Some ( & TaggedValue :: F64 ( inner) ) ) = ( node_inputs[ 2 ] . as_value ( ) , node_inputs[ 3 ] . as_value ( ) ) else {
123
+ return result;
124
+ } ;
125
+
126
+ let mut index = 0 ;
127
+
128
+ let inner_point = vector_data. point_domain . position_ids ( ) . find ( |( _, pos) | {
129
+ let transformed = transform. transform_point2 ( * * pos) ;
130
+ if transformed. distance ( mouse_pos) >= 5.0 {
131
+ return false ;
132
+ }
133
+
134
+ let dist = pos. distance ( center) ;
135
+ if ( dist - inner) . abs ( ) < 1e-6 {
136
+ index = 3 ;
137
+
138
+ true
139
+ } else if ( dist - outer) . abs ( ) < 1e-6 {
140
+ index = 2 ;
141
+ log:: info!( "dist to outer {:?}" , ( dist - outer) . abs( ) ) ;
142
+
143
+ true
144
+ } else {
145
+ false
146
+ }
147
+ } ) ;
148
+
149
+ // Only insert if we found an inner point
150
+ if let Some ( ( point_id, vertex_pos) ) = inner_point {
151
+ result. insert ( layer, ( center, * vertex_pos, point_id, index) ) ;
152
+ break ;
153
+ }
154
+ }
155
+
156
+ result
157
+ }
158
+
28
159
pub fn update_shape (
29
160
document : & DocumentMessageHandler ,
30
161
ipp : & InputPreprocessorMessageHandler ,
@@ -74,4 +205,54 @@ impl Star {
74
205
}
75
206
false
76
207
}
208
+
209
+ pub fn update_inner_radius (
210
+ document : & DocumentMessageHandler ,
211
+ input : & InputPreprocessorMessageHandler ,
212
+ layer : LayerNodeIdentifier ,
213
+ responses : & mut VecDeque < Message > ,
214
+ shape_tool_data : & mut ShapeToolData ,
215
+ ) {
216
+ let Some ( node_id) = graph_modification_utils:: get_star_id ( layer, & document. network_interface ) else {
217
+ return ;
218
+ } ;
219
+
220
+ let Some ( vector_data) = document. network_interface . compute_modified_vector ( layer) else {
221
+ return ;
222
+ } ;
223
+
224
+ let Some ( node_inputs) = NodeGraphLayer :: new ( layer, & document. network_interface ) . find_node_inputs ( "Star" ) else {
225
+ return ;
226
+ } ;
227
+
228
+ let path = vector_data. stroke_bezier_paths ( ) . next ( ) . unwrap ( ) ;
229
+ let center = path. length_centroid ( None , true ) . unwrap ( ) ;
230
+ let transform = document. network_interface . document_metadata ( ) . transform_to_viewport ( layer) ;
231
+ let index = shape_tool_data. star_data . point_radius_handle . index ;
232
+
233
+ // inner radiust
234
+ let Some ( & TaggedValue :: F64 ( required_radius) ) = node_inputs[ index] . as_value ( ) else {
235
+ return ;
236
+ } ;
237
+
238
+ // update_radius_sign(start, end, layer, document, responses);
239
+
240
+ let delta = input. mouse . position - shape_tool_data. last_mouse_position ;
241
+ let radius = document. metadata ( ) . document_to_viewport . transform_point2 ( shape_tool_data. data . drag_start ) - transform. transform_point2 ( center) ;
242
+ let projection = delta. project_onto ( radius) ;
243
+ let sign = radius. dot ( delta) . signum ( ) ;
244
+
245
+ let net_delta = projection. length ( ) * sign;
246
+ shape_tool_data. last_mouse_position = input. mouse . position ;
247
+
248
+ // overlay_context.line(transform.transform_point2(center), transform.transform_point2(inner + net_delta), None, None);
249
+
250
+ // We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
251
+
252
+ responses. add ( NodeGraphMessage :: SetInput {
253
+ input_connector : InputConnector :: node ( node_id, index) ,
254
+ input : NodeInput :: value ( TaggedValue :: F64 ( required_radius + net_delta) , false ) ,
255
+ } ) ;
256
+ responses. add ( NodeGraphMessage :: RunDocumentGraph ) ;
257
+ }
77
258
}
0 commit comments