Blender  V2.93
transform_convert_curve.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_curve_types.h"
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 
31 #include "BKE_context.h"
32 #include "BKE_curve.h"
33 
34 #include "transform.h"
35 #include "transform_snap.h"
36 
37 /* Own include. */
38 #include "transform_convert.h"
39 #include "transform_orientations.h"
40 
41 /* -------------------------------------------------------------------- */
49 static int bezt_select_to_transform_triple_flag(const BezTriple *bezt, const bool hide_handles)
50 {
51  int flag = 0;
52 
53  if (hide_handles) {
54  if (bezt->f2 & SELECT) {
55  flag = (1 << 0) | (1 << 1) | (1 << 2);
56  }
57  }
58  else {
59  flag = (((bezt->f1 & SELECT) ? (1 << 0) : 0) | ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
60  ((bezt->f3 & SELECT) ? (1 << 2) : 0));
61  }
62 
63  /* Special case for auto & aligned handles:
64  * When a center point is being moved without the handles,
65  * leaving the handles stationary makes no sense and only causes strange behavior,
66  * where one handle is arbitrarily anchored, the other one is aligned and lengthened
67  * based on where the center point is moved. Also a bug when canceling, see: T52007.
68  *
69  * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'.
70  * However that doesn't resolve odd behavior, so best transform the handles in this case.
71  */
72  if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) {
73  if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) && ELEM(bezt->h2, HD_AUTO, HD_ALIGN)) {
74  flag = (1 << 0) | (1 << 1) | (1 << 2);
75  }
76  }
77 
78  return flag;
79 }
80 
82 {
83 
84 #define SEL_F1 (1 << 0)
85 #define SEL_F2 (1 << 1)
86 #define SEL_F3 (1 << 2)
87 
88  t->data_len_all = 0;
89 
90  /* Count control points (one per #BezTriple) if any number of handles are selected.
91  * Needed for #transform_around_single_fallback_ex. */
92  int data_len_all_pt = 0;
93 
95  Curve *cu = tc->obedit->data;
96  BLI_assert(cu->editnurb != NULL);
97  BezTriple *bezt;
98  BPoint *bp;
99  int a;
100  int count = 0, countsel = 0;
101  int count_pt = 0, countsel_pt = 0;
102  const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
103  const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
104  View3D *v3d = t->view;
105  short hide_handles = (v3d != NULL) ? (v3d->overlay.handle_display == CURVE_HANDLE_NONE) :
106  false;
107 
108  /* count total of vertices, check identical as in 2nd loop for making transdata! */
109  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
110  LISTBASE_FOREACH (Nurb *, nu, nurbs) {
111  if (nu->type == CU_BEZIER) {
112  for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
113  if (bezt->hide == 0) {
114  const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
115  if (bezt_tx & (SEL_F1 | SEL_F2 | SEL_F3)) {
116  if (bezt_tx & SEL_F1) {
117  countsel++;
118  }
119  if (bezt_tx & SEL_F2) {
120  countsel++;
121  }
122  if (bezt_tx & SEL_F3) {
123  countsel++;
124  }
125  countsel_pt++;
126  }
127  if (is_prop_edit) {
128  count += 3;
129  count_pt++;
130  }
131  }
132  }
133  }
134  else {
135  for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
136  if (bp->hide == 0) {
137  if (bp->f1 & SELECT) {
138  countsel++;
139  countsel_pt++;
140  }
141  if (is_prop_edit) {
142  count++;
143  count_pt++;
144  }
145  }
146  }
147  }
148  }
149 
150  /* Support other objects using PET to adjust these, unless connected is enabled. */
151  if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) {
152  tc->data_len = 0;
153  continue;
154  }
155 
156  int data_len_pt = 0;
157 
158  if (is_prop_edit) {
159  tc->data_len = count;
160  data_len_pt = count_pt;
161  }
162  else {
163  tc->data_len = countsel;
164  data_len_pt = countsel_pt;
165  }
166  tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
167 
168  t->data_len_all += tc->data_len;
169  data_len_all_pt += data_len_pt;
170  }
171 
172  transform_around_single_fallback_ex(t, data_len_all_pt);
173  t->data_len_all = -1;
174 
176  if (tc->data_len == 0) {
177  continue;
178  }
179 
180  Curve *cu = tc->obedit->data;
181  BezTriple *bezt;
182  BPoint *bp;
183  int a;
184  const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
185  View3D *v3d = t->view;
186  short hide_handles = (v3d != NULL) ? (v3d->overlay.handle_display == CURVE_HANDLE_NONE) :
187  false;
188 
189  bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
191  float mtx[3][3], smtx[3][3];
192 
193  copy_m3_m4(mtx, tc->obedit->obmat);
195 
196  TransData *td = tc->data;
197  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
198  LISTBASE_FOREACH (Nurb *, nu, nurbs) {
199  TransData *head, *tail;
200  head = tail = td;
201  bool has_any_selected = false;
202  if (nu->type == CU_BEZIER) {
203  for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
204  if (bezt->hide == 0) {
206  float axismtx[3][3];
207 
208  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
209  float normal[3], plane[3];
210 
212  BKE_nurb_bezt_calc_plane(nu, bezt, plane);
213 
214  if (createSpaceNormalTangent(axismtx, normal, plane)) {
215  /* pass */
216  }
217  else {
219  axis_dominant_v3_to_m3(axismtx, normal);
220  invert_m3(axismtx);
221  }
222  }
223 
224  /* Elements that will be transform (not always a match to selection). */
225  const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
226  has_any_selected |= bezt_tx != 0;
227 
228  if (is_prop_edit || bezt_tx & SEL_F1) {
229  copy_v3_v3(td->iloc, bezt->vec[0]);
230  td->loc = bezt->vec[0];
231  copy_v3_v3(td->center,
232  bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
233  (bezt->f2 & SELECT)) ?
234  1 :
235  0]);
236  if (hide_handles) {
237  if (bezt->f2 & SELECT) {
238  td->flag = TD_SELECTED;
239  }
240  else {
241  td->flag = 0;
242  }
243  }
244  else {
245  if (bezt->f1 & SELECT) {
246  td->flag = TD_SELECTED;
247  }
248  else {
249  td->flag = 0;
250  }
251  }
252  td->ext = NULL;
253  td->val = NULL;
254 
255  hdata = initTransDataCurveHandles(td, bezt);
256 
257  copy_m3_m3(td->smtx, smtx);
258  copy_m3_m3(td->mtx, mtx);
259  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
260  copy_m3_m3(td->axismtx, axismtx);
261  }
262 
263  td++;
264  tail++;
265  }
266 
267  /* This is the Curve Point, the other two are handles */
268  if (is_prop_edit || bezt_tx & SEL_F2) {
269  copy_v3_v3(td->iloc, bezt->vec[1]);
270  td->loc = bezt->vec[1];
271  copy_v3_v3(td->center, td->loc);
272  if (bezt->f2 & SELECT) {
273  td->flag = TD_SELECTED;
274  }
275  else {
276  td->flag = 0;
277  }
278  td->ext = NULL;
279 
280  /* TODO - make points scale */
281  if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/
282  td->val = &(bezt->radius);
283  td->ival = bezt->radius;
284  }
285  else if (t->mode == TFM_TILT) {
286  td->val = &(bezt->tilt);
287  td->ival = bezt->tilt;
288  }
289  else {
290  td->val = NULL;
291  }
292 
293  copy_m3_m3(td->smtx, smtx);
294  copy_m3_m3(td->mtx, mtx);
295  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
296  copy_m3_m3(td->axismtx, axismtx);
297  }
298 
299  if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) {
300  /* If the middle is selected but the sides aren't, this is needed. */
301  if (hdata == NULL) {
302  /* if the handle was not saved by the previous handle */
303  hdata = initTransDataCurveHandles(td, bezt);
304  }
305  }
306 
307  td++;
308  tail++;
309  }
310  if (is_prop_edit || bezt_tx & SEL_F3) {
311  copy_v3_v3(td->iloc, bezt->vec[2]);
312  td->loc = bezt->vec[2];
313  copy_v3_v3(td->center,
314  bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
315  (bezt->f2 & SELECT)) ?
316  1 :
317  2]);
318  if (hide_handles) {
319  if (bezt->f2 & SELECT) {
320  td->flag = TD_SELECTED;
321  }
322  else {
323  td->flag = 0;
324  }
325  }
326  else {
327  if (bezt->f3 & SELECT) {
328  td->flag = TD_SELECTED;
329  }
330  else {
331  td->flag = 0;
332  }
333  }
334  td->ext = NULL;
335  td->val = NULL;
336 
337  if (hdata == NULL) {
338  /* if the handle was not saved by the previous handle */
339  hdata = initTransDataCurveHandles(td, bezt);
340  }
341 
342  copy_m3_m3(td->smtx, smtx);
343  copy_m3_m3(td->mtx, mtx);
344  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
345  copy_m3_m3(td->axismtx, axismtx);
346  }
347 
348  td++;
349  tail++;
350  }
351 
352  (void)hdata; /* quiet warning */
353  }
354  }
355  }
356  else {
357  for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
358  if (bp->hide == 0) {
359  if (is_prop_edit || (bp->f1 & SELECT)) {
360  float axismtx[3][3];
361 
362  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
363  if (nu->pntsv == 1) {
364  float normal[3], plane[3];
365 
367  BKE_nurb_bpoint_calc_plane(nu, bp, plane);
368 
369  if (createSpaceNormalTangent(axismtx, normal, plane)) {
370  /* pass */
371  }
372  else {
374  axis_dominant_v3_to_m3(axismtx, normal);
375  invert_m3(axismtx);
376  }
377  }
378  }
379 
380  copy_v3_v3(td->iloc, bp->vec);
381  td->loc = bp->vec;
382  copy_v3_v3(td->center, td->loc);
383  if (bp->f1 & SELECT) {
384  td->flag = TD_SELECTED;
385  has_any_selected |= true;
386  }
387  else {
388  td->flag = 0;
389  }
390  td->ext = NULL;
391 
392  if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_RESIZE)) {
393  td->val = &(bp->radius);
394  td->ival = bp->radius;
395  }
396  else {
397  td->val = &(bp->tilt);
398  td->ival = bp->tilt;
399  }
400 
401  copy_m3_m3(td->smtx, smtx);
402  copy_m3_m3(td->mtx, mtx);
403  if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
404  if (nu->pntsv == 1) {
405  copy_m3_m3(td->axismtx, axismtx);
406  }
407  }
408 
409  td++;
410  tail++;
411  }
412  }
413  }
414  }
415  if (is_prop_edit && head != tail) {
416  tail -= 1;
417  if (!has_any_selected) {
418  for (td = head; td <= tail; td++) {
419  td->flag |= TD_NOTCONNECTED;
420  }
421  }
422  bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
423  calc_distanceCurveVerts(head, tail, cyclic);
424  }
425 
426  /* TODO - in the case of tilt and radius we can also avoid allocating the
427  * initTransDataCurveHandles but for now just don't change handle types */
428  if ((nu->type == CU_BEZIER) &&
430  /* sets the handles based on their selection,
431  * do this after the data is copied to the TransData */
432  BKE_nurb_handles_test(nu, !hide_handles, use_around_origins_for_handles_test);
433  }
434  }
435  }
436 #undef SEL_F1
437 #undef SEL_F2
438 #undef SEL_F3
439 }
440 
442 {
443  if (t->state != TRANS_CANCEL) {
445  applyProject(t);
446  }
447 
449  Curve *cu = tc->obedit->data;
450  ListBase *nurbs = BKE_curve_editNurbs_get(cu);
451  Nurb *nu = nurbs->first;
452 
453  DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
454 
455  if (t->state == TRANS_CANCEL) {
456  while (nu) {
457  /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
459  nu = nu->next;
460  }
461  }
462  else {
463  /* Normal updating */
465  }
466  }
467 }
468 
void BKE_nurb_handles_calc(struct Nurb *nu)
Definition: curve.c:4092
void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3])
Definition: curve.c:1091
struct ListBase * BKE_curve_editNurbs_get(struct Curve *cu)
Definition: curve.c:437
void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_normal[3])
Definition: curve.c:1128
void BKE_curve_dimension_update(struct Curve *cu)
Definition: curve.c:467
void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_normal[3])
void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, struct BPoint *bp, float r_plane[3])
Definition: curve.c:1151
void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles, const bool use_around_local)
Definition: curve.c:4217
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
Definition: math_geom.c:3752
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
#define PSEUDOINVERSE_EPSILON
bool invert_m3(float R[3][3])
Definition: math_matrix.c:1152
void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
Definition: math_matrix.c:3228
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ CU_BEZIER
@ CU_NURB_CYCLIC
@ HD_AUTO
@ HD_ALIGN
@ V3D_AROUND_LOCAL_ORIGINS
@ CURVE_HANDLE_NONE
@ TFM_RESIZE
Definition: ED_transform.h:48
@ TFM_CURVE_SHRINKFATTEN
Definition: ED_transform.h:61
@ TFM_TILT
Definition: ED_transform.h:54
@ TFM_DUMMY
Definition: ED_transform.h:45
_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 SELECT
IconTextureDrawCall normal
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
short hide
uint8_t f1
float vec[4]
float radius
float tilt
float vec[3][3]
EditNurb * editnurb
void * first
Definition: DNA_listBase.h:47
struct Nurb * next
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
View3DOverlay overlay
@ T_PROP_CONNECTED
Definition: transform.h:112
@ T_PROP_EDIT
Definition: transform.h:111
@ TRANS_CANCEL
Definition: transform.h:193
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition: transform.h:813
void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic)
void transform_around_single_fallback_ex(TransInfo *t, int data_len_all)
bool transform_mode_use_local_origins(const TransInfo *t)
void clipMirrorModifier(TransInfo *t)
TransDataCurveHandleFlags * initTransDataCurveHandles(TransData *td, struct BezTriple *bezt)
conversion and adaptation of different datablocks to a common struct.
void createTransCurveVerts(TransInfo *t)
#define SEL_F1
#define SEL_F2
static int bezt_select_to_transform_triple_flag(const BezTriple *bezt, const bool hide_handles)
#define SEL_F3
void recalcData_curve(TransInfo *t)
@ TD_NOTCONNECTED
@ TD_SELECTED
bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3])
void applyProject(TransInfo *t)