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 20 /** \file 21 * \ingroup edtransform 22 */ 23 24 #pragma once 25 26 #include "ED_numinput.h" 27 #include "ED_transform.h" 28 #include "ED_view3d.h" 29 30 #include "RE_engine.h" 31 32 #include "DNA_listBase.h" 33 #include "DNA_object_enums.h" 34 35 #include "DEG_depsgraph.h" 36 37 #include "transform_data.h" 38 39 /* ************************** Types ***************************** */ 40 41 struct ARegion; 42 struct Depsgraph; 43 struct NumInput; 44 struct Object; 45 struct RNG; 46 struct ReportList; 47 struct Scene; 48 struct ScrArea; 49 struct SnapObjectContext; 50 struct TransDataContainer; 51 struct TransInfo; 52 struct TransSnap; 53 struct TransformOrientation; 54 struct ViewLayer; 55 struct bContext; 56 struct wmEvent; 57 struct wmKeyConfig; 58 struct wmKeyMap; 59 struct wmTimer; 60 61 /* transinfo->redraw */ 62 typedef enum { 63 TREDRAW_NOTHING = 0, 64 TREDRAW_HARD = 1, 65 TREDRAW_SOFT = 2, 66 } eRedrawFlag; 67 68 typedef struct TransSnapPoint { 69 struct TransSnapPoint *next, *prev; 70 float co[3]; 71 } TransSnapPoint; 72 73 typedef struct TransSnap { 74 short mode; 75 short target; 76 short modePoint; 77 short modeSelect; 78 bool align; 79 bool project; 80 bool snap_self; 81 bool peel; 82 bool use_backface_culling; 83 char status; 84 /* Snapped Element Type (currently for objects only). */ 85 char snapElem; 86 /** snapping from this point (in global-space). */ 87 float snapPoint[3]; 88 /** to this point (in global-space). */ 89 float snapTarget[3]; 90 float snapNormal[3]; 91 char snapNodeBorder; 92 ListBase points; 93 TransSnapPoint *selectedPoint; 94 double last; 95 void (*applySnap)(struct TransInfo *, float *); 96 void (*calcSnap)(struct TransInfo *, float *); 97 void (*targetSnap)(struct TransInfo *); 98 /** 99 * Get the transform distance between two points (used by Closest snap) 100 * 101 * \note Return value can be anything, 102 * where the smallest absolute value defines what's closest. 103 */ 104 float (*distance)(struct TransInfo *t, const float p1[3], const float p2[3]); 105 106 /** 107 * Re-usable snap context data. 108 */ 109 struct SnapObjectContext *object_context; 110 } TransSnap; 111 112 typedef struct TransCon { 113 /** Description of the constraint for header_print. */ 114 char text[50]; 115 /** Projection constraint matrix (same as #imtx with some axis == 0). */ 116 float pmtx[3][3]; 117 /** Initial mouse value for visual calculation 118 * the one in #TransInfo is not guarantee to stay the same (Rotates change it). */ 119 int imval[2]; 120 /** Mode flags of the constraint. */ 121 int mode; 122 void (*drawExtra)(struct TransInfo *t); 123 124 /* Note: if 'tc' is NULL, 'td' must also be NULL. 125 * For constraints that needs to draw differently from the other 126 * uses this instead of the generic draw function. */ 127 128 /** Apply function pointer for linear vectorial transformation 129 * The last three parameters are pointers to the in/out/printable vectors. */ 130 void (*applyVec)(struct TransInfo *t, 131 struct TransDataContainer *tc, 132 struct TransData *td, 133 const float in[3], 134 float out[3]); 135 /** Apply function pointer for size transformation. */ 136 void (*applySize)(struct TransInfo *t, 137 struct TransDataContainer *tc, 138 struct TransData *td, 139 float smat[3][3]); 140 /** Apply function pointer for rotation transformation */ 141 void (*applyRot)(struct TransInfo *t, 142 struct TransDataContainer *tc, 143 struct TransData *td, 144 float vec[3], 145 float *angle); 146 } TransCon; 147 148 typedef struct MouseInput { 149 void (*apply)(struct TransInfo *t, struct MouseInput *mi, const double mval[2], float output[3]); 150 void (*post)(struct TransInfo *t, float values[3]); 151 152 /** Initial mouse position. */ 153 int imval[2]; 154 bool precision; 155 float precision_factor; 156 float center[2]; 157 float factor; 158 /** Additional data, if needed by the particular function. */ 159 void *data; 160 161 /** 162 * Use virtual cursor, which takes precision into account 163 * keeping track of the cursors 'virtual' location, 164 * to avoid jumping values when its toggled. 165 * 166 * This works well for scaling drag motion, 167 * but not for rotating around a point (rotation needs its own custom accumulator) 168 */ 169 bool use_virtual_mval; 170 struct { 171 double prev[2]; 172 double accum[2]; 173 } virtual_mval; 174 } MouseInput; 175 176 typedef struct TransCustomData { 177 void *data; 178 void (*free_cb)(struct TransInfo *, 179 struct TransDataContainer *tc, 180 struct TransCustomData *custom_data); 181 unsigned int use_free : 1; 182 } TransCustomData; 183 184 typedef struct TransCenterData { 185 float global[3]; 186 unsigned int is_set : 1; 187 } TransCenterData; 188 189 /** 190 * Rule of thumb for choosing between mode/type: 191 * - If transform mode uses the data, assign to `mode` 192 * (typically in transform.c). 193 * - If conversion uses the data as an extension to the #TransData, assign to `type` 194 * (typically in transform_conversion.c). 195 */ 196 typedef struct TransCustomDataContainer { 197 /** Owned by the mode (grab, scale, bend... ).*/ 198 union { 199 TransCustomData mode, first_elem; 200 }; 201 TransCustomData type; 202 } TransCustomDataContainer; 203 #define TRANS_CUSTOM_DATA_ELEM_MAX (sizeof(TransCustomDataContainer) / sizeof(TransCustomData)) 204 205 typedef struct TransDataContainer { 206 /** Transformed data (array). */ 207 TransData *data; 208 /** Transformed data extension (array). */ 209 TransDataExtension *data_ext; 210 /** Transformed data for 2d (array). */ 211 TransData2D *data_2d; 212 /** Transformed data for mirror elements (array). */ 213 TransDataMirror *data_mirror; 214 215 /** Total number of transformed data, data_ext, data_2d. */ 216 int data_len; 217 /** Total number of transformed data_mirror. */ 218 int data_mirror_len; 219 220 struct Object *obedit; 221 222 float mat[4][4]; 223 float imat[4][4]; 224 /** 3x3 copies of matrices above. */ 225 float mat3[3][3]; 226 float imat3[3][3]; 227 228 /** Normalized 'mat3' */ 229 float mat3_unit[3][3]; 230 231 /** if 't->flag & T_POSE', this denotes pose object */ 232 struct Object *poseobj; 233 234 /** Center of transformation (in local-space), Calculated from #TransInfo.center_global. */ 235 float center_local[3]; 236 237 /** 238 * Use for cases we care about the active, eg: active vert of active mesh. 239 * if set this will _always_ be the first item in the array. 240 */ 241 bool is_active; 242 243 /** 244 * Store matrix, this avoids having to have duplicate check all over 245 * Typically: 'obedit->obmat' or 'poseobj->obmat', but may be used elsewhere too. 246 */ 247 bool use_local_mat; 248 249 /** Mirror option. */ 250 union { 251 struct { 252 uint use_mirror_axis_x : 1; 253 uint use_mirror_axis_y : 1; 254 uint use_mirror_axis_z : 1; 255 }; 256 /* For easy checking. */ 257 char use_mirror_axis_any; 258 }; 259 260 TransCustomDataContainer custom; 261 } TransDataContainer; 262 263 typedef struct TransInfo { 264 TransDataContainer *data_container; 265 int data_container_len; 266 267 /** eTransConvertType 268 * TODO: It should be a member of TransDataContainer. */ 269 int data_type; 270 271 /** Combine length of all #TransDataContainer.data_len 272 * Use to check if nothing is selected or if we have a single selection. */ 273 int data_len_all; 274 275 /** Current mode. */ 276 int mode; 277 /** Generic flags for special behaviors. */ 278 int flag; 279 /** Special modifiers, by function, not key. */ 280 int modifiers; 281 /** Current state (running, canceled. */ 282 short state; 283 /** Current context/options for transform. */ 284 int options; 285 void (*transform)(struct TransInfo *, const int[2]); 286 /** Transform function pointer. */ 287 eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *); 288 /* event handler function pointer RETURN 1 if redraw is needed */ 289 /** transformed constraint. */ 290 TransCon con; 291 TransSnap tsnap; 292 /** numerical input. */ 293 NumInput num; 294 /** mouse input. */ 295 MouseInput mouse; 296 /** redraw flag. */ 297 eRedrawFlag redraw; 298 /** proportional circle radius. */ 299 float prop_size; 300 /** proportional falloff text. */ 301 char proptext[20]; 302 /** 303 * Spaces using non 1:1 aspect, (uv's, f-curve, movie-clip... etc) 304 * use for conversion and snapping. 305 */ 306 float aspect[3]; 307 /** center of transformation (in global-space) */ 308 float center_global[3]; 309 /** center in screen coordinates. */ 310 float center2d[2]; 311 /* Lazy initialize center data for when we need other center values. 312 * V3D_AROUND_ACTIVE + 1 (static assert checks this) */ 313 TransCenterData center_cache[5]; 314 /** maximum index on the input vector. */ 315 short idx_max; 316 /** Snapping Gears. */ 317 float snap[2]; 318 /** Spatial snapping gears(even when rotating, scaling... etc). */ 319 float snap_spatial[2]; 320 /** Mouse side of the current frame, 'L', 'R' or 'B' */ 321 char frame_side; 322 323 /** copy from G.vd, prevents feedback. */ 324 float viewmat[4][4]; 325 /** and to make sure we don't have to. */ 326 float viewinv[4][4]; 327 /** access G.vd from other space types. */ 328 float persmat[4][4]; 329 float persinv[4][4]; 330 short persp; 331 short around; 332 /** spacetype where transforming is. */ 333 char spacetype; 334 /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */ 335 char helpline; 336 /** Avoid looking inside TransDataContainer obedit. */ 337 short obedit_type; 338 339 /** translation, to show for widget. */ 340 float vec[3]; 341 /** rot/rescale, to show for widget. */ 342 float mat[3][3]; 343 344 /** orientation matrix of the current space. */ 345 float spacemtx[3][3]; 346 float spacemtx_inv[3][3]; 347 /** name of the current space, MAX_NAME. */ 348 char spacename[64]; 349 350 /*************** NEW STUFF *********************/ 351 /** event type used to launch transform. */ 352 short launch_event; 353 /** Is the actual launch event a tweak event? (launch_event above is set to the corresponding 354 * mouse button then.) */ 355 bool is_launch_event_tweak; 356 357 struct { 358 short type; 359 float matrix[3][3]; 360 } orient[3]; 361 short orient_curr; 362 363 /** backup from view3d, to restore on end. */ 364 short gizmo_flag; 365 366 short prop_mode; 367 368 /** Value taken as input, either through mouse coordinates or entered as a parameter. */ 369 float values[4]; 370 371 /** Offset applied ontop of modal input. */ 372 float values_modal_offset[4]; 373 374 /** Final value of the transformation (displayed in the redo panel). 375 * If the operator is executed directly (not modal), this value is usually the 376 * value of the input parameter, except when a constrain is entered. */ 377 float values_final[4]; 378 379 /* Axis members for modes that use an axis separate from the orientation (rotate & shear). */ 380 381 /** Primary axis, rotate only uses this. */ 382 int orient_axis; 383 /** Secondary axis, shear uses this. */ 384 int orient_axis_ortho; 385 386 /** remove elements if operator is canceled. */ 387 bool remove_on_cancel; 388 389 void *view; 390 /** Only valid (non null) during an operator called function. */ 391 struct bContext *context; 392 struct wmMsgBus *mbus; 393 struct ScrArea *area; 394 struct ARegion *region; 395 struct Depsgraph *depsgraph; 396 struct Scene *scene; 397 struct ViewLayer *view_layer; 398 struct ToolSettings *settings; 399 struct wmTimer *animtimer; 400 /** so we can do lookups for header text. */ 401 struct wmKeyMap *keymap; 402 /** assign from the operator, or can be NULL. */ 403 struct ReportList *reports; 404 /** current mouse position. */ 405 int mval[2]; 406 /** use for 3d view. */ 407 float zfac; 408 void *draw_handle_apply; 409 void *draw_handle_view; 410 void *draw_handle_pixel; 411 void *draw_handle_cursor; 412 413 /** Currently only used for random curve of proportional editing. */ 414 struct RNG *rng; 415 416 /** Typically for mode settings. */ 417 TransCustomDataContainer custom; 418 } TransInfo; 419 420 /* ******************** Macros & Prototypes *********************** */ 421 422 /* transinfo->state */ 423 enum { 424 TRANS_STARTING = 0, 425 TRANS_RUNNING = 1, 426 TRANS_CONFIRM = 2, 427 TRANS_CANCEL = 3, 428 }; 429 430 /* transinfo->flag */ 431 enum { 432 T_OBJECT = 1 << 0, 433 /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */ 434 T_EDIT = 1 << 1, 435 T_POSE = 1 << 2, 436 T_TEXTURE = 1 << 3, 437 /** Transforming the 3d view. */ 438 T_CAMERA = 1 << 4, 439 /** Transforming the 3D cursor. */ 440 T_CURSOR = 1 << 5, 441 /** Transform points, having no rotation/scale. */ 442 T_POINTS = 1 << 6, 443 /** restrictions flags */ 444 T_NO_CONSTRAINT = 1 << 7, 445 T_NULL_ONE = 1 << 8, 446 T_NO_ZERO = 1 << 9, 447 T_ALL_RESTRICTIONS = T_NO_CONSTRAINT | T_NULL_ONE | T_NO_ZERO, 448 449 T_PROP_EDIT = 1 << 10, 450 T_PROP_CONNECTED = 1 << 11, 451 T_PROP_PROJECTED = 1 << 12, 452 T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED, 453 454 T_V3D_ALIGN = 1 << 13, 455 /** For 2d views like uv or fcurve. */ 456 T_2D_EDIT = 1 << 14, 457 T_CLIP_UV = 1 << 15, 458 459 /** Auto-ik is on. */ 460 T_AUTOIK = 1 << 16, 461 462 /** Don't use mirror even if the data-block option is set. */ 463 T_NO_MIRROR = 1 << 17, 464 465 /** To indicate that the value set in the `value` parameter is the final 466 * value of the transformation, modified only by the constrain. */ 467 T_INPUT_IS_VALUES_FINAL = 1 << 18, 468 469 /** To specify if we save back settings at the end. */ 470 T_MODAL = 1 << 19, 471 472 /** No retopo. */ 473 T_NO_PROJECT = 1 << 20, 474 475 T_RELEASE_CONFIRM = 1 << 21, 476 477 /** Alternative transformation. used to add offset to tracking markers. */ 478 T_ALT_TRANSFORM = 1 << 22, 479 480 /** #TransInfo.center has been set, don't change it. */ 481 T_OVERRIDE_CENTER = 1 << 23, 482 483 T_MODAL_CURSOR_SET = 1 << 24, 484 485 T_CLNOR_REBUILD = 1 << 25, 486 487 /* Special Aftertrans. */ 488 T_AUTOMERGE = 1 << 26, 489 T_AUTOSPLIT = 1 << 27, 490 }; 491 492 /** #TransInfo.modifiers */ 493 enum { 494 MOD_CONSTRAINT_SELECT = 1 << 0, 495 MOD_PRECISION = 1 << 1, 496 MOD_SNAP = 1 << 2, 497 MOD_SNAP_INVERT = 1 << 3, 498 MOD_CONSTRAINT_PLANE = 1 << 4, 499 }; 500 501 /* use node center for transform instead of upper-left corner. 502 * disabled since it makes absolute snapping not work so nicely 503 */ 504 // #define USE_NODE_CENTER 505 506 /* ******************************************************************************** */ 507 508 /** #TransInfo.helpline */ 509 enum { 510 HLP_NONE = 0, 511 HLP_SPRING = 1, 512 HLP_ANGLE = 2, 513 HLP_HARROW = 3, 514 HLP_VARROW = 4, 515 HLP_CARROW = 5, 516 HLP_TRACKBALL = 6, 517 }; 518 519 /** #TransCon.mode, #TransInfo.con.mode */ 520 enum { 521 /** When set constraints are in use. */ 522 CON_APPLY = 1 << 0, 523 /** These are only used for modal execution. */ 524 CON_AXIS0 = 1 << 1, 525 CON_AXIS1 = 1 << 2, 526 CON_AXIS2 = 1 << 3, 527 CON_SELECT = 1 << 4, 528 /** Does not reorient vector to face viewport when on. */ 529 CON_NOFLIP = 1 << 5, 530 CON_USER = 1 << 6, 531 }; 532 533 /** #TransSnap.status */ 534 enum { 535 SNAP_FORCED = 1 << 0, 536 TARGET_INIT = 1 << 1, 537 POINT_INIT = 1 << 2, 538 MULTI_POINTS = 1 << 3, 539 }; 540 541 /** keymap modal items */ 542 /* NOTE: these values are saved in keymap files, do not change then but just add new ones. */ 543 enum { 544 TFM_MODAL_CANCEL = 1, 545 TFM_MODAL_CONFIRM = 2, 546 TFM_MODAL_TRANSLATE = 3, 547 TFM_MODAL_ROTATE = 4, 548 TFM_MODAL_RESIZE = 5, 549 TFM_MODAL_SNAP_INV_ON = 6, 550 TFM_MODAL_SNAP_INV_OFF = 7, 551 TFM_MODAL_SNAP_TOGGLE = 8, 552 TFM_MODAL_AXIS_X = 9, 553 TFM_MODAL_AXIS_Y = 10, 554 TFM_MODAL_AXIS_Z = 11, 555 TFM_MODAL_PLANE_X = 12, 556 TFM_MODAL_PLANE_Y = 13, 557 TFM_MODAL_PLANE_Z = 14, 558 TFM_MODAL_CONS_OFF = 15, 559 TFM_MODAL_ADD_SNAP = 16, 560 TFM_MODAL_REMOVE_SNAP = 17, 561 562 /* 18 and 19 used by numinput, defined in transform.h */ 563 564 TFM_MODAL_PROPSIZE_UP = 20, 565 TFM_MODAL_PROPSIZE_DOWN = 21, 566 TFM_MODAL_AUTOIK_LEN_INC = 22, 567 TFM_MODAL_AUTOIK_LEN_DEC = 23, 568 569 TFM_MODAL_EDGESLIDE_UP = 24, 570 TFM_MODAL_EDGESLIDE_DOWN = 25, 571 572 /* for analog input, like trackpad */ 573 TFM_MODAL_PROPSIZE = 26, 574 /* node editor insert offset (aka auto-offset) direction toggle */ 575 TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27, 576 577 TFM_MODAL_AUTOCONSTRAINT = 28, 578 TFM_MODAL_AUTOCONSTRAINTPLANE = 29, 579 }; 580 581 bool initTransform(struct bContext *C, 582 struct TransInfo *t, 583 struct wmOperator *op, 584 const struct wmEvent *event, 585 int mode); 586 void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op); 587 int transformEvent(TransInfo *t, const struct wmEvent *event); 588 void transformApply(struct bContext *C, TransInfo *t); 589 int transformEnd(struct bContext *C, TransInfo *t); 590 591 void setTransformViewMatrices(TransInfo *t); 592 void setTransformViewAspect(TransInfo *t, float r_aspect[3]); 593 void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy); 594 void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DProjTest flag); 595 void projectIntView(TransInfo *t, const float vec[3], int adr[2]); 596 void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV3DProjTest flag); 597 void projectFloatView(TransInfo *t, const float vec[3], float adr[2]); 598 599 void applyAspectRatio(TransInfo *t, float vec[2]); 600 void removeAspectRatio(TransInfo *t, float vec[2]); 601 602 struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); 603 604 /*********************** transform_gizmo.c ********** */ 605 606 #define GIZMO_AXIS_LINE_WIDTH 2.0f 607 608 /* return 0 when no gimbal for selection */ 609 bool gimbal_axis(struct Object *ob, float gmat[3][3]); 610 void drawDial3d(const TransInfo *t); 611 612 /*********************** TransData Creation and General Handling *********** */ 613 bool transdata_check_local_islands(TransInfo *t, short around); 614 615 /********************** Mouse Input ******************************/ 616 617 typedef enum { 618 INPUT_NONE, 619 INPUT_VECTOR, 620 INPUT_SPRING, 621 INPUT_SPRING_FLIP, 622 INPUT_SPRING_DELTA, 623 INPUT_ANGLE, 624 INPUT_ANGLE_SPRING, 625 INPUT_TRACKBALL, 626 INPUT_HORIZONTAL_RATIO, 627 INPUT_HORIZONTAL_ABSOLUTE, 628 INPUT_VERTICAL_RATIO, 629 INPUT_VERTICAL_ABSOLUTE, 630 INPUT_CUSTOM_RATIO, 631 INPUT_CUSTOM_RATIO_FLIP, 632 } MouseInputMode; 633 634 void initMouseInput( 635 TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], const bool precision); 636 void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode); 637 eRedrawFlag handleMouseInput(struct TransInfo *t, 638 struct MouseInput *mi, 639 const struct wmEvent *event); 640 void applyMouseInput(struct TransInfo *t, 641 struct MouseInput *mi, 642 const int mval[2], 643 float output[3]); 644 645 void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]); 646 void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]); 647 void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float values[3])); 648 649 /*********************** Generics ********************************/ 650 651 void initTransDataContainers_FromObjectData(TransInfo *t, 652 struct Object *obact, 653 struct Object **objects, 654 uint objects_len); 655 void initTransInfo(struct bContext *C, 656 TransInfo *t, 657 struct wmOperator *op, 658 const struct wmEvent *event); 659 void freeTransCustomDataForMode(TransInfo *t); 660 void postTrans(struct bContext *C, TransInfo *t); 661 void resetTransModal(TransInfo *t); 662 void resetTransRestrictions(TransInfo *t); 663 664 void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options); 665 666 /* DRAWLINE options flags */ 667 #define DRAWLIGHT 1 668 669 void applyTransObjects(TransInfo *t); 670 void restoreTransObjects(TransInfo *t); 671 void recalcData(TransInfo *t); 672 673 void calculateCenter2D(TransInfo *t); 674 void calculateCenterLocal(TransInfo *t, const float center_global[3]); 675 676 const TransCenterData *transformCenter_from_type(TransInfo *t, int around); 677 void calculateCenter(TransInfo *t); 678 679 /* API functions for getting center points */ 680 void calculateCenterBound(TransInfo *t, float r_center[3]); 681 void calculateCenterMedian(TransInfo *t, float r_center[3]); 682 void calculateCenterCursor(TransInfo *t, float r_center[3]); 683 void calculateCenterCursor2D(TransInfo *t, float r_center[2]); 684 void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2]); 685 bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]); 686 687 void calculatePropRatio(TransInfo *t); 688 689 void getViewVector(const TransInfo *t, const float coord[3], float vec[3]); 690 691 void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot); 692 693 void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data); 694 695 /* TODO. transform_query.c */ 696 bool checkUseAxisMatrix(TransInfo *t); 697 698 #define TRANSFORM_SNAP_MAX_PX 100.0f 699 #define TRANSFORM_DIST_INVALID -FLT_MAX 700 701 /* Temp macros. */ 702 703 #define TRANS_DATA_CONTAINER_FIRST_OK(t) (&(t)->data_container[0]) 704 /* For cases we _know_ there is only one handle. */ 705 #define TRANS_DATA_CONTAINER_FIRST_SINGLE(t) \ 706 (BLI_assert((t)->data_container_len == 1), (&(t)->data_container[0])) 707 708 #define FOREACH_TRANS_DATA_CONTAINER(t, th) \ 709 for (TransDataContainer *tc = (t)->data_container, \ 710 *tc_end = (t)->data_container + (t)->data_container_len; \ 711 th != tc_end; \ 712 th++) 713 714 #define FOREACH_TRANS_DATA_CONTAINER_INDEX(t, th, i) \ 715 for (TransDataContainer *tc = ((i = 0), (t)->data_container), \ 716 *tc_end = (t)->data_container + (t)->data_container_len; \ 717 th != tc_end; \ 718 th++, i++) 719