76 if (link->fromnode ==
from) {
77 if (link->tonode == to) {
106 current_node = current_node->next) {
194 linkdata->
data = oplink;
255 const float cursor_link_touch_distance = 12.5f *
UI_DPI_FAC;
262 if (link->tosock == socket) {
269 vec[0][0], vec[1][0], vec[2][0], vec[3][0],
data, resolution,
sizeof(
float[2]));
271 vec[0][1], vec[1][1], vec[2][1], vec[3][1],
data + 1, resolution,
sizeof(
float[2]));
273 for (
int i = 0; i < resolution * 2; i += 2) {
274 float *l1 = &
data[i];
275 float *l2 = &
data[i + 2];
277 if (
distance < cursor_link_touch_distance) {
290 if (last_picked_link) {
291 link_to_pick = last_picked_link;
335 const bool allow_multiple)
343 if (sock->flag &
SELECT) {
355 if (sock->type == sock_target->
type) {
356 if (
STREQ(sock->name, sock_target->
name)) {
369 if (sock->type == sock_target->
type) {
377 return node->outputs.first;
389 maxtype =
max_ii(sock->type, maxtype);
394 for (
int socktype = maxtype; socktype >= 0; socktype--) {
401 if (sock->type == socktype) {
446 return link_a_y > link_b_y ? 1 : -1;
459 int total_inputs = socket->total_inputs + 1;
474 input_links[index] = link_and_position;
481 link_and_position->
link = drag_link;
483 input_links[index] = link_and_position;
489 for (
int i = 0; i < index; i++) {
493 for (
int i = 0; i < index; i++) {
494 if (input_links[i]) {
504 const bool allow_multiple,
523 bool has_selected_inputs =
false;
525 if (nli->next ==
NULL) {
529 bNode *node_fr = nli->node;
538 if (sock_to->flag &
SELECT) {
539 has_selected_inputs = 1;
557 if (!has_selected_inputs) {
561 for (
int i = 0; i < num_inputs; i++) {
616 if (viewer_node ==
NULL) {
646 for (sock = sock->
next; sock; sock = sock->
next) {
732 ot->
name =
"Link to Viewer Node";
750 BLI_strncpy(header,
TIP_(
"LMB: drag node link, RMB: cancel"),
sizeof(header));
779 if (tlink && tlink->fromsock ==
from) {
780 if (from_count > from_link_limit) {
787 if (tlink && tlink->tosock == to) {
788 if (to_count > to_link_limit) {
793 else if (tlink->fromsock ==
from) {
810 bool do_tag_update =
false;
889 if (existing_link->fromsock ==
link->
fromsock && existing_link->tosock == tsock) {
890 existing_link_connected_to_fromsock = existing_link;
899 if (existing_link_connected_to_fromsock) {
963 switch (event->
type) {
1008 if (num_links > 0 && (num_links >= link_limit || detach)) {
1016 linkdata->
data = oplink;
1052 if (num_links > 0) {
1062 link_to_pick =
link;
1069 linkdata->
data = oplink;
1070 *oplink = *link_to_pick;
1146 ot->
description =
"Use the mouse to create a link between two nodes";
1166 "The operation has placed a link. Only used for multi-input sockets, where the "
1167 "link is picked later");
1176 "The position of the mouse cursor at the start of the operation",
1211 ot->
description =
"Makes a link between selected output in input sockets";
1223 ot->
srna,
"replace", 0,
"Replace",
"Replace socket connections with the new links");
1232 for (
int i = 0; i < tot - 1; i++) {
1234 if (
isect_seg_seg_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
1249 bool do_tag_update =
false;
1252 float mcoords[256][2];
1258 ®ion->
v2d, (
int)loc[0], (
int)loc[1], &mcoords[i][0], &mcoords[i][1]);
1278 if (found ==
false) {
1284 do_tag_update |= (do_tag_update ||
1299 if (do_tag_update) {
1316 ot->
description =
"Use the mouse to cut (remove) some links";
1344 bool do_tag_update =
false;
1347 float mcoords[256][2];
1353 ®ion->
v2d, (
int)loc[0], (
int)loc[1], &mcoords[i][0], &mcoords[i][1]);
1386 do_tag_update |= (do_tag_update ||
1406 if (do_tag_update) {
1466 ot->
name =
"Detach Links";
1467 ot->
idname =
"NODE_OT_links_detach";
1469 "Remove all links to selected nodes, and try to connect neighbor nodes together";
1490 if (
node == frame) {
1508 ot->
name =
"Make Parent";
1523 #define NODE_JOIN_DONE 1
1524 #define NODE_JOIN_IS_DESCENDANT 2
1530 if (
node == frame) {
1533 else if (
node->parent) {
1602 ot->
description =
"Attach selected nodes to a new common frame";
1617 const int mouse_xy[2])
1656 for (parent = frame->
parent; parent; parent = parent->
parent) {
1657 if (parent ==
node->parent) {
1683 ot->
name =
"Attach Nodes";
1699 #define NODE_DETACH_DONE 1
1700 #define NODE_DETACH_IS_DESCENDANT 2
1755 ot->
name =
"Detach Nodes";
1845 float dist_best = FLT_MAX;
1854 float dist = FLT_MAX;
1863 const float node_xy[] = {
select->totr.xmin,
select->totr.ymax};
1873 if (dist < dist_best) {
1891 maxtype =
max_ii(sock->type, maxtype);
1906 if (
type == sock->type) {
1948 #define NODE_INSOFS_ANIM_DURATION 0.25f
1957 const bool reversed)
1960 bNode *ofs_node = reversed ? fromnode : tonode;
1976 const bNode *parent,
1978 const bool reversed)
1994 const bool reversed)
1997 bNode *ofs_node = reversed ? fromnode : tonode;
1999 if (
data->insert_parent) {
2012 else if (ofs_node->
parent) {
2025 const int mouse_xy[2],
2026 const bool right_alignment)
2033 const float min_margin =
U.node_margin *
UI_DPI_FAC;
2035 const bool needs_alignment = (
next->totr.xmin - prev->
totr.
xmax) < (
width + (min_margin * 2.0f));
2037 float margin =
width;
2084 float dist = right_alignment ? totr_insert.
xmin - prev->
totr.
xmax :
2085 next->totr.xmin - totr_insert.
xmax;
2087 if (dist < min_margin) {
2088 const float addval = (min_margin - dist) * (right_alignment ? 1.0f : -1.0f);
2092 totr_insert.
xmin += addval;
2093 totr_insert.
xmax += addval;
2094 margin += min_margin;
2099 dist = right_alignment ?
next->totr.xmin - totr_insert.
xmax : totr_insert.
xmin - prev->
totr.
xmax;
2101 if (dist < min_margin) {
2102 const float addval = (min_margin - dist) * (right_alignment ? 1.0f : -1.0f);
2103 if (needs_alignment) {
2104 bNode *offs_node = right_alignment ?
next : prev;
2121 if (needs_alignment) {
2129 right_alignment ?
next : prev,
2135 insert->parent = init_parent;
2145 bool redraw =
false;
2157 const float endval =
node->anim_init_locx +
node->anim_ofsx;
2161 if (
node->anim_ofsx < 0) {
2180 node->anim_init_locx =
node->anim_ofsx = 0.0f;
2192 #undef NODE_INSOFS_ANIM_DURATION
2199 if (!iofsd || !iofsd->
insert) {
2220 ot->
name =
"Insert Offset";
2221 ot->
description =
"Automatically offset nodes on insertion";
2222 ot->
idname =
"NODE_OT_insert_offset";
2254 if (best_input && best_output) {
typedef float(TangentPoint)[2]
struct AnimData * BKE_animdata_from_id(struct ID *id)
struct ScrArea * CTX_wm_area(const bContext *C)
struct SpaceNode * CTX_wm_space_node(const bContext *C)
struct wmWindowManager * CTX_wm_manager(const bContext *C)
struct ARegion * CTX_wm_region(const bContext *C)
struct Main * CTX_data_main(const bContext *C)
struct wmWindow * CTX_wm_window(const bContext *C)
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
void BKE_main_id_tag_listbase(struct ListBase *lb, const int tag, const bool value)
void ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable)
bool nodeLinkIsHidden(const struct bNodeLink *link)
bool nodeAttachNodeCheck(const struct bNode *node, const struct bNode *parent)
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node)
void nodeRemSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock)
#define NODE_CUSTOM_GROUP
bool nodeIsChildOf(const bNode *parent, const bNode *child)
void nodeChainIter(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *, const bool), void *userdata, const bool reversed)
void nodeAttachNode(struct bNode *node, struct bNode *parent)
struct bNode * nodeGetActive(struct bNodeTree *ntree)
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link)
int nodeSocketIsHidden(const struct bNodeSocket *sock)
void nodeMuteLinkToggle(struct bNodeTree *ntree, struct bNodeLink *link)
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree)
int nodeSocketLinkLimit(const struct bNodeSocket *sock)
struct bNodeLink * nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock)
void nodeParentsIter(bNode *node, bool(*callback)(bNode *, void *), void *userdata)
struct bNode * nodeFindRootParent(bNode *node)
int nodeCountSocketLinks(const struct bNodeTree *ntree, const struct bNodeSocket *sock)
void nodeDetachNode(struct bNode *node)
float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration)
void BLI_kdtree_nd_() insert(KDTree *tree, int index, const float co[KD_DIMS]) ATTR_NONNULL(1
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
bool BLI_rctf_isect_x(const rctf *rect, const float x)
bool BLI_rctf_isect_y(const rctf *rect, const float y)
bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2])
bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
#define NODE_LINK_TEMP_HIGHLIGHT
#define NODE_LINKFLAG_HILITE
@ SNODE_INSERTOFS_DIR_RIGHT
void ED_node_tag_update_id(struct ID *id)
bool ED_node_is_geometry(struct SpaceNode *snode)
void ED_node_sort(struct bNodeTree *ntree)
void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain)
void ED_area_tag_redraw(ScrArea *area)
bool ED_operator_node_editable(struct bContext *C)
void ED_region_tag_redraw(struct ARegion *region)
void ED_workspace_status_text(struct bContext *C, const char *str)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel CMP_NODE_SPLITVIEWER
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White CMP_NODE_VIEWER
#define RNA_BEGIN(sptr, itemptr, propname)
StructRNA RNA_OperatorMousePath
#define UI_PRECISION_FLOAT_MAX
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
bool node_link_bezier_points(const View2D *v2d, const SpaceNode *snode, const bNodeLink *link, float coord_array[][2], const int resol)
bool node_link_bezier_handles(const View2D *v2d, const SpaceNode *snode, const bNodeLink *link, float vec[4][2])
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
static void area(int d1, int d2, int e1, int e2, float weights[2])
bNode * node_add_node(const bContext *C, const char *idname, int type, float locx, float locy)
void node_to_updated_rect(const bNode *node, rctf *r_rect)
void snode_update(SpaceNode *snode, bNode *node)
void snode_dag_update(bContext *C, SpaceNode *snode)
void node_link_calculate_multi_input_position(const float socket_x, const float socket_y, const int index, const int total_inputs, float r[2])
void snode_notify(bContext *C, SpaceNode *snode)
int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, const float cursor[2], int in_out)
bool composite_node_editable(bContext *C)
void node_deselect_all_input_sockets(struct SpaceNode *snode, const bool deselect_nodes)
void node_deselect_all_output_sockets(struct SpaceNode *snode, const bool deselect_nodes)
static int node_make_link_exec(bContext *C, wmOperator *op)
#define NODE_DETACH_IS_DESCENDANT
static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
struct LinkAndPosition LinkAndPosition
static int cut_links_exec(bContext *C, wmOperator *op)
static int node_attach_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static void node_link_cancel(bContext *C, wmOperator *op)
static void node_join_attach_recursive(bNode *node, bNode *frame)
static void node_link_update_header(bContext *C, bNodeLinkDrag *UNUSED(nldrag))
void NODE_OT_attach(wmOperatorType *ot)
static bool node_link_insert_offset_frame_chain_cb(bNode *fromnode, bNode *tonode, void *userdata, const bool reversed)
void NODE_OT_parent_set(wmOperatorType *ot)
void sort_multi_input_socket_links(SpaceNode *snode, bNode *node, bNodeLink *drag_link, float cursor[2])
void NODE_OT_link_make(wmOperatorType *ot)
static bNode * node_find_frame_to_attach(ARegion *region, const bNodeTree *ntree, const int mouse_xy[2])
static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
static void pick_link(const bContext *C, wmOperator *op, bNodeLinkDrag *nldrag, SpaceNode *snode, bNode *node, bNodeLink *link_to_pick)
void NODE_OT_detach(wmOperatorType *ot)
struct NodeInsertOfsData NodeInsertOfsData
static void clear_picking_highlight(ListBase *links)
static int node_detach_exec(bContext *C, wmOperator *UNUSED(op))
static int compare_link_by_y_position(const void *a, const void *b)
static void snode_autoconnect(Main *bmain, SpaceNode *snode, const bool allow_multiple, const bool replace)
static bool ntree_check_nodes_connected(bNodeTree *ntree, bNode *from, bNode *to)
static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket)
static void node_remove_extra_links(SpaceNode *snode, bNodeLink *link)
static bool node_link_insert_offset_chain_cb(bNode *fromnode, bNode *tonode, void *userdata, const bool reversed)
void NODE_OT_links_cut(wmOperatorType *ot)
static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
static bool ed_node_link_conditions(ScrArea *area, bool test, SpaceNode **r_snode, bNode **r_select)
static void pick_input_link_by_link_intersect(const bContext *C, wmOperator *op, bNodeLinkDrag *nldrag, const float *cursor)
static void node_detach_recursive(bNode *node)
void NODE_OT_insert_offset(wmOperatorType *ot)
void NODE_OT_link(wmOperatorType *ot)
void NODE_OT_links_detach(wmOperatorType *ot)
#define NODE_JOIN_IS_DESCENDANT
static int node_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
#define NODE_INSOFS_ANIM_DURATION
static int mute_links_exec(bContext *C, wmOperator *op)
static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int sort_nodes_locx(const void *a, const void *b)
static void node_parent_offset_apply(NodeInsertOfsData *data, bNode *parent, const float offset_x)
struct bNodeListItem bNodeListItem
static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd, ARegion *region, const int mouse_xy[2], const bool right_alignment)
void NODE_OT_join(wmOperatorType *ot)
static bool node_group_has_output_dfs(bNode *node)
void NODE_OT_link_viewer(wmOperatorType *ot)
static void node_link_find_socket(bContext *C, wmOperator *op, float cursor[2])
static bNodeSocket * best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace)
static bool node_parents_offset_flag_enable_cb(bNode *parent, void *UNUSED(userdata))
void ED_node_link_insert(Main *bmain, ScrArea *area)
static bool node_group_has_output(Main *bmain, bNode *node)
static bool socket_is_available(bNodeTree *UNUSED(ntree), bNodeSocket *sock, const bool allow_used)
static LinkData * create_drag_link(Main *bmain, SpaceNode *snode, bNode *node, bNodeSocket *sock)
static bool snode_autoconnect_input(SpaceNode *snode, bNode *node_fr, bNodeSocket *sock_fr, bNode *node_to, bNodeSocket *sock_to, int replace)
static bNodeLinkDrag * node_link_init(Main *bmain, SpaceNode *snode, float cursor[2], bool detach)
static bool node_links_intersect(bNodeLink *link, const float mcoords[][2], int tot)
static void node_link_insert_offset_frame_chains(const bNodeTree *ntree, const bNode *parent, NodeInsertOfsData *data, const bool reversed)
static bNodeSocket * socket_best_match(ListBase *sockets)
static void node_offset_apply(bNode *node, const float offset_x)
static int node_insert_offset_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
void ED_node_link_intersect_test(ScrArea *area, int test)
static int node_insert_offset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool ntree_has_drivers(bNodeTree *ntree)
static bool ntree_check_nodes_connected_dfs(bNodeTree *ntree, bNode *from, bNode *to)
static int node_link_viewer(const bContext *C, bNode *tonode)
bool node_connected_to_output(Main *bmain, bNodeTree *ntree, bNode *node)
void NODE_OT_links_mute(wmOperatorType *ot)
static bNodeSocket * best_socket_output(bNodeTree *ntree, bNode *node, bNodeSocket *sock_target, const bool allow_multiple)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
float multi_socket_position[2]
struct NodeInsertOfsData * iofsd
SpaceNode_Runtime * runtime
struct bNodeTree * edittree
struct bNodeLink * last_picked_multi_input_socket_link
struct bNode * last_node_hovered_while_dragging_a_link
bool from_multi_input_socket
int multi_input_socket_index
struct bNodeListItem * next
struct bNodeListItem * prev
struct bNodeSocket * next
void(* insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link)
struct bNodeType * typeinfo
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
void(* cancel)(struct bContext *, struct wmOperator *)
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
ccl_device_inline float distance(const float2 &a, const float2 &b)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_lines_cancel(bContext *C, wmOperator *op)
int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer)
wmTimer * WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)