Blender V4.5
transform_snap_object_armature.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "BLI_listbase.h"
12
13#include "BKE_armature.hh"
14
15#include "ED_armature.hh"
17
18#include "ANIM_armature.hh"
19
21
22namespace blender::ed::transform {
23
25 const Object *ob_eval,
26 const float4x4 &obmat,
27 bool is_object_active)
28{
30
32 /* Currently only edge and vert. */
33 return retval;
34 }
35
36 bArmature *arm = static_cast<bArmature *>(ob_eval->data);
37
38 SnapData nearest2d(sctx, obmat);
39
40 nearest2d.clip_planes_enable(sctx, ob_eval);
41
42 const float *head_vec = nullptr, *tail_vec = nullptr;
43
44 const bool is_editmode = arm->edbo != nullptr;
45 const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
46 const bool skip_selected = (is_editmode || is_posemode) &&
49
50 if (arm->edbo) {
51 LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) {
53 const bool is_selected = (eBone->flag & (BONE_ROOTSEL | BONE_TIPSEL)) != 0;
54 if (is_selected && skip_selected) {
55 continue;
56 }
57
58 if (nearest2d.snap_edge(eBone->head, eBone->tail)) {
59 head_vec = eBone->head;
60 tail_vec = eBone->tail;
61 }
62 }
63 }
64 }
65 else if (ob_eval->pose && ob_eval->pose->chanbase.first) {
66 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_eval->pose->chanbase) {
67 Bone *bone = pchan->bone;
68 if (!bone || !blender::animrig::bone_is_visible_pchan(arm, pchan)) {
69 /* Skip hidden bones. */
70 continue;
71 }
72
73 const bool is_selected = (bone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0;
74 if (is_selected && skip_selected) {
75 continue;
76 }
77
78 if (nearest2d.snap_edge(pchan->pose_head, pchan->pose_tail)) {
79 head_vec = pchan->pose_head;
80 tail_vec = pchan->pose_tail;
81 }
82 }
83 }
84
85 if (nearest2d.nearest_point.index != -2) {
86 retval = sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE;
87 if (retval == SCE_SNAP_TO_NONE) {
88 nearest2d.nearest_point.index = -2;
89 }
90
92 float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
93 nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
94 if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
96 }
97 else if (retval) {
98 nearest2d.nearest_point.dist_sq = dist_px_sq_edge;
99 }
100 }
101 }
102
103 if (retval) {
104 nearest2d.register_result(sctx, ob_eval, &arm->id);
105 }
106 return retval;
107}
108
109} // namespace blender::ed::transform
Functions to deal with Armatures.
#define LISTBASE_FOREACH(type, var, list)
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_TIPSEL
@ OB_MODE_POSE
@ SCE_SNAP_TARGET_NOT_SELECTED
@ SCE_SNAP_TO_EDGE
@ SCE_SNAP_TO_FACE
@ SCE_SNAP_TO_EDGE_ENDPOINT
@ SCE_SNAP_TO_NONE
void clip_planes_enable(SnapObjectContext *sctx, const Object *ob_eval, bool skip_occlusion_plane=false)
bool snap_edge(const float3 &va, const float3 &vb, int edge_index=-1)
bool snap_point(const float3 &co, int index=-1)
static void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const float4x4 &obmat, BVHTreeNearest *r_nearest)
bool bone_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
bool bone_is_visible_pchan(const bArmature *armature, const bPoseChannel *pchan)
eSnapMode snapArmature(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat, bool is_object_active)
MatBase< float, 4, 4 > float4x4
void * first
struct bPose * pose
ListBase * edbo
ListBase chanbase
struct blender::ed::transform::SnapObjectContext::@023363036215051051114130033143317235151004224004 runtime
struct blender::ed::transform::SnapObjectContext::@252151137362251112213357331153135115250002101241 ret