Files
test/source/blender/editors/transform/transform.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

874 lines
25 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
/** \file
* \ingroup edtransform
2011-02-27 20:29:51 +00:00
*/
#pragma once
#include "ED_numinput.h"
#include "ED_transform.h"
#include "ED_view3d.h"
#include "DNA_listBase.h"
#include "DNA_object_enums.h"
Refactor: Snap-related. Clarified attribute names and refactored #defines into enums The transformation snapping code contains a bunch of `#define`s, some ambiguously or incorrectly named attributes. This patch contains refactored code to improve this. This patch does (should) not change functionality of snapping. Clarified ambiguously / incorrectly named attributes. - "Target" is used to refer to the part of the source that is to be snapped (Active, Median, Center, Closest), but several other areas of Blender use the term "target" to refer to the thing being snapped to and "source" to refer to the thing getting snapped. Moreover, the implications of the previous terms do not match the descriptions. For example: `SCE_SNAP_TARGET_CENTER` does not snap the grabbed geometry to the center of the target, but instead "Snap transforamtion center onto target". - "Select" refers to the condition for an object to be a possible target for snapping. - `SCE_SNAP_MODE_FACE` is renamed to `SCE_SNAP_MODE_FACE_RAYCAST` to better describe its affect and to make way for other face snapping methods (ex: nearest). Refactored related `#define` into `enum`s. In particular, constants relating to... - `ToolSettings.snap_flag` are now in `enum eSnapFlag` - `ToolSettings.snap_mode` are now in `enum eSnapMode` - `ToolSettings.snap_source` (was `snap_target`) are now in `enum eSnapSourceSelect` - `ToolSettings.snap_flag` (`SCE_SNAP_NO_SELF`) and `TransSnap.target_select` are now in `enum eSnapTargetSelect` As the terms became more consistent and the constants were packed together into meaningful enumerations, some of the attribute names seemed ambiguous. For example, it is unclear whether `SnapObjectParams.snap_select` referred to the target or the source. This patch also adds a small amount of clarity. This patch also swaps out generic types (ex: `char`, `short`, `ushort`) and unclear hard coded numbers (ex: `0`) used with snap-related enumerations with the actual `enum`s and values. Note: I did leave myself some comments to follow-up with further refactoring. Specifically, using "target" and "source" consistently will mean the Python API will need to change (ex: `ToolSettings.snap_target` is not `ToolSettings.snap_source`). If the API is going to change, it would be good to make sure that the used terms are descriptive enough. For example, `bpy.ops.transform.translate` uses a `snap` argument to determine if snapping should be enabled while transforming. Perhaps `use_snap` might be an improvement that's more consistent with other conventions. This patch is (mostly) a subset of D14591, as suggested by @mano-wii. Task T69342 proposes to separate the `Absolute Grid Snap` option out from `Increment` snapping method into its own method. Also, there might be reason to create additional snapping methods or options. (Indeed, D14591 heads in this direction). This patch can work along with these suggestions, as this patch is trying to clarify the snapping code and to prompt more work in this area. Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D15037
2022-06-06 10:28:14 -04:00
#include "DNA_scene_types.h"
#include "DEG_depsgraph.h"
#include "transform_data.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -------------------------------------------------------------------- */
/** \name Types/
* \{ */
struct ARegion;
struct Depsgraph;
struct NumInput;
struct Object;
struct RNG;
struct ReportList;
struct Scene;
struct ScrArea;
struct SnapObjectContext;
struct TransConvertTypeInfo;
struct TransDataContainer;
struct TransInfo;
struct TransSnap;
struct ViewLayer;
struct bContext;
struct wmEvent;
struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmTimer;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Enums and Flags
* \{ */
/** #TransInfo.options */
typedef enum {
CTX_NONE = 0,
/* These are similar to TransInfo::data_type. */
CTX_CAMERA = (1 << 0),
CTX_CURSOR = (1 << 1),
CTX_EDGE_DATA = (1 << 2),
CTX_GPENCIL_STROKES = (1 << 3),
CTX_MASK = (1 << 4),
CTX_MOVIECLIP = (1 << 5),
CTX_OBJECT = (1 << 6),
CTX_PAINT_CURVE = (1 << 7),
CTX_POSE_BONE = (1 << 8),
CTX_TEXTURE_SPACE = (1 << 9),
CTX_SEQUENCER_IMAGE = (1 << 10),
CTX_NO_PET = (1 << 11),
CTX_AUTOCONFIRM = (1 << 12),
/** When transforming object's, adjust the object data so it stays in the same place. */
CTX_OBMODE_XFORM_OBDATA = (1 << 13),
/** Transform object parents without moving their children. */
CTX_OBMODE_XFORM_SKIP_CHILDREN = (1 << 14),
/** Enable edge scrolling in 2D views */
CTX_VIEW2D_EDGE_PAN = (1 << 15),
} eTContext;
/** #TransInfo.flag */
typedef enum {
/** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */
T_EDIT = 1 << 0,
/** Transform points, having no rotation/scale. */
T_POINTS = 1 << 1,
/** restrictions flags */
T_NO_CONSTRAINT = 1 << 2,
T_NULL_ONE = 1 << 3,
2021-04-24 11:34:02 -03:00
T_PROP_EDIT = 1 << 4,
T_PROP_CONNECTED = 1 << 5,
T_PROP_PROJECTED = 1 << 6,
2021-04-24 11:34:02 -03:00
T_V3D_ALIGN = 1 << 7,
/** For 2D views such as UV or f-curve. */
2021-04-24 11:34:02 -03:00
T_2D_EDIT = 1 << 8,
T_CLIP_UV = 1 << 9,
/** Auto-IK is on. */
2021-04-24 11:34:02 -03:00
T_AUTOIK = 1 << 10,
/** Don't use mirror even if the data-block option is set. */
2021-04-24 11:34:02 -03:00
T_NO_MIRROR = 1 << 11,
/** To indicate that the value set in the `value` parameter is the final
* value of the transformation, modified only by the constrain. */
2021-04-24 11:34:02 -03:00
T_INPUT_IS_VALUES_FINAL = 1 << 12,
/** To specify if we save back settings at the end. */
2021-04-24 11:34:02 -03:00
T_MODAL = 1 << 13,
/** No re-topology (projection). */
2021-04-24 11:34:02 -03:00
T_NO_PROJECT = 1 << 14,
2021-04-24 11:34:02 -03:00
T_RELEASE_CONFIRM = 1 << 15,
/** Alternative transformation. used to add offset to tracking markers. */
2021-04-24 11:34:02 -03:00
T_ALT_TRANSFORM = 1 << 16,
/** #TransInfo.center has been set, don't change it. */
2021-04-24 11:34:02 -03:00
T_OVERRIDE_CENTER = 1 << 17,
2021-04-24 11:34:02 -03:00
T_MODAL_CURSOR_SET = 1 << 18,
2021-04-24 11:34:02 -03:00
T_CLNOR_REBUILD = 1 << 19,
/** Merges unselected into selected after transforming (runs after transforming). */
2021-04-24 11:34:02 -03:00
T_AUTOMERGE = 1 << 20,
/** Runs auto-merge & splits. */
2021-04-24 11:34:02 -03:00
T_AUTOSPLIT = 1 << 21,
Edge-scrolling for node editor Starts scrolling when dragging a node or node link and going outside the current window. Largely copied from the VIEW2D_OT_edge_pan operator. Edge panning operator customdata and supporting functions now in UI_view2d.h, so they could be used by operators in other editor libraries. The VIEW2D_OT_edge_pan operator also uses this customdata and shared functions now. Operators properties can be used to configure edge panning margins and speed for each use case, rather than using hardcoded values. The speed function for edge panning has been tweaked somewhat: * "Speed per pixel" has been replaced with a "speed ramp" distance. This is more intuitive and also creates an upper bound for the speed, which can otherwise become extreme with large cursor distance. * "Max speed" is reached at the end of the speed ramp. * Padding the region inside and outside is applied as before, but both values are operator properties now. Node transform operator also supports edge panning. This requires an offset for changes in the view2d rect, otherwise nodes are "stuck" to the original view. Transform operator had cursor wrapping categorically enabled, but this gets quite confusing with the edge scrolling mechanism. A new TransInfo option T_NO_CURSOR_WRAP has been introduced to disable this behavior. The double negative is a bit annoying, but want to avoid affecting the existing transform modes, so by default it should still set the OP_IS_MODAL_GRAB_CURSOR flag (which then sets the WM_CURSOR_WRAP_XY flag during modal execution). Reviewed By: HooglyBoogly, JacquesLucke Differential Revision: https://developer.blender.org/D11073
2021-06-16 18:17:07 +01:00
/** Use drag-start position of the event, otherwise use the cursor coordinates (unmodified). */
T_EVENT_DRAG_START = 1 << 22,
Edge-scrolling for node editor Starts scrolling when dragging a node or node link and going outside the current window. Largely copied from the VIEW2D_OT_edge_pan operator. Edge panning operator customdata and supporting functions now in UI_view2d.h, so they could be used by operators in other editor libraries. The VIEW2D_OT_edge_pan operator also uses this customdata and shared functions now. Operators properties can be used to configure edge panning margins and speed for each use case, rather than using hardcoded values. The speed function for edge panning has been tweaked somewhat: * "Speed per pixel" has been replaced with a "speed ramp" distance. This is more intuitive and also creates an upper bound for the speed, which can otherwise become extreme with large cursor distance. * "Max speed" is reached at the end of the speed ramp. * Padding the region inside and outside is applied as before, but both values are operator properties now. Node transform operator also supports edge panning. This requires an offset for changes in the view2d rect, otherwise nodes are "stuck" to the original view. Transform operator had cursor wrapping categorically enabled, but this gets quite confusing with the edge scrolling mechanism. A new TransInfo option T_NO_CURSOR_WRAP has been introduced to disable this behavior. The double negative is a bit annoying, but want to avoid affecting the existing transform modes, so by default it should still set the OP_IS_MODAL_GRAB_CURSOR flag (which then sets the WM_CURSOR_WRAP_XY flag during modal execution). Reviewed By: HooglyBoogly, JacquesLucke Differential Revision: https://developer.blender.org/D11073
2021-06-16 18:17:07 +01:00
/** No cursor wrapping on region bounds */
T_NO_CURSOR_WRAP = 1 << 23,
/** Do not display Xform gizmo even though it is available. */
T_NO_GIZMO = 1 << 24,
} eTFlag;
ENUM_OPERATORS(eTFlag, T_NO_GIZMO);
#define T_ALL_RESTRICTIONS (T_NO_CONSTRAINT | T_NULL_ONE)
#define T_PROP_EDIT_ALL (T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED)
/** #TransInfo.modifiers */
typedef enum {
MOD_CONSTRAINT_SELECT_AXIS = 1 << 0,
MOD_PRECISION = 1 << 1,
MOD_SNAP = 1 << 2,
MOD_SNAP_INVERT = 1 << 3,
2021-11-18 14:19:59 -03:00
MOD_CONSTRAINT_SELECT_PLANE = 1 << 4,
MOD_NODE_ATTACH = 1 << 5,
MOD_SNAP_FORCED = 1 << 6,
} eTModifier;
ENUM_OPERATORS(eTModifier, MOD_NODE_ATTACH)
/** #TransSnap.status */
Refactor: Snap-related. Clarified attribute names and refactored #defines into enums The transformation snapping code contains a bunch of `#define`s, some ambiguously or incorrectly named attributes. This patch contains refactored code to improve this. This patch does (should) not change functionality of snapping. Clarified ambiguously / incorrectly named attributes. - "Target" is used to refer to the part of the source that is to be snapped (Active, Median, Center, Closest), but several other areas of Blender use the term "target" to refer to the thing being snapped to and "source" to refer to the thing getting snapped. Moreover, the implications of the previous terms do not match the descriptions. For example: `SCE_SNAP_TARGET_CENTER` does not snap the grabbed geometry to the center of the target, but instead "Snap transforamtion center onto target". - "Select" refers to the condition for an object to be a possible target for snapping. - `SCE_SNAP_MODE_FACE` is renamed to `SCE_SNAP_MODE_FACE_RAYCAST` to better describe its affect and to make way for other face snapping methods (ex: nearest). Refactored related `#define` into `enum`s. In particular, constants relating to... - `ToolSettings.snap_flag` are now in `enum eSnapFlag` - `ToolSettings.snap_mode` are now in `enum eSnapMode` - `ToolSettings.snap_source` (was `snap_target`) are now in `enum eSnapSourceSelect` - `ToolSettings.snap_flag` (`SCE_SNAP_NO_SELF`) and `TransSnap.target_select` are now in `enum eSnapTargetSelect` As the terms became more consistent and the constants were packed together into meaningful enumerations, some of the attribute names seemed ambiguous. For example, it is unclear whether `SnapObjectParams.snap_select` referred to the target or the source. This patch also adds a small amount of clarity. This patch also swaps out generic types (ex: `char`, `short`, `ushort`) and unclear hard coded numbers (ex: `0`) used with snap-related enumerations with the actual `enum`s and values. Note: I did leave myself some comments to follow-up with further refactoring. Specifically, using "target" and "source" consistently will mean the Python API will need to change (ex: `ToolSettings.snap_target` is not `ToolSettings.snap_source`). If the API is going to change, it would be good to make sure that the used terms are descriptive enough. For example, `bpy.ops.transform.translate` uses a `snap` argument to determine if snapping should be enabled while transforming. Perhaps `use_snap` might be an improvement that's more consistent with other conventions. This patch is (mostly) a subset of D14591, as suggested by @mano-wii. Task T69342 proposes to separate the `Absolute Grid Snap` option out from `Increment` snapping method into its own method. Also, there might be reason to create additional snapping methods or options. (Indeed, D14591 heads in this direction). This patch can work along with these suggestions, as this patch is trying to clarify the snapping code and to prompt more work in this area. Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D15037
2022-06-06 10:28:14 -04:00
typedef enum eTSnap {
SNAP_RESETTED = 0,
SNAP_SOURCE_FOUND = 1 << 0,
/* Special flag for snap to grid. */
SNAP_TARGET_GRID_FOUND = 1 << 1,
SNAP_TARGET_FOUND = 1 << 2,
SNAP_MULTI_POINTS = 1 << 3,
} eTSnap;
ENUM_OPERATORS(eTSnap, SNAP_MULTI_POINTS)
/** #TransCon.mode, #TransInfo.con.mode */
typedef enum {
/** When set constraints are in use. */
CON_APPLY = 1 << 0,
/** These are only used for modal execution. */
CON_AXIS0 = 1 << 1,
CON_AXIS1 = 1 << 2,
CON_AXIS2 = 1 << 3,
CON_SELECT = 1 << 4,
/** Does not reorient vector to face viewport when on. */
CON_NOFLIP = 1 << 5,
CON_USER = 1 << 6,
} eTConstraint;
/** #TransInfo.state */
typedef enum {
TRANS_STARTING = 0,
TRANS_RUNNING = 1,
TRANS_CONFIRM = 2,
TRANS_CANCEL = 3,
} eTState;
/** #TransInfo.redraw */
typedef enum {
TREDRAW_NOTHING = 0,
TREDRAW_SOFT = (1 << 0),
TREDRAW_HARD = (1 << 1) | TREDRAW_SOFT,
} eRedrawFlag;
2022-11-17 17:13:38 +01:00
ENUM_OPERATORS(eRedrawFlag, TREDRAW_HARD)
/** #TransInfo.helpline */
typedef enum {
HLP_NONE = 0,
HLP_SPRING = 1,
HLP_ANGLE = 2,
HLP_HARROW = 3,
HLP_VARROW = 4,
HLP_CARROW = 5,
HLP_TRACKBALL = 6,
} eTHelpline;
typedef enum {
O_DEFAULT = 0,
O_SCENE,
O_SET,
} eTOType;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Keymap Modal Items
*
* \note these values are saved in key-map files, do not change then but just add new ones.
* \{ */
enum {
TFM_MODAL_CANCEL = 1,
TFM_MODAL_CONFIRM = 2,
TFM_MODAL_TRANSLATE = 3,
TFM_MODAL_ROTATE = 4,
TFM_MODAL_RESIZE = 5,
TFM_MODAL_SNAP_INV_ON = 6,
TFM_MODAL_SNAP_INV_OFF = 7,
TFM_MODAL_SNAP_TOGGLE = 8,
TFM_MODAL_AXIS_X = 9,
TFM_MODAL_AXIS_Y = 10,
TFM_MODAL_AXIS_Z = 11,
TFM_MODAL_PLANE_X = 12,
TFM_MODAL_PLANE_Y = 13,
TFM_MODAL_PLANE_Z = 14,
TFM_MODAL_CONS_OFF = 15,
TFM_MODAL_ADD_SNAP = 16,
TFM_MODAL_REMOVE_SNAP = 17,
/* 18 and 19 used by number-input, defined in `ED_numinput.h`. */
// NUM_MODAL_INCREMENT_UP = 18,
// NUM_MODAL_INCREMENT_DOWN = 19,
TFM_MODAL_PROPSIZE_UP = 20,
TFM_MODAL_PROPSIZE_DOWN = 21,
TFM_MODAL_AUTOIK_LEN_INC = 22,
TFM_MODAL_AUTOIK_LEN_DEC = 23,
TFM_MODAL_NODE_ATTACH_ON = 24,
TFM_MODAL_NODE_ATTACH_OFF = 25,
/** For analog input, like track-pad. */
TFM_MODAL_PROPSIZE = 26,
/** Node editor insert offset (also called auto-offset) direction toggle. */
TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27,
TFM_MODAL_AUTOCONSTRAINT = 28,
TFM_MODAL_AUTOCONSTRAINTPLANE = 29,
TFM_MODAL_PRECISION = 30,
TFM_MODAL_VERT_EDGE_SLIDE = 31,
TFM_MODAL_TRACKBALL = 32,
TFM_MODAL_ROTATE_NORMALS = 33,
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Transform Types
* \{ */
typedef struct TransSnapPoint {
2012-04-29 15:47:02 +00:00
struct TransSnapPoint *next, *prev;
float co[3];
} TransSnapPoint;
typedef struct TransSnap {
Refactor: Snap-related. Clarified attribute names and refactored #defines into enums The transformation snapping code contains a bunch of `#define`s, some ambiguously or incorrectly named attributes. This patch contains refactored code to improve this. This patch does (should) not change functionality of snapping. Clarified ambiguously / incorrectly named attributes. - "Target" is used to refer to the part of the source that is to be snapped (Active, Median, Center, Closest), but several other areas of Blender use the term "target" to refer to the thing being snapped to and "source" to refer to the thing getting snapped. Moreover, the implications of the previous terms do not match the descriptions. For example: `SCE_SNAP_TARGET_CENTER` does not snap the grabbed geometry to the center of the target, but instead "Snap transforamtion center onto target". - "Select" refers to the condition for an object to be a possible target for snapping. - `SCE_SNAP_MODE_FACE` is renamed to `SCE_SNAP_MODE_FACE_RAYCAST` to better describe its affect and to make way for other face snapping methods (ex: nearest). Refactored related `#define` into `enum`s. In particular, constants relating to... - `ToolSettings.snap_flag` are now in `enum eSnapFlag` - `ToolSettings.snap_mode` are now in `enum eSnapMode` - `ToolSettings.snap_source` (was `snap_target`) are now in `enum eSnapSourceSelect` - `ToolSettings.snap_flag` (`SCE_SNAP_NO_SELF`) and `TransSnap.target_select` are now in `enum eSnapTargetSelect` As the terms became more consistent and the constants were packed together into meaningful enumerations, some of the attribute names seemed ambiguous. For example, it is unclear whether `SnapObjectParams.snap_select` referred to the target or the source. This patch also adds a small amount of clarity. This patch also swaps out generic types (ex: `char`, `short`, `ushort`) and unclear hard coded numbers (ex: `0`) used with snap-related enumerations with the actual `enum`s and values. Note: I did leave myself some comments to follow-up with further refactoring. Specifically, using "target" and "source" consistently will mean the Python API will need to change (ex: `ToolSettings.snap_target` is not `ToolSettings.snap_source`). If the API is going to change, it would be good to make sure that the used terms are descriptive enough. For example, `bpy.ops.transform.translate` uses a `snap` argument to determine if snapping should be enabled while transforming. Perhaps `use_snap` might be an improvement that's more consistent with other conventions. This patch is (mostly) a subset of D14591, as suggested by @mano-wii. Task T69342 proposes to separate the `Absolute Grid Snap` option out from `Increment` snapping method into its own method. Also, there might be reason to create additional snapping methods or options. (Indeed, D14591 heads in this direction). This patch can work along with these suggestions, as this patch is trying to clarify the snapping code and to prompt more work in this area. Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D15037
2022-06-06 10:28:14 -04:00
/* Snapping options stored as flags */
eSnapFlag flag;
/* Method(s) used for snapping source to target */
eSnapMode mode;
/* Part of source to snap to target */
eSnapSourceOP source_operation;
Refactor: Snap-related. Clarified attribute names and refactored #defines into enums The transformation snapping code contains a bunch of `#define`s, some ambiguously or incorrectly named attributes. This patch contains refactored code to improve this. This patch does (should) not change functionality of snapping. Clarified ambiguously / incorrectly named attributes. - "Target" is used to refer to the part of the source that is to be snapped (Active, Median, Center, Closest), but several other areas of Blender use the term "target" to refer to the thing being snapped to and "source" to refer to the thing getting snapped. Moreover, the implications of the previous terms do not match the descriptions. For example: `SCE_SNAP_TARGET_CENTER` does not snap the grabbed geometry to the center of the target, but instead "Snap transforamtion center onto target". - "Select" refers to the condition for an object to be a possible target for snapping. - `SCE_SNAP_MODE_FACE` is renamed to `SCE_SNAP_MODE_FACE_RAYCAST` to better describe its affect and to make way for other face snapping methods (ex: nearest). Refactored related `#define` into `enum`s. In particular, constants relating to... - `ToolSettings.snap_flag` are now in `enum eSnapFlag` - `ToolSettings.snap_mode` are now in `enum eSnapMode` - `ToolSettings.snap_source` (was `snap_target`) are now in `enum eSnapSourceSelect` - `ToolSettings.snap_flag` (`SCE_SNAP_NO_SELF`) and `TransSnap.target_select` are now in `enum eSnapTargetSelect` As the terms became more consistent and the constants were packed together into meaningful enumerations, some of the attribute names seemed ambiguous. For example, it is unclear whether `SnapObjectParams.snap_select` referred to the target or the source. This patch also adds a small amount of clarity. This patch also swaps out generic types (ex: `char`, `short`, `ushort`) and unclear hard coded numbers (ex: `0`) used with snap-related enumerations with the actual `enum`s and values. Note: I did leave myself some comments to follow-up with further refactoring. Specifically, using "target" and "source" consistently will mean the Python API will need to change (ex: `ToolSettings.snap_target` is not `ToolSettings.snap_source`). If the API is going to change, it would be good to make sure that the used terms are descriptive enough. For example, `bpy.ops.transform.translate` uses a `snap` argument to determine if snapping should be enabled while transforming. Perhaps `use_snap` might be an improvement that's more consistent with other conventions. This patch is (mostly) a subset of D14591, as suggested by @mano-wii. Task T69342 proposes to separate the `Absolute Grid Snap` option out from `Increment` snapping method into its own method. Also, there might be reason to create additional snapping methods or options. (Indeed, D14591 heads in this direction). This patch can work along with these suggestions, as this patch is trying to clarify the snapping code and to prompt more work in this area. Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D15037
2022-06-06 10:28:14 -04:00
/* Determines which objects are possible target */
eSnapTargetOP target_operation;
Transform Snap: nearest face snap mode, snapping options, refactoring. This commit adds a new face nearest snapping mode, adds new snapping options, and (lightly) refactors code around snapping. The new face nearest snapping mode will snap transformed geometry to the nearest surface in world space. In contrast, the original face snapping mode uses projection (raycasting) to snap source to target geometry. Face snapping therefore only works with what is visible, while nearest face snapping can snap geometry to occluded parts of the scene. This new mode is critical for retopology work, where some of the target mesh might be occluded (ex: sliding an edge loop that wraps around the backside of target mesh). The nearest face snapping mode has two options: "Snap to Same Target" and "Face Nearest Steps". When the Snap to Same Object option is enabled, the selected source geometry will stay near the target that it is nearest before editing started, which prevents the source geometry from snapping to other targets. The Face Nearest Steps divides the overall transformation for each vertex into n smaller transformations, then applies those n transformations with surface snapping interlacing each step. This steps option handles transformations that cross U-shaped targets better. The new snapping options allow the artist to better control which target objects (objects to which the edited geometry is snapped) are considered when snapping. In particular, the only option for filtering target objects was a "Project onto Self", which allowed the currently edited mesh to be considered as a target. Now, the artist can choose any combination of the following to be considered as a target: the active object, any edited object that isn't active (see note below), any non- edited object. Additionally, the artist has another snapping option to exclude objects that are not selectable as potential targets. The Snapping Options dropdown has been lightly reorganized to allow for the additional options. Included in this patch: - Snap target selection is more controllable for artist with additional snapping options. - Renamed a few of the snap-related functions to better reflect what they actually do now. For example, `applySnapping` implies that this handles the snapping, while `applyProject` implies something entirely different is done there. However, better names would be `applySnappingAsGroup` and `applySnappingIndividual`, respectively, where `applySnappingIndividual` previously only does Face snapping. - Added an initial coordinate parameter to snapping functions so that the nearest target before transforming can be determined(for "Snap to Same Object"), and so the transformation can be broken into smaller steps (for "Face Nearest Steps"). - Separated the BVH Tree getter code from mesh/edit mesh to its own function to reduce code duplication. - Added icon for nearest face snapping. - The original "Project onto Self" was actually not correct! This option should be called "Project onto Active" instead, but that only matters when editing multiple meshes at the same time. This patch makes this change in the UI. Reviewed By: Campbell Barton, Germano Cavalcante Differential Revision: https://developer.blender.org/D14591
2022-06-29 20:52:00 -04:00
short face_nearest_steps;
eTSnap status;
/* Snapped Element Type (currently for objects only). */
Refactor: Snap-related. Clarified attribute names and refactored #defines into enums The transformation snapping code contains a bunch of `#define`s, some ambiguously or incorrectly named attributes. This patch contains refactored code to improve this. This patch does (should) not change functionality of snapping. Clarified ambiguously / incorrectly named attributes. - "Target" is used to refer to the part of the source that is to be snapped (Active, Median, Center, Closest), but several other areas of Blender use the term "target" to refer to the thing being snapped to and "source" to refer to the thing getting snapped. Moreover, the implications of the previous terms do not match the descriptions. For example: `SCE_SNAP_TARGET_CENTER` does not snap the grabbed geometry to the center of the target, but instead "Snap transforamtion center onto target". - "Select" refers to the condition for an object to be a possible target for snapping. - `SCE_SNAP_MODE_FACE` is renamed to `SCE_SNAP_MODE_FACE_RAYCAST` to better describe its affect and to make way for other face snapping methods (ex: nearest). Refactored related `#define` into `enum`s. In particular, constants relating to... - `ToolSettings.snap_flag` are now in `enum eSnapFlag` - `ToolSettings.snap_mode` are now in `enum eSnapMode` - `ToolSettings.snap_source` (was `snap_target`) are now in `enum eSnapSourceSelect` - `ToolSettings.snap_flag` (`SCE_SNAP_NO_SELF`) and `TransSnap.target_select` are now in `enum eSnapTargetSelect` As the terms became more consistent and the constants were packed together into meaningful enumerations, some of the attribute names seemed ambiguous. For example, it is unclear whether `SnapObjectParams.snap_select` referred to the target or the source. This patch also adds a small amount of clarity. This patch also swaps out generic types (ex: `char`, `short`, `ushort`) and unclear hard coded numbers (ex: `0`) used with snap-related enumerations with the actual `enum`s and values. Note: I did leave myself some comments to follow-up with further refactoring. Specifically, using "target" and "source" consistently will mean the Python API will need to change (ex: `ToolSettings.snap_target` is not `ToolSettings.snap_source`). If the API is going to change, it would be good to make sure that the used terms are descriptive enough. For example, `bpy.ops.transform.translate` uses a `snap` argument to determine if snapping should be enabled while transforming. Perhaps `use_snap` might be an improvement that's more consistent with other conventions. This patch is (mostly) a subset of D14591, as suggested by @mano-wii. Task T69342 proposes to separate the `Absolute Grid Snap` option out from `Increment` snapping method into its own method. Also, there might be reason to create additional snapping methods or options. (Indeed, D14591 heads in this direction). This patch can work along with these suggestions, as this patch is trying to clarify the snapping code and to prompt more work in this area. Reviewed By: mano-wii Differential Revision: https://developer.blender.org/D15037
2022-06-06 10:28:14 -04:00
eSnapMode snapElem;
/** snapping from this point (in global-space). */
float snap_source[3];
/** to this point (in global-space). */
float snap_target[3];
float snap_target_grid[3];
float snapNormal[3];
char snapNodeBorder;
ListBase points;
TransSnapPoint *selectedPoint;
double last;
void (*snap_target_fn)(struct TransInfo *, float *);
void (*snap_source_fn)(struct TransInfo *);
/**
* Get the transform distance between two points (used by Closest snap)
*
* \note Return value can be anything,
* where the smallest absolute value defines what's closest.
*/
float (*snap_mode_distance_fn)(struct TransInfo *t, const float p1[3], const float p2[3]);
void (*snap_mode_apply_fn)(struct TransInfo *, float *);
/**
* Re-usable snap context data.
*/
union {
struct SnapObjectContext *object_context;
struct TransSeqSnapData *seq_context;
};
} TransSnap;
typedef struct TransCon {
/** Description of the constraint for header_print. */
char text[50];
/** Projection constraint matrix (same as #imtx with some axis == 0). */
float pmtx[3][3];
/** Initial mouse value for visual calculation
* the one in #TransInfo is not guarantee to stay the same (Rotates change it). */
int imval[2];
/** Mode flags of the constraint. */
eTConstraint mode;
2013-01-15 13:08:51 +00:00
void (*drawExtra)(struct TransInfo *t);
/* NOTE: if 'tc' is NULL, 'td' must also be NULL.
* For constraints that needs to draw differently from the other
* uses this instead of the generic draw function. */
/** Apply function pointer for linear vectorial transformation
* The last three parameters are pointers to the in/out/printable vectors. */
void (*applyVec)(const struct TransInfo *t,
const struct TransDataContainer *tc,
2021-10-04 13:12:40 +11:00
const struct TransData *td,
const float in[3],
float r_out[3]);
/** Apply function pointer for size transformation. */
void (*applySize)(const struct TransInfo *t,
const struct TransDataContainer *tc,
2021-10-04 13:12:40 +11:00
const struct TransData *td,
float r_smat[3][3]);
/** Apply function pointer for rotation transformation */
void (*applyRot)(const struct TransInfo *t,
const struct TransDataContainer *tc,
2021-10-04 13:12:40 +11:00
const struct TransData *td,
float r_axis[3],
float *r_angle);
} TransCon;
typedef struct MouseInput {
void (*apply)(struct TransInfo *t, struct MouseInput *mi, const double mval[2], float output[3]);
void (*post)(struct TransInfo *t, float values[3]);
/** Initial mouse position. */
int imval[2];
float imval_unproj[3];
float center[2];
float factor;
float precision_factor;
bool precision;
/** Additional data, if needed by the particular function. */
void *data;
/**
2015-11-07 17:31:28 +11:00
* Use virtual cursor, which takes precision into account
* keeping track of the cursors 'virtual' location,
* to avoid jumping values when its toggled.
*
* This works well for scaling drag motion,
2020-09-06 01:45:38 +10:00
* but not for rotating around a point (rotation needs its own custom accumulator)
*/
bool use_virtual_mval;
struct {
double prev[2];
double accum[2];
} virtual_mval;
} MouseInput;
typedef struct TransCustomData {
void *data;
void (*free_cb)(struct TransInfo *,
struct TransDataContainer *tc,
struct TransCustomData *custom_data);
unsigned int use_free : 1;
} TransCustomData;
typedef struct TransCenterData {
float global[3];
unsigned int is_set : 1;
} TransCenterData;
/**
* Rule of thumb for choosing between mode/type:
* - If transform mode uses the data, assign to `mode`
* (typically in transform.c).
* - If conversion uses the data as an extension to the #TransData, assign to `type`
* (typically in transform_conversion.c).
*/
typedef struct TransCustomDataContainer {
/** Owned by the mode (grab, scale, bend... ). */
union {
TransCustomData mode, first_elem;
};
TransCustomData type;
} TransCustomDataContainer;
#define TRANS_CUSTOM_DATA_ELEM_MAX (sizeof(TransCustomDataContainer) / sizeof(TransCustomData))
/**
* Container for Transform Data
*
* Used to implement multi-object modes, so each object can have its
* own data array as well as object matrix, local center etc.
*
* Anything that can't be shared between all objects
* and doesn't make sense to store for every vertex (in the #TransDataContainer.data).
*
* \note at some point this could be used to store non object containers
* although this only makes sense if each container has its own matrices,
* otherwise all elements may as well be stored in one array (#TransDataContainer.data),
* as is already done for curve-objects, f-curves. etc.
*/
typedef struct TransDataContainer {
/** Transformed data (array). */
TransData *data;
/** Transformed data extension (array). */
TransDataExtension *data_ext;
/** Transformed data for 2d (array). */
TransData2D *data_2d;
/** Transformed data for mirror elements (array). */
TransDataMirror *data_mirror;
/** Total number of transformed data, data_ext, data_2d. */
int data_len;
/** Total number of transformed data_mirror. */
int data_mirror_len;
Animation: Add GP layers in regular Dopesheet Grease Pencil animation channels are now also shown in the Dopesheet mode of the Dopesheet editor and in the Timeline. Grease pencil related events are now listened not only by container `SACTCONT_GPENCIL` (Grease Pencil Dopesheet), but also `SACTCONT_DOPESHEET` (main Dopesheet), and `SACTCONT_TIMELINE` (timeline). A new Animation Filter flag was added: `ANIMFILTER_FCURVESONLY`. For now this only filters out Grease Pencil Layer channels. **Implemented:** - Preview range set: now only considers selected Grease Pencil keyframes when `onlySel` parameter is true. Not only this allows the operator to work with grease pencil keyframes in main dopesheet, but it also fixes the operator in the Grease Pencil dopesheet. - Translation: allocation (and freeing) of specific memory for translation of Grease Pencil keyframes. - Copy/Paste: call to both Fcurve and GPencil operators, to allow for mixed selection. Errors are only reported when both the FCurve and GPencil functions fail to paste anything. - Keyframe Type change and Insert Keyframe: removed some code here to unify Grease Pencil dopesheet and main dopesheet code. - Jump, Snap, Mirror, Select all/box/lasso/circle, Select left/right, Clickselect: account for Grease Pencil channels within the channels loop, no need for `ANIMFILTER_FCURVESONLY` there. **Not Implemented:** - Graph-related operators. The filter `ANIMFILTER_FCURVESONLY` is naively added to all graph-related operators, meaning more-or-less all operators that used `ANIMFILTER_CURVE_VISIBLE`. - Select linked: is for F-curves channel only - Select more/less: not yet implemented for grease pencil layers. - Clean Keys, Sample, Extrapolation, Interpolation, Easing, and Handle type change: work on Fcurve-channels only, so the `ANIMFILTER_FCURVESONLY` filter is activated Graying out these operators (when no fcurve keyframe is selected) can be done with custom poll functions BUT may affect performance. This is NOT done in this patch. **Dopesheet Summary Selection:** The main summary of the dopesheet now also takes into account Grease Pencil keyframes, using some nasty copy/pasting of code, as explained [on devtalk](https://devtalk.blender.org/t/gpencil-layers-integration-in-main-dopesheet-selection-issue/24527). It works, but may be improved, providing some deeper changes. Reviewed By: mendio, pepeland, sybren Maniphest Tasks: T97477 Differential Revision: https://developer.blender.org/D15003
2022-06-30 15:16:05 +02:00
/** Total number of transformed gp-frames. */
int data_gpf_len;
struct Object *obedit;
float mat[4][4];
float imat[4][4];
/** 3x3 copies of matrices above. */
float mat3[3][3];
float imat3[3][3];
/** Normalized 'mat3' */
float mat3_unit[3][3];
/** if 't->flag & T_POSE', this denotes pose object */
struct Object *poseobj;
/** Center of transformation (in local-space), Calculated from #TransInfo.center_global. */
float center_local[3];
/**
* Use for cases we care about the active, eg: active vert of active mesh.
* if set this will _always_ be the first item in the array.
*/
bool is_active;
/**
* Store matrix, this avoids having to have duplicate check all over
* Typically: 'obedit->object_to_world' or 'poseobj->object_to_world', but may be used elsewhere
* too.
*/
bool use_local_mat;
/** Mirror option. */
union {
struct {
uint use_mirror_axis_x : 1;
uint use_mirror_axis_y : 1;
uint use_mirror_axis_z : 1;
};
/* For easy checking. */
char use_mirror_axis_any;
};
TransCustomDataContainer custom;
} TransDataContainer;
typedef struct TransInfo {
TransDataContainer *data_container;
int data_container_len;
/** Combine length of all #TransDataContainer.data_len
* Use to check if nothing is selected or if we have a single selection. */
int data_len_all;
/** TODO: It should be a member of #TransDataContainer. */
struct TransConvertTypeInfo *data_type;
/** Current context/options for transform. */
eTContext options;
/** Generic flags for special behaviors. */
eTFlag flag;
/** Special modifiers, by function, not key. */
eTModifier modifiers;
/** Current state (running, canceled. */
eTState state;
/** Redraw flag. */
eRedrawFlag redraw;
/** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */
eTHelpline helpline;
/** Current mode. */
eTfmMode mode;
/** Main transform mode function. */
void (*transform)(struct TransInfo *, const int[2]);
/* Event handler function that determines whether the viewport needs to be redrawn. */
eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *);
/**
* Optional callback to transform a single matrix.
*
* \note used by the gizmo to transform the matrix used to position it.
*/
void (*transform_matrix)(struct TransInfo *t, float mat_xform[4][4]);
/** Constraint Data. */
TransCon con;
/** Snap Data. */
TransSnap tsnap;
/** Numerical input. */
NumInput num;
/** Mouse input. */
MouseInput mouse;
/** proportional circle radius. */
float prop_size;
/** proportional falloff text. */
char proptext[20];
/**
* Spaces using non 1:1 aspect, (uv's, f-curve, movie-clip... etc)
* use for conversion and snapping.
*/
float aspect[3];
/** center of transformation (in global-space) */
float center_global[3];
/** center in screen coordinates. */
float center2d[2];
/** maximum index on the input vector. */
short idx_max;
/** Snapping Gears. */
float snap[2];
/** Spatial snapping gears(even when rotating, scaling... etc). */
float snap_spatial[3];
/**
* Precision factor that is multiplied to snap_spatial when precision
* modifier is enabled for snap to grid or incremental snap.
*/
float snap_spatial_precision;
2020-09-06 01:45:38 +10:00
/** Mouse side of the current frame, 'L', 'R' or 'B' */
char frame_side;
/** copy from #RegionView3D, prevents feedback. */
float viewmat[4][4];
/** and to make sure we don't have to. */
float viewinv[4][4];
/** Access #RegionView3D from other space types. */
float persmat[4][4];
float persinv[4][4];
short persp;
short around;
/** space-type where transforming is. */
char spacetype;
/** Type of active object being edited. */
short obedit_type;
/** translation, to show for widget. */
float vec[3];
/** Rotate/re-scale, to show for widget. */
float mat[3][3];
/** orientation matrix of the current space. */
float spacemtx[3][3];
float spacemtx_inv[3][3];
/** name of the current space, MAX_NAME. */
char spacename[64];
/*************** NEW STUFF *********************/
/** event type used to launch transform. */
short launch_event;
/**
* Is the actual launch event a drag event?
* (`launch_event` is set to the corresponding mouse button then.)
*/
bool is_launch_event_drag;
bool is_orient_default_overwrite;
struct {
short type;
float matrix[3][3];
} orient[3];
eTOType orient_curr;
/**
* All values from `TransInfo.orient[].type` converted into a flag
* to allow quickly checking which orientation types are used.
*/
int orient_type_mask;
short prop_mode;
/** Value taken as input, either through mouse coordinates or entered as a parameter. */
float values[4];
/** Offset applied on top of modal input. */
float values_modal_offset[4];
/** Final value of the transformation (displayed in the redo panel).
* If the operator is executed directly (not modal), this value is usually the
* value of the input parameter, except when a constrain is entered. */
float values_final[4];
/** Cache safe value for constraints that require iteration or are slow to calculate. */
float values_inside_constraints[4];
/* Axis members for modes that use an axis separate from the orientation (rotate & shear). */
/** Primary axis, rotate only uses this. */
int orient_axis;
/** Secondary axis, shear uses this. */
int orient_axis_ortho;
/** remove elements if operator is canceled. */
bool remove_on_cancel;
void *view;
/** Only valid (non null) during an operator called function. */
struct bContext *context;
struct wmMsgBus *mbus;
struct ScrArea *area;
struct ARegion *region;
struct Depsgraph *depsgraph;
struct Scene *scene;
struct ViewLayer *view_layer;
struct ToolSettings *settings;
struct wmTimer *animtimer;
/** Needed so we can perform a look up for header text. */
struct wmKeyMap *keymap;
/** assign from the operator, or can be NULL. */
struct ReportList *reports;
/** current mouse position. */
int mval[2];
/** use for 3d view. */
float zfac;
void *draw_handle_view;
void *draw_handle_pixel;
void *draw_handle_cursor;
/** Currently only used for random curve of proportional editing. */
struct RNG *rng;
/** Typically for mode settings. */
TransCustomDataContainer custom;
/* Needed for sculpt transform. */
const char *undo_name;
} TransInfo;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Public Transform API
* \{ */
/**
* \note caller needs to free `t` on a 0 return
* \warning \a event might be NULL (when tweaking from redo panel)
* \see #saveTransform which writes these values back.
*/
bool initTransform(struct bContext *C,
struct TransInfo *t,
struct wmOperator *op,
const struct wmEvent *event,
int mode);
/**
* \see #initTransform which reads values from the operator.
*/
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
int transformEvent(TransInfo *t, const struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
int transformEnd(struct bContext *C, TransInfo *t);
void setTransformViewMatrices(TransInfo *t);
void setTransformViewAspect(TransInfo *t, float r_aspect[3]);
void convertViewVec(TransInfo *t, float r_vec[3], double dx, double dy);
void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], eV3DProjTest flag);
void projectIntView(TransInfo *t, const float vec[3], int adr[2]);
void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], eV3DProjTest flag);
void projectFloatView(TransInfo *t, const float vec[3], float adr[2]);
void applyAspectRatio(TransInfo *t, float vec[2]);
void removeAspectRatio(TransInfo *t, float vec[2]);
/**
* Called in transform_ops.c, on each regeneration of key-maps.
*/
struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf);
2.5 Modal keymaps. I've tried to make it as simple as possible, yet still using sufficient facilities to enable self-documenting UIs, saving/reading in files, and proper Python support. The simplicity is: the 'modal keymap' just checks an event, uses event matching similarly to other keymap matching, and if there's a match it changes the event type, and sets the event value to what the modal keymap has defined. The event values are being defined using EnumPropertyItem structs, so the UI will be able to show all options in self-documenting way. This system also allows to still handle hardcoded own events. Tech doc: 1) define keymap - Create map with unique name, WM_modalkeymap_add() - Give map property definitions (EnumPropertyItem *) This only for UI, so user can get information on available options 2) items - WM_modalkeymap_add_item(): give it an enum value for events 3) activate - In keymap definition code, assign the modal keymap to operatortype WM_modalkeymap_assign() 4) event manager - The event handler will check for modal keymap, if so: - If the modal map has a match: - Sets event->type to EVT_MODAL_MAP - Sets event->val to the enum value 5) modal handler - If event type is EVT_MODAL_MAP: - Check event->val, handle it - Other events can just be handled still Two examples added in the code: editors/transform/transform.c: transform_modal_keymap() editors/screen/screen_ops.c: keymap_modal_set() Also: to support 'key release' the define KM_RELEASE now is officially used in event manager, this is not '0', so don't check key events with the old convention if(event->val) but use if(event->val==KM_PRESS)
2009-07-21 11:03:07 +00:00
/**
* Transform a single matrix using the current `t->final_values`.
*/
bool transform_apply_matrix(TransInfo *t, float mat[4][4]);
void transform_final_value_get(const TransInfo *t, float *value, int value_num);
/** \} */
/* -------------------------------------------------------------------- */
/** \name TransData Creation and General Handling
* \{ */
bool transdata_check_local_islands(TransInfo *t, short around);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Mouse Input
* \{ */
typedef enum {
INPUT_NONE,
INPUT_VECTOR,
INPUT_SPRING,
INPUT_SPRING_FLIP,
INPUT_SPRING_DELTA,
INPUT_ANGLE,
INPUT_ANGLE_SPRING,
INPUT_TRACKBALL,
INPUT_HORIZONTAL_RATIO,
INPUT_HORIZONTAL_ABSOLUTE,
INPUT_VERTICAL_RATIO,
INPUT_VERTICAL_ABSOLUTE,
INPUT_CUSTOM_RATIO,
INPUT_CUSTOM_RATIO_FLIP,
} MouseInputMode;
void initMouseInput(
TransInfo *t, MouseInput *mi, const float center[2], const int mval[2], bool precision);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
void applyMouseInput(struct TransInfo *t,
struct MouseInput *mi,
const int mval[2],
float output[3]);
void transform_input_update(TransInfo *t, const float fac);
void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]);
void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float values[3]));
/** \} */
/* -------------------------------------------------------------------- */
/** \name Generics
* \{ */
/**
* Setup internal data, mouse, vectors
*
* \note \a op and \a event can be NULL
*
* \see #saveTransform does the reverse.
*/
void initTransInfo(struct bContext *C,
TransInfo *t,
struct wmOperator *op,
const struct wmEvent *event);
/**
* Needed for mode switching.
*/
void freeTransCustomDataForMode(TransInfo *t);
/**
* Here I would suggest only #TransInfo related issues, like free data & reset vars. Not redraws.
*/
2013-04-18 01:52:38 +00:00
void postTrans(struct bContext *C, TransInfo *t);
/**
* Free data before switching to another mode.
*/
void resetTransModal(TransInfo *t);
void resetTransRestrictions(TransInfo *t);
/* DRAWLINE options flags */
#define DRAWLIGHT 1
void applyTransObjects(TransInfo *t);
void restoreTransObjects(TransInfo *t);
void calculateCenter2D(TransInfo *t);
void calculateCenterLocal(TransInfo *t, const float center_global[3]);
void calculateCenter(TransInfo *t);
/**
* Called every time the view changes due to navigation.
* Adjusts the mouse position relative to the object.
*/
void tranformViewUpdate(TransInfo *t);
/* API functions for getting center points */
void calculateCenterBound(TransInfo *t, float r_center[3]);
void calculateCenterMedian(TransInfo *t, float r_center[3]);
void calculateCenterCursor(TransInfo *t, float r_center[3]);
void calculateCenterCursor2D(TransInfo *t, float r_center[2]);
void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2]);
/**
* \param select_only: only get active center from data being transformed.
*/
bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]);
void calculatePropRatio(TransInfo *t);
/**
* Rotate an element, low level code, ignore protected channels.
* (use for objects or pose-bones)
* Similar to #ElementRotation.
*/
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
struct Object *transform_object_deform_pose_armature_get(const TransInfo *t, struct Object *ob);
void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data);
2018-05-25 22:24:24 +05:30
/* TODO: move to: `transform_query.c`. */
bool checkUseAxisMatrix(TransInfo *t);
#define TRANSFORM_SNAP_MAX_PX 100.0f
#define TRANSFORM_DIST_INVALID -FLT_MAX
/* Temp macros. */
#define TRANS_DATA_CONTAINER_FIRST_OK(t) (&(t)->data_container[0])
/* For cases we _know_ there is only one handle. */
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t) \
(BLI_assert((t)->data_container_len == 1), (&(t)->data_container[0]))
#define FOREACH_TRANS_DATA_CONTAINER(t, th) \
for (TransDataContainer *tc = (t)->data_container, \
*tc_end = (t)->data_container + (t)->data_container_len; \
th != tc_end; \
th++)
#define FOREACH_TRANS_DATA_CONTAINER_INDEX(t, th, i) \
for (TransDataContainer *tc = ((i = 0), (t)->data_container), \
*tc_end = (t)->data_container + (t)->data_container_len; \
th != tc_end; \
th++, i++)
/** \} */
#ifdef __cplusplus
}
#endif