Blender V4.3
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
9#include "BLI_math_matrix.hh"
10
11#include "BKE_armature.hh"
12#include "BKE_bvhutils.hh"
13#include "DNA_armature_types.h"
14
16
18
20
22
24 const Object *ob_eval,
25 const float4x4 &obmat,
26 bool is_object_active)
27{
29
31 /* Currently only edge and vert. */
32 return retval;
33 }
34
35 bArmature *arm = static_cast<bArmature *>(ob_eval->data);
36
37 SnapData nearest2d(sctx, obmat);
38
39 const bool is_editmode = arm->edbo != nullptr;
40
41 if (is_editmode == false) {
42 const std::optional<blender::Bounds<blender::float3>> bounds = BKE_armature_min_max(ob_eval);
43 if (bounds && !nearest2d.snap_boundbox(bounds->min, bounds->max)) {
44 return retval;
45 }
46 }
47
48 nearest2d.clip_planes_enable(sctx, ob_eval);
49
50 const float *head_vec = nullptr, *tail_vec = nullptr;
51
52 const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
53 const bool skip_selected = (is_editmode || is_posemode) &&
56
57 if (arm->edbo) {
58 LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) {
59 if (ANIM_bonecoll_is_visible_editbone(arm, eBone)) {
60 if (eBone->flag & BONE_HIDDEN_A) {
61 /* Skip hidden bones. */
62 continue;
63 }
64
65 const bool is_selected = (eBone->flag & (BONE_ROOTSEL | BONE_TIPSEL)) != 0;
66 if (is_selected && skip_selected) {
67 continue;
68 }
69
70 if (nearest2d.snap_edge(eBone->head, eBone->tail)) {
71 head_vec = eBone->head;
72 tail_vec = eBone->tail;
73 }
74 }
75 }
76 }
77 else if (ob_eval->pose && ob_eval->pose->chanbase.first) {
78 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_eval->pose->chanbase) {
79 Bone *bone = pchan->bone;
80 if (!bone || (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
81 /* Skip hidden bones. */
82 continue;
83 }
84
85 const bool is_selected = (bone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0;
86 if (is_selected && skip_selected) {
87 continue;
88 }
89
90 if (nearest2d.snap_edge(pchan->pose_head, pchan->pose_tail)) {
91 head_vec = pchan->pose_head;
92 tail_vec = pchan->pose_tail;
93 }
94 }
95 }
96
97 if (nearest2d.nearest_point.index != -2) {
98 retval = sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE;
99 if (retval == SCE_SNAP_TO_NONE) {
100 nearest2d.nearest_point.index = -2;
101 }
102
104 float dist_px_sq_edge = nearest2d.nearest_point.dist_sq;
105 nearest2d.nearest_point.dist_sq = sctx->ret.dist_px_sq;
106 if (nearest2d.snap_point(head_vec) || nearest2d.snap_point(tail_vec)) {
108 }
109 else if (retval) {
110 nearest2d.nearest_point.dist_sq = dist_px_sq_edge;
111 }
112 }
113 }
114
115 if (retval) {
116 nearest2d.register_result(sctx, ob_eval, &arm->id);
117 }
118 return retval;
119}
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
bool ANIM_bonecoll_is_visible_editbone(const bArmature *armature, const EditBone *ebone)
std::optional< blender::Bounds< blender::float3 > > BKE_armature_min_max(const Object *ob)
Definition armature.cc:3024
#define LISTBASE_FOREACH(type, var, list)
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_HIDDEN_A
@ BONE_HIDDEN_P
@ BONE_TIPSEL
@ BONE_HIDDEN_PG
@ 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
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
void clip_planes_enable(SnapObjectContext *sctx, const Object *ob_eval, bool skip_occlusion_plane=false)
bool snap_point(const blender::float3 &co, int index=-1)
static void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval, const blender::float4x4 &obmat, BVHTreeNearest *r_nearest)
BVHTreeNearest nearest_point
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max)
bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index=-1)
void * first
struct bPose * pose
struct SnapObjectContext::@590 ret
struct SnapObjectContext::@589 runtime
ListBase * edbo
ListBase chanbase
eSnapMode snapArmature(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat, bool is_object_active)