Blender  V3.3
transform_convert_node.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "DNA_space_types.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_listbase.h"
13 #include "BLI_math.h"
14 #include "BLI_rect.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_node.h"
18 #include "BKE_node_tree_update.h"
19 #include "BKE_report.h"
20 
21 #include "ED_node.h"
22 
23 #include "UI_interface.h"
24 #include "UI_view2d.h"
25 
26 #include "transform.h"
27 #include "transform_convert.h"
28 #include "transform_snap.h"
29 
32 
33  /* Compare if the view has changed so we can update with `transformViewUpdate`. */
35 };
36 
37 /* -------------------------------------------------------------------- */
41 /* transcribe given node into TransData2D for Transforming */
42 static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac)
43 {
44  float locx, locy;
45 
46  /* account for parents (nested nodes) */
47  if (node->parent) {
48  nodeToView(node->parent, node->locx, node->locy, &locx, &locy);
49  }
50  else {
51  locx = node->locx;
52  locy = node->locy;
53  }
54 
55  /* use top-left corner as the transform origin for nodes */
56  /* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */
57 #ifdef USE_NODE_CENTER
58  td2d->loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node->totr) * +0.5f);
59  td2d->loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node->totr) * -0.5f);
60 #else
61  td2d->loc[0] = locx * dpi_fac;
62  td2d->loc[1] = locy * dpi_fac;
63 #endif
64  td2d->loc[2] = 0.0f;
65  td2d->loc2d = td2d->loc; /* current location */
66 
67  td->loc = td2d->loc;
68  copy_v3_v3(td->iloc, td->loc);
69  /* use node center instead of origin (top-left corner) */
70  td->center[0] = td2d->loc[0];
71  td->center[1] = td2d->loc[1];
72  td->center[2] = 0.0f;
73 
74  memset(td->axismtx, 0, sizeof(td->axismtx));
75  td->axismtx[2][2] = 1.0f;
76 
77  td->ext = NULL;
78  td->val = NULL;
79 
80  td->flag = TD_SELECTED;
81  td->dist = 0.0f;
82 
83  unit_m3(td->mtx);
84  unit_m3(td->smtx);
85 
86  td->extra = node;
87 }
88 
90 {
91  while ((node = node->parent)) {
92  if (node->flag & NODE_TRANSFORM) {
93  return true;
94  }
95  }
96  return false;
97 }
98 
100 {
101  const float dpi_fac = UI_DPI_FAC;
102  SpaceNode *snode = t->area->spacedata.first;
103 
104  /* Custom data to enable edge panning during the node transform */
105  struct TransCustomDataNode *customdata = MEM_callocN(sizeof(*customdata), __func__);
106  UI_view2d_edge_pan_init(t->context,
107  &customdata->edgepan_data,
114  customdata->viewrect_prev = customdata->edgepan_data.initial_rect;
115 
116  t->custom.type.data = customdata;
117  t->custom.type.use_free = true;
118 
120 
121  tc->data_len = 0;
122 
123  if (!snode->edittree) {
124  return;
125  }
126 
127  /* Nodes don't support PET and probably never will. */
128  t->flag &= ~T_PROP_EDIT_ALL;
129 
130  /* set transform flags on nodes */
131  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
132  if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) {
133  node->flag |= NODE_TRANSFORM;
134  tc->data_len++;
135  }
136  else {
137  node->flag &= ~NODE_TRANSFORM;
138  }
139  }
140 
141  if (tc->data_len == 0) {
142  return;
143  }
144 
145  TransData *td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData");
146  TransData2D *td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
147  "TransNode TransData2D");
148 
149  LISTBASE_FOREACH (bNode *, node, &snode->edittree->nodes) {
150  if (node->flag & NODE_TRANSFORM) {
151  NodeToTransData(td++, td2d++, node, dpi_fac);
152  }
153  }
154 }
155 
158 /* -------------------------------------------------------------------- */
163 {
164  const float dpi_fac = UI_DPI_FAC;
165 
166  struct TransCustomDataNode *customdata = (struct TransCustomDataNode *)t->custom.type.data;
167 
168  if (t->options & CTX_VIEW2D_EDGE_PAN) {
169  if (t->state == TRANS_CANCEL) {
170  UI_view2d_edge_pan_cancel(t->context, &customdata->edgepan_data);
171  }
172  else {
173  /* Edge panning functions expect window coordinates, mval is relative to region */
174  const int xy[2] = {
175  t->region->winrct.xmin + t->mval[0],
176  t->region->winrct.ymin + t->mval[1],
177  };
178  UI_view2d_edge_pan_apply(t->context, &customdata->edgepan_data, xy);
179  }
180  }
181 
182  float offset[2] = {0.0f, 0.0f};
183  if (t->state != TRANS_CANCEL) {
184  if (!BLI_rctf_compare(&customdata->viewrect_prev, &t->region->v2d.cur, FLT_EPSILON)) {
185  /* Additional offset due to change in view2D rect. */
186  BLI_rctf_transform_pt_v(&t->region->v2d.cur, &customdata->viewrect_prev, offset, offset);
188  customdata->viewrect_prev = t->region->v2d.cur;
189  }
190  }
191 
194 
195  /* flush to 2d vector from internally used 3d vector */
196  for (int i = 0; i < tc->data_len; i++) {
197  TransData *td = &tc->data[i];
198  TransData2D *td2d = &tc->data_2d[i];
199  bNode *node = td->extra;
200 
201  float loc[2];
202  add_v2_v2v2(loc, td2d->loc, offset);
203 
204 #ifdef USE_NODE_CENTER
205  loc[0] -= 0.5f * BLI_rctf_size_x(&node->totr);
206  loc[1] += 0.5f * BLI_rctf_size_y(&node->totr);
207 #endif
208 
209  /* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */
210  loc[0] /= dpi_fac;
211  loc[1] /= dpi_fac;
212 
213  /* account for parents (nested nodes) */
214  if (node->parent) {
215  nodeFromView(node->parent, loc[0], loc[1], &loc[0], &loc[1]);
216  }
217 
218  node->locx = loc[0];
219  node->locy = loc[1];
220  }
221 
222  /* handle intersection with noodles */
223  if (tc->data_len == 1) {
224  ED_node_link_intersect_test(t->area, 1);
225  }
226  }
227 }
228 
231 /* -------------------------------------------------------------------- */
236 {
237  struct Main *bmain = CTX_data_main(C);
238  const bool canceled = (t->state == TRANS_CANCEL);
239 
240  SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
241  if (canceled && t->remove_on_cancel) {
242  /* remove selected nodes on cancel */
243  bNodeTree *ntree = snode->edittree;
244  if (ntree) {
246  if (node->flag & NODE_SELECT) {
247  nodeRemoveNode(bmain, ntree, node, true);
248  }
249  }
251  }
252  }
253 
254  if (!canceled) {
256  ED_node_link_insert(bmain, t->area);
257  }
258 
259  /* clear link line */
260  ED_node_link_intersect_test(t->area, 0);
261 }
262 
266  /* flags */ (T_POINTS | T_2D_EDIT),
267  /* createTransData */ createTransNodeData,
268  /* recalcData */ flushTransNodes,
269  /* special_aftertrans_update */ special_aftertrans_update__node,
270 };
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
void nodeFromView(const struct bNode *node, float x, float y, float *rx, float *ry)
void nodeRemoveNode(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node, bool do_id_user)
Definition: node.cc:3011
void nodeToView(const struct bNode *node, float x, float y, float *rx, float *ry)
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2])
Definition: rct.c:529
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, float limit)
#define UNUSED(x)
#define NODE_SELECT
#define NODE_TRANSFORM
void ED_node_link_insert(struct Main *bmain, struct ScrArea *area)
void ED_node_post_apply_transform(struct bContext *C, struct bNodeTree *ntree)
#define NODE_EDGE_PAN_OUTSIDE_PAD
Definition: ED_node.h:38
#define NODE_EDGE_PAN_INSIDE_PAD
Definition: ED_node.h:37
#define NODE_EDGE_PAN_MAX_SPEED
Definition: ED_node.h:40
void ED_node_link_intersect_test(struct ScrArea *area, int test)
#define NODE_EDGE_PAN_DELAY
Definition: ED_node.h:41
#define NODE_EDGE_PAN_ZOOM_INFLUENCE
Definition: ED_node.h:42
void ED_node_tree_propagate_change(const struct bContext *C, struct Main *bmain, struct bNodeTree *ntree)
#define NODE_EDGE_PAN_SPEED_RAMP
Definition: ED_node.h:39
_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 GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
#define UI_DPI_FAC
Definition: UI_interface.h:305
void UI_view2d_edge_pan_apply(struct bContext *C, struct View2DEdgePanData *vpd, const int xy[2]) ATTR_NONNULL(1
void UI_view2d_edge_pan_init(struct bContext *C, struct View2DEdgePanData *vpd, float inside_pad, float outside_pad, float speed_ramp, float max_speed, float delay, float zoom_influence)
void UI_view2d_edge_pan_cancel(struct bContext *C, struct View2DEdgePanData *vpd)
OperationNode * node
bNodeTree * ntree
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
void tranformViewUpdate(TransInfo *t)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition: BKE_main.h:121
struct bNodeTree * edittree
View2DEdgePanData edgepan_data
float * loc2d
float loc[3]
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
ListBase nodes
conversion and adaptation of different datablocks to a common struct.
static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac)
static void special_aftertrans_update__node(bContext *C, TransInfo *t)
static bool is_node_parent_select(bNode *node)
static void flushTransNodes(TransInfo *t)
static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
TransConvertTypeInfo TransConvertType_Node
@ TD_SELECTED
void applyGridAbsolute(TransInfo *t)
int xy[2]
Definition: wm_draw.c:135